feat(gitea): generalise mirror creation
Some checks failed
Security Scan / security (push) Failing after 10s
Test / test (push) Successful in 2m20s

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-01 07:15:44 +00:00
parent f2c9cb39d0
commit 64042ac8a6
2 changed files with 48 additions and 7 deletions

View file

@ -123,16 +123,14 @@ func (c *Client) GetRepo(owner, name string) (*gitea.Repository, error) {
return repo, nil
}
// CreateMirror creates a mirror repository on Gitea from a GitHub clone URL.
// This uses the Gitea migration API to set up a pull mirror.
// If authToken is provided, it is used to authenticate against the source (e.g. for private GitHub repos).
// Usage: CreateMirror(...)
func (c *Client) CreateMirror(owner, name, cloneURL, authToken string) (*gitea.Repository, error) {
// CreateMirrorFromService creates a mirror repository from an arbitrary git service.
// Usage: CreateMirrorFromService(...)
func (c *Client) CreateMirrorFromService(owner, name, cloneURL string, service gitea.GitServiceType, authToken string) (*gitea.Repository, error) {
opts := gitea.MigrateRepoOption{
RepoName: name,
RepoOwner: owner,
CloneAddr: cloneURL,
Service: gitea.GitServiceGithub,
Service: service,
Mirror: true,
Description: "Mirror of " + cloneURL,
}
@ -143,12 +141,20 @@ func (c *Client) CreateMirror(owner, name, cloneURL, authToken string) (*gitea.R
repo, _, err := c.api.MigrateRepo(opts)
if err != nil {
return nil, log.E("gitea.CreateMirror", "failed to create mirror", err)
return nil, log.E("gitea.CreateMirrorFromService", "failed to create mirror", err)
}
return repo, nil
}
// CreateMirror creates a mirror repository on Gitea from a GitHub clone URL.
// This uses the Gitea migration API to set up a pull mirror.
// If authToken is provided, it is used to authenticate against the source (e.g. for private GitHub repos).
// Usage: CreateMirror(...)
func (c *Client) CreateMirror(owner, name, cloneURL, authToken string) (*gitea.Repository, error) {
return c.CreateMirrorFromService(owner, name, cloneURL, gitea.GitServiceGithub, authToken)
}
// DeleteRepo deletes a repository from Gitea.
// Usage: DeleteRepo(...)
func (c *Client) DeleteRepo(owner, name string) error {

View file

@ -3,6 +3,9 @@
package gitea
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
giteaSDK "code.gitea.io/sdk/gitea"
@ -97,6 +100,38 @@ func TestClient_CreateMirror_Bad_ServerError_Good(t *testing.T) {
assert.Contains(t, err.Error(), "failed to create mirror")
}
func TestClient_CreateMirrorFromService_Good_Gitea_Good(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/api/v1/version", func(w http.ResponseWriter, r *http.Request) {
jsonResponse(w, map[string]string{"version": "1.21.0"})
})
mux.HandleFunc("/api/v1/repos/migrate", func(w http.ResponseWriter, r *http.Request) {
var opts map[string]any
require.NoError(t, json.NewDecoder(r.Body).Decode(&opts))
assert.Equal(t, "gitea", opts["service"])
assert.Equal(t, true, opts["mirror"])
assert.Equal(t, "https://forge.example.org/core/go-scm.git", opts["clone_addr"])
assert.Equal(t, "secret-token", opts["auth_token"])
w.WriteHeader(http.StatusCreated)
jsonResponse(w, map[string]any{
"id": 40, "name": "public-mirror", "full_name": "test-org/public-mirror",
"owner": map[string]any{"login": "test-org"},
"mirror": true,
})
})
srv := httptest.NewServer(mux)
defer srv.Close()
client, err := New(srv.URL, "test-token")
require.NoError(t, err)
repo, err := client.CreateMirrorFromService("test-org", "public-mirror", "https://forge.example.org/core/go-scm.git", giteaSDK.GitServiceGitea, "secret-token")
require.NoError(t, err)
require.NotNil(t, repo)
assert.Equal(t, "public-mirror", repo.Name)
}
func TestClient_DeleteRepo_Good(t *testing.T) {
client, srv := newTestClient(t)
defer srv.Close()