check in the script

This commit is contained in:
eyedeekay
2025-04-20 21:44:02 -04:00
parent af02e61b3b
commit 4900c0e04f
4 changed files with 90 additions and 56 deletions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2025 idk
Copyright (c) 2025 idk, go-i2p
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,2 +1,73 @@
# gitlab-to-gitea
A port of the old gitlab-to-gitea migration script from python to Go with feature improvements
Go-based tool for migrating GitLab repositories, users, groups, issues and related data to Gitea instances.
## Core Functionality
- Migrates users, groups, and their relationships from GitLab to Gitea
- Transfers repositories with labels, milestones, issues, and comments
- Preserves user relationships (collaborators) and SSH keys
- Supports resumable migrations through state tracking
- Handles username normalization and entity mapping between platforms
## Installation
1. Ensure Go 1.24+ is installed
2. Clone the repository:
```bash
git clone https://github.com/go-i2p/gitlab-to-gitea.git
cd gitlab-to-gitea
```
3. Install dependencies:
```bash
go mod download
```
4. Build the executable:
```bash
go build -o gitlab-to-gitea ./cmd/migrate/
```
## Configuration
1. Copy the example environment file:
```bash
cp _env.example .env
```
2. Edit `.env` with your GitLab and Gitea details:
```
GITLAB_URL=https://your-gitlab-instance.com
GITLAB_TOKEN=your-gitlab-token
GITEA_URL=https://your-gitea-instance.com
GITEA_TOKEN=your-gitea-token
```
## Usage
Execute the migration tool after configuration:
```bash
./gitlab-to-gitea
```
The tool will:
1. Connect to both GitLab and Gitea instances
2. Migrate users and groups first
3. Migrate projects with all associated data
4. Track progress in `migration_state.json` (resumable if interrupted)
## Key Dependencies
- github.com/xanzy/go-gitlab: GitLab API client
- github.com/joho/godotenv: Environment variable handling
- github.com/go-sql-driver/mysql: Optional database connectivity for action import
## Optional Features
For commit action import to Gitea's activity timeline:
1. Configure database details in `.env`
2. Generate a commit log file
3. Use the database import functionality in the `gitea` package
## License
MIT License

View File

@ -10,8 +10,11 @@ import (
"io"
"net/http"
"net/url"
"regexp"
"strings"
"time"
"github.com/go-i2p/gitlab-to-gitea/utils"
)
// Client handles communication with the Gitea API
@ -27,66 +30,26 @@ type VersionResponse struct {
}
// FetchCSRFToken retrieves a CSRF token from Gitea
func (c *Client) FetchCSRFToken() error {
// Create a request to the Gitea login page to get a CSRF token
u, err := c.baseURL.Parse("/")
// I don't think it works.
func (c *Client) FetchCSRFToken() (string, error) {
resp, err := c.request("GET", "/user/login", nil, nil)
if err != nil {
return fmt.Errorf("invalid URL: %w", err)
}
// Use a normal HTTP client without our custom transport for this request
// to avoid circular dependency (we need the token for the transport)
httpClient := &http.Client{}
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}
resp, err := httpClient.Do(req)
if err != nil {
return fmt.Errorf("request failed: %w", err)
return "", fmt.Errorf("failed to fetch login page: %w", err)
}
defer resp.Body.Close()
// Extract CSRF token from Set-Cookie header
for _, cookie := range resp.Cookies() {
if cookie.Name == "_csrf" {
// Update the transport with the CSRF token
transport, ok := c.httpClient.Transport.(*CSRFTokenTransport)
if ok {
transport.CSRFToken = cookie.Value
return nil
}
return fmt.Errorf("transport is not a CSRFTokenTransport")
}
}
// If we couldn't find a CSRF token, try to extract it from the response body
bodyBytes, err := io.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %w", err)
return "", fmt.Errorf("failed to read response body: %w", err)
}
// Look for <meta name="_csrf" content="..." /> in the HTML
body := string(bodyBytes)
csrfMetaStart := strings.Index(body, `<meta name="_csrf" content="`)
if csrfMetaStart != -1 {
csrfMetaStart += len(`<meta name="_csrf" content="`)
csrfMetaEnd := strings.Index(body[csrfMetaStart:], `"`)
if csrfMetaEnd != -1 {
csrfToken := body[csrfMetaStart : csrfMetaStart+csrfMetaEnd]
transport, ok := c.httpClient.Transport.(*CSRFTokenTransport)
if ok {
transport.CSRFToken = csrfToken
return nil
}
return fmt.Errorf("transport is not a CSRFTokenTransport")
}
// Use a single approach targeting Gitea's current HTML structure
metaTagRegex := regexp.MustCompile(`<meta name="_csrf" content="([^"]+)"`)
if matches := metaTagRegex.FindSubmatch(body); len(matches) > 1 {
return string(matches[1]), nil
}
return fmt.Errorf("could not find CSRF token in response")
return "", fmt.Errorf("could not find CSRF token in login page")
}
func NewClient(baseURL, token string) (*Client, error) {
@ -178,7 +141,7 @@ func (c *Client) request(method, path string, data, result interface{}) (*http.R
}
// Debug output to see what endpoint is being called
fmt.Printf("Making %s request to: %s%s\n", method, c.baseURL.String(), path)
utils.PrintInfo(fmt.Sprintf("Making %s request to: %s%s\n", method, c.baseURL.String(), path))
u, err := c.baseURL.Parse(path)
if err != nil {

View File

@ -59,13 +59,13 @@ func (m *Manager) ImportUser(user *gitlab.User, notify bool) error {
}
// Debug what endpoint we're calling and with what method
fmt.Printf("Attempting to create user via: POST /admin/users\n")
utils.PrintInfo("Attempting to create user via: POST /admin/users\n")
var result map[string]interface{}
err := m.giteaClient.Post("/admin/users", userReq, &result)
if err != nil {
// Try the alternative user creation endpoint if the first one failed
fmt.Printf("First attempt failed, trying alternative endpoint\n")
utils.PrintInfo("First attempt failed, trying alternative endpoint\n")
err = m.giteaClient.Post("/api/v1/admin/users", userReq, &result)
if err != nil {
return fmt.Errorf("failed to create user %s: %w", user.Username, err)