From f0d078184d6dd2776e09bb6a019c1e591b3aa3d0 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 10 Sep 2026 22:31:33 +0000 Subject: [PATCH] ci: run every workflow step under bash -euo pipefail The runner's default shell is "bash -e {0}", so an unset variable expanded to an empty string and a command that failed mid-pipeline went unnoticed. Set the shell once per workflow via defaults.run instead, and drop the per-step "set -euo pipefail" lines it supersedes. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0146WGNYA5chgKdzwn1ZGLw3 --- .github/workflows/ci.yml | 9 ++++++--- .github/workflows/release.yml | 8 ++++++-- .github/workflows/update-material.yml | 10 ++++++---- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 64e0166..2678470 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,12 @@ env: # renovate: datasource=npm depName=@devcontainers/cli DEVCONTAINER_CLI_VERSION: "0.89.0" +# The runner's default shell adds only -e, so an unset variable or a failure +# mid-pipeline would otherwise pass silently. +defaults: + run: + shell: bash -euo pipefail {0} + jobs: discover: name: Discover features @@ -33,7 +39,6 @@ jobs: - name: List features under src/ id: discover run: | - set -euo pipefail features="$(find src -mindepth 2 -maxdepth 2 -name devcontainer-feature.json -printf '%h\n' \ | xargs -r -n1 basename \ | sort \ @@ -77,8 +82,6 @@ jobs: env: WORKSPACE: ${{ runner.temp }}/smoke run: | - set -euo pipefail - if [ ! -f "src/${FEATURE}/smoke_test.sh" ]; then echo "::error::src/${FEATURE}/smoke_test.sh is missing; every feature must ship one." exit 1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 41e5de6..8ce614e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,6 +14,12 @@ concurrency: group: ${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && 'release' || github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} +# The runner's default shell adds only -e, so an unset variable or a failure +# mid-pipeline would otherwise pass silently. +defaults: + run: + shell: bash -euo pipefail {0} + jobs: release: name: Publish features @@ -49,8 +55,6 @@ jobs: env: GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} run: | - set -euo pipefail - changed=$(git status --porcelain -- 'src/*/README.md' | awk '{print $2}') if [ -z "$changed" ]; then echo "No documentation changes." diff --git a/.github/workflows/update-material.yml b/.github/workflows/update-material.yml index d2c952d..064c045 100644 --- a/.github/workflows/update-material.yml +++ b/.github/workflows/update-material.yml @@ -15,6 +15,12 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} +# The runner's default shell adds only -e, so an unset variable or a failure +# mid-pipeline would otherwise pass silently. +defaults: + run: + shell: bash -euo pipefail {0} + jobs: update: name: Refresh trusted material @@ -30,8 +36,6 @@ jobs: - name: Refresh trusted material id: update run: | - set -euo pipefail - changed="$(bash scripts/update-material.sh)" echo "changed=${changed}" >> "${GITHUB_OUTPUT}" @@ -48,8 +52,6 @@ jobs: env: GH_TOKEN: ${{ steps.app-token.outputs.token }} run: | - set -euo pipefail - OWNER="${GITHUB_REPOSITORY_OWNER}" REPO="${GITHUB_REPOSITORY#*/}" BRANCH="housekeeper/update-material"