GitHub Actions
GitHub Actions — workflows, jobs, steps, secrets, OIDC
GitHub Actions puts CI/CD inside the GitHub repository. It went into beta in 2018 and moved to GA in 2019.
1. About GitHub Actions
It is a CI/CD platform run by GitHub. The traits people highlight are that workflow definitions live inside the repo at .github/workflows/*.yml, and that the marketplace lets us reuse off-the-shelf actions, which lowers the cost of getting started. Pricing is free for public repos, with a free tier for private repos plus metered usage on top. Enterprise pricing is separate.
| Term | Meaning |
|---|---|
| Workflow | An automation defined by one YAML file (on: + jobs:) |
| Event | A trigger (push · pull_request · schedule · workflow_dispatch, etc.) |
| Job | A bundle of steps run serially or in parallel on the same runner |
| Step | One line that runs a command (run:) or an action (uses:) |
| Runner | The machine that actually executes a job (hosted or self-hosted) |
| Action | A reusable unit (uses: actions/checkout@v4) |
name: ci
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npm test
2. Runner
- Hosted (GitHub-hosted) — ephemeral VMs supplied by GitHub. Ubuntu, Windows, macOS. A fresh VM per job.
- Self-hosted — run the runner agent on our own server or VM. Workflows match by label.
- Larger runner — beefier hosted options (paid).
Hosted's strength is the cleanliness of a uniform environment; self-hosted's strength is cost and environment control (e.g. GPU, internal network access).
3. Matrix
Run the same job with several parameter combinations in parallel.
strategy:
matrix:
node: [18, 20, 22]
os: [ubuntu-latest, windows-latest]
Combinations grow cost and time fast, so narrowing them with include and exclude is the common shape.
4. Reusable workflow · Composite action
- Reusable workflow — called from another workflow with
uses:. Inputs and secrets are declared. - Composite action — wraps multiple steps into one action. Reuse at a smaller granularity.
Both show up together when standardizing CI across larger orgs.
5. Cache and artifacts
actions/cache— store and restore dependencies and build outputs by key. A matching key hits.actions/upload-artifact/download-artifact— pass outputs between jobs and across workflows.- Many setup actions (
setup-node·setup-go·setup-python, etc.) include caching internally.
Cache keys typically come from a hash of the lock file (package-lock.json · pnpm-lock.yaml, etc.). A key that is too short keeps missing the cache.
6. Secrets and environments
- Repository secrets — repo-scoped.
- Environment secrets — environment-scoped (staging, production). Approvals and waits available.
- Organization secrets — org-scoped.
Logs auto-mask secrets, but leaks are reported when echoing or forwarding to external services.
7. OIDC
A GitHub Actions-issued OIDC token is verified by a cloud (e.g. AWS, GCP, Azure), which then issues short-lived credentials. We get cloud permissions without storing static keys in secrets, and that wins on both security and operations.
permissions:
id-token: write
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123:role/GitHubActions
aws-region: ap-northeast-2
GCP's Workload Identity Federation and Azure's OIDC integration follow the same grain.
8. Other CI tools
| Tool | Released | Grain |
|---|---|---|
| GitHub Actions | 2018 beta / 2019 GA | Repo-bound · marketplace |
| GitLab CI | 2015~ | GitLab-bound · self-hosting friendly |
| CircleCI | 2011 | Workflow DSL with a fast on-ramp |
| Jenkins | 2011 (originally Hudson 2005) | Standard for self-hosting · plugin-rich |
| Buildkite | 2014 | Self-hosted agents + SaaS UI |
| Travis CI | 2011 | Once a standard in OSS, share has shifted |
| Drone CI | 2014 | Container-native |
| Bitbucket Pipelines | 2016 | Bitbucket-bound |
The grain of the choice:
- Coupling with the repo host — GitHub → Actions, GitLab → GitLab CI, Bitbucket → Pipelines.
- Self-hosting first — Jenkins, Drone, self-hosted GitLab Runner.
- Marketplace and ecosystem — Actions is widely seen as the richest.
- Cost predictability — different unit pricing and concurrent-job caps.
9. PR guards and the grain of deploy
PR guards:
- Build and unit tests.
- Lint and type checks.
- Integration tests (with service containers or Testcontainers when needed).
- Code coverage report.
- Security scans (CodeQL · Dependabot · SCA).
Deploys:
- Auto-deploy to staging on merge to main.
- Production behind an environment approval gate.
- Pull cloud permissions through OIDC.
- Pair with cloud-side tooling for canary or rolling deploys.
10. Schedule and matrix cost
Use on: schedule with cron for periodic jobs. Data pipelines, doc generation, consistency checks — all common spots. Watch out for usage limits and cost on per-minute schedules.
Keep matrix combinations of OS and language versions from blowing up, and understand what fail-fast: true and continue-on-error: false actually mean.
11. Common stumbles
Secret leaks — echo $SECRET or forwarding to an external service can break masking. Block them with explicit add-mask or by minimizing permissions.
OIDC permission breadth — if the assumable role is overly permissive, the OIDC win shrinks.
Secrets on fork PRs — secrets are not exposed by default to PRs from forks (security). When needed, pull_request_target exists, but it carries security traps.
Infinite triggers — workflows that push their own changes re-trigger themselves. Block with paths or if.
Runner environment drift — the default tooling and versions on ubuntu-latest change over time. Pinning is safer.
Cache miss — too long a key almost always misses; too short uses the wrong cache.
Self-hosted isolation — letting self-hosted runners take fork PRs is dangerous. Off by default.
Concurrency — fast pushes on the same branch start parallel jobs that collide. Use a concurrency: group with cancel.
Action provenance — uses: on an untrusted action grants code execution. Pinning by SHA is recommended.
Closing thoughts
CI/CD operational load grows with the amount adopted. Starting with a single PR guard and only expanding into deploys and schedules once it has settled in is the safer path. When pulling in marketplace actions, double-check provenance and pin by SHA.
Next
- vitest-pytest-real-world
See GitHub Actions docs, Workflow syntax, Reusable workflows, OIDC integration, actions/cache, and GitLab CI.