| name | migrate-to-teamcity |
| version | 0.3.0 |
| description | Migrating CI/CD pipelines to TeamCity. Use when the user wants to migrate, convert, or switch to TeamCity from GitHub Actions (.github/workflows/) or Bamboo (bamboo-specs/*.yml), even if they only say "move our CI". Other CI systems (GitLab, Jenkins, CircleCI, Azure DevOps, Travis, Bitbucket) are not supported yet. |
Migrate to TeamCity
Quick Start
teamcity migrate
teamcity migrate --dry-run --json
teamcity pipeline validate f.tc.yml
teamcity project vcs create --url <repo-url> --auth anonymous -p ProjectId
teamcity pipeline create name -p ProjectId -f f.tc.yml --vcs-root <VcsRootId>
teamcity run start PipelineId --watch
Run teamcity migrate from the repo root -- detection scans .github/workflows/ and bamboo-specs/ relative to the current directory.
Reading the report
- Needs review -- problems inside the generated YAML: TODO stubs, dropped steps, reusable-workflow placeholders. Fix these in the file before creating the pipeline.
- Manual setup needed -- work the converter cannot do. Sort each item onto one of two sides: YAML edits (secrets, matrix expansion, expression
runs-on, container:/services:) go before pipeline create; server-side configuration (connections, if:-derived branch filters, triggers, notifications) comes after. The checklist below orders them.
- Exit code 1 means at least one source failed to convert or one generated file failed schema validation -- files that converted cleanly are still written. Read the per-file ✓/⚠/✗ lines instead of treating exit 1 as total failure.
--json prints {"sources": [...], "results": [...]} to stdout; each result carries outputFile, yaml, needsReview, manualSetup, and validationError.
Gotchas
- Always
type: script for ./gradlew and ./mvnw. TC's type: gradle/type: maven runners use the agent's version, not the project's. This causes real build failures.
- Schema valid does not mean pipeline works. Migration is not done until builds pass.
- Private repos: use a GitHub App connection, not a PAT. Start with
teamcity project connection create github-app -p <project> -- its output prints the authorize, App-install, and vcs create follow-up commands. That flow opens a browser; in headless runs pass existing App credentials (--no-manifest --app-id <id> --client-id <id> --private-key-file <pem> --stdin, client secret piped to stdin) or use SSH deploy keys (teamcity project ssh upload with a git@github.com: URL). Public repos: --auth anonymous.
- Secrets, triggers, and branch filters are always manual. The converter flags them but cannot create them -- the checklist below covers each.
- VCS root must exist before pipeline create.
teamcity pipeline create takes --vcs-root <id>, not a URL. Create it first with teamcity project vcs create.
- Default branch defaults to
main. Pass --branch refs/heads/master to teamcity project vcs create if the repo uses master.
- Unknown actions/tasks become stubs. Read the action's source, write an equivalent shell script. Most actions are thin CLI wrappers. See mappings.
Workflow
Goal: get all pipeline jobs green on the TC server, not just generate valid YAML.
Copy this checklist and check off items as you complete them:
Migration progress:
- [ ] Convert: run `teamcity migrate` from the repo root
- [ ] Fix every "Needs review" item, plus "Manual setup" items needing YAML edits (matrix expansion, expression `runs-on`, container/services) -- see mappings.md and gotchas.md
- [ ] Wire up secrets in the YAML: the converter rewrites `${{ secrets.X }}` to `%X%` but does not define it -- store the value (`teamcity project token put <project> <value>`) and add `X: "credentialsJSON:<uuid>"` under the top-level `secrets:` block (see schema.md)
- [ ] Validate: `teamcity pipeline validate <file>` -- only proceed when it passes
- [ ] Create VCS root (`teamcity project vcs create`), then `teamcity pipeline create <name> -p <project> -f <file> --vcs-root <id>`
- [ ] Set up the remaining runtime "Manual setup needed" items before running: registry/cloud connections the steps reference (the first run fails without them), and any `if:`-condition items -- gate converted deploy/release steps via branch filter, execution condition, or a guard in the script so the first run cannot deploy from the wrong branch
- [ ] Run: `teamcity run start <id> --watch`; on failure read `teamcity run log <id> --failed --raw`, fix, `teamcity pipeline push`, re-run until green
- [ ] Do the trigger-only "Manual setup needed" items: triggers, notifications
- [ ] Report: what migrated and what remains manual
References
- Mappings -- GitHub Actions and Bamboo to TeamCity translation tables
- Schema -- TC pipeline YAML quick reference
- Gotchas -- skip list, matrix expansion, troubleshooting, manual setup items