SkillAgentSearch skills...

authoring-github-workflows

Author and review GitHub Actions workflow YAML safely so syntactically-valid YAML can't ship a workflow that GitHub Actions refuses to run.

Install / Use

npx skills add dotnet/skills --skill authoring-github-workflows

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

87/100

Category

Automation

Supported Platforms

Universal

Our assessment of authoring-github-workflows

authoring-github-workflows scores 87/100 on our quality scale, 907th of 1,554 Automation skills we index.

Its SKILL.md is 8.8 KB long, well organised into 18 sections with 5 code examples: a thorough specification that gives an agent plenty to work with.

With 5,471 GitHub stars, it is one of the more widely adopted skills in the catalogue.

Substance
29/30
Structure
20/20
Description
15/15
Adoption
16/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 2 days ago, so authoring-github-workflows is actively maintained.
  • It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

authoring-github-workflows compared with similar skills

All 4 of these similar skills score higher than authoring-github-workflows; compare them before choosing.

SkillScoreStarsUpdatedFormat
authoring-github-workflows (this skill)by dotnet875.5k2d agoSKILL.md
Agent-Reachby Panniantong10085.6k11d agoCLAUDE.md
rufloby ruvnet10073.3ktodayCLAUDE.md
Scraplingby D4Vinci10083.9ktodayMCP Server
algorithmic-artby anthropics100177.9k4d agoSKILL.md

Frequently asked questions

How do I install authoring-github-workflows?
Run npx skills add dotnet/skills --skill authoring-github-workflows. The install tabs above show the steps for each supported agent.
Which AI agents does authoring-github-workflows work with?
It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
Is authoring-github-workflows safe to use?
It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is authoring-github-workflows still maintained?
The repository was last updated 2 days ago, so authoring-github-workflows is actively maintained.

name: authoring-github-workflows description: "Author and review GitHub Actions workflow YAML safely so syntactically-valid YAML can't ship a workflow that GitHub Actions refuses to run. USE FOR: editing, adding, or reviewing any file under .github/workflows/, writing run-name/name/if/env/run values that contain ${{ }} expressions, diagnosing a run that fails with 'This run likely failed because of a workflow file issue' and no jobs starting, deciding when a workflow scalar must be quoted, validating workflows with actionlint. DO NOT USE FOR: authoring application YAML unrelated to GitHub Actions, Azure Pipelines, GitLab CI, or non-workflow YAML. SCOPE: this skill covers syntactic/structural correctness of workflow YAML (quoting, parsing, actionlint); for semantic and functional workflow design (what a workflow should do, agentic-workflow behavior), see .github/agents/agentic-workflows.agent.md — the two are complementary. INVOKES: actionlint (downloaded pinned binary) plus git/grep for inspection." license: MIT

Authoring GitHub Actions Workflows Safely

