From 75fc18d3aedad0b54bde31b0b4919d96cdad49d1 Mon Sep 17 00:00:00 2001 From: Sebastian Mendel Date: Mon, 20 Jul 2026 14:25:27 +0200 Subject: [PATCH 1/2] docs(reusable-workflows): make pitfall #6 fire when editing a consumer workflow Pitfall #6 already states that a CI gap belongs upstream in the shared workflow rather than in the consumer. It did not fire in a session that added a local acceptance-test job -- with its own checkout and PHP setup -- to two consumer repos, and the maintainer had to correct it twice. Two reasons, both addressed here. The skill was never loaded: the description said "authoring reusable workflows", which reads as authoring the shared workflow, not as editing a consumer's .github/workflows. The description and the When to Use list now name that case, kept within the 500-word cap by folding the duplicated branch-protection note into its list entry. And the pitfall stated the principle without a test for it. It now gives the consumer-side tell -- every job in a consumer is a `uses:` of a shared workflow, so a job with its own `steps:` or any non-org action is the smell, with a grep to check it -- plus the mechanics of the upstream alternative: an additive input defaulting to off, pins copied from a neighbouring job, a graceful skip for consumers that are not ready, and a warning against smuggling an extra suite through a command-override input, which silently drops the instrumented default such as the coverage upload. Signed-off-by: Sebastian Mendel --- skills/github-project/SKILL.md | 11 +++--- .../references/reusable-workflow-pitfalls.md | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/skills/github-project/SKILL.md b/skills/github-project/SKILL.md index 6cb5664..7321082 100644 --- a/skills/github-project/SKILL.md +++ b/skills/github-project/SKILL.md @@ -1,6 +1,6 @@ --- name: github-project -description: "Use when bootstrapping a repo (apply branch protection before first PR), PRs won't merge or BLOCKED, AI reviewer pushback, auto-merge fails for Dependabot/Renovate, branch protection or rulesets, CI fails, authoring reusable workflows, harden-runner, or CODEOWNERS/PR templates." +description: "Use when bootstrapping a repo (apply branch protection before first PR), PRs won't merge or BLOCKED, AI reviewer pushback, auto-merge fails for Dependabot/Renovate, branch protection or rulesets, CI fails, authoring or consuming reusable workflows, editing a repo's own .github/workflows, harden-runner, or CODEOWNERS/PR templates." license: "(MIT AND CC-BY-SA-4.0). See LICENSE-MIT and LICENSE-CC-BY-SA-4.0" compatibility: "Requires gh CLI, git." metadata: @@ -14,7 +14,8 @@ allowed-tools: Bash(gh:*) Bash(git:*) Bash(grep:*) Read Write ## When to Use -- **Post `gh repo create` + initial push, before first PR** — apply branch protection (REQUIRED, see below) +- **Post `gh repo create`, before first PR** — REQUIRED: `scripts/init-branch-protection.sh OWNER/REPO` (`references/repo-bootstrap.md`) +- Adding a job to a repo's workflow — see pitfall #6 - PR won't merge / threads - Auto-merge fails (Dependabot/Renovate) - Solo auto-approve @@ -26,8 +27,6 @@ allowed-tools: Bash(gh:*) Bash(git:*) Bash(grep:*) Read Write - CODEOWNERS, templates, labels - Fork PR merge base -> **REQUIRED post `gh repo create`:** `scripts/init-branch-protection.sh OWNER/REPO` — see `references/repo-bootstrap.md`. - ## Quick Diagnostics ### PR Won't Merge @@ -72,7 +71,7 @@ gh pr view PR --repo OWNER/REPO --json reviewThreads --jq '.reviewThreads' ### Merge Strategy Issues -See `references/auto-merge-guide.md` (signed-commit rebase fixes, workflow-file PRs, Copilot auto-approve race). +See `references/auto-merge-guide.md` (signed-commit rebase, workflow-file PRs, Copilot race). ## Running Scripts @@ -84,7 +83,7 @@ scripts/verify-github-project.sh /path/to/repository # local-checkout audit ## No editorializing -State what a change does, not how good it is; no self-praise. See `references/no-editorializing.md`. +State what a change does, not how good it is. See `references/no-editorializing.md`. ## References diff --git a/skills/github-project/references/reusable-workflow-pitfalls.md b/skills/github-project/references/reusable-workflow-pitfalls.md index a28b245..24b9294 100644 --- a/skills/github-project/references/reusable-workflow-pitfalls.md +++ b/skills/github-project/references/reusable-workflow-pitfalls.md @@ -103,6 +103,42 @@ Before adding a guard, check, or fix to a project's own workflow files, ask whet This is distinct from pitfalls #1–#5 above (which cover *how* to author and reference reusable workflows) — this is about *where* a fix belongs. +### The consumer-side tell + +The rule is easiest to apply as a property of the consumer's workflow file: **every job in a +consumer repo is a `uses:` of a shared workflow.** A job with its own `steps:` — checkout, +setup, install, run — is the smell, and third-party actions (`actions/checkout`, +`shivammathur/setup-php`, …) appearing anywhere outside the shared-workflow repo is the same +smell stated in terms of `uses:`. Verify with: + +```bash +grep -rn "uses:" .github/workflows/ | grep -v "YOUR_ORG/" +``` + +Anything that returns is either a genuinely project-specific exception or work that belongs +upstream. Pinning such an action to a SHA does not make it compliant — the pin is a separate +requirement (`reusable-workflow-security.md`), not a substitute for this one. + +### Extending the shared workflow instead + +When the shared workflow has no input for what the consumer needs, add one — this is the +supported path, not a workaround: + +- Add the input **defaulting to off** (`type: boolean`, `default: false`) and gate the new + job on it, so every existing consumer is unaffected. Verify the diff is purely additive + (`git diff -U0 | grep -E '^-[^-]'` returns nothing) — an existing consumer must not change + behaviour because another repo needed a feature. +- Copy the action pins verbatim from a neighbouring job in the same file rather than picking + versions independently; a shared workflow with two different `actions/checkout` SHAs is its + own maintenance problem. +- Give the new job a graceful skip (a `::notice::`) when the consumer lacks the underlying + script, so enabling the input in a repo that is not ready cannot hard-fail. +- Land it, then flip the input on in the consumer. The consumer's change is one line. + +Do not reach for `unit-test-command`-style override inputs to smuggle an extra suite into an +existing job: those replace the job's instrumented default command and silently drop whatever +it did (coverage upload, for instance). + ## 7. Run with zero jobs whose name is the file path = workflow-validation failure A run with `conclusion: startup_failure` (or `failure`), **zero jobs**, and a displayed name that falls back to the workflow **file path** failed at workflow *validation*, before any job started. The exact reason is **only in the Actions UI banner** — it is not exposed via the REST API (`gh run view --log[-failed]` returns "log not found"; run/annotations/check-suite endpoints are empty). If you can't see the UI, ask for the banner text. Two causes seen in practice: From 66cf07cb83cc5f9033d3a3b2f4d7060789c83985 Mon Sep 17 00:00:00 2001 From: Sebastian Mendel Date: Mon, 20 Jul 2026 14:49:29 +0200 Subject: [PATCH 2/2] docs(reusable-workflows): address review feedback on pitfall #6 Restores "+ push" to the bootstrap entry: init-branch-protection.sh exits 4 on an empty repo ("default branch ref does not yet exist"), so the push is a precondition, not narrative. Compressing that line to stay under the word cap had dropped it. SKILL.md is at 499 words. Makes the consumer-side grep case-insensitive, since an org can appear with different casing in a uses: path, and compares against the base branch rather than the working tree when checking that the upstream change is additive -- git diff -U0 alone reports nothing once the change is staged or committed, which would read as a pass. Signed-off-by: Sebastian Mendel --- skills/github-project/SKILL.md | 2 +- .../github-project/references/reusable-workflow-pitfalls.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/skills/github-project/SKILL.md b/skills/github-project/SKILL.md index 7321082..eb59567 100644 --- a/skills/github-project/SKILL.md +++ b/skills/github-project/SKILL.md @@ -14,7 +14,7 @@ allowed-tools: Bash(gh:*) Bash(git:*) Bash(grep:*) Read Write ## When to Use -- **Post `gh repo create`, before first PR** — REQUIRED: `scripts/init-branch-protection.sh OWNER/REPO` (`references/repo-bootstrap.md`) +- **Post `gh repo create` + push, before first PR** — REQUIRED: `scripts/init-branch-protection.sh OWNER/REPO` (`references/repo-bootstrap.md`) - Adding a job to a repo's workflow — see pitfall #6 - PR won't merge / threads - Auto-merge fails (Dependabot/Renovate) diff --git a/skills/github-project/references/reusable-workflow-pitfalls.md b/skills/github-project/references/reusable-workflow-pitfalls.md index 24b9294..f315195 100644 --- a/skills/github-project/references/reusable-workflow-pitfalls.md +++ b/skills/github-project/references/reusable-workflow-pitfalls.md @@ -112,7 +112,7 @@ setup, install, run — is the smell, and third-party actions (`actions/checkout smell stated in terms of `uses:`. Verify with: ```bash -grep -rn "uses:" .github/workflows/ | grep -v "YOUR_ORG/" +grep -rn "uses:" .github/workflows/ | grep -vi "YOUR_ORG/" ``` Anything that returns is either a genuinely project-specific exception or work that belongs @@ -126,7 +126,7 @@ supported path, not a workaround: - Add the input **defaulting to off** (`type: boolean`, `default: false`) and gate the new job on it, so every existing consumer is unaffected. Verify the diff is purely additive - (`git diff -U0 | grep -E '^-[^-]'` returns nothing) — an existing consumer must not change + (`git diff origin/main... -U0 | grep -E '^-[^-]'` returns nothing) — an existing consumer must not change behaviour because another repo needed a feature. - Copy the action pins verbatim from a neighbouring job in the same file rather than picking versions independently; a shared workflow with two different `actions/checkout` SHAs is its