🤖 Generated by the Agentic Engineer
Evidence
validate-go-project.yaml's lint job runs MegaLinter with APPLY_FIXES: all and then pushes the
result with git-auto-commit-action, using a GitHub App token minted with permission-contents: write only. When MegaLinter's auto-fix touches a workflow file, the push is refused and the job
fails:
! [remote rejected] HEAD -> claude/lint-gate-green-2775
(refusing to allow a GitHub App to create or update workflow
`.github/workflows/ci.yaml` without `workflows` permission)
Measured on devantler-tech/platform, run 29857799818, job 88726527021: the lint step itself
succeeded — every linter green or non-blocking — and the job still reported failure, on step 9.
Why it has stayed hidden
The push step has no always(), so it only runs when linting passed. On any repository whose
MegaLinter baseline is red, the step is skipped and the defect is invisible. It surfaces the moment
a repository first gets its lint gate green — which is exactly when someone is least expecting a
failure, and when the failure text is furthest from the cause: the summary reads "Lint" and the log
shows a clean linter table.
Who it affects
Every repository consuming this workflow whose YAML formatting differs from prettier's defaults in
.github/**, which is easy to reach — a long needs: [...] array or single-quoted strings are
enough.
Expected behaviour
Either the auto-fix push succeeds for workflow files, or MegaLinter never rewrites them.
Options
- Add
permission-workflows: write to the App token in the lint job. Smallest change, but it
widens a token that today can only touch file contents, on a job that runs against pull-request
branches — worth weighing rather than assuming.
- Keep the token as-is and stop the fixers touching
.github/**, so the push can never contain a
workflow change. Loses prettier's formatting check on workflow files, which actionlint and
yamllint do not replace.
- Let the step fail soft with a clear message telling the author to run the formatter locally,
which is what the sibling fork-PR step already does.
I have no strong preference between 2 and 3; 1 deserves a deliberate decision because it is a
permission widening on a token reachable from pull-request branches.
Workaround in place
devantler-tech/platform formats its own .github/** YAML so there is nothing to push back. That
works per-repository but does not stop the next repo hitting it.
Acceptance criteria
Rough size: small.
Evidence
validate-go-project.yaml'slintjob runs MegaLinter withAPPLY_FIXES: alland then pushes theresult with
git-auto-commit-action, using a GitHub App token minted withpermission-contents: writeonly. When MegaLinter's auto-fix touches a workflow file, the push is refused and the jobfails:
Measured on
devantler-tech/platform, run 29857799818, job 88726527021: the lint step itselfsucceeded — every linter green or non-blocking — and the job still reported
failure, on step 9.Why it has stayed hidden
The push step has no
always(), so it only runs when linting passed. On any repository whoseMegaLinter baseline is red, the step is skipped and the defect is invisible. It surfaces the moment
a repository first gets its lint gate green — which is exactly when someone is least expecting a
failure, and when the failure text is furthest from the cause: the summary reads "Lint" and the log
shows a clean linter table.
Who it affects
Every repository consuming this workflow whose YAML formatting differs from prettier's defaults in
.github/**, which is easy to reach — a longneeds: [...]array or single-quoted strings areenough.
Expected behaviour
Either the auto-fix push succeeds for workflow files, or MegaLinter never rewrites them.
Options
permission-workflows: writeto the App token in thelintjob. Smallest change, but itwidens a token that today can only touch file contents, on a job that runs against pull-request
branches — worth weighing rather than assuming.
.github/**, so the push can never contain aworkflow change. Loses prettier's formatting check on workflow files, which
actionlintandyamllintdo not replace.which is what the sibling fork-PR step already does.
I have no strong preference between 2 and 3; 1 deserves a deliberate decision because it is a
permission widening on a token reachable from pull-request branches.
Workaround in place
devantler-tech/platformformats its own.github/**YAML so there is nothing to push back. Thatworks per-repository but does not stop the next repo hitting it.
Acceptance criteria
🧹 Lint - mega-linterjob.Rough size: small.