GitHub Actions Workflow Generator
Backend engineers standing up CI on a new service, platform teams standardizing pipelines across dozens of repos, and open-source maintainers adding a first test job all write the same YAML skeleton from memory and then fix cache and permission typos by trial and error. This generator assembles a valid workflow file for Node, Python, Go, Docker, or static-site projects with checkout, version setup, dependency caching, test and build steps, artifacts, and GHCR push already wired. Pick a preset, adjust the fields, and commit the result straight to .github/workflows/.
How the Generator Builds Workflow YAML
The generator keeps one options object in memory and renders it through a preset-specific step list. Each preset contributes its own ordered steps: checkout first, then runtime setup with dependency caching, then install, test, and build. The Node preset branches on the package manager to insert pnpm/action-setup or corepack enable before setup-node, because cache: pnpm fails if pnpm is not installed when setup-node runs.
Docker jobs emit buildx setup, an optional GHCR login that reads the built-in GITHUB_TOKEN, and a build-push step with GHA layer caching. The static-site preset swaps the artifact upload for actions/upload-pages-artifact and appends a deploy job with pages: write and id-token: write permissions plus a github-pages environment binding. YAML is emitted with two-space indentation and no tabs so the GitHub parser accepts it on the first commit.
Caching and frozen lockfiles
Install commands default to npm ci, pnpm install --frozen-lockfile, or yarn install --frozen-lockfile. These fail when the committed lockfile does not match package.json, which catches accidental dependency drift before it reaches main. setup-node caches the package-manager cache directory keyed on the lockfile hash, so warm runs skip re-downloading unchanged tarballs.
Expressions inside single quotes
GitHub evaluates ${{ ... }} expressions at workflow runtime. The generator emits them literally inside YAML values such as the GHCR username and image tags, so the committed file resolves github.actor, secrets.GITHUB_TOKEN, and github.repository on each run. Do not wrap these values in quotes that would make the expression part of a plain string after YAML parsing; the generated layout keeps the expression unquoted where GitHub requires it.
Before and after: from ad-hoc script to full CI job
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm install
- run: npm test name: CI
on:
push:
branches: ['main']
pull_request:
branches: ['main']
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Build
run: npm run build Use Cases
| Developer | Production | Workflow |
|---|---|---|
| Add a first CI pipeline to a brand-new service repo | Standardize test and build steps across a monorepo fleet | Review a contributor PR that touches .github/workflows |
| Wire GHCR pushes for an internal Docker image | Enforce frozen lockfiles so dependency drift fails CI | Bootstrap Pages deploy for a docs site in one commit |
| Debug a cache miss by comparing generated YAML | Port a Travis or CircleCI job to Actions with equivalent steps | Onboard a new team to the shared runner labels |
Common Mistakes and Troubleshooting
The most common failure is committing the file to the wrong path. Workflows only run from .github/workflows/ at the repository root; a workflows folder anywhere else is ignored. The second is a package.json without a test script while the workflow still runs npm test, which exits non-zero and fails the job. Point the test command at the real script or clear the field to skip the step.
Docker jobs that log in to GHCR need packages: write permission when the default token scope is restricted at the org level. Static deploys fail with an environment error when repository Pages settings still point at a branch instead of GitHub Actions. If setup-node caching fails on pnpm, confirm pnpm/action-setup runs before setup-node; the generator emits that order automatically.
Best Practices for Action Workflows
Trigger on both push and pull_request for the main branch so contributors get feedback before merge while main stays green. Prefer npm ci over npm install in CI. Pin third-party actions to a major version tag your team reviews quarterly, or to a full commit SHA if your threat model requires it. Keep secrets in GitHub Secrets, never in the YAML, and grant the workflow the least permissions it needs with a top-level permissions: block.
Pair this generator with the gitignore generator to keep .github out of Docker images via the dockerignore generator, the Dockerfile generator for the image the Docker preset builds, and the git command generator when you need the exact add and commit invocations for the new workflow file.
GitHub Actions Workflow Generator FAQ
Where do I put the generated workflow file?
Commit the file to your repository under .github/workflows/ with a .yml extension, for example .github/workflows/ci.yml. GitHub picks up any workflow in that directory automatically; there is no registration step. The workflow runs on the next push or pull request that matches the branches you configured.
Why does the generator use actions/checkout@v4 and setup-node@v4?
Major-version tags like @v4 track the latest patch release of that major line, so security fixes land without editing every workflow. Pinning to an exact SHA is stricter and recommended for high-security repos, but the moving major tag is the default documented by GitHub and keeps the generated YAML readable for teams.
When should I use pnpm or yarn instead of npm ci?
Use the package manager that matches the lockfile committed to the repo. npm ci fails when package-lock.json is missing or out of sync, which is the behavior you want in CI. pnpm and yarn need their own setup steps and cache configuration; the generator inserts pnpm/action-setup or corepack enable automatically when you switch the package manager.
What does the Docker preset push to GHCR?
With push enabled, the workflow logs in to the GitHub Container Registry using the built-in GITHUB_TOKEN secret and tags the image as ghcr.io/OWNER/REPO:NAME. No extra secrets are needed for pushing to GHCR inside the same repository. Disable the push option to keep the workflow build-only for pull requests.
How does the static site preset deploy to GitHub Pages?
The static preset uploads the build output with actions/upload-pages-artifact and adds a second deploy job that calls actions/deploy-pages. The deploy job needs pages: write and id-token: write permissions, which the generator includes. In repository settings, set Pages source to GitHub Actions so the deployment job is allowed to publish.
Can the generated YAML run on self-hosted runners?
Yes. Change runs-on from ubuntu-latest to self-hosted, or to a custom label group your organization defines such as [self-hosted, linux, x64]. Everything else in the workflow stays the same because steps run on whatever runner the job selects.
Is the workflow sent anywhere when I generate it?
No. The YAML is assembled in the browser from the options you pick and never leaves the page. Copy it or download it and commit it yourself; there is no account, no API call, and no server-side rendering step.
Related Tools
Compose .gitignore for the repo you automate
Build commit and push commands for workflow files
Create the Dockerfile the CI job builds
Define services your pipeline deploys
Check env files CI injects at build time
Keep secrets and caches out of build context