Migrating from Jenkins to GitHub Actions is safest when treated as a controlled delivery change rather than a YAML rewrite. This guide provides a reusable CI/CD migration checklist, a Jenkins-versus-GitHub Actions comparison, starter templates for common workloads, and a testing and rollback workflow that preserves security, approvals, and deployment continuity.
Overview
A Jenkins migration can affect source control, credentials, build environments, deployment permissions, notifications, artifacts, and operational ownership. The goal is not to reproduce every plugin exactly. The goal is to preserve required behavior, remove unnecessary complexity, and make the new pipeline observable and reversible.
Use the following assumptions as a starting point: Jenkins remains available during the migration; GitHub Actions workflows are stored with the application code; production deployment requires an explicit approval or equivalent control; and the team can run both systems against non-production environments. Adjust the plan if your organization uses a different source-control model, private runners, external deployment orchestration, or regulated change controls.
Jenkins versus GitHub Actions: migration considerations
| Area | Jenkins | GitHub Actions | Migration question |
|---|---|---|---|
| Execution | Controller and agent model, commonly configured through nodes, labels, and plugins. | Hosted or self-hosted runners selected through workflow configuration and labels. | Which jobs require a particular operating system, toolchain, network route, or hardware profile? |
| Secrets | Credentials are commonly managed by Jenkins credentials stores, folders, or plugins. | Secrets and variables can be scoped at repository, environment, or organization levels. | Which credentials are needed, who can use them, and can permissions be narrowed? |
| Approvals | Often implemented with pipeline steps, permissions, plugins, or external change processes. | Can be represented through protected deployment environments and required review controls. | What must happen before production access is granted, and where is that decision recorded? |
| Extensibility | Uses plugins and shared libraries, with behavior sometimes distributed across controller configuration. | Uses reusable workflows, composite actions, marketplace actions, and scripts. | Is each plugin still necessary, and is there a maintained replacement or a simpler script? |
| Artifacts and reports | Typically handled by plugins or archived build outputs. | Configured explicitly through workflow steps and artifact or report actions. | Which files, test results, logs, and metadata must remain available after a run? |
Do not assume feature parity from names alone. Build an inventory of actual pipeline behavior, including triggers, retries, environment variables, workspace assumptions, manual steps, notifications, and deployment side effects.
Checklist by scenario
Phase 1: inventory and design
- List pipelines: Record repository, service owner, branch triggers, scheduled jobs, deployment targets, and the last meaningful run for each Jenkins job.
- Map dependencies: Identify shared libraries, plugins, Docker images, package registries, cloud accounts, databases, cluster contexts, and external APIs.
- Classify risk: Separate build-only jobs, non-production deployments, production deployments, infrastructure changes, scheduled maintenance, and release jobs.
- Capture controls: Document required reviews, separation of duties, approval points, audit records, rollback actions, and emergency procedures.
- Define success: Agree on acceptable runtime, artifact equivalence, test coverage, deployment behavior, notification behavior, and a cutover owner.
For team access and ownership, pair this inventory with the DevOps developer onboarding checklist. For broader delivery bottlenecks, use the CI/CD pipeline optimization checklist.
Phase 2: monolith application template
This starter workflow builds a single application, runs tests, packages the result, and preserves the package for a later deployment job. Replace commands and paths with the project's actual build system.
name: monolith-ci
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
build-test-package:
runs-on: ubuntu-latest
steps:
- name: Check out source
uses: actions/checkout@v4
- name: Set up runtime
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test -- --runInBand
- name: Build application
run: npm run build
- name: Package build
run: tar -czf application.tgz dist/
- name: Upload package
uses: actions/upload-artifact@v4
with:
name: application-package
path: application.tgzFor another language, replace the setup and package commands while keeping the same separation between checkout, dependency installation, tests, build, and artifact publication. Confirm that the generated artifact is equivalent to the Jenkins artifact before cutover.
Phase 3: microservices template
Microservices usually benefit from a matrix or reusable workflow, but begin with an explicit service list so failures are easy to diagnose. Add container publishing only after registry credentials, image naming, and tagging rules are confirmed.
name: services-ci
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
test:
strategy:
fail-fast: false
matrix:
service: [users, orders, payments]
runs-on: ubuntu-latest
defaults:
run:
working-directory: services/${{ matrix.service }}
steps:
- uses: actions/checkout@v4
- name: Set up runtime
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
cache-dependency-path: services/${{ matrix.service }}/package-lock.json
- run: npm ci
- run: npm test
- run: npm run buildUse a reusable workflow when multiple repositories share the same contract. Keep service-specific configuration at the caller level, and make the reusable workflow's inputs, outputs, permissions, and required secrets explicit.
Phase 4: infrastructure-as-code template
Infrastructure pipelines should separate formatting and validation from planning and applying. A pull request should normally produce a reviewable plan; production changes should require an explicit approval process appropriate to the environment.
name: infrastructure
on:
pull_request:
paths: ['infra/**']
push:
branches: [main]
paths: ['infra/**']
permissions:
contents: read
jobs:
plan:
runs-on: ubuntu-latest
defaults:
run:
working-directory: infra
steps:
- uses: actions/checkout@v4
- name: Set up Terraform
uses: hashicorp/setup-terraform@v3
- run: terraform init -input=false
- run: terraform fmt -check -recursive
- run: terraform validate
- run: terraform plan -input=false -out=tfplan
- name: Save plan
uses: actions/upload-artifact@v4
with:
name: terraform-plan
path: infra/tfplan
apply:
if: github.ref == 'refs/heads/main'
needs: plan
runs-on: ubuntu-latest
environment: production
defaults:
run:
working-directory: infra
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init -input=false
- name: Download plan
uses: actions/download-artifact@v4
with:
name: terraform-plan
path: infra
- run: terraform apply -input=false tfplanReview this pattern with your state-locking, cloud identity, drift detection, and recovery procedures. For cluster or network changes, link the workflow to a tested operational runbook rather than relying on pipeline comments alone.
What to double-check before cutover
Security and permissions
- Replace broad Jenkins credentials with narrowly scoped repository or environment secrets where practical.
- Use read-only workflow permissions by default and grant additional permissions only to the job that needs them.
- Prefer short-lived cloud identity or workload federation patterns when they are supported by your environment; do not copy long-lived tokens into workflow files.
- Review third-party actions by source, version reference, maintenance ownership, required permissions, and behavior. Pinning references according to your organization's supply-chain policy can improve repeatability.
- Confirm that logs do not print tokens, connection strings, private keys, or sensitive deployment output.
- Test fork and pull-request behavior separately. Secrets and write permissions may intentionally differ from trusted branch runs.
The software supply chain security checklist provides a useful control baseline for this review.
Runner and environment sizing
Choose a hosted runner when the job fits its operating system, CPU, memory, disk, network, and tool requirements. Consider self-hosted runners when builds require private network access, specialized hardware, custom images, or predictable local dependencies. In either case, measure actual job behavior rather than selecting capacity from assumptions. Check parallelism, queue time, disk cleanup, cache behavior, tool installation time, and isolation between jobs.
Functional equivalence
- Compare test commands, test selection, coverage thresholds, linting, and generated reports.
- Compare artifact names, checksums where appropriate, metadata, retention expectations, and publication destinations.
- Verify that deployment targets receive the same configuration and that environment-specific values are not silently replaced.
- Exercise rollback, cancellation, retry, timeout, and partial-failure behavior.
- Confirm notifications and status checks used by developers, release managers, and incident responders.
Testing and rollback workflow
- Run a shadow build. Trigger GitHub Actions from the same commit used by Jenkins without allowing the new workflow to deploy. Compare duration, logs, test results, artifacts, and exit status.
- Test in a disposable or non-production environment. Use representative dependencies and deployment permissions, but keep the blast radius limited.
- Perform an approval rehearsal. Verify who can approve, what evidence they see, whether the environment is protected, and how a rejected deployment behaves.
- Run a controlled canary. Migrate one low-risk service or deployment target first. Define success and stop conditions before starting.
- Cut over by trigger, not by deletion. Disable the Jenkins trigger for the selected job only after the GitHub Actions workflow has passed its acceptance checks. Keep the Jenkins definition and credentials available during the agreed rollback window.
- Monitor the first production runs. Watch deployment status, application health, error rates, logs, queue times, and artifact publication. Connect the change to an incident response runbook if the migration affects customer-facing delivery.
- Rollback deliberately. Re-enable the Jenkins trigger or use the previously approved deployment path, then record which commit, artifact, and configuration were used. Avoid running both production deployment triggers at the same time unless that behavior has been explicitly tested.
Reliability targets can help define whether a migration is behaving acceptably; see the SLO and error budget template. For operational escalation, use the incident response runbook template.
Common mistakes
- Translating syntax instead of behavior: A Jenkinsfile may hide shared-library logic, controller settings, or plugin defaults. Reconstruct the behavior first.
- Migrating every pipeline at once: Start with a representative, low-risk workload and use its findings to improve the migration pattern.
- Leaving approvals implicit: A manual step in Jenkins is not automatically equivalent to a protected deployment environment. Test the complete authorization path.
- Copying secrets without ownership review: Recreate only credentials that are still needed, with clear owners and rotation procedures.
- Ignoring workspace differences: Filesystem paths, tool versions, line endings, caches, and clean-checkout behavior can change results.
- Using floating dependencies without a policy: Uncontrolled action, image, or tool updates can make builds difficult to reproduce. Establish a review and update process.
- Removing Jenkins too early: Keep a tested fallback until the new workflow has completed the agreed production observation period.
When to revisit
Revisit this checklist before seasonal planning cycles, annual CI audits, platform upgrades, major repository changes, or a change in deployment strategy. Update templates when workflow syntax, runner images, action versions, authentication methods, or important CI plugins change. A security advisory affecting Jenkins, GitHub Actions, a runner image, a third-party action, or a build dependency should trigger an earlier review.
Make the review actionable: assign an owner, record the last validation date, list approved runner labels and deployment environments, and test one representative workflow after each material change. When a new service is added, copy the closest template, remove unused permissions, run it in shadow mode, and compare its artifacts and deployment behavior with the established pipeline. This turns the migration guide into a maintained platform practice rather than a one-time project document.