CI How-To by Platform
How to do the same CI task on GitHub Actions, GitLab, CircleCI, Jenkins, and more.
Step-by-step how-tos for common CI/CD tasks - caching, secrets, matrix builds, artifacts, services, manual and scheduled triggers - shown for GitHub Actions, GitLab CI, CircleCI, Jenkins, Azure Pipelines, and Bitbucket.
GitHub Actions
Task how-tos for GitHub Actions.
Build provenance attestationEmit signed SLSA build provenance for an artifact in GitHub Actions with actions/attest-build-provenance,
Rust multi-target buildCross-build a Rust binary for several platform targets in GitHub Actions with a matrix, using cross or rustup
Cache dev containerBuild a dev container in GitHub Actions with the devcontainers CLI and cache its layers so repeated CI runs
Close stale issuesMark and close inactive issues and pull requests on a schedule in GitHub Actions with the stale action,
Comment on a PRPost a comment on a pull request from a GitHub Actions workflow using actions/github-script and the
Debug a failing workflowA repeatable procedure for CI failures you cannot reproduce locally: enable debug logging, dump contexts,
Branch vs line coverageTurn on branch coverage in CI so both sides of every conditional are measured, a stricter signal than line
Encrypt artifactsEncrypt sensitive build outputs with GPG or openssl in GitHub Actions before calling upload-artifact so the
Prow-style /lgtm /approveImplement Prow-style commands such as /lgtm and /approve in GitHub Actions, mapping each to a label and a
Bypass required reviewsAllow a workflow to merge past required pull request reviews by adding a GitHub App to the branch protection
Multi-arch image to ECRBuild and push a multi-arch (amd64 + arm64) Docker image to Amazon ECR in GitHub Actions using OIDC to
Keyless push to GHCRPush container images to GitHub Container Registry from Actions using the built-in GITHUB_TOKEN and packages:
Restrict workflow_dispatchLimit who can manually run a GitHub Actions workflow_dispatch by checking the actor permission level with the
Reuse a workflowBuild a reusable GitHub Actions workflow with on.workflow_call, declaring inputs and secrets, then call it
Run fork PRs safelyRun GitHub Actions on fork pull requests without leaking secrets by splitting untrusted build from a
Comment commandsBuild a slash-command bot in GitHub Actions that triggers on issue_comment, parses a command like /deploy,
kubeconform manifestsValidate Kubernetes manifests against the API schemas in GitHub Actions with kubeconform so invalid YAML is
rustfmt + clippyCheck Rust formatting and lints in GitHub Actions with rustfmt and clippy so unformatted code or clippy
Set a commit statusSet a custom commit status from GitHub Actions with the GITHUB_TOKEN and the statuses API, so an external
Matrix from job outputBuild a dynamic GitHub Actions matrix from a previous jobs output by emitting a JSON array to GITHUB_OUTPUT
GitHub Actions OIDC to AWSReplace long-lived AWS keys in GitHub Actions with short-lived OIDC credentials, including the trust policy
Sign image with cosignSign a container image in GitHub Actions with cosign keyless signing over OIDC, producing a verifiable
Sign artifacts (cosign keyless)Sign a release artifact in GitHub Actions with cosign keyless signing, using the workflow OIDC token and
Webhook triggerFire a GitHub Actions workflow from any external system by POSTing a repository_dispatch event to the GitHub
Trigger on push to branchesRun a GitHub Actions workflow only when commits are pushed to named branches using on.push.branches, so
Use set -euo pipefailMake GitHub Actions bash scripts fail loudly by starting them with set -euo pipefail, so unset variables and
Verify /version matches SHAConfirm the running release is the exact commit you deployed in GitHub Actions by comparing a /version
GitLab CI
Task how-tos for GitLab CI.
Cache Maven dependenciesSpeed up GitLab CI Java builds by caching the Maven local repository (.m2) keyed on pom.xml so dependencies
Cancel redundant pipelinesCancel redundant GitLab CI pipelines with interruptible jobs plus auto-cancel redundant pipelines, and use
Retry a failing jobAutomatically retry a failing GitLab CI job with the retry keyword - set max attempts and scope retries to
Set a job timeoutSet a job timeout in GitLab CI with the timeout keyword, how it interacts with the project and runner
Set an env varSet environment variables in GitLab CI with the variables: keyword at global and job scope, plus dotenv
Trigger manuallyTrigger a GitLab CI pipeline or job manually - when: manual jobs, manual gates with allow_failure, and the
CircleCI
Task how-tos for CircleCI.
Cache with restore_keysUse CircleCI save_cache and restore_cache with layered keys so a partial cache hit on restore_keys still
Run a security scanRun a dependency and SAST security scan in CircleCI with the Snyk orb or a plain npm audit step, failing the
Use setup_remote_dockerGet a real Docker daemon inside a CircleCI docker-executor job with setup_remote_docker, so you can run
Jenkins
Task how-tos for Jenkins.
Archive build artifactsSave build outputs in Jenkins with archiveArtifacts so binaries, bundles, and reports attach to the build and
Build a multi-arch imageBuild a multi-architecture Docker image in a Jenkins pipeline with docker buildx and QEMU, pushing one amd64
Cache Gradle dependenciesCache Gradle dependencies in a Jenkins pipeline by pinning GRADLE_USER_HOME to a persistent path, or using
Lock a resourceSerialize access to a shared resource like a staging environment in Jenkins using the lock step from the
Bind a secret fileExpose a stored Secret file credential as a temporary path with withCredentials in Jenkins, so tools like
Pass data between stagesPass data between Jenkins pipeline stages with environment variables, script-scoped variables, and
Publish a coverage reportPublish a code-coverage report in a Jenkins pipeline with the Coverage plugin recordCoverage step, parsing
Run a serviceRun a Postgres service in a Jenkins pipeline using docker.image().withRun via the Docker Pipeline plugin so
Use a matrixUse the matrix directive in a Jenkins declarative pipeline to run a set of stages across axis combinations
Use stages and stepsUse stages and steps in a Jenkins declarative pipeline to structure work into visible phases, each containing
Azure Pipelines
Task how-tos for Azure Pipelines.
Retry a failing taskRetry a failing task in Azure Pipelines with retryCountOnTaskFailure, plus job-level retries via the
Run a matrix buildRun a matrix build in Azure Pipelines with strategy:matrix to fan a job across versions, plus maxParallel and
Use conditions and expressionsControl when stages, jobs, and steps run in Azure Pipelines with condition expressions - succeeded, eq, and,
Bitbucket
Task how-tos for Bitbucket Pipelines.
Build a multi-arch imageBuild a multi-architecture Docker image in Bitbucket Pipelines with the docker service, Buildx, and QEMU,
Cache Docker layersCache Docker layers in Bitbucket Pipelines with the built-in docker cache, or push a registry-backed Buildx
Define a custom pipeline triggerCreate a manually triggered Bitbucket Pipelines workflow under the custom: section so an operator can run a
Pass artifactsPass build artifacts between steps in Bitbucket Pipelines with the artifacts: keyword and glob paths so a
Retry a failing stepRetry a failing step in Bitbucket Pipelines - the manual rerun of failed steps and a script-level bash retry
Run parallel stepsRun independent Bitbucket Pipelines steps at the same time with the parallel key to cut wall-clock time on
Pull request pipelinesRun a pipeline only when a pull request is open with the pull-requests section, which merges the source and
Set a variableSet variables in Bitbucket Pipelines - repository/workspace variables, inline export in scripts, and passing
Set up a monorepo pipelineSet up a monorepo pipeline in Bitbucket Pipelines with the condition.changesets includePaths key so a step
Set up branch-specific pipelinesRun different Bitbucket Pipelines steps per branch by defining entries under the branches: section so main,
Track deploymentsMark a Bitbucket Pipelines step as a deployment with the deployment key so it shows up in the Deployments
Trigger a pipeline via APITrigger a Bitbucket pipeline programmatically through the REST API, posting a target branch and a custom
Use parallel with cachesRun Bitbucket Pipelines steps concurrently with a parallel block while each step restores the node cache so a
Explore other topics
GitHub ActionsWorkflow, runner, and YAML errors - diagnosed and fixed.
Node.js & npmnpm, yarn, and pnpm failures in CI - solved.
DockerBuild, run, compose, and registry errors - explained.
Pythonpip, poetry, venv, and pytest failures - fixed.
Java & JVMMaven, Gradle, and JVM failures in CI - resolved.
GoGo build, module, and test failures - diagnosed.