agentleFS
mikejhillmikejhill/agent-skills/skills/github-actions/SKILL.md

github-actions

Skill0 starsChanged 8 months agoMITView on GitHub

Use when creating, modifying, or refactoring GitHub Actions workflows for any project. Covers CI/CD pipeline design, GitOps-based releases with automated tagging and changelog generation, Conventional Commits enforcement, multi-environment matrix builds, performance optimization (caching, parallelism), test result presentation, and trusted action selection.

  • Reads credentials

49 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use react-native-brownfield-migration, gitlab-ci and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • maikotrindadeSkill

    react-native-brownfield-migration

    Provides an incremental adoption strategy to migrate native iOS or Android apps to React Native or Expo using @callstack/react-native-brownfield for initial setup. Use when planning migration steps, packaging XCFramework/AAR artifacts, and integrating them into host apps.

    Also in 4 projects that use this

  • jcsaaddupuySkill

    gitlab-ci

    GitLab CI/CD configuration guide

    Also in 3 projects that use this

  • maikotrindadeSkill

    upgrading-react-native

    Upgrades React Native apps to newer versions by applying rn-diff-purge template diffs, updating package.json dependencies, migrating native iOS and Android configuration, resolving CocoaPods and Gradle changes, and handling breaking API updates. Use when upgrading React Native, bumping RN version, updating from RN 0.x to 0.y, or migrating Expo SDK alongside a React Native upgrade.

    Also in 3 projects that use this

  • rogue-dev-studioSkill

    nodejs

    Node.js development environment. Use when the project needs this capability or the user / team manifest asks for it. Use for specialized `nodejs` work when listed in TEAM.yaml or explicitly requested.

    Also in 4 projects that use this

  • Sorcha-PlatformSkill

    grpc

    Build or review gRPC services and clients in .NET. USE FOR: ASP.NET Core gRPC, protobuf contracts, unary or streaming RPC, gRPC client factory, interceptors, deadlines, cancellation, channel reuse, backend service integration. DO NOT USE FOR: broad browser-facing APIs without gRPC-Web tradeoff review, SignalR realtime hubs, plain REST APIs. INVOKES: dotnet build/test and focused service or client smoke checks when code changes.

    Also in 3 projects that use this

  • ihiteshguptaSkill

    terraform

    Expert in Infrastructure as Code with Terraform. Use for creating, managing, and versioning infrastructure across cloud providers.

    Also in 5 projects that use this

The file

Show its rules and text

We split this skill into the rules it gives an agent

