Skip to content

Migrate from GitHub

Codebahn runs most GitHub Actions workflows, supports the same SSH keys, and uses standard Git. Import carries code, issues, pull requests, labels, milestones, and releases in one pass.

There are two ways to import: connect the Codebahn GitHub App (no tokens to copy), or paste a personal access token. Both produce the same result.

The fastest path. Codebahn connects to your GitHub account directly, lists your repos, and lets you pick which ones to import.

  1. Sign in to Codebahn
  2. Click + > Import repository > GitHub
  3. On the Connect GitHub tab, click Connect GitHub account
  4. Authorize the Codebahn app on GitHub. If this is your first time, install it on your account or organization and grant access to the repos you want to import
  5. Back on Codebahn, select the repos to import. Use the filter to narrow a long list
  6. Choose which metadata to bring along: issues, pull requests, labels, milestones, releases
  7. Choose an owner (your account or an organization)
  8. Click Import selected

The connection lasts 30 minutes. A countdown shows the remaining time. When it expires, click Connect GitHub account again to reconnect. Reconnecting is instant if the app is still installed.

Codebahn does not keep access to your GitHub after the connection expires. No tokens or credentials are stored.

If you prefer not to install the app, or need to import from a GitHub account where you cannot install apps, use a token.

A fine-grained token scoped to specific repos is the safest option.

  1. Open GitHub > Settings > Developer settings > Personal access tokens > Fine-grained tokens
  2. Click Generate new token
  3. Under Resource owner, select the GitHub org that owns the repos
  4. Set a short expiration. Seven days is enough
  5. Under Repository access, select Only select repositories and pick the ones you are migrating
  6. Under Permissions, grant what you need:
What you are importing Required permission
Code Contents: Read-only
Issues, labels, milestones Issues: Read-only
Pull requests Pull requests: Read-only
Releases Contents: Read-only

Fine-grained tokens always require Metadata: Read-only. It is added automatically when you select any other permission.

  1. Click Generate token and copy the value

If your org enforces token approval, an owner must approve it under Settings > Personal access tokens > Pending requests before it works.

  1. Sign in to Codebahn
  2. Click + > Import repository > GitHub
  3. Switch to the Personal access token tab
  4. In Clone URL, paste the HTTPS URL of your repo, e.g. https://github.com/your-org/your-repo.git. SSH URLs are converted to HTTPS automatically
  5. Paste your token in the Access token field
  6. Leave This repository will be a mirror unchecked for a full one-time import
  7. Select what to import: issues, pull requests, labels, milestones, releases
  8. Choose your org as the owner and confirm the repo name
  9. Click Migrate repository

After it completes, the Codebahn repo is independent from GitHub.

Point your local clone at Codebahn:

Terminal window
git remote set-url origin git@codebahn.net:your-org/your-repo.git

Add your SSH key first under Settings > SSH / GPG Keys if you haven’t.

Your .github/workflows/ files run on Codebahn. Actions resolve from GitHub by default, so uses: actions/checkout@v7 works as-is.

runs-on: ubuntu-latest routes to the hosted EU runners. You can also use codebahn-small, codebahn-medium, or codebahn-large for specific runner sizes. A different label (e.g. ubuntu-22.04) needs updating.

Codebahn’s default runner (ubuntu-latest) has 3 GB of usable memory, less than GitHub’s 8 GB (for private repos). Most workflows run fine. If a build that worked on GitHub is killed without a clear error, it likely hit the memory limit. Switch to codebahn-medium for 7 GB (2x cost factor).

What won’t run: GitHub-specific actions that call the GitHub API, macOS and Windows jobs, OIDC federation, code scanning, and GitHub Pages. See CI compatibility for the full list. GitLab-style .gitlab-ci.yml is also ignored; rewrite it to Actions.

Codebahn also reads workflows from .codebahn/workflows/, .forgejo/workflows/, and .gitea/workflows/. See workflow directories for precedence.

Pushing a new commit to a branch with a running workflow cancels the in-progress run. GitHub does not do this by default. To let all runs finish, add:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

GitHub’s Dependabot does not run on Codebahn. Your .github/dependabot.yml file is ignored.

Use Renovate instead. It runs as a scheduled CI workflow on Codebahn’s runners and opens pull requests the same way Dependabot does. The guide includes a field-by-field mapping from dependabot.yml to renovate.json.

The GitHub App flow supports bulk import: select multiple repos and import them all at once (up to 100 per batch).

With the token flow, import one repo at a time, or script it via the migration API.

If the migration form won’t fit your case, clone and push by hand:

Terminal window
git clone --bare https://github.com/your-org/your-repo.git
cd your-repo.git
git push --mirror git@codebahn.net:your-org/your-repo.git

This moves code and branches only. Issues, pull requests, and releases are not included.

“Only http(s):// or git:// locations can be used” You pasted an SSH URL. Use the HTTPS URL: https://github.com/your-org/your-repo.git

401 or “Authentication failed” The token is expired, revoked, or missing permissions. Generate a new one with at least Contents: Read-only.

404 or “Not found” The repo is private and the token lacks access, or an org owner hasn’t approved the token yet.

Issues or pull requests missing after import The token needs Issues: Read-only and Pull requests: Read-only. Re-run with a new token.

“Could not list repositories. The installation may have been removed.” The Codebahn app was uninstalled from your GitHub account. Click Connect GitHub account to re-install it.

GitHub App connection expired Connections last 30 minutes. Click Connect GitHub account to reconnect. Reconnecting is instant if the app is still installed.

What you import, you can take back out. Org Settings > Export produces a tar.gz with every repo’s full Git history plus issues, pull requests, labels, milestones, and releases. Portable by design.