Implicit
jg-ci
A single check workflow, permissions, timeouts, caching, and action pinning for GitHub Actions.
- Usage
- Loads automatically
When to use it
It loads on its own when a task touches GitHub Actions workflows, including CI and deployment pipelines. Call it by name to load it before such a task.
When it loads
Your agent loads the skill on its own when a request like this touches its area.
Add a GitHub Actions workflow that runs the tests on every pull request.
Runs the project's check command with read-only permissions, a timeout, cancelled superseded runs, and lockfile-keyed caching, adding no bots or extra jobs.
SKILL.md
What the agent reads
The complete instructions your agent loads when a task touches its area.
Application
The agent loads this skill on its own when a task touches its area. This skill’s area is GitHub Actions workflows, reusable workflows, composite actions, Dependabot configuration, and CI and deployment pipelines built on GitHub Actions.
- It adds domain rules to the task. It never authorizes actions, widens scope, or replaces the workflow or approvals of a skill the developer invoked.
- It ranks with the repository’s coding instructions. When they conflict, the coding instructions win, except for the exceptions this skill states for its own area.
- The repository’s established conventions win over this skill’s naming, layout, and style rules. Its correctness and safety rules, and the exceptions it states for its own area, still apply.
- Check the installed versions first. This skill was written for GitHub Actions as of October 2026, with
actions/checkoutv7,actions/setup-nodev7,actions/cachev6,actions/upload-artifactv7, andactions/download-artifactv8, plus npm 11 and 12 and pnpm 10 and 11 for its install rules. An item marked with a minimum version, written like (18+), applies only when that version or a later one is installed. For an older installed version, follow that version’s official documentation. - Before relying on one of this skill’s version-specific items, check it against the current official guidance when the installed version of the technology is newer than the one this skill was written for, or when the version bullet gives a review month for something without an installed version, such as a hosted service or browser behavior, and that month is more than six months before the current date. Where an item differs from that guidance, follow the guidance. Version-specific items are API, syntax, and feature recommendations, and anything marked with a minimum version. This skill’s conventions and requirements, such as its naming, layout, style, reuse, and safety rules, keep their usual precedence even where official guidance suggests otherwise. Report each item that looks outdated in the summary, with the installed version and what the current guidance says, and offer there to open an issue on the jg-skills repository,
https://github.com/jesusgraterol/jg-skills:- Never pause or stop a run for the offer, including an autonomous run. When no one can answer, include the pre-filled link described below instead of asking.
- First search the repository’s open issues, and skip the offer when one already covers the item. When the search can’t run, say so next to the link, so the developer checks the existing issues before submitting.
- Open an issue only after the developer agrees, because it is public. Title it
<skill>: <item> looks outdated on <technology> <version>, and include only the skill name, the outdated item, the installed version, and a link to the official documentation, never code, file paths, or project details. Add no label. - Use
gh issue createwhenghis installed and signed in. Otherwise give the developer a pre-filled link,https://github.com/jesusgraterol/jg-skills/issues/new?title=…&body=…, with both values URL-encoded.
- This skill isn’t a complete list. Where it says nothing, follow the official guidance for the installed version, and in new code the task touches, prefer the features that guidance currently recommends over older ones that do the same job, unless the repository has an established pattern for that job. Before using a newer approach instead of one this skill gives, confirm it in that version’s official documentation, never from memory alone, and report the item as outdated as described above. When that documentation can’t be reached, keep this skill’s approach and report that the newer approach couldn’t be confirmed, without pausing the run.
- Rules that say “prefer” are defaults: departing from one with a stated reason is fine. Rules that say “never”, “always”, or “must” are requirements.
- Nothing in this skill requires adding a dependency, enabling a compiler or tool, upgrading, or migrating existing code.
Changing CI
- CI changes affect every contributor and every deployment, so change workflows only when the task is about them. When other work can’t pass CI without a workflow change, propose that change instead of making it, and never propose CI improvements the task doesn’t need.
- Never weaken, skip, or disable a check, a required status check, or branch protection to make a run pass.
Requirements
-
Always set the workflow’s top-level
permissionsto the minimum, usuallycontents: read, and raise them per job only where that job needs more. -
Always set
timeout-minuteson every job that runs steps, because the default is 360 minutes. A job that calls a reusable workflow can’t take one, so the called workflow’s own jobs set it. -
Always pass untrusted event data, such as pull request titles and bodies, branch names, or commit messages, to
run:scripts throughenv:. Never interpolate it into a script with${{ }}, because the value becomes part of the script:yaml - name: Check the pull request title env: TITLE: ${{ github.event.pull_request.title }} run: | if [[ ${#TITLE} -gt 72 ]]; then echo "::error::The title is longer than 72 characters." exit 1 fi -
Never check out or run a pull request’s code in a
pull_request_targetorworkflow_runworkflow, even with read-only permissions, because both run in the base repository’s context with its secrets and caches. Usepull_requestfor anything that runs the pull request’s code. -
Never print secrets. Mask values derived from them with
::add-mask::before anything can log them, and keep production secrets in environments with protection rules. -
Never cancel a deployment in progress. In a workflow that both verifies pull requests and deploys, cancel only pull request runs:
yaml concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} -
Never restore caches in workflows triggered by releases or tags, or that publish packages: no
actions/cache, no setup-action caching, andpackage-manager-cache: falseonactions/setup-node, which otherwise caches on its own whenpackage.jsonnames npm as itspackageManager. A poisoned cache would end up in what gets published. CI and site deploys keep caching.
Foundation
- Prefer one workflow per repository. Its check job runs the project’s check command on
pull_requestand on pushes to the default branch, even when the task mentions only pull requests, so the merged tree is checked too. When the project deploys, a deploy jobneedsthe check job and runs only for pushes to the default branch. - Prefer one check command that runs every check the project has, such as
npm run check, so CI and developers run the same thing. When there is none, run the project’s existing test, lint, and build commands as steps of the one job. - A new check reaches CI by joining the check command. Never add a job, a matrix, a workflow, a scheduled run, or a bot unless the developer asks for it or another loaded skill requires it for its own area, such as jg-npm-package’s runtime and release jobs.
- When creating a repository’s first workflow, offer once, in the summary, to turn on Dependabot alerts and security updates in the repository’s settings. They need no configuration file, and they open pull requests only for alerts that have a fix available. Turn them on only with the developer’s agreement.
Defaults
- Prefer cancelling superseded runs with a concurrency group per workflow and ref, such as
${{ github.workflow }}-${{ github.ref }}. - Prefer the setup actions’ built-in caching, such as
cache: npmonactions/setup-node, which keys the cache by the lockfile. Publishing workflows are the exception the requirements state. - Prefer installs that keep the lockfile frozen:
npm ci, orpnpm install --frozen-lockfile. - Prefer installs that run no dependency lifecycle scripts. npm 12 skips scripts its
allowScriptspolicy doesn’t approve, pnpm 10 skips unapproved builds with a warning, and pnpm 11 fails on them; with npm 11 and older or pnpm 9 and older, pass--ignore-scripts. Approve the packages that need their scripts in npm’sallowScriptsor pnpm’sallowBuilds(10.26+), never with an allow-all flag such as--dangerously-allow-all-scriptsordangerouslyAllowAllBuilds. - Prefer setting
timeout-minutesnear a job’s normal duration, about twice its typical run time, so a slowdown fails visibly instead of running unnoticed for most of an hour. - Prefer OIDC (
id-token: write) for deployments over long-lived cloud or registry secrets.
Pinning
- When the repository already pins actions another way, such as with an
actions.lockfile, follow that setup. - Otherwise, pin third-party actions to a full commit SHA with the version in a same-line comment, such as
# v6.0.0, and keep GitHub’s ownactions/*on major tags, such as@v7. Prefer arun:step or one of GitHub’s own actions over a third-party action. - Resolve a SHA from the action’s repository, for example with
git ls-remote --tags https://github.com/<owner>/<action>, and for an annotated tag take the peeled line ending in^{}, which holds the commit rather than the tag object. Never write a SHA from memory. When it can’t be resolved, use the release tag and list the action in the summary as unpinned. - A new
uses:line takes the action’s latest release, checked rather than recalled, for example withgh release view --repo <owner>/<action>. When the release can’t be checked, say so in the summary. - Don’t migrate existing workflows or their
uses:versions only to follow this skill. Only newly addeduses:lines follow these rules.
Verification
- Run
actionlint, andzizmorfor security, when they are installed. Never install them. - Without linting, state that the workflow is unverified until it runs.
- When a run exists, read its result with
gh run viewinstead of assuming it passed.