Migrate from Semaphore to GitHub Actions: Step-by-Step
Moving from Semaphore to GitHub Actions is mostly a translation job: Pipeline (.semaphore/*.yml) become workflows and jobs. This guide maps the concepts and shows the before/after.
Semaphore and GitHub Actions share the same primitives - pipelines, jobs, and steps - under different names. The migration is methodical: translate the config, port secrets and caching, and verify in parallel before cutting over.
Concept mapping
| Semaphore | GitHub Actions |
|---|---|
| Pipeline (.semaphore/*.yml) | Workflow (.github/workflows/*.yml) |
| block / task | Job (jobs.<id>) |
| Step / command | Step (run: or uses:) |
| Secrets (org/project) | Encrypted secrets / variables |
| cache CLI | actions/cache |
| Agent / executor | Runner (runs-on:) |
Before and after
version: v1.0
blocks:
- name: Test
task:
jobs:
- name: unit
commands:
- npm ci
- npm testThe GitHub Actions equivalent
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm testMigration steps
- Inventory your Semaphore pipelines and list every job, trigger, and secret.
- Create
.github/workflows/ci.ymland translate one pipeline at a time. - Move secrets into GitHub Actions encrypted secrets (port blocks and promotions).
- Add
actions/cachefor dependencies to match prior build speed. - Run the new workflow in parallel with the old pipeline on a branch and compare results.
- Cut over once green, then archive the old config.
Common pitfalls
- Semaphore blocks map to jobs; block dependencies map to
needs:. - The Semaphore
cacheCLI maps toactions/cache. - Promotions (manual/auto) map to environments,
workflow_dispatch, orif:gating.
After you migrate: cut cost and flakiness
Once on GitHub Actions, the next wins are cost and reliability. Managed runners like Latchkey run the same workflows at roughly 69% lower per-minute cost than GitHub-hosted, warm pools remove queue time, and self-healing retries transient failures automatically - so the pipeline you just migrated stays green and cheap. The switch is usually a one-line runs-on: change.
Key takeaways
- Pipeline (.semaphore/*.yml) map cleanly to GitHub Actions workflows.
- Port secrets and caching to match speed and security.
- Run both pipelines in parallel before cutting over.
- Then move to managed runners to cut cost and flaky re-runs.