Skip to content

fix(release): make the new CI scripts executable, and pin the exec-bit class - #1349

Merged
DeusData merged 2 commits into
mainfrom
fix/script-exec-bits
Jul 30, 2026
Merged

fix(release): make the new CI scripts executable, and pin the exec-bit class#1349
DeusData merged 2 commits into
mainfrom
fix/script-exec-bits

Conversation

@DeusData

Copy link
Copy Markdown
Owner

What

Every unix build leg of release run 30499236230 died during packaging:

scripts/package-release.sh: line 190: scripts/ci/check-binary-composition.sh: Permission denied

The composition gate added in #1344 was committed 100644 while being invoked as a command. It passed every local check because my working copy had the exec bit — only the committed mode was wrong, which nothing you can run locally reveals.

scripts/ci/append-vt-notes.sh had the identical defect waiting in the verify step, the last step of the release. So this would have failed a second time, after two hours of tests, build, smoke and soak had already run.

Fix, on both sides

Either alone is sufficient; the pair is mode-proof.

  • Both scripts are now 100755.
  • Both call sites invoke them via bash, which is what most of this repo already does and which cannot break if a mode bit is lost to a patch application or a non-POSIX checkout.

Contract

tests/test_script_exec_bit_contract.sh pins the class: any tracked .sh whose committed mode is non-executable must not appear as the first word of a command in workflows, scripts/, test-infrastructure/ or the Makefiles.

Verified in both directions — it passes on this tree, and fails on the exact defect when the mode and call site are reverted together. It also joins backslash continuations before analysing, because its own first draft reported a false positive on a call whose interpreter sat on the preceding line:

... && bash \
    test-infrastructure/vm/vm-run-tests.sh --soak

A contract that cries wolf teaches people to ignore contracts, so that had to be right before it was worth having.

Verification

  • 16/16 local contracts green (including the new one).
  • Reproduced the CI failure locally: direct invocation without the bit gives rc=126; the bash form runs the gate.
  • Product code untouched. The test phase of the failed run was 27/27 green on this exact tree, and a file mode cannot change a test outcome — so this re-release skips the test phase.

Note

Two commits rather than one: the first landed with only the mode changes because the call-site edits were not staged when it committed, and --amend is denied in this repo, so the follow-up is additive.

DeusData added 2 commits July 30, 2026 03:04
…tay so

Every unix build leg of release run 30499236230 died during packaging:

  scripts/package-release.sh: line 190: scripts/ci/check-binary-composition.sh: Permission denied

The composition gate was committed 100644 while being invoked as a command. It
passed every local check because my WORKING COPY had the exec bit -- only the
committed mode was wrong, and nothing you can run locally reveals that.

scripts/ci/append-vt-notes.sh had the identical defect waiting in the verify
step, the last step of the release, so this would have failed a second time after
two hours of tests, build, smoke and soak.

Fixed on BOTH sides, because either alone suffices and the pair is mode-proof:
the two scripts are now 100755, and their call sites invoke them through `bash`,
which is what most of this repo already does and which cannot break if a mode bit
is ever lost to a patch application or a non-POSIX checkout.

tests/test_script_exec_bit_contract.sh pins the class: any tracked .sh whose
COMMITTED mode is non-executable must not appear as the first word of a command
in workflows, scripts, test-infrastructure or the Makefiles. Verified in both
directions -- it passes on this tree, and fails on the exact defect when the mode
and the call site are reverted. It also joins backslash continuations before
analysing, because its own first draft reported a false positive on

    ... && bash \
        test-infrastructure/vm/vm-run-tests.sh --soak

and a contract that cries wolf teaches people to ignore contracts.

Product code is untouched: the test phase of the failed run was 27/27 green on
this exact tree, and a file mode cannot change a test outcome.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
…t class

Completes the previous commit, which carried only the two mode changes because
the call-site edits were not staged when it landed (--amend is denied in this
repo, so this is additive rather than a rewrite).

Call sites now go through `bash`, which is what most of this repo already does and
which cannot break if a mode bit is lost to a patch application or a non-POSIX
checkout:

  scripts/package-release.sh   -> bash scripts/ci/check-binary-composition.sh
  .github/workflows/release.yml -> bash scripts/ci/append-vt-notes.sh

With the 100755 modes from the previous commit, both sides are now correct, and
either alone would have been sufficient.

tests/test_script_exec_bit_contract.sh pins the class so it cannot recur: any
tracked .sh whose COMMITTED mode is non-executable must not appear as the first
word of a command in workflows, scripts, test-infrastructure or the Makefiles.
The committed mode is the thing that matters and the thing no local run can
check -- the working copy having the bit is exactly why this shipped.

Verified in both directions: passes on this tree, and fails on the exact defect
when the mode and the call site are reverted together. It joins backslash
continuations before analysing, because its own first draft reported a false
positive on

    ... && bash \
        test-infrastructure/vm/vm-run-tests.sh --soak

where the interpreter sits on the preceding line. A contract that cries wolf
teaches people to ignore contracts, so that had to be right before it could be
useful.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
@DeusData
DeusData merged commit c16da50 into main Jul 30, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant