Cc-devops-skills github-actions-validator
Validate, lint, audit, fix GitHub Actions workflows (.github/workflows).
git clone https://github.com/akin-ozer/cc-devops-skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/akin-ozer/cc-devops-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/devops-skills-plugin/skills/github-actions-validator" ~/.claude/skills/akin-ozer-cc-devops-skills-github-actions-validator && rm -rf "$T"
devops-skills-plugin/skills/github-actions-validator/SKILL.mdGitHub Actions Validator
Overview
Validate and test GitHub Actions workflows, custom actions, and public actions using industry-standard tools (actionlint and act). This skill provides comprehensive validation including syntax checking, static analysis, local workflow execution testing, and action verification with version-aware documentation lookup.
Trigger Phrases
Use this skill when the request includes phrases like:
- "validate this GitHub Actions workflow"
- "check my
file".github/workflows/*.yml - "debug actionlint errors"
- "test this workflow locally with act"
- "verify GitHub Action versions or deprecations"
When to Use This Skill
Use this skill when:
- Validating workflow files: Checking
for syntax errors and best practices.github/workflows/*.yml - Testing workflows locally: Running workflows with
before pushing to GitHubact - Debugging workflow failures: Identifying issues in workflow configuration
- Validating custom actions: Checking composite, Docker, or JavaScript actions
- Verifying public actions: Validating usage of actions from GitHub Marketplace
- Pre-commit validation: Ensuring workflows are valid before committing
Required Execution Flow
Every validation run should follow these steps in order.
Step 1: Set Skill Path and Run Validation
Run commands from the repository root that contains
.github/workflows/.
SKILL_DIR="devops-skills-plugin/skills/github-actions-validator" bash "$SKILL_DIR/scripts/validate_workflow.sh" <workflow-file-or-directory>
Step 2: Map Each Error to a Reference
For each actionlint/act error, consult the mapping table below, then extract the matching fix pattern.
Step 3: Apply Minimal-Quote Policy
For each issue:
- Include the exact error line from tool output.
- Quote only the smallest useful snippet from
(prefer <=8 lines).references/ - Paraphrase the rest and cite the source file/section.
- Show corrected workflow code.
Step 4: Handle Unmapped Errors Explicitly
If an error does not match any mapping:
- Label it as
.UNMAPPED - Capture exact tool output, workflow file, and line number (if available).
- Check
general sections first.references/common_errors.md - If still unresolved, search official docs with the exact error string.
- Mark the fix as
until post-fix rerun passes.provisional
Step 5: Verify Public Action Versions
For each
uses: owner/action@version:
- Check
.references/action_versions.md - For unknown actions, verify against official docs.
- Confirm required inputs and deprecations.
Offline mode behavior:
- If network/doc lookup is unavailable, rely on
only.references/action_versions.md - Mark unknown actions as
.UNVERIFIED-OFFLINE - Do not claim "latest" version without an online verification pass.
Step 6: Mandatory Post-Fix Rerun
After applying fixes, rerun validation before finalizing:
SKILL_DIR="devops-skills-plugin/skills/github-actions-validator" bash "$SKILL_DIR/scripts/validate_workflow.sh" <workflow-file-or-directory>
Step 7: Provide Final Summary
Final output should include:
- Issues found and fixes applied
- Any
orUNMAPPED
itemsUNVERIFIED-OFFLINE - Post-fix rerun command and result
- Remaining warnings/risk notes
Error Type to Reference File Mapping
| Error Pattern in Output | Reference File to Read | Section to Quote |
|---|---|---|
, , , , | | Runner labels |
, | | Schedule Errors |
, , | | Expression Errors |
, , | | Job Configuration Errors |
, , | | Action Errors |
, , | | Script Injection section |
, , | | Syntax Errors |
, | | Troubleshooting |
, , , | | Version table |
, , | | Relevant section |
, , , | | Path Filter Errors |
Example: Complete Error Handling Workflow
User's workflow has this error:
runs-on: ubuntu-lastest
Step 1 - Script output:
label "ubuntu-lastest" is unknown
Step 2 - Read
or references/runners.md
:
Find the "Invalid Runner Label" section.references/common_errors.md
Step 3 - Quote the fix to user:
Error:
label "ubuntu-lastest" is unknownCause: Typo in runner label (from
):references/common_errors.md# Bad runs-on: ubuntu-lastest # TypoFix (from
):references/common_errors.md# Good runs-on: ubuntu-latestValid runner labels (from
):references/runners.md
,ubuntu-latest,ubuntu-24.04ubuntu-22.04 ,windows-latest,windows-2025windows-2022 ,macos-latest,macos-15macos-14
Step 4 - Provide corrected code:
runs-on: ubuntu-latest
Quick Start
Set once per shell session:
SKILL_DIR="devops-skills-plugin/skills/github-actions-validator"
Initial Setup
bash "$SKILL_DIR/scripts/install_tools.sh"
This installs act (local workflow execution) and actionlint (static analysis) to
scripts/.tools/.
Basic Validation
# Validate a single workflow bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/ci.yml # Validate all workflows bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/ # Lint-only (fastest) bash "$SKILL_DIR/scripts/validate_workflow.sh" --lint-only .github/workflows/ci.yml # Test-only with act (requires Docker) bash "$SKILL_DIR/scripts/validate_workflow.sh" --test-only .github/workflows/
Core Validation Workflow
1. Static Analysis with actionlint
Start with static analysis to catch syntax errors and common issues:
bash "$SKILL_DIR/scripts/validate_workflow.sh" --lint-only .github/workflows/ci.yml
What actionlint checks: YAML syntax, schema compliance, expression syntax, runner labels, action inputs/outputs, job dependencies, CRON syntax, glob patterns, shell scripts, security vulnerabilities.
2. Local Testing with act
After passing static analysis, test workflow execution:
bash "$SKILL_DIR/scripts/validate_workflow.sh" --test-only .github/workflows/
Note: act has limitations - see
references/act_usage.md.
3. Full Validation
bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/ci.yml
Default behavior if tools/runtime are unavailable:
- If
is missing, full validation falls back to actionlint-only.act - If Docker is unavailable, full validation skips act and continues with actionlint.
works in offline/local mode using--check-versions
.references/action_versions.md
Validating Resource Types
Workflows
# Single workflow bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/ci.yml # All workflows bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/
Key validation points: triggers, job configurations, runner labels, environment variables, secrets, conditionals, matrix strategies.
Custom Local Actions
Create a test workflow that uses the custom action, then validate:
bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/test-custom-action.yml
Public Actions
When workflows use public actions (e.g.,
actions/checkout@v6):
- Check
firstreferences/action_versions.md - Use official docs (or web search) for unknown actions
- Verify required inputs and version
- Check for deprecation warnings
- Run validation script
If offline:
- Mark unknown versions as
UNVERIFIED-OFFLINE - Avoid "latest/current" claims until online verification is possible
Search format:
"[action-name] [version] github action documentation"
Reference File Consultation Guide
Mandatory Reference Consultation
| Situation | Reference File | Action |
|---|---|---|
| actionlint reports any mapped error | | Find matching error and apply minimal quote policy |
| actionlint reports unmapped error | + official docs | Label as , capture exact output and verify by rerun |
| act fails with Docker/runtime error | | Check Troubleshooting section |
| act fails but workflow works on GitHub | | Read Limitations section |
| User asks about actionlint config | | Provide examples |
| User asks about act options | | Read Advanced Options |
| Security vulnerability detected | | Quote minimal safe fix snippet |
| Validating action versions | | Check version table and offline note |
| Using modern features | | Check syntax examples |
| Runner questions/errors | | Check labels and availability |
Script Output to Reference Mapping
| Output Pattern | Reference File |
|---|---|
, parse, YAML errors | - Syntax Errors |
, , condition parsing | - Expression Errors |
, , input/output mismatch | - Action Errors |
with CRON/schedule text | - Schedule Errors |
, injection warnings | - Security section |
or unknown label | |
dependency errors | - Job Configuration Errors |
, , pattern errors | - Path Filter Errors |
| Docker/pull/image errors from act | - Troubleshooting |
| No pattern match | + official docs (label ) |
Reference Files Summary
| File | Content |
|---|---|
| Act tool usage, commands, options, limitations, troubleshooting |
| Actionlint validation categories, configuration, integration |
| Common errors catalog with fixes |
| Current action versions, deprecation timeline, SHA pinning |
| Reusable workflows, SBOM, OIDC, environments, containers |
| GitHub-hosted runners (ARM64, GPU, M2 Pro, deprecations) |
Troubleshooting
| Issue | Solution |
|---|---|
| "Tools not found" | Run |
| "Docker daemon not running" | Start Docker or use |
| "Permission denied" | Run |
| act fails but GitHub works | See Limitations |
Debug Mode
actionlint -verbose .github/workflows/ci.yml # Verbose actionlint act -v # Verbose act act -n # Dry-run (no execution)
Best Practices
- Always validate locally first - Catch errors before pushing
- Use actionlint in CI/CD - Automate validation in pipelines
- Pin action versions - Use
not@v6
for stability; SHA pinning for security@main - Keep tools updated - Regularly update actionlint and act
- Use official docs for unknown actions - Verify usage and versions
- Check version compatibility - See
references/action_versions.md - Enable shellcheck - Catch shell script issues early
- Review security warnings - Address script injection issues
Limitations
- act limitations: Not all GitHub Actions features work locally
- Docker requirement: act requires Docker to be running
- Network actions: Some GitHub API actions may fail locally
- Private actions: Cannot validate without access
- Runtime behavior: Static analysis cannot catch all issues
- File location: act can only validate workflows in
directory; files outside (like.github/workflows/
) can only be validated with actionlintexamples/
Quick Examples
Example 1: Pre-commit Validation
SKILL_DIR="devops-skills-plugin/skills/github-actions-validator" bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/ git add .github/workflows/ && git commit -m "Update workflows"
Example 2: Debug Failing Workflow
bash "$SKILL_DIR/scripts/validate_workflow.sh" --lint-only .github/workflows/failing.yml # Fix issues bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/failing.yml
Complete Worked Example: Multi-Error Workflow
This example demonstrates the full assistant workflow for handling multiple errors.
User's Problematic Workflow
name: Broken CI on: schedule: - cron: '0 0 * * 8' # ERROR 1 jobs: build: runs-on: ubuntu-lastest # ERROR 2 steps: - uses: actions/checkout@v3 # ERROR 3 (outdated) - run: echo ${{ github.event.issue.title }} # ERROR 4 (security) deploy: needs: biuld # ERROR 5 (typo) runs-on: ubuntu-latest steps: - run: echo "Deploying"
Step 1: Run Validation
bash "$SKILL_DIR/scripts/validate_workflow.sh" --lint-only workflow.yml
Output:
[ERROR] invalid CRON format "0 0 * * 8" [ERROR] label "ubuntu-lastest" is unknown [WARN] "github.event.issue.title" is potentially untrusted [ERROR] job "deploy" needs job "biuld" which does not exist
Step 2-3: Consult References and Quote Fixes
Error 1: Invalid CRON Expression
From
- Schedule Errors:references/common_errors.md
Cause: Day of week 8 doesn't exist (valid: 0-6, where 0 = Sunday)
# Bad schedule: - cron: '0 0 * * 8' # Day 8 doesn't exist # Good schedule: - cron: '0 0 * * 0' # SundayCRON format:
minute hour day month weekday
- Weekday: 0-6 (0 = Sunday)
Fix: Change
8 to 0 (Sunday) or 1-6 for Monday-Saturday.
Error 2: Invalid Runner Label
From
- Job Configuration Errors and references/common_errors.md
:references/runners.md
Cause: Typo in runner label
# Bad runs-on: ubuntu-lastest # Typo # Good runs-on: ubuntu-latestValid labels (from
):references/runners.md
(Ubuntu 24.04)ubuntu-latest ,ubuntu-24.04ubuntu-22.04 (macOS 15)macos-latest (Windows Server 2022)windows-latest
Fix: Change
ubuntu-lastest to ubuntu-latest.
Error 3: Outdated Action Version
From
:references/action_versions.md
Action Current Version Minimum Supported actions/checkoutv6 v4 SHA Pinning Best Practice:
# Recommended: SHA pinning with version comment - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
Fix: Update from
@v3 to @v6 (or SHA-pinned version).
Error 4: Security Vulnerability (Script Injection)
From
- Expression Errors:references/common_errors.md
Warning: Potential script injection via untrusted input
# Bad - vulnerable to injection run: echo ${{ github.event.issue.title }} # Good - use environment variables env: TITLE: ${{ github.event.issue.title }} run: echo "$TITLE"Why: Untrusted input (issue titles, PR bodies, commit messages) can contain malicious commands. Using environment variables sanitizes the input.
Fix: Pass untrusted input through environment variable.
Error 5: Undefined Job Dependency
From
- Job Configuration Errors:references/common_errors.md
Error: Job 'deploy' depends on job 'biuld' which does not exist
# Bad jobs: build: runs-on: ubuntu-latest deploy: needs: biuld # Typo # Good jobs: build: runs-on: ubuntu-latest deploy: needs: build
Fix: Change
biuld to build.
Step 4: Provide Corrected Workflow
name: Fixed CI on: schedule: - cron: '0 0 * * 0' # Fixed: Sunday (0-6 valid) jobs: build: runs-on: ubuntu-latest # Fixed: typo corrected steps: - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - Fixed: updated version - name: Process issue env: TITLE: ${{ github.event.issue.title }} # Fixed: use env var run: echo "$TITLE" deploy: needs: build # Fixed: typo corrected runs-on: ubuntu-latest steps: - run: echo "Deploying"
Step 5: Mandatory Rerun
bash "$SKILL_DIR/scripts/validate_workflow.sh" --lint-only workflow.yml
Expected rerun result:
- No previous errors reproduced
- Remaining warnings, if any, are documented explicitly
Step 6: Summary
| Error | Type | Fix Applied |
|---|---|---|
CRON | Schedule | Changed to |
| Runner | Changed to |
| Outdated Action | Updated to (SHA-pinned) |
Direct in run | Security | Wrapped in environment variable |
| Job Dependency | Changed to |
Recommendations:
- Run
regularlybash "$SKILL_DIR/scripts/validate_workflow.sh" --check-versions - Use SHA pinning for all actions in production workflows
- Always pass untrusted input through environment variables
Done Criteria
Validation work is complete when all are true:
- Trigger matched and correct validation mode selected.
- Each mapped error includes source reference and minimal quote.
- Each unmapped error is labeled
with exact output captured.UNMAPPED - Public action versions are verified, or marked
.UNVERIFIED-OFFLINE - Post-fix rerun executed and result reported.
Summary
- Setup: Install tools with
install_tools.sh - Validate: Run
on workflow filesvalidate_workflow.sh - Fix: Address issues using reference documentation
- Rerun: Verify fixes with a mandatory post-fix validation run
- Search: Use official docs to verify unknown actions
- Commit: Push validated workflows with confidence
For detailed information, consult the appropriate reference file in
references/.