GitHub Actions workflow files are YAML, but valid YAML is not the same as a valid workflow. A workflow can parse cleanly with yaml.safe_load (or a casual review) yet still be rejected by GitHub Actions at load time — producing the opaque failure "This run likely failed because of a workflow file issue" with zero jobs started. This skill teaches the YAML-vs-Actions traps (the #-as-comment trap above all), how to quote expression scalars correctly, and how to validate with actionlint before merge.

Scope: syntactic vs. semantic. This skill is about the syntactic and structural correctness of workflow YAML — quoting, parsing, and actionlint-level validity that determines whether GitHub Actions will load and run a file at all. It is not about what a workflow should do or how an agentic workflow should behave. For semantic and functional guidance (designing workflow logic, agentic-workflow patterns, gh-aw authoring), use .github/agents/agentic-workflows.agent.md. The two are complementary: get the behavior right with the agent, get the YAML right with this skill.

When to Use

  • Editing, adding, or reviewing any file under .github/workflows/.
  • Writing a run-name, name, if, env, with, or run value that embeds a ${{ }} expression.
  • A workflow run failed with "This run likely failed because of a workflow file issue" and no jobs ran.
  • Eval/CI on main suddenly breaks for every run after a workflow edit merged, even though the change "looked fine."
  • Deciding whether a YAML scalar needs quoting.

When Not to Use

  • Authoring non-Actions YAML (app config, Kubernetes, Compose, Azure Pipelines, GitLab CI).
  • Pure shell/script logic inside an already-valid run: block (that is a scripting task, not a workflow-syntax task).

The #1 Trap: # inside an unquoted expression becomes a YAML comment

In YAML, a space followed by # starts a comment. In an unquoted (plain) scalar, everything from that space-then-# to end-of-line is silently discarded:

# BAD — the run-name is silently truncated at " #"
run-name: ${{ inputs.pr_number != '' && format('Evaluate PR #{0} @ {1}', inputs.pr_number, inputs.head_sha) || '' }}

YAML parses this as run-name: ${{ inputs.pr_number != '' && format('Evaluate PR — an unterminated ${{ expression. yaml.safe_load succeeds (it just sees a truncated string with a trailing comment), so the bug passes naive validation, but GitHub Actions rejects the malformed expression and refuses to start any run.

# GOOD — wrap the whole value in double quotes so '#' stays inside the scalar
run-name: "${{ inputs.pr_number != '' && format('Evaluate PR #{0} @ {1}', inputs.pr_number, inputs.head_sha) || '' }}"

The inner expression already uses single quotes, so double-quoting the scalar is safe. This is exactly the bug that broke dotnet/skills evaluation on main (PR #746 → fixed by quoting).

Other characters that force quoting in a plain scalar

| Character / pattern | Why it breaks | Fix | |---------------------|---------------|-----| | space then # (space-hash) | Starts a YAML comment; truncates the value | Quote the whole value | | Leading *, &, !, ?, \|, >, @, ` | YAML anchors/aliases/tags/block scalars | Quote the value | | Leading { or [ | Parsed as flow mapping/sequence (a bare ${{ }} starts with $, which is safe, but {{ after a leading char is risky) | Quote the value | | : then space (colon-space) inside the value | Parsed as a nested mapping key | Quote the value | | Leading/trailing spaces that matter | Plain scalars strip them | Quote the value | | Values that are true/false/yes/no/on/off/numbers but must stay strings | YAML type coercion | Quote the value |

Rule of thumb: if a name, run-name, if, env, or with value contains a ${{ }} expression and any literal #, :, or leading special character, wrap the entire scalar in double quotes.

Workflow

Step 1: Identify the changed/authored workflow files

git diff --name-only origin/main... -- .github/workflows/

For each file, scan every line that contains ${{ together with a #, a colon-space, or a leading special character.

Step 2: Quote risky expression scalars

Wrap the full value in double quotes when the value embeds an expression and contains a # or other special character (see the table above). Prefer double quotes when the inner expression uses single quotes, and vice-versa. Do not escape the ${{ }} braces — quoting the scalar is enough.

Step 3: Validate with actionlint (authoritative)

actionlint understands the GitHub Actions schema and the expression grammar, so it catches exactly this class of bug that plain YAML linters miss. Download a pinned release and run it:

ACTIONLINT_VERSION=1.7.7
ACTIONLINT_SHA256=023070a287cd8cccd71515fedc843f1985bf96c436b7effaecce67290e7e0757
curl -fsSLo actionlint.tar.gz \
  "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
# Verify the download against the pinned checksum before extracting/executing it:
echo "${ACTIONLINT_SHA256}  actionlint.tar.gz" | sha256sum -c -
tar -xzf actionlint.tar.gz actionlint
# Focus on workflow/expression correctness; silence shell/py style noise:
./actionlint -shellcheck= -pyflakes= -color .github/workflows/*.yml

On Windows PowerShell, use the actionlint_<ver>_windows_amd64.zip asset and Expand-Archive.

The truncated-expression bug surfaces as:

got unexpected EOF while lexing end of string literal, expecting ''' [expression]

A clean exit code 0 means the workflows are structurally valid.

Step 4: Confirm a YAML-only check is not enough

Do not rely on yaml.safe_load, yamllint, or "it parses" as proof. They accept the truncated-comment form. Only actionlint (or pushing and watching GitHub Actions parse it) validates the Actions layer.

Step 5: Keep the CI gate green

This repository runs actionlint automatically (see .github/workflows/actionlint.yml) on any PR that touches .github/workflows/. Ensure your change passes that check before requesting review. If you add a new workflow, the gate covers it automatically.

Validation

  • [ ] Every ${{ }} value containing #, a colon-space, or a leading special character is wrapped in quotes.
  • [ ] actionlint -shellcheck= -pyflakes= .github/workflows/*.yml exits 0.
  • [ ] No workflow run reports "This run likely failed because of a workflow file issue".
  • [ ] The actionlint CI check is green on the PR.

Common Pitfalls

| Pitfall | Solution | |---------|----------| | Unquoted run-name/name with # inside the expression | Wrap the whole value in double quotes | | Trusting yaml.safe_load/yamllint/a code review to catch it | Run actionlint; YAML-only checks accept the truncated form | | Escaping ${{ braces to "fix" it | Don't — quote the scalar instead; escaping breaks the expression | | Using single quotes around a value that contains single quotes | Use double quotes for the outer scalar | | Adding actionlint with shellcheck enabled and drowning in pre-existing shell-style warnings | Run with -shellcheck= -pyflakes= to focus on workflow/expression errors | | Assuming a green YAML lint means the workflow will run | Push and confirm jobs actually start, or rely on the actionlint gate |

References

Related Skills

View on GitHub
GitHub Stars5.5k
CategoryAutomation
Updated2d ago
Forks418

Languages

C#

Trust signals

100/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

No cautions