Don't like ads? Go Ad-Free Today

GitHub Actions YAML Linter & Formatter

DataDeveloperText
ADVERTISEMENT · REMOVE?

Options

ADVERTISEMENT · REMOVE?

Guide

GitHub Actions YAML Linter & Formatter

GitHub Actions YAML Linter & Formatter

Paste a GitHub Actions workflow file and instantly catch broken structure, deprecated syntax, and risky patterns before they fail a CI run. The linter validates your workflow against a built-in schema for triggers, jobs, steps, runners, permissions, and reusable workflow calls, then reformats the YAML with a workflow-aware key order so every file in your repository looks the same.

How to Use

  1. Paste your .github/workflows/*.yml file into the input box, or click one of the example links to load a sample CI, release, or deprecated-syntax workflow.
  2. Toggle Sort Keys to reorder fields using the canonical GitHub Actions order (name, on, permissions, jobs, then per-job runs-on, needs, steps).
  3. Keep Validate Against GitHub Actions Schema enabled to flag missing required fields, unknown event types, invalid runner labels, and broken needs references.
  4. Keep Show Best Practice Hints enabled for supply-chain and reliability suggestions (pin third-party actions to a SHA, add timeout-minutes, replace deprecated workflow commands).
  5. Copy the formatted YAML or download it as a .yml file ready to commit.

Features

  • Schema validation – Required top-level fields (on, jobs), allowed trigger event names, valid job and step keys, and correct permission scopes.
  • Reusable workflow rules – Detects when a job mixes uses with runs-on or steps, which GitHub will reject at runtime.
  • needs graph check – Flags self-references and dependencies on jobs that do not exist in the file.
  • Action reference parser – Catches uses: values that are missing @ref or are not in owner/repo form.
  • Deprecated syntax detection – Warns on ::set-env, ::set-output, ::save-state, and node12/node16 runtimes with the modern replacement.
  • Best practice hints – Suggests pinning third-party actions to a commit SHA and adding timeout-minutes to prevent runaway jobs.
  • Cron sanity check – Validates that on.schedule cron entries have exactly five fields.
  • Workflow-aware formatter – Reorders top-level, job-level, and step-level keys into the conventional GitHub Actions order for consistent diffs.
  • Runs entirely in your browser – No workflow content is ever sent to a server.

FAQ

  1. Why are GitHub Actions workflows so prone to structural errors?

    Workflow YAML follows a strict schema with required top-level keys, fixed event names, and per-job key rules that change depending on whether the job is a normal job or a reusable workflow call. The file is only parsed when a trigger fires on GitHub, so a typo in a key name or an unknown event silently sits in the repository until the next push or PR fails. Schema-based linting catches these classes of errors before they reach the runner.

  2. What does pinning an action to a commit SHA actually protect against?

    GitHub Actions resolves uses: owner/action@v1 to whatever commit the v1 tag points to at run time. Because tags are mutable, a maintainer (or an attacker who compromises the maintainer's account) can move v1 to a malicious commit and every workflow that depends on it will execute the new code on the next run. Pinning to a full 40-character commit SHA freezes the action's source code at a known revision, so a future tag change cannot silently swap in different behavior.

  3. Why were ::set-env, ::set-output, and ::save-state deprecated?

    Those workflow commands wrote environment variables, step outputs, and saved state by emitting specially-formatted lines on stdout. Any tool the runner executed could print the same format and inject arbitrary values into GITHUB_ENV or step outputs, including overriding PATH or secrets the next step relied on. The replacements use dedicated, append-only files ($GITHUB_ENV, $GITHUB_OUTPUT, $GITHUB_STATE) that subprocesses cannot read or modify after the fact.

  4. Why does the linter ask for a timeout-minutes value on each job?

    Without timeout-minutes, a GitHub-hosted job will run for up to 360 minutes (six hours) before the platform cancels it. A hung process, a misconfigured wait, or a runaway test can consume the full window, blocking the queue and burning minutes from your plan. Setting an explicit upper bound on each job turns that worst case into a fast failure that surfaces the bug immediately.

Want To enjoy an ad-free experience? Go Ad-Free Today

Install Our Extensions

Add IO tools to your favorite browser for instant access and faster searching

Add to Chrome Extension Add to Edge Extension Add to Firefox Extension Add to Opera Extension

Scoreboard Has Arrived!

Scoreboard is a fun way to keep track of your games, all data is stored in your browser. More features are coming soon!

ADVERTISEMENT · REMOVE?
ADVERTISEMENT · REMOVE?
ADVERTISEMENT · REMOVE?

News Corner w/ Tech Highlights

Get Involved

Help us continue providing valuable free tools

Buy me a coffee
ADVERTISEMENT · REMOVE?