Describe the bug
The README regeneration bot in .github/workflows/documentation.yml fails to push
whenever the triggering commit changed any file under .github/workflows/.
GitHub treats every file in .github/workflows/ as a workflow definition —
including a plain Markdown file such as .github/workflows/README.md — and
refuses a push that touches one unless the pushing token carries the workflows
permission. The App token is deliberately least-privilege
(permission-contents: write, permission-pull-requests: write), so the push is
rejected:
[remote rejected] chore/readme-regeneration -> chore/readme-regeneration
(refusing to allow a GitHub App to create or update workflow
`.github/workflows/README.md` without `workflows` permission)
error: failed to push some refs to 'https://github.com/lightspeedwp/.github'
The process '/usr/bin/git' failed with exit code 1
The chain that causes it:
- A push to
develop changes a file under .github/workflows/ (the workflow's
push.paths filter includes .github/workflows/**).
- "Resolve impacted README files" runs
scripts/workflows/resolve-readme-files.cjs,
which adds the README.md in each changed file's directory — so
.github/workflows/README.md enters the set.
scripts/agents/meta.agent.js rewrites it.
- "Create or update README PR" (
peter-evans/create-pull-request v8.1.1, pinned
5f6978faf089d4d20b00c7766989d076bb2fc7f1) stages and pushes the branch.
- GitHub refuses the push.
Since 2026-09-24 exactly two develop commits changed a workflow file, and both
regeneration runs failed. All other merges in that window passed.
To Reproduce
- Push a commit to
develop that modifies .github/workflows/documentation.yml
(the push trigger's paths filter includes .github/workflows/**).
- Observe the "Auto-regenerate Documentation" job.
- "Create or update README PR" fails at the push.
The step's resolved file list, run locally against the two real commits, contains
the offending path:
$ EVENT_NAME=push PUSH_BEFORE=d7e98f3^ PUSH_SHA=d7e98f3 \
GITHUB_OUTPUT=/tmp/out node scripts/workflows/resolve-readme-files.cjs
$ cat /tmp/out
files=.github/workflows/README.md,README.md,docs/README.md,scripts/README.md,scripts/agents/includes/README.md,scripts/agents/includes/__tests__/README.md
Expected behavior
The regeneration bot never stages, commits or pushes anything under
.github/workflows/, so a workflow-only push completes without attempting the
refused push. The App stays at least-privilege; permission-workflows is
not added and App settings are unchanged.
Screenshots
Not applicable. The failure is in the Actions log, not the UI.
WordPress Environment
Not applicable — this is a repository CI/automation defect in lightspeedwp/.github,
not a WordPress runtime issue.
Device and Browser Info
Not applicable — CI runs on ubuntu-latest.
Additional Context
Failing runs
| Run |
Commit |
Triggering change |
Result |
| 36567389709 |
d7e98f3 (#3682 merge) |
.github/workflows/documentation.yml |
failure — push refused |
| 36519808147 |
759dbb8 (#3683 merge) |
.github/workflows/changelog-unified.yml |
failure — push refused |
The docs-maintenance job has the same latent flaw
The maintain job in the same workflow mints its App token identically and runs
repository-wide fixers (fix-mermaid-diagrams.cjs, fix-staleness-dates.cjs). It
has never pushed a workflow file, because no fixture it runs writes there — but it
has the same exposure and is fixed alongside.
Open regeneration PR #3448 is not affected
Checked and not modified: PR #3448 (chore/readme-regeneration → develop)
contains only .github/metrics/meta-metrics.json, README.md and
docs/README.md. No file under .github/workflows/, so it needs no action.
Why not grant the permission
The upstream peter-evans/create-pull-request documentation states the
workflows permission is only needed "if pull requests could contain changes to
Actions workflows". These pull requests never intend to. Keeping the App at least
privilege and excluding the directory is the safer of the two options.
Fix
scripts/workflows/resolve-readme-files.cjs never returns a README under
.github/workflows/ (handles ./ prefixes, backslashes, nested subdirectories
and mixed changed-file lists; behaviour for every other directory unchanged).
- Both
create-pull-request steps get an add-paths input excluding the
directory, as last-gate defence in depth.
- Both "has changes" checks exclude the directory, so a workflow-only change
yields has_changes=false (no empty commit, no failure).
- Comments on each token step record that
permission-workflows is intentionally
absent.
Linked Stories/Tasks/PRs
Related: #3448 (open regeneration PR, unaffected).
Not a duplicate of #2423 (closed, an unrelated earlier failure of the same job).
Milestones & Timeline
- 2026-09-24 — first failure observed (
759dbb8).
- 2026-09-29 — second failure (
d7e98f3); bug filed and fixed.
Definition of Ready (DoR)
Definition of Done (DoD)
Describe the bug
The README regeneration bot in
.github/workflows/documentation.ymlfails to pushwhenever the triggering commit changed any file under
.github/workflows/.GitHub treats every file in
.github/workflows/as a workflow definition —including a plain Markdown file such as
.github/workflows/README.md— andrefuses a push that touches one unless the pushing token carries the
workflowspermission. The App token is deliberately least-privilege
(
permission-contents: write,permission-pull-requests: write), so the push isrejected:
The chain that causes it:
developchanges a file under.github/workflows/(the workflow'spush.pathsfilter includes.github/workflows/**).scripts/workflows/resolve-readme-files.cjs,which adds the
README.mdin each changed file's directory — so.github/workflows/README.mdenters the set.scripts/agents/meta.agent.jsrewrites it.peter-evans/create-pull-requestv8.1.1, pinned5f6978faf089d4d20b00c7766989d076bb2fc7f1) stages and pushes the branch.Since 2026-09-24 exactly two
developcommits changed a workflow file, and bothregeneration runs failed. All other merges in that window passed.
To Reproduce
developthat modifies.github/workflows/documentation.yml(the
pushtrigger'spathsfilter includes.github/workflows/**).The step's resolved file list, run locally against the two real commits, contains
the offending path:
Expected behavior
The regeneration bot never stages, commits or pushes anything under
.github/workflows/, so a workflow-only push completes without attempting therefused push. The App stays at least-privilege;
permission-workflowsisnot added and App settings are unchanged.
Screenshots
Not applicable. The failure is in the Actions log, not the UI.
WordPress Environment
Not applicable — this is a repository CI/automation defect in
lightspeedwp/.github,not a WordPress runtime issue.
Device and Browser Info
Not applicable — CI runs on
ubuntu-latest.Additional Context
Failing runs
d7e98f3(#3682 merge).github/workflows/documentation.yml759dbb8(#3683 merge).github/workflows/changelog-unified.ymlThe
docs-maintenancejob has the same latent flawThe
maintainjob in the same workflow mints its App token identically and runsrepository-wide fixers (
fix-mermaid-diagrams.cjs,fix-staleness-dates.cjs). Ithas never pushed a workflow file, because no fixture it runs writes there — but it
has the same exposure and is fixed alongside.
Open regeneration PR #3448 is not affected
Checked and not modified: PR #3448 (
chore/readme-regeneration→develop)contains only
.github/metrics/meta-metrics.json,README.mdanddocs/README.md. No file under.github/workflows/, so it needs no action.Why not grant the permission
The upstream
peter-evans/create-pull-requestdocumentation states theworkflowspermission is only needed "if pull requests could contain changes toActions workflows". These pull requests never intend to. Keeping the App at least
privilege and excluding the directory is the safer of the two options.
Fix
scripts/workflows/resolve-readme-files.cjsnever returns a README under.github/workflows/(handles./prefixes, backslashes, nested subdirectoriesand mixed changed-file lists; behaviour for every other directory unchanged).
create-pull-requeststeps get anadd-pathsinput excluding thedirectory, as last-gate defence in depth.
yields
has_changes=false(no empty commit, no failure).permission-workflowsis intentionallyabsent.
Linked Stories/Tasks/PRs
Related: #3448 (open regeneration PR, unaffected).
Not a duplicate of #2423 (closed, an unrelated earlier failure of the same job).
Milestones & Timeline
759dbb8).d7e98f3); bug filed and fixed.Definition of Ready (DoR)
Definition of Done (DoD)
fix/)