Validate a GitHub Actions Workflow

GitHub Actions workflows are defined in YAML files stored in .github/workflows/ and automatically run when specified events occur. A syntax error in the workflow file silently prevents the pipeline from running — you push a commit, nothing happens, and the only way to discover the problem is to navigate to the Actions tab and look for a red X on the workflow. Validating YAML syntax before pushing saves this frustrating debugging cycle. This example defines a CI workflow that runs on pushes and pull requests to the main branch. It has a single job (lint-and-test) that runs on the latest Ubuntu runner and executes four sequential steps: checking out the repository code, setting up Node.js 20 with npm caching enabled, installing dependencies with npm ci (which is faster and more reliable than npm install in CI), and running lint and test commands. Key YAML structure points: on: is the trigger configuration — the colon after on is required and the indented push and pull_request blocks define which events trigger the workflow. Each trigger has a branches list using YAML array syntax ([main]). The steps list uses dash notation for each step item. The uses key references a reusable action (like actions/checkout@v4) while run executes a shell command directly on the runner. The cache: npm option on the setup-node action is worth highlighting. Without caching, npm ci downloads and installs all packages on every workflow run. With caching, the action stores node_modules keyed to the hash of package-lock.json. When the lock file hasn't changed, subsequent runs restore from cache instead of downloading, cutting CI time by minutes on large projects. Common reasons a workflow doesn't trigger: the branch name in the on.push.branches list doesn't exactly match the branch you're pushing to (case-sensitive), the workflow file is on a feature branch rather than the default branch (GitHub only auto-discovers workflows on the default branch), or the YAML has an indentation error that makes the trigger configuration invalid. Real-world scenarios: a pull request workflow that runs tests and posts a status check that must pass before merging; a release workflow that builds and deploys when a version tag is pushed; a scheduled workflow that runs nightly security scans. To customise: adjust the Node.js version, replace npm with pnpm or yarn, add additional steps for building, deploying, or sending notifications.

Example
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint-and-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 run lint
      - run: npm test
[ open in YAML Validator → ]

FAQ

Why is my GitHub Actions workflow not triggering?
Common causes are incorrect branch names in the on trigger, YAML indentation errors that make the file invalid, or the workflow file not being on the default branch.
What is the difference between uses and run in a step?
uses references a reusable action from the marketplace or a repository. run executes a shell command directly on the runner.
How do I cache dependencies in GitHub Actions?
The setup-node action has a built-in cache option. Set cache: npm, pnpm, or yarn and it automatically caches the dependency directory based on your lock file.

Related Examples