From 7191eac0a3e5bc5b20fe9183a8ca3d700520354a Mon Sep 17 00:00:00 2001 From: jan-kubica Date: Wed, 13 May 2026 17:03:25 +0200 Subject: [PATCH 1/2] fix(actions): invoke publish.sh via `bash `, not direct exec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous shape ran the script path as a command. That requires the file's exec bit to be set on the runner's action checkout — which is mostly true but not guaranteed: the runner cloning behaviour can drop the file mode in some configurations, and "permission denied" then surfaces as exit 1 with **no script output**, which is exactly the failure mode the stdnum v0.0.1 dispatch hit. Switching to `bash ` removes the dependency: bash reads and interprets the file regardless of its mode. Surfaced by stella/stdnum's release dispatch against v0.0.1 — the script's `chmod +x` was preserved in git (tree mode 100755 confirmed) but the runner-side artifact did not honour it. --- .github/actions/npm-publish-hardened/action.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/actions/npm-publish-hardened/action.yml b/.github/actions/npm-publish-hardened/action.yml index 43b069f..7fbc327 100644 --- a/.github/actions/npm-publish-hardened/action.yml +++ b/.github/actions/npm-publish-hardened/action.yml @@ -39,4 +39,10 @@ runs: env: TARBALL: ${{ inputs.tarball }} DIST_TAG: ${{ inputs.tag }} - run: ${{ github.action_path }}/publish.sh + # Invoke bash explicitly rather than running the path as a command. + # The GitHub Actions runner does not always preserve the file-mode + # exec bit on action checkouts, so `./publish.sh` can silently + # fail with "permission denied" while still surfacing as exit 1 + # with no script output. `bash ` removes that dependency + # entirely — bash reads the file regardless of its mode. + run: bash "${{ github.action_path }}/publish.sh" From 811cc64d7c25c02b837a6e790159d42af6e14024 Mon Sep 17 00:00:00 2001 From: jan-kubica Date: Wed, 13 May 2026 17:15:38 +0200 Subject: [PATCH 2/2] fix(actions): pass -e -o pipefail to the sub-bash invocation The shebang's flags are ignored when invoked via `bash `. publish.sh's second line is `set -euo pipefail`, so the safety settings are in effect from the script's perspective, but making the sub-bash flags explicit aligns with the runner's own default shell config (`bash --noprofile --norc -e -o pipefail {0}`) and removes the empty-but-uncovered window before line 2 executes. Addresses gemini medium on PR #28. --- .github/actions/npm-publish-hardened/action.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/actions/npm-publish-hardened/action.yml b/.github/actions/npm-publish-hardened/action.yml index 7fbc327..1d04249 100644 --- a/.github/actions/npm-publish-hardened/action.yml +++ b/.github/actions/npm-publish-hardened/action.yml @@ -45,4 +45,9 @@ runs: # fail with "permission denied" while still surfacing as exit 1 # with no script output. `bash ` removes that dependency # entirely — bash reads the file regardless of its mode. - run: bash "${{ github.action_path }}/publish.sh" + # + # `-e -o pipefail` mirror the runner's default shell flags. The + # shebang's flags are ignored when invoked via `bash `, so + # passing them explicitly here protects the empty window between + # bash startup and the script's own `set -euo pipefail` on line 2. + run: bash -eo pipefail "${{ github.action_path }}/publish.sh"