33 rules. 0 are common, 17 are distinctive, and 16 are very specific to this project.

  • 0

    Common

    Most of the 38 edited versions we read keep these.

  • 17

    Distinctive

    This author's own choices. Worth a look.

  • 16

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    All commits MUST follow the Conventional Commits specification.

    line 22
  2. Distinctive:

    When using squash-merge, the PR title serves as the merge commit message and MUST follow conventional commit format

    line 34
  3. Very specific:

    Every project MUST maintain a CHANGELOG.md file following Keep a Changelog.

    line 53
  4. Distinctive:

    Use these categories: Added, Changed, Deprecated, Removed, Fixed, Security

    line 59
  5. Distinctive:

    Every project MUST have at minimum these workflows:

    line 69
  6. Distinctive:

    Do not mix these responsibilities.

    line 92
  7. Very specific:

    Run these jobs in parallel (no needs unless a true dependency exists):

    line 129
  8. Distinctive:

    Run in dry-run mode first.

    line 221
  9. Very specific:

    Use sed to insert a versioned section header below [Unreleased].

    line 226
  10. Very specific:

    Use setup actions with built-in caching.

    line 255
  11. Very specific:

    Add needs only when a job requires another's output.

    line 273
  12. Distinctive:

    Use matrix strategies to parallelize across OS and runtime versions.

    line 274
  13. Very specific:

    Use paths-ignore to skip CI for documentation-only changes.

    line 285
  14. Very specific:

    Use if conditions for expensive steps that apply only to specific matrix entries.

    line 286
  15. Very specific:

    Use if: always() on reporting steps so they execute even when earlier steps fail.

    line 292
  16. Very specific:

    Write Markdown to $GITHUB_STEP_SUMMARY for rich output on the run page.

    line 315
  17. Distinctive:

    Always emit JUnit XML from test runs and render it into the run UI with a dedicated reporter action.

    line 320
  18. Very specific:

    When running a matrix, give each leg a unique check_name so results don't overwrite each other.

    line 355
  19. Very specific:

    Use ::error file=path,line=N::message and ::warning::message workflow commands to surface issues inline on files.

    line 370
  20. Distinctive:

    Prefer OIDC trusted publishing for registries that support it (PyPI, npm).

    line 420
  21. Distinctive:

    Use GitHub environment protection rules with required reviewers for production deployments.

    line 422
  22. Distinctive:

    When SHA-pinning, look up the full commit hash for the tag on the action's releases page.

    line 437
  23. Distinctive:

    Every workflow MUST use the latest major version of every action it references.

    line 446
  24. Very specific:

    Before committing a workflow, verify each uses: reference is on the latest major version:

    line 471
  25. Very specific:

    Every referenced action MUST declare using: node24 (or a non-Node runtime such as docker / composite) at the pinned tag.

    line 482
  26. Very specific:

    Not every publisher maintains a floating major tag.

    line 487
  27. Very specific:

    If only vN.M.P tags are published (e.g.

    line 494
  28. Distinctive:

    Treat the resulting bump PRs as routine maintenance.

    line 502
  29. Distinctive:

    Only use actions that meet ALL of these requirements:

    line 512
  30. Very specific:

    Every project with GitHub Actions workflows MUST include status badges in the README.

    line 560
  31. Distinctive:

    Add these when applicable:

    line 576
  32. Distinctive:

    Use Markdown image-link syntax with the badge image and a link to the relevant page:

    line 588
  33. Distinctive:

    Place all badges on consecutive lines (one per line) with a blank line before and after the badge block.

    line 597

“Common” is measured: kept by at least 6 in 10 of the 38 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

GitHub Actions Skill

Overview

This skill defines standards for GitHub Actions workflows across any releasable project, regardless of language or framework. It produces CI pipelines, release automation, and deployment workflows that are fast, secure, and maintainable.

Three practices are mandatory and non-negotiable. Every workflow produced by this skill enforces them.

Required Practices

1. Conventional Commits

All commits MUST follow the Conventional Commits specification.

  • Format: type(scope): description (scope is optional)
  • Standard types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
  • Breaking changes: append ! after type/scope OR include BREAKING CHANGE: in the commit footer
  • Version bump mapping: fix → PATCH, feat → MINOR, breaking change → MAJOR
  • CI MUST validate commit messages on pull requests
  • When using squash-merge, the PR title serves as the merge commit message and MUST follow conventional commit format

2. GitOps Tag-Driven Releases

Git tags are the sole source of truth for releases. Tags and releases are tightly coupled.

  • Version tags use the format vMAJOR.MINOR.PATCH (e.g., v1.2.3)
  • Pre-release tags use a suffix: v1.2.3-rc.1, v1.2.3-beta.1
  • Tags MUST be created exclusively by the release workflow — never pushed manually by developers
  • Configure repository rulesets to protect tag patterns matching v* and restrict creation to the GitHub Actions actor
  • One tag = one release = one set of published artifacts. This coupling is absolute.

3. Keep a Changelog

Every project MUST maintain a CHANGELOG.md file following Keep a Changelog.

  • The ## [Unreleased] section accumulates changes between releases
  • During release, the workflow promotes [Unreleased] entries into a new versioned section with a date
  • Use these categories: Added, Changed, Deprecated, Removed, Fixed, Security
  • Developers write entries under [Unreleased]; the release workflow handles promotion. Never manually edit versioned sections.
  • CHANGELOG.md is the human-curated record for developers. GitHub Release notes are the auto-generated record for consumers. Maintain both.

Workflow Architecture

Every project MUST have at minimum these workflows:

WorkflowFileTriggerPurpose
CIci.ymlpush and pull_requestValidate code, run tests, check build
Releaserelease.ymlworkflow_dispatch manualVersion, tag, release, publish

Optional workflows:

WorkflowFileTriggerPurpose
Deploydeploy.ymlrelease event or workflow_dispatchPromote a release to an environment

Separation of Concerns

  • CI validates that code is correct and mergeable. It runs on every push and pull request. It NEVER publishes anything.
  • Release ships code. It runs on demand via workflow_dispatch. It determines the version, creates the tag, builds artifacts, and publishes to registries.
  • Deploy promotes a release to an environment. It is optional and only needed when deployment is separate from publishing.

Do not mix these responsibilities. CI does not release. Release does not deploy (unless publishing IS the deployment).

CI Workflow Design

Scaffold

name: CI

on:
  push:
    branches: [main]
    paths-ignore:
      - "*.md"
      - "docs/**"
      - "LICENSE"
  pull_request:
    branches: [main]
  merge_group:

permissions:
  contents: read
  checks: write
  pull-requests: read

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true

Note: paths-ignore is set on push only — not on pull_request — because skipping PR runs can block merge when required status checks are configured.

Jobs

Run these jobs in parallel (no needs unless a true dependency exists):

  1. Commit lint (PR only) — Validate the PR title follows Conventional Commits
  2. Lint — Static analysis, formatting, type checking
  3. Test — Unit and integration tests (matrix for OS/versions if applicable)
  4. Build — Verify artifacts can be produced (do NOT publish)

Optional: Markdown lint, Security audit

For branch protection stability, add a ci-pass aggregator job that needs all other jobs and serves as the sole required status check. This prevents matrix or job name changes from breaking protection rules. See Advanced Patterns for the full pattern.

Commit Message Validation

For squash-merge repositories (the most common strategy with Conventional Commits), validate the PR title:

commit-lint:
  if: github.event_name == 'pull_request'
  runs-on: ubuntu-latest
  permissions:
    pull-requests: read
  steps:
    - uses: amannn/action-semantic-pull-request@v6
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

For merge-commit or rebase-merge repositories, validate individual commit messages using commitlint.

PR vs Default Branch Deviations

ConcernPull RequestDefault Branch Push
Commit message validationYES — validate PR titleSKIP — validated at PR time
Full test matrixYESYES
Build artifactsVerify build succeedsVerify build succeeds
Code coverageCheck and reportRecord and report
Publish / deployNEVERNEVER

See CI Workflow Examples for complete, production-ready templates for each ecosystem.

Release Process

The release workflow uses workflow_dispatch so a human decides when to release but automation handles the execution. This is the recommended default; teams practicing continuous deployment may trigger releases automatically on merge instead.

Sequence

Execute these steps strictly in order. If any step fails, the workflow halts — no partial releases.

  1. Checkout — fetch-depth: 0 for full git history
  2. Determine version — Analyze conventional commits since the last tag; compute the next semantic version via dry-run
  3. Guard — Abort if no releasable commits exist and force-patch is false
  4. Validate — Run the full lint and test suite; MUST NOT proceed on failure
  5. Update CHANGELOG.md — Promote [Unreleased] entries to a new versioned section
  6. Update version files — Bump version in ecosystem manifests (package.json, Cargo.toml, pyproject.toml, etc.)
  7. Build — Produce release artifacts
  8. Commit and tag — Commit all changed files, create version tag, push both; use bot identity for the commit
  9. GitHub Release — Create release with artifacts and generated release notes
  10. Publish — Push to package registries (npm, PyPI, Maven Central, crates.io, NuGet, etc.)

See Release Automation Reference for the complete workflow template with full YAML.

Version Determination

ToolBest For
semantic-release (npm package)Node.js projects (rich plugin ecosystem)
go-semantic-release/action@v1Language-agnostic projects (no runtime dependency)
Custom scriptFull control over version logic

Run in dry-run mode first. Use the computed version for CHANGELOG, build, and tag steps.

CHANGELOG and Release Automation

Use sed to insert a versioned section header below [Unreleased]. Validate the CHANGELOG before and after mutation — confirm [Unreleased] exists before sed and the new version header exists after. Commit all changed files (CHANGELOG, manifests) — not just CHANGELOG.md. Create the tag and push atomically. Use softprops/action-gh-release@v2 with generate_release_notes: true for the GitHub Release.

See Release Automation Reference for the complete workflow template with full YAML, ecosystem-specific publishing, Docker layer caching, artifact attestation, and recovery procedures.

Branch Protection

The release workflow pushes commits and tags to the default branch. Configure a branch protection bypass for github-actions[bot] or use a GitHub App token. Document this in the repository's contributing guide.

Performance Optimization

Runner Cost

GitHub-hosted runner billing: Linux 1×, Windows 2×, macOS 10×. Use Linux for all jobs unless the project explicitly requires another OS.

Caching

Use setup actions with built-in caching. Avoid manual actions/cache unless no setup action covers your ecosystem.

EcosystemSetup ActionCaching
Gradlegradle/actions/setup-gradle@v4Automatic
Mavenactions/setup-java@v4cache: maven
Python (uv)astral-sh/setup-uv@v8.1.0Automatic
Python (pip)actions/setup-python@v5cache: pip
Node.jsactions/setup-node@v4cache: npm (or pnpm, yarn)
Goactions/setup-go@v5Automatic
RustSwatinem/rust-cache@v2Automatic
.NETactions/setup-dotnet@v4Use actions/cache for NuGet

Parallelism

  • Jobs without needs run concurrently. Exploit this by splitting lint, test, and build into separate jobs.
  • Add needs only when a job requires another's output.
  • Use matrix strategies to parallelize across OS and runtime versions.

Concurrency Control

  • CI workflows: cancel-in-progress: true — newer pushes supersede stale runs.
  • Release workflows: cancel-in-progress: false — never cancel an in-progress release.

Conditional Execution

  • Use paths-ignore to skip CI for documentation-only changes.
  • Use if conditions for expensive steps that apply only to specific matrix entries.
  • Collect code coverage on ONE matrix combination only (typically the latest runtime version on ubuntu-latest). Enforce thresholds with ecosystem tools (--fail-under=80, jacocoTestCoverageVerification, c8 --check-coverage).
  • Use if: always() on reporting steps so they execute even when earlier steps fail.

Timeouts

Set timeout-minutes on every job. Use 2–3× the expected duration.

Multi-Environment Testing

Configure matrix strategies with fail-fast: false so all combinations run to completion. Include only OS/version combinations the project actually supports. Use exclude to skip unnecessary combinations and include to attach flags (like coverage: true) to a single entry. Name jobs descriptively: name: "Test (${{ matrix.os }}, v${{ matrix.version }})".

See CI Workflow Examples for matrix patterns in each ecosystem.

Presentation

Job Summaries

Write Markdown to $GITHUB_STEP_SUMMARY for rich output on the run page. Use if: always() so summaries appear even on failure.

Test Reporters

Always emit JUnit XML from test runs and render it into the run UI with a dedicated reporter action. Two reporters are currently node24-native and actively maintained:

  • dorny/test-reporter@v3 — creates a GitHub check with file-level annotations for failures. Good when you want a linkable check listed alongside other required checks.
  • mikepenz/action-junit-report@v6 — posts a detailed table into the run summary, adds check annotations, and supports passing a custom check_name per matrix leg. Good default when you want the results visible directly on the workflow run page.

Emit JUnit output from the test step and pass the XML to the reporter in an if: always() step so failures still produce a report:

- run: pytest --junitxml=junit.xml                              # or vitest, jest --reporters=jest-junit, gradle test, etc.
- name: Publish test report
  if: always()
  uses: mikepenz/action-junit-report@v6
  with:
    report_paths: junit.xml
    check_name: Tests (${{ matrix.os }} / py${{ matrix.python-version }})
    include_passed: true
    detailed_summary: true
    require_tests: true
- name: Upload test results
  if: always()
  uses: actions/upload-artifact@v7
  with:
    name: test-results-${{ matrix.os }}-py${{ matrix.python-version }}
    path: junit.xml
    if-no-files-found: ignore

When running a matrix, give each leg a unique check_name so results don't overwrite each other. When running a pull_request from a fork, note that checks: write is unavailable — fall back to $GITHUB_STEP_SUMMARY markdown tables in that case.

Do NOT omit test reporters. A green workflow with no visible test results is operationally equivalent to one that never ran tests.

Build Scans (Gradle)

gradle/actions/setup-gradle@v4 links build scans in workflow output automatically. Add --scan to Gradle commands for public URLs.

Annotations

Use ::error file=path,line=N::message and ::warning::message workflow commands to surface issues inline on files.

Security

Permissions

Declare explicit permissions in every workflow. Never rely on repository defaults. Start from zero and add only what each workflow requires.

  • CI: contents: read, checks: write, pull-requests: read
  • Release: contents: write (push tags, create releases)
  • OIDC publishing: add id-token: write
  • PR interactions: add pull-requests: write

Script Injection Prevention

Never interpolate event data directly in run: blocks. This is the number-one Actions security vulnerability.

# DANGEROUS — attacker-controlled PR title executes as shell code
run: echo "PR: ${{ github.event.pull_request.title }}"

# SAFE — pass through an environment variable
env:
  PR_TITLE: ${{ github.event.pull_request.title }}
run: echo "PR: $PR_TITLE"

Any github.event.* value that originates from user input (PR title, branch name, commit message, issue body) MUST be passed via env:, never via ${{ }} in run:.

Fork Pull Request Security

Secrets are unavailable and GITHUB_TOKEN is read-only on pull_request from forks. Do NOT use pull_request_target as a workaround — it runs fork code with write permissions. See Advanced Patterns for the safe two-workflow pattern.

GITHUB_TOKEN Scope

GITHUB_TOKEN cannot trigger other workflows. If the release workflow must trigger a deployment workflow, use a GitHub App installation token or a fine-grained PAT with minimum necessary scopes.

Authentication

  • Prefer OIDC trusted publishing for registries that support it (PyPI, npm).
  • Use GitHub environment protection rules with required reviewers for production deployments.
  • Store third-party credentials as encrypted repository or environment secrets. Never log them.

Action Pinning

Pin to major version tags for readability, or full commit SHAs for maximum security in release workflows:

uses: actions/checkout@v6                                              # Major tag
uses: actions/checkout@<full-commit-sha>                               # SHA pin

When SHA-pinning, look up the full commit hash for the tag on the action's releases page. Dependabot automatically updates SHA pins.

Configure Dependabot to keep action versions current. See Release Automation Reference for the Dependabot configuration.

Action Version Currency

Every workflow MUST use the latest major version of every action it references. Stale versions cause three classes of problem observed in practice:

  1. Runtime deprecation warnings. GitHub periodically retires Node.js runtimes (Node 16 in 2023, Node 20 in 2026). Actions pinned to old majors still declare using: node20 and generate deprecation annotations on every run until bumped.
  2. Missing bug fixes and performance improvements. Major bumps of actions/checkout, actions/upload-artifact, actions/setup-*, and astral-sh/setup-uv routinely deliver faster caching, larger upload limits, and security patches.
  3. Incompatibility with newer runner images. Older action majors occasionally break when Ubuntu / Windows / macOS runner images update their preinstalled toolchains.

Do NOT use FORCE_JAVASCRIPT_ACTIONS_TO_NODE24, FORCE_JAVASCRIPT_ACTIONS_TO_NODE20, or ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION as a workaround. These environment variables force a mismatched Node runtime onto actions that declare an older one. They silence the annotation but do not fix the underlying maintenance debt, and they can introduce subtle runtime incompatibilities. Bump the action version instead.

Verifying currency

Before committing a workflow, verify each uses: reference is on the latest major version:

# Latest release of an action
gh api repos/{owner}/{repo}/releases/latest --jq .tag_name

# Node runtime declared by a published tag
curl -s https://raw.githubusercontent.com/{owner}/{repo}/{tag}/action.yml | grep "using:"

Every referenced action MUST declare using: node24 (or a non-Node runtime such as docker / composite) at the pinned tag. If a dependency still ships using: node20 at its latest tag, raise an upstream issue and consider alternatives; do not mask the warning.

Not every publisher maintains a floating major tag. Before pinning to @vN, confirm the tag exists:

gh api repos/{owner}/{repo}/tags --jq '.[].name' | head

If only vN.M.P tags are published (e.g. astral-sh/setup-uv at the time of writing), pin to the specific patch version instead of @vN; a non-existent floating tag causes an immediate workflow failure.

Keeping currency

  • Enable Dependabot for github-actions with interval: weekly and an open-pull-requests-limit that allows batched updates.
  • Treat the resulting bump PRs as routine maintenance. Merge them after CI passes; they should rarely require manual intervention.
  • During reviews, reject workflow changes that introduce @v4 or older of any action with a newer major available, unless there is a documented, time-bounded blocker in a code comment.

Trusted Actions

Selection Criteria

Only use actions that meet ALL of these requirements:

  • Published by GitHub (actions/*), a verified creator, or a recognized open-source organization
  • Actively maintained — updated within the past 12 months
  • Widely adopted — significant community usage and stars
  • Open source — auditable code

Curated List

PurposeAction
Checkoutactions/checkout@v6
Artifactsactions/upload-artifact@v7
Artifactsactions/download-artifact@v8
Attestationactions/attest@v4
Cacheactions/cache@v4
Javaactions/setup-java@v4
Node.jsactions/setup-node@v4
Pythonactions/setup-python@v5
Goactions/setup-go@v5
.NETactions/setup-dotnet@v4
Gradlegradle/actions/setup-gradle@v4
UV (Python)astral-sh/setup-uv@v8.1.0
Rust toolchaindtolnay/rust-toolchain@stable
Rust cacheSwatinem/rust-cache@v2
Go lintgolangci/golangci-lint-action@v6
GitHub Releasesoftprops/action-gh-release@v3
Docker buildxdocker/setup-buildx-action@v3
Docker builddocker/build-push-action@v6
Docker logindocker/login-action@v3
PyPI publishpypa/gh-action-pypi-publish@release/v1
Test reporterdorny/test-reporter@v3
JUnit reportermikepenz/action-junit-report@v6
PR title lintamannn/action-semantic-pull-request@v6
Semantic releasego-semantic-release/action@v1
Markdown lintDavidAnson/markdownlint-cli2-action@v23

The table above reflects current latest major versions. Action versions move; see Action Version Currency for how to keep them fresh on each repository.

Avoid actions with fewer than 100 stars, no updates in 12+ months, unknown publishers, excessive permission requirements, or functionality already covered by official actions/* actions.

README Badges

Every project with GitHub Actions workflows MUST include status badges in the README. Badges go immediately below the top-level heading (# Project Name), before any description text.

Required Badges

At minimum, include these badges:

BadgeSource
CIGitHub Actions workflow badge for ci.yml
ReleaseGitHub Actions workflow badge for release.yml
Licenseimg.shields.io/github/license/{owner}/{repo}

Optional Badges

Add these when applicable:

BadgeWhen to IncludeSource
VersionPublished to a package registryimg.shields.io/pypi/v/{pkg}, npmjs.com, etc.
Python versionPython projectsimg.shields.io/pypi/pyversions/{pkg}
CoverageCoverage service configuredCodecov, Coveralls, or shields.io
HACSHome Assistant integrationsHACS badge from hacs.xyz
DownloadsPublished to a registryimg.shields.io/pypi/dm/{pkg}, etc.

Format

Use Markdown image-link syntax with the badge image and a link to the relevant page:

[![CI](https://github.com/{owner}/{repo}/actions/workflows/ci.yml/badge.svg)](https://github.com/{owner}/{repo}/actions/workflows/ci.yml)
[![Release](https://github.com/{owner}/{repo}/actions/workflows/release.yml/badge.svg)](https://github.com/{owner}/{repo}/actions/workflows/release.yml)
[![License](https://img.shields.io/github/license/{owner}/{repo})](LICENSE)

Place all badges on consecutive lines (one per line) with a blank line before and after the badge block.

Anti-patterns

  • Manual tags — Developers pushing tags bypasses the release workflow and violates GitOps
  • Tag-triggered releases — Creates a chicken-and-egg problem; use workflow_dispatch instead
  • Publishing without validation — The release workflow MUST run tests before publishing
  • Default permissions — Repository defaults grant write-all; always declare explicit minimal permissions
  • Unbounded workflows — Missing timeouts, concurrency groups, and path filters waste CI minutes
  • Untrusted actions — Low-star, unmaintained actions are a supply-chain risk
  • Manual CHANGELOG edits for releases — Automate the version section promotion in the release workflow
  • Mixing CI and release — CI validates; release ships. Separate workflows, separate triggers, separate concerns.
  • Expression injection — Using ${{ github.event.*.title }} or similar user-controlled values directly in run: blocks
  • pull_request_target with checkout — Runs fork code with write token; use the two-workflow pattern instead
  • continue-on-error: true — Silently hides failures; use if: always() on reporting steps instead
  • version: latest in lint actions — Breaks caching and reproducibility; pin to a specific version
  • Stale action majors — Leaving @v4 / @v5 pinned after newer majors ship; causes Node.js runtime deprecation warnings and misses upstream fixes. See Action Version Currency.
  • FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 / ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION — Masks deprecation warnings instead of fixing them; bump the action version instead.
  • Tests without a reporter — Running pytest / jest / go test without emitting JUnit XML and publishing it via a test-reporter action makes failures invisible on the run page. See Test Reporters.

Related Files

  • references/release-automation.md: Complete release workflow template with CHANGELOG automation, ecosystem-specific publishing, deployment gating, Docker layer caching, artifact attestation, release failure recovery, and tag protection setup.
  • references/ci-workflow-examples.md: Production-ready CI workflow templates for Gradle, Python, Node.js, Go, Rust, and .NET.
  • references/advanced-patterns.md: Reusable workflows, composite actions, ci-pass aggregator job, GITHUB_TOKEN scope, fork PR handling, and debugging.

Example

Input: "Create CI and release workflows for a Python project using UV"

Output:

  1. .github/workflows/ci.yml — Commit lint (PR only), ruff check + format, mypy, pytest matrix (ubuntu + windows, Python 3.12 + 3.13), markdownlint, concurrency control, path filters
  2. .github/workflows/release.yml — go-semantic-release version determination, CHANGELOG promotion, uv build, tag push, GitHub Release, PyPI publish via OIDC

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.