Skip to content

Formatters & Code

GitHub Actions Workflow

CI workflow for Node, Python or Go in seconds.

Runs in your browser
GitHub Actions workflow · .github/workflows/ci.yml
lines: 21chars: 353size: 353 B
live

Understanding GitHub Actions

A pipeline written in YAML, paid for by GitHub.

The mental model behind workflows, jobs and steps — and the handful of gotchas that turn a "simple" CI file into a half-day debug.

Workflow → jobs → steps.

A workflow is one YAML file under .github/workflows/. Each workflow has one or more jobs; each job runs on a runner (a Linux/Windows/Mac VM); each job has one or more steps. Steps run sequentially within a job; jobs run in parallel by default unless needs: chains them. The defining unit of isolation is the job: separate jobs get separate VMs, separate caches, separate filesystems.

Triggers — the most-confused part.

on: push fires on every push to any branch. on: pull_request fires when a PR is opened or updated, and runs against the merge commit (not the branch HEAD). on: workflow_dispatch adds a manual "Run workflow" button. The most common bug: filtering with on: push: branches: [main] means the workflow runs only when main is pushed — pull requests targeting main don't trigger it. Use both push and pull_request with appropriate filters if you want it to fire in both shapes.

actions/checkout is step 1.

A fresh runner has no code on it. The first step in almost every workflow is uses: actions/checkout@v4, which clones the repository at the relevant commit. By default it clones depth 1 (no history) — if your build needs git history (changelog generators, conventional-commit tools, semantic-release), set with: { fetch-depth: 0 }. Forgetting this is a perennial cause of "works on my machine, fails in CI" bugs.

A worked Node workflow.

The minimum viable Node CI: name: ci on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 20, cache: npm } - run: npm ci - run: npm test Five steps: clone, install Node with built-in npm cache, install deps, test. The cache hint to setup-node automatically restores ~/.npm based on lockfile hash — no separate cache action needed.

Minimum CI shape

checkout + setup-node + install + test

Four steps cover 80 % of small projects.

actions/checkout + actions/setup-node + npm ci + npm test

= Working CI in ~10 lines

Caching beyond setup-* actions.

For caches that setup-node/setup-python/etc. don't manage, use actions/cache@v4 directly. The key is what determines a cache hit; almost always it should incorporate the lockfile's hash, plus the OS, plus the framework version. Misspecifying the key is the most common cache bug: too restrictive and you never get a hit; too loose and you restore stale state. The hierarchical fallback (restore-keys) lets you recover from a near-miss.

Secrets and permissions.

Repository secrets are environment variables available to workflow runs via ${{ secrets.NAME }}. Pull requests from forks do not get secrets by default — a critical security default that some workflows accidentally bypass with pull_request_target. Permissions are scoped via the workflow- level permissions block — default to contents: read and only grant write where needed. The principle of least privilege applies the same here as anywhere else.

Matrix builds.

To run the same job across Node 18, 20 and 22 — or across Ubuntu, macOS and Windows — use a matrix: strategy: { matrix: { node: [18, 20, 22] } } and reference ${{ matrix.node }} in your steps. Each combination runs as a separate parallel job; failing one doesn't necessarily fail the others (set fail-fast: false if you want them all to run regardless).

What Actions isn't suited for.

Actions runners are general-purpose VMs with limited disk and bandwidth; they're not ideal for long-running jobs (60-minute hard cap on Linux Free tier), heavy GPU work, or workloads with consistent enterprise SLAs. For those, self-hosted runners are available — you get the same workflow syntax against your own hardware. The free tier is generous for typical project CI; once you're paying for compute or running private repos, the cost model becomes worth understanding.

Frequently asked questions

Quick answers.

Where do I put the generated file?

Place the YAML file in your repository at `.github/workflows/`. You can name the file anything, such as `ci.yml` or `main.yml`, as long as it has a `.yml` or `.yaml` extension.

Which languages are supported?

The generator currently supports Node.js, Python, and Go. It includes standard steps for dependency installation and running test scripts specific to each ecosystem.

Is my repository data sent to your server?

No. The logic for template generation runs entirely in your browser. No information about your project or its configuration is ever transmitted or stored.

How do I trigger the workflow?

The generated templates default to triggering on `push` and `pull_request` events for the `main` branch. You can manually edit the `on:` section in the YAML to add other triggers like `workflow_dispatch`.

People also search for

Related tools

More in this room.

See all in Formatters & Code