120 lines
4.9 KiB
Markdown
120 lines
4.9 KiB
Markdown
---
|
|
name: gitea-transfer
|
|
description: Guide for transferring repositories from GitHub to self-hosted Gitea, including remotes, branches, PR migration, Gitea Actions porting, runner images, and cutover verification.
|
|
---
|
|
|
|
# Gitea Transfer
|
|
|
|
Use when moving a repository from GitHub to self-hosted Gitea, converting a Gitea mirror into the canonical source, migrating active branches/PRs, or porting GitHub Actions to Gitea Actions.
|
|
|
|
## Principles
|
|
|
|
- Treat Gitea as canonical only after verifying the repo is no longer a mirror and the default branch exists there.
|
|
- Keep GitHub as a recovery/reference remote unless the user explicitly asks to remove it.
|
|
- Prefer `tea` or the Gitea API for Gitea operations; do not use `gh` for Gitea work.
|
|
- Never paste, log, commit, or store registration tokens, API tokens, deploy keys, or package credentials.
|
|
- Do not merge PRs, force-push, or rewrite shared branches unless the user explicitly approves.
|
|
- Verify each cutover step with `git`, `tea`, or API output before moving on.
|
|
|
|
## Preflight
|
|
|
|
```bash
|
|
git status --short --branch
|
|
git remote -v
|
|
git branch --show-current
|
|
tea login list
|
|
tea repo ls
|
|
tea api repos/{owner}/{repo}
|
|
```
|
|
|
|
If Gitea sits behind a reverse proxy, ensure dot directories such as `.gitea` and `.github` are not blocked by generic hidden-file rules.
|
|
|
|
## Mirror To Source
|
|
|
|
If the Gitea repo was imported as a mirror, convert it to a normal source repo in the UI or API, then verify `mirror` is `false`:
|
|
|
|
```bash
|
|
tea api repos/{owner}/{repo}
|
|
```
|
|
|
|
Enable repository features as needed, using fields supported by the installed Gitea version:
|
|
|
|
```bash
|
|
tea api --method PATCH repos/{owner}/{repo} \
|
|
--field has_pull_requests=true \
|
|
--field has_actions=true
|
|
```
|
|
|
|
## Remote Cutover
|
|
|
|
Keep GitHub as fallback and make Gitea `origin`:
|
|
|
|
```bash
|
|
git remote rename origin github
|
|
git remote add origin ssh://git@git.example.com:30009/{owner}/{repo}.git
|
|
git remote -v
|
|
git fetch github --prune
|
|
git push origin {default-branch}:{default-branch}
|
|
tea api repos/{owner}/{repo}/branches/{default-branch}
|
|
```
|
|
|
|
If `origin` already exists, adjust non-destructively with `git remote set-url origin ...` and add `github` only if absent.
|
|
|
|
## Branches And PRs
|
|
|
|
- Push only active work branches, not every stale remote branch by default.
|
|
- For each open GitHub PR, recreate enough context in Gitea: title, body, base, head, draft/WIP state, and original GitHub PR link.
|
|
- Verify each recreated PR is open, points at the expected branches, and has the expected conflict state.
|
|
|
|
```bash
|
|
git branch -r
|
|
git push origin github/{branch-name}:refs/heads/{branch-name}
|
|
tea pr create --repo {owner}/{repo} --base {base} --head {head} --title "{title}" --description "{body}"
|
|
tea pr {index} --repo {owner}/{repo}
|
|
```
|
|
|
|
## Actions Porting
|
|
|
|
Gitea Actions workflows live in `.gitea/workflows/`. Port incrementally: tests first, then build/deploy. Keep syntax close to GitHub Actions where Gitea supports it, validate YAML, and use small commits so failures isolate one change.
|
|
|
|
Common changes:
|
|
|
|
- Replace GitHub-only secrets with neutral Gitea secrets such as `REGISTRY_USERNAME`, `REGISTRY_TOKEN`, `REVIEW_BOT_TOKEN`, and `OPENCODE_GO_TOKEN`.
|
|
- Avoid secret names beginning with `GITEA_` or `GITHUB_`.
|
|
- Remove GitHub Packages auth unless it is still intentionally used.
|
|
- Use service hostnames such as `postgres`, not `127.0.0.1`, for service containers.
|
|
- Add explicit service readiness checks.
|
|
- Do not rely on `permissions:` for security-sensitive sandboxing; some Gitea versions ignore it.
|
|
|
|
See [runner images](references/runner-images.md), [OpenCode PR review](references/opencode-review.md), and [deploy porting](references/deploy-porting.md) for deeper CI guidance.
|
|
|
|
## Package Registry Cutover
|
|
|
|
Identify GitHub-specific package auth before enabling Gitea CI: npm/Bun scopes, Composer auth, workflow-written `.npmrc`, private package tarballs in lockfiles, and deploy/package secrets.
|
|
|
|
Choose deliberately: remove dependency, mirror package to Gitea Packages, or keep GitHub Packages temporarily with explicit Gitea secrets. Do not leave workflows requiring missing secrets.
|
|
|
|
## Verification Checklist
|
|
|
|
- Gitea repo is not a mirror.
|
|
- `origin` points to Gitea; `github` remote exists if retained.
|
|
- Default branch and active PR branches are pushed.
|
|
- Open PRs are recreated.
|
|
- Pull requests and Actions are enabled.
|
|
- Test workflow passes on PR and default branch.
|
|
- Deploy workflow succeeds or skips cleanly with a clear missing-secrets message.
|
|
- Runner is online with generic labels and job containers pull expected images.
|
|
- Optional `/review` workflow posts or updates the aggregate review comment.
|
|
- Local default branch is synchronized with Gitea.
|
|
|
|
```bash
|
|
git pull --rebase origin {default-branch}
|
|
git push origin {default-branch}
|
|
git rev-list --left-right --count origin/{default-branch}...{default-branch}
|
|
git status --short --branch
|
|
```
|
|
|
|
Expected commit comparison after sync: `0 0`.
|
|
|
|
See [failure modes](references/failure-modes.md) when cutover or CI fails.
|