Migrating from GitHub Actions
Your org policies probably cover most of it already.
The short version
Import your repo,
then check Settings → GitHub Actions Import on the repo page.
gittan reads your .github/workflows/ files,
compares them to what your org policies already provide, and tells you what (if anything) needs a .gittan.yaml.
For most repos, org policies already cover install, test, build, and publish. The import tool will say "No .gittan.yaml needed."
What maps and what doesn't
| GitHub Actions | gittan | Notes |
|---|---|---|
| run: pnpm test | run: pnpm test | Direct mapping |
| uses: actions/checkout@v4 | (not needed) | gittan mounts workspace automatically |
| uses: actions/setup-node@v4 | image: node:22 | Specify the image directly |
| uses: docker/build-push-action | publish: | Built-in — just specify image name + Dockerfile |
| services: postgres: | services: [postgres:16] | Sidecar containers for tests |
| needs: [test] | needs: [test] | Same concept |
| secrets.API_KEY | secrets: [API_KEY] | Declare, then add via repo/team/org settings |
| uses: org/custom-action@v1 | No equivalent | Replace with shell commands or shared steps |
| strategy: matrix: | Not supported | Use separate steps instead |
Marketplace actions
GitHub Actions relies on a marketplace of third-party actions. gittan doesn't have a marketplace — by design. Instead, you write shell commands directly. This is simpler, auditable, and doesn't depend on someone else's CI plugin being maintained.
Most marketplace actions wrap a single CLI tool. Replace uses: some-org/deploy-action@v3 with
the actual command the action runs — it's usually in the action's README.
Example: before and after
GitHub Actions
name: CI
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: pnpm install --frozen-lockfile
- run: pnpm test
- run: pnpm build
- uses: docker/build-push-action@v6
with:
push: true
tags: myorg/api:latest gittan (if not covered by policies)
steps:
- name: install
run: pnpm install --frozen-lockfile
cache: [node_modules]
- name: test
run: pnpm test
needs: [install]
- name: build
run: pnpm build
needs: [install]
- name: publish
publish:
image: api
needs: [test, build] No checkout, no setup action, no Docker login, no tag strategy. The image tag
is generated automatically (YYYYMMDD-HHMMSS-sha),
and publish is gated to main by default.
What you can skip
Things that are handled automatically in gittan and don't need configuration:
- Checkout — workspace is mounted automatically
- Docker login — registry auth is handled by the platform
- Image tagging — timestamp-sha format, no :latest
- Secret scanning — runs as a platform policy on every push
- Dependency scanning — runs as a platform policy on every push
- Artifact caching — just list paths in
cache: