All skills
akin-ozer avatar

/github-actions-validator

@1b2342a

Validate, lint, audit, fix GitHub Actions workflows (.github/workflows).

Use this Skill: https://skilld.dev/gh/akin-ozer/cc-devops-skills/github-actions-validator

This session only. Nothing lands on disk.

referencesactionlint_usage.md

≈1.8k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Actionlint (rhysd/actionlint) - Usage Reference

Actionlint is a static checker for GitHub Actions workflow files that catches errors before they cause CI failures.

Installation

# Download and install using the official script
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)

# Or use the skill's installation script
bash scripts/install_tools.sh

Core Usage

Basic Validation

Validate a single workflow file:

actionlint .github/workflows/ci.yml

Validate all workflow files in a directory:

actionlint .github/workflows/*.yml

Validate all workflows in the default location:

actionlint

Output Formats

Default Format (human-readable)
actionlint

Output example:

.github/workflows/ci.yml:5:7: unexpected key "job" for "workflow" section [syntax-check]
.github/workflows/ci.yml:10:15: invalid CRON format "0 0 * * 8" in schedule event [events]
JSON Format
actionlint -format '{{json .}}'

Useful for programmatic processing and integration with other tools.

Sarif Format
actionlint -format sarif

For integration with GitHub Code Scanning and other security tools.

Validation Categories

1. Syntax Checking

Validates YAML syntax and GitHub Actions schema:

  • Required fields
  • Valid keys and values
  • Proper nesting
  • Type correctness

2. Expression Validation

Validates GitHub Actions expressions ${{ }}:

  • Syntax errors
  • Type checking (string, number, boolean)
  • Function calls
  • Context access

Example caught errors:

# Error: Boolean expression expected
if: ${{ 'true' }}  # String, not boolean

# Error: Unknown function
run: echo ${{ unknown() }}

# Error: Type mismatch
if: ${{ 42 }}  # Number, not boolean

3. Runner Label Validation

Validates runner labels against known GitHub-hosted runners:

Ubuntu:

  • ubuntu-latest (currently ubuntu-24.04)
  • ubuntu-24.04, ubuntu-22.04, ubuntu-20.04

Windows:

  • windows-latest (currently windows-2022)
  • windows-2025 (NEW - recently added)
  • windows-2022, windows-2019

macOS:

  • macos-latest (currently macos-15)
  • macos-15 (Apple Silicon M1/M2/M3)
  • macos-14 (Apple Silicon M1)
  • macos-26 (preview)
  • macos-13 (Intel - RETIRED November 14, 2025)
  • macos-12 (Intel - RETIRED)

Example:

runs-on: ubuntu-lastest  # Error: Did you mean "ubuntu-latest"?

4. Action Validation

Validates action references:

  • Action exists
  • Valid version/ref
  • Required inputs provided
  • No unknown inputs

Example:

# Error: Missing required input "path"
- uses: actions/checkout@v5

# Error: Unknown input "invalid_input"
- uses: actions/checkout@v5
  with:
    invalid_input: value

5. Job Dependencies

Validates needs: dependencies:

  • Referenced jobs exist
  • No circular dependencies
  • Valid job IDs

6. CRON Syntax

Validates schedule event CRON expressions:

# Error: Day of week must be 0-6
schedule:
  - cron: '0 0 * * 8'

7. Shell Script Validation

Integrates with shellcheck to validate shell scripts in run: steps:

# Warning: Quote to prevent word splitting
run: echo $VARIABLE

8. Glob Pattern Validation

Validates glob patterns in paths: and paths-ignore: filters for structural errors (e.g., empty patterns or malformed syntax).

Note: The pattern **.js (double-star without a slash) is not flagged by actionlint as of v1.7.x. It is functionally equivalent to **/*.js in GitHub's glob engine but **/*.js is more explicit and widely understood. Use **/*.js as a best practice, not because actionlint will warn about the alternative.

# Best practice (clear intent)
on:
  push:
    paths:
      - '**/*.js'   # Matches any .js file in any subdirectory
      - 'src/**'    # Matches everything under src/

9. Security Checks

Detects potential security issues:

  • Injection vulnerabilities
  • Insecure credential handling
  • Dangerous patterns

Example:

# Warning: Potential script injection
run: echo ${{ github.event.issue.title }}

Configuration

Create .github/actionlint.yaml or .github/actionlint.yml:

# Configure shellcheck
shellcheck:
  enable: true
  shell: bash

# Configure pyflakes for Python
pyflakes:
  enable: true
  executable: pyflakes

# Ignore specific rules
ignore:
  - 'SC2086'  # Ignore shellcheck rule
  - 'action-validation'  # Ignore action validation

# Custom runner labels
self-hosted-runner:
  labels:
    - my-custom-runner
    - gpu-runner

Exit Codes

  • 0: Success - no errors found
  • 1: Validation errors found
  • 2: Fatal error (invalid file, config error, etc.)

Integration

Pre-commit Hook

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/rhysd/actionlint
    rev: v1.7.9  # Check https://github.com/rhysd/actionlint/releases for latest version
    hooks:
      - id: actionlint

Note: Always use the latest version of actionlint. Check the releases page for the most recent version.

GitHub Actions Workflow

name: Lint GitHub Actions workflows
on: [push, pull_request]
jobs:
  actionlint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
      - name: Download actionlint
        run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
      - name: Run actionlint
        run: ./actionlint

VS Code Integration

Install the "actionlint" extension for real-time validation in VS Code.

Common Error Examples

1. Typo in Runner Label

# Error
runs-on: ubuntu-lastest

# Fix
runs-on: ubuntu-latest

2. Invalid CRON Expression

# Error
schedule:
  - cron: '0 0 * * 8'  # Day of week 8 doesn't exist

# Fix
schedule:
  - cron: '0 0 * * 0'  # Sunday = 0

3. Missing Required Input

# Error
- uses: actions/checkout@v4

# Fix (if repository input is required)
- uses: actions/checkout@v4
  with:
    repository: owner/repo

4. Invalid Expression

# Error
if: ${{ success() && 'true' }}  # Mixing boolean and string

# Fix
if: ${{ success() && true }}

5. Undefined Job in needs

# Error
jobs:
  deploy:
    needs: biuld  # Typo

# Fix
jobs:
  deploy:
    needs: build

Best Practices

  1. Run locally before pushing: Catch errors early
  2. Use in CI/CD: Add actionlint to your workflow
  3. Configure for custom runners: Update config for self-hosted runners
  4. Enable shellcheck: Catch shell script issues
  5. Review all warnings: Even non-fatal warnings can indicate issues
  6. Keep actionlint updated: New rules and features are added regularly

Limitations

  • Cannot validate runtime behavior (only static analysis)
  • Cannot access private actions (must be public to validate)
  • May not catch all possible issues (e.g., environment-specific problems)
  • Custom actions may require manual verification

Source: SKILL.md on GitHub

1 alert16d4 checks · Risk HIGH
  • Gen Agent Trust Hub16d

    The skill is designed to validate GitHub Actions workflows using actionlint and act. It includes a setup script that downloads and executes remote installation scripts directly via bash piping and process substitution. While these downloads are intended to fetch the official linting and local testing utilities, running unverified remote scripts poses a supply chain risk.

  • Socket16d

    3 alerts: gptSecurity, gptAnomaly

  • Snyk16d

    Risk: LOW · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 1b2342a. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 7 months ago

README badge

README badge for akin-ozer/cc-devops-skills/github-actions-validator