skills/devops-pipeline/SKILL.md
Configure pre-commit hooks and lean GitHub Actions for shift-left quality assurance. Use when adding or auditing CI/CD to maximize local test coverage and minimize CI cost. Skip for Terraform/K8s, deployment pipelines, or non-GitHub CI providers.
npx skillsauth add luongnv89/skills devops-pipelineInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Implement comprehensive DevOps quality gates adapted to project type, with a shift-left philosophy: run as many checks as possible locally via pre-commit so developers get fast feedback and CI is a safety net rather than the primary gate.
Core principle: if a check can run on a developer's machine, it runs there. GitHub Actions runs only what a laptop genuinely cannot — matrix version testing, secrets-dependent scans, deployment, coverage publishing — plus one cheap job proving the hooks were not bypassed.
Every check lands in exactly one lane. This table is the single source of truth: workflow steps 2 and 3, the reference files, and any config this skill generates must agree with it.
| Lane | Time budget | What runs there |
|------|-------------|-----------------|
| pre-commit stage (every commit) | < 10s, changed files only | Format, lint, type-check, offline security scans, fast unit tests, compile/import check |
| pre-push stage (every push) | < 60s, whole repo | Full test suite, CLI E2E, coverage threshold, slow lint rulesets |
| GitHub Actions | billed per minute | Version matrix, secrets-dependent scans, coverage upload, deploy/release, bypass guard |
A check that fits an earlier lane must not be repeated in a later one. CI re-running the whole hook set on every push is the failure mode this skill exists to prevent.
To stay within the agent's context budget, this SKILL keeps templates short and links to references/*.md for language-specific configs, workflow templates, and the CLI E2E script.
Before creating/updating/deleting files in an existing repository, sync the current branch with remote:
branch="$(git rev-parse --abbrev-ref HEAD)"
git fetch origin
git pull --rebase origin "$branch"
If the working tree is not clean, stash first, sync, then restore:
git stash push -u -m "pre-sync"
branch="$(git rev-parse --abbrev-ref HEAD)"
git fetch origin && git pull --rebase origin "$branch"
git stash pop
If origin is missing, pull is unavailable, or rebase/stash conflicts occur, stop and ask the user before continuing.
This skill writes config into someone else's repository and installs git hooks. Observe all of these:
.pre-commit-config.yaml or .github/workflows/*.yml. Write a <file>.bak backup first, merge the new hooks into the existing file, show the user the diff, and ask them to confirm before writing. Preserve user-defined hooks and pinned rev: values, and leave the backup in place until the user confirms the merge.pre-commit validate-config, and run pre-commit run --all-files before installing the hooks — findings surface without any commit being blocked. Show the generated workflow as a diff; never land a file the user has not seen.pre-commit install preserves a foreign hook by moving it to .git/hooks/pre-commit.legacy and running in migration mode. Never pass -f/--overwrite, which removes that hook silently — if the user wants it gone, have them confirm the deletion explicitly.git commit --no-verify or git push --no-verify on the user's behalf. A failing hook is a finding to report, not an obstacle to route around.SKIP, relax a lint rule, or lower a coverage threshold to turn a run green. Report the failure and let the user decide.pre-commit is absent, or origin is missing — see Edge Cases for each.Detect project characteristics:
# Check for package files and configs
ls -la package.json pyproject.toml Cargo.toml go.mod pom.xml build.gradle *.csproj 2>/dev/null
ls -la .eslintrc* .prettierrc* tsconfig.json mypy.ini setup.cfg ruff.toml 2>/dev/null
ls -la .pre-commit-config.yaml .github/workflows/*.yml 2>/dev/null
Identify:
--help, click/argparse/cobra source) to build an E2E test suiteInstall pre-commit framework:
pip install pre-commit # or brew install pre-commit
Create .pre-commit-config.yaml based on detected stack. See references/precommit-configs.md for language-specific configurations.
pre-commit stage — every commit, under 10 seconds on changed files:
detect-secrets)pre-push stage — every git push, under 60 seconds:
GitHub Actions only — what a laptop cannot do:
Use the modern stage names. pre-commit 3.2 renamed commit to pre-commit and push to pre-push; the old names emit a deprecation warning on 4.x and are scheduled for removal. Always emit the new names, and run pre-commit migrate-config against any pre-existing config still using the old ones.
If the project is a CLI tool, create scripts/e2e_test.sh that exercises every command/subcommand to verify the CLI works end-to-end (not just compiles). Wire it into pre-commit on the pre-push stage.
See references/cli-e2e.md for command discovery patterns, the script template, and the pre-commit hook snippet.
Install hooks:
pre-commit install
pre-commit install --hook-type pre-push # pre-push hooks are NOT installed by default
pre-commit run --all-files # test commit-stage hooks against existing code
git commit --no-verify and git push --no-verify skip every hook, and nothing local can prevent that. The CI bypass guard in step 3 is what keeps these gates enforceable — do not drop it when trimming CI.
Create .github/workflows/ci.yml. Keep it thin: the hooks already ran everything that runs locally, so CI covers the third lane of the routing table plus one guard. See references/github-actions.md for workflow templates.
CI runs exactly four kinds of thing:
--no-verify otherwise makes local gates optional.The bypass guard, in full:
hooks:
name: Verify hooks were not bypassed
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# ... set up the project toolchain and Python here ...
- name: Run both hook stages over the PR diff
run: |
pip install pre-commit
base="${{ github.event.pull_request.base.sha }}"
pre-commit run --from-ref "$base" --to-ref HEAD
pre-commit run --hook-stage pre-push --from-ref "$base" --to-ref HEAD
Four details are load-bearing; drop any one and the job fails on its first run:
pre-commit run lines. The first executes commit-stage hooks only — the full suite and the CLI E2E tests live on pre-push and are silently skipped without the second. pre-commit/[email protected] shares this blind spot, so call the CLI directly.fetch-depth: 0. actions/checkout clones at depth 1, so the base SHA is absent and --from-ref dies on a bad object.if: github.event_name == 'pull_request'. On a push event github.event.before is all zeros for a branch's first push and stale after a force-push.language: system shell out to npm, mypy, go, or cargo.Keep the matrix off the hot path: gate it on push to the default branch or on a release tag, not on every PR commit. A three-version matrix on every push is triple the bill for a signal the hooks already gave locally.
# Commit-stage hooks
pre-commit run --all-files
# Push-stage hooks (full suite, includes E2E) — not covered by the line above
pre-commit run --all-files --hook-stage pre-push
# Verify the CLI E2E script directly
bash scripts/e2e_test.sh
If all local checks pass, GitHub Actions becomes a thin verification layer, not the primary quality gate.
| Language | Formatter | Linter | Type Check | Security | Tests | |----------|-----------|--------|------------|----------|-------| | JS/TS | Prettier | ESLint | tsc | npm audit | Jest/Vitest | | Python | Ruff/Black | Ruff | mypy | Bandit + detect-secrets | pytest | | Go | gofmt | golangci-lint | built-in | gosec | go test | | Rust | rustfmt | Clippy | built-in | cargo-audit | cargo test | | Java | google-java-format | Checkstyle | - | SpotBugs | mvn test |
Which lane each of these belongs to is fixed by the Check Routing Table above — do not re-split checks differently here.
After running the skill, the repository contains:
.pre-commit-config.yaml — formatting, linting, type-checking, and fast unit tests on the pre-commit stage; full test suite, coverage threshold, and E2E tests on the pre-push stage..github/workflows/ci.yml — CI carrying only the four responsibilities from step 3: diff-scoped bypass guard, version matrix, secrets-dependent work, deploy. No standalone lint, format, type-check, or test steps duplicating a hook.scripts/e2e_test.sh (CLI projects only) — executable script exercising every CLI command/subcommand.Example .pre-commit-config.yaml snippet for a Python project:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.4
hooks:
- id: ruff
stages: [pre-commit]
- id: ruff-format
stages: [pre-commit]
- repo: local
hooks:
- id: mypy
name: mypy type check
entry: mypy src/
language: system
stages: [pre-commit]
- id: pytest-fast
name: fast unit tests
entry: pytest tests/unit -x -q
language: system
stages: [pre-commit]
- id: pytest-full
name: full test suite
entry: pytest --cov=src --cov-report=xml
language: system
stages: [pre-push]
A run passes when all of the following are true:
.pre-commit-config.yaml exists at the repo root and lists at least one hook for the detected primary language (formatter, linter, or type checker).id from .pre-commit-config.yaml appears in a workflow run: step other than the bypass guard, and no check runnable on a laptop is CI-only.stages: use the modern names (pre-commit, pre-push, manual); no generated config emits the deprecated commit or push.pre-commit install and pre-commit install --hook-type pre-push..github/workflows/*.yml exists and carries only the four CI responsibilities from step 3.--from-ref/--to-ref) and runs both stages.pre-commit run --all-files and pre-commit run --all-files --hook-stage pre-push both succeed (or their failures are surfaced explicitly to the user, not auto-suppressed).pre-push stage per the language reference files.pip install pre-commit or brew install pre-commit) and stop; don't generate config files for a tool that isn't present..pre-commit-config.yaml: Merge new hooks into the existing file rather than overwriting; preserve user-defined hooks and pinned revs.files: path filters so hooks only run on relevant subdirectories. Local language: system entries must also target the package dir (npm --prefix frontend, pytest backend/tests) — files: only filters which files trigger the hook, not cwd.origin remote: Skip the repo-sync step and inform the user; proceed with local-only setup.pre-commit to pre-push, or pre-push to CI — and record the reason in a comment on the hook so the next reader knows it was measured, not guessed.pre-commit migrate-config before merging new hooks in, so the file does not end up half-migrated.--no-verify: Local gates cannot stop this. Keep the CI bypass guard, and report the bypass rate rather than adding more hooks.After completing each major step, output a status report in this format:
◆ [Step Name] ([step N of M] — [context])
··································································
[Check 1]: √ pass
[Check 2]: √ pass (note if relevant)
[Check 3]: × fail — [reason]
[Check 4]: √ pass
[Criteria]: √ N/M met
____________________________
Result: PASS | FAIL | PARTIAL
Adapt the check names to match what the step actually validates. Use √ for pass, × for fail, and — to add brief context. The "Criteria" line summarizes how many acceptance criteria were met. The "Result" line gives the overall verdict.
Phase: Project Analysis — checks: Project detection, Existing tooling scan, CLI detection, Command enumeration
Phase: Pre-commit Configuration — checks: Pre-commit setup, Commit-stage hooks installed, Push-stage hooks installed, Modern stage names used, E2E script created (if CLI)
Phase: GitHub Actions Setup — checks: GitHub Actions config, CI limited to the four responsibilities, Bypass guard runs both stages, Matrix off the per-commit path
Phase: Pipeline Verification — checks: Commit-stage hooks pass, Push-stage hooks pass, E2E tests pass (if CLI), No check duplicated across lanes
pre-push tests and E2E hookspre-push hookdevelopment
Scan a live site with isitagentready.com, then approve each step: triage the 0-5 agent-readiness score, write agent-ready-plan.md, file issues via /plan-to-issues. Don't use for applying llms.txt/SEO fixes (seo-ai-optimizer) or app-store ASO.
development
Review a product codebase and landing page against 32 viral principles and produce a Virality Score plus ranked fixes. Use to audit virality or prioritize growth. Don't use for SEO, ASO, copywriting, or code review.
development
Generate a Technical Architecture Document (TAD) from a PRD. Use when asked to design system architecture or define how a product is built. Updates tad.md and reports GitHub links. Don't use for PRD authoring, sprint tasks, or code implementation.
development
Check product and brand names for conflicts across trademarks, domains, social handles, and package registries. Returns a risk level and Proceed/Modify/Abandon recommendation. Skip for name brainstorming, logo design, or trademark filings.