Repository navigation
feat(shell-ci): fail when a script invoked by path is not executable in git - #144
Merged
Merged
Conversation
…in git chmod +x in a working tree is local state; the mode git records is what reaches the runner. When they disagree the job dies with exit 126 and "Permission denied" - a message about the file, not about the mode, which is why it costs a round trip to diagnose every time. It happened twice in one day in apt: once on scripts/build-installers.sh (#116) and once on tests/build-installers.test.sh a few hours later. The check is deliberately narrow. It does not assert that every .sh is 0755, which would be wrong - apt/scripts/install-template.sh is read and substituted, never executed, and is correctly 0644. It derives the list from how the calling repo workflows actually invoke each script, so a repo using `bash path` finds nothing. Measured: apt, homebrew-tap and scoop-bucket invoke by path; podup, epistle, helmly, unitpm and glyndor.net do not, and have 21 non-executable scripts between them that are not defects. Default on rather than opt-in, because the SHA pin is the buffer: no consumer sees it until it bumps its pin deliberately, which is the moment to look at a new red. I ran the logic against three real states rather than reading it: apt today passes, apt at the broken commit fails naming the file and the mode, podup reports nothing to check. Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
docs-current caught it: the pages are generated by scripts/render-reusable-docs.py and the check fails when the committed ones disagree with the workflows. Adding check-exec-bit made shell-ci.md stale, which is the gate working as designed. Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
chmod +xin a working tree is local state. The mode git records is what reaches the runner, and when they disagree the job dies with exit 126 andPermission denied— a message about the file, not about the mode, which is why it costs a round trip to diagnose every time.It happened twice in one day in
apt:scripts/build-installers.shin #116 this morning,tests/build-installers.test.sha few hours later.Deliberately narrow
It does not assert that every
.shis0755. That would be wrong:apt/scripts/install-template.shis read and substituted, never executed, and is correctly0644.The list is derived from how the calling repo
s workflows actually invoke each script — every./something.shmentioned under.github/workflows/. A repo that runsbash path` finds nothing and passes. Measured across the org:./pathbash pathThose four on the right hold 21 non-executable scripts between them and not one is a defect. A blanket "every .sh must be 0755" gate would have turned all 21 red for nothing. This finds zero of them.
Default on, not opt-in
The SHA pin is the buffer. No consumer sees this until it deliberately bumps its pin — which is exactly the moment to look at a new red. A guard nobody enables protects nobody.
Run, not read
I executed the logic against three real repository states rather than reviewing it:
Every script invoked by path is executable in git.(rc=0)ee6de9d, the broken state from this afternoon → rc=1,tests/build-installers.test.sh is invoked as ./tests/... but git records mode 100644. It catches the actual failure.No script is invoked as ./path by any workflow; nothing to check.(rc=0)actionlintand a YAML parse are clean.Before tagging
Per
standards/ci, a reusable is proved on a real consumer before a tag is cut. Once this merges I will pinaptat the merge SHA, wait for its CI, and only then propose the release.