From 171e27636c66d94cf7c874616f41baf55ef4c946 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Sun, 17 May 2026 05:47:22 +0100 Subject: [PATCH] fix(ci): make finishingbot/seambot/rhodibot workflows actually green MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bots were re-enabled against gitbot-fleet in #42, but the workflows still fail on every run for two structural reasons unrelated to the bots: 1. Step order. `Swatinem/rust-cache` ran *before* the gitbot-fleet clone, with `workspaces:` pointing at a path that did not yet exist. rust-cache errored ("cwd ... does not exist") and, for seambot, left `$RUNNER_TEMP/gitbot-fleet` present so the subsequent `git clone` died with `destination path ... already exists` (exit 128). Fix: clone first, then cache; `rm -rf` the dir before cloning. 2. Exit-code capture. `bin ... > results.txt 2>&1; echo $? > code.txt` runs under `bash -e`; a non-zero bot exit (the *intended* gating signal) aborts the step before the exit-code file is written, so the non-continue-on-error "Display results" step then hard-fails on a missing file. Fix: `rc=0; bin ... || rc=$?; echo "$rc" > code.txt; exit "$rc"` — records the code, preserves the failure outcome so the "Fail on …findings/violations" gate still fires, and the job goes green only when the bot is genuinely clean. Display `cat` hardened. Binary invocations verified against gitbot-fleet @ pinned ref 2e0ea3ca (incl. gitbot-fleet#150's `rhodibot check` CLI): finishing-bot `--path audit`, `seambot check`, `rhodibot check --owner --repo` all match the clap definitions at that ref. Closes #39 Closes #40 Closes #41 Refs #37 Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/finishingbot.yml | 27 +++++++++++++++++++-------- .github/workflows/rhodibot.yml | 27 +++++++++++++++++++-------- .github/workflows/seambot.yml | 27 ++++++++++++++++++--------- 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/.github/workflows/finishingbot.yml b/.github/workflows/finishingbot.yml index 7a751a7..8210b32 100644 --- a/.github/workflows/finishingbot.yml +++ b/.github/workflows/finishingbot.yml @@ -29,18 +29,23 @@ jobs: with: toolchain: stable - - name: Cache dependencies - uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2 - with: - workspaces: ${{ runner.temp }}/gitbot-fleet/bots/finishingbot - + # Clone BEFORE the rust-cache step: rust-cache needs the workspace + # (Cargo.lock) to exist to key the cache, and cloning into a + # cache-created directory fails with `destination path ... already + # exists and is not an empty directory` (exit 128). - name: Fetch gitbot-fleet at pinned ref run: | + rm -rf "$RUNNER_TEMP/gitbot-fleet" git clone --no-checkout --filter=tree:0 \ https://github.com/hyperpolymath/gitbot-fleet.git \ "$RUNNER_TEMP/gitbot-fleet" git -C "$RUNNER_TEMP/gitbot-fleet" checkout "$GITBOT_FLEET_REF" + - name: Cache dependencies + uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2 + with: + workspaces: ${{ runner.temp }}/gitbot-fleet/bots/finishingbot + - name: Build finishingbot working-directory: ${{ runner.temp }}/gitbot-fleet/bots/finishingbot env: @@ -52,9 +57,15 @@ jobs: continue-on-error: true run: | # The finishingbot crate's binary is `finishing-bot` (hyphenated). + # A non-zero audit is the intended gating signal. Capture it + # without letting `set -e` abort the step before the exit-code + # file is written, then re-exit with it so this step's outcome + # is `failure` and the "Fail on …findings" step below triggers. + rc=0 "$RUNNER_TEMP/gitbot-fleet/bots/finishingbot/target/release/finishing-bot" \ - --path "$GITHUB_WORKSPACE" audit > finishingbot-results.txt 2>&1 - echo $? > finishingbot-exit-code.txt + --path "$GITHUB_WORKSPACE" audit > finishingbot-results.txt 2>&1 || rc=$? + echo "$rc" > finishingbot-exit-code.txt + exit "$rc" - name: Display results if: always() @@ -65,7 +76,7 @@ jobs: cat finishingbot-results.txt >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY - exit_code=$(cat finishingbot-exit-code.txt) + exit_code=$(cat finishingbot-exit-code.txt 2>/dev/null || echo unknown) if [ "$exit_code" = "0" ]; then echo "✅ Release readiness checks passed" >> $GITHUB_STEP_SUMMARY else diff --git a/.github/workflows/rhodibot.yml b/.github/workflows/rhodibot.yml index f27d605..5ca5bda 100644 --- a/.github/workflows/rhodibot.yml +++ b/.github/workflows/rhodibot.yml @@ -30,18 +30,23 @@ jobs: with: toolchain: stable - - name: Cache dependencies - uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2 - with: - workspaces: ${{ runner.temp }}/gitbot-fleet/bots/rhodibot - + # Clone BEFORE the rust-cache step: rust-cache needs the workspace + # (Cargo.lock) to exist to key the cache, and cloning into a + # cache-created directory fails with `destination path ... already + # exists and is not an empty directory` (exit 128). - name: Fetch gitbot-fleet at pinned ref run: | + rm -rf "$RUNNER_TEMP/gitbot-fleet" git clone --no-checkout --filter=tree:0 \ https://github.com/hyperpolymath/gitbot-fleet.git \ "$RUNNER_TEMP/gitbot-fleet" git -C "$RUNNER_TEMP/gitbot-fleet" checkout "$GITBOT_FLEET_REF" + - name: Cache dependencies + uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2 + with: + workspaces: ${{ runner.temp }}/gitbot-fleet/bots/rhodibot + - name: Build rhodibot working-directory: ${{ runner.temp }}/gitbot-fleet/bots/rhodibot env: @@ -56,11 +61,17 @@ jobs: # read-only workflow token is sufficient (no PAT needed). GITHUB_TOKEN: ${{ github.token }} run: | + # A non-zero check is the intended gating signal. Capture it + # without letting `set -e` abort the step before the exit-code + # file is written, then re-exit with it so this step's outcome + # is `failure` and the "Fail on …violations" step below triggers. + rc=0 "$RUNNER_TEMP/gitbot-fleet/bots/rhodibot/target/release/rhodibot" check \ --owner "${{ github.repository_owner }}" \ --repo "${{ github.event.repository.name }}" \ - > rhodibot-results.txt 2>&1 - echo $? > rhodibot-exit-code.txt + > rhodibot-results.txt 2>&1 || rc=$? + echo "$rc" > rhodibot-exit-code.txt + exit "$rc" - name: Display results if: always() @@ -71,7 +82,7 @@ jobs: cat rhodibot-results.txt >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY - exit_code=$(cat rhodibot-exit-code.txt) + exit_code=$(cat rhodibot-exit-code.txt 2>/dev/null || echo unknown) if [ "$exit_code" = "0" ]; then echo "✅ RSR compliance checks passed" >> $GITHUB_STEP_SUMMARY else diff --git a/.github/workflows/seambot.yml b/.github/workflows/seambot.yml index 0f4c76a..4804f63 100644 --- a/.github/workflows/seambot.yml +++ b/.github/workflows/seambot.yml @@ -39,20 +39,25 @@ jobs: with: toolchain: stable - - name: Cache dependencies - if: steps.check-seam.outputs.has_seam == 'true' - uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2 - with: - workspaces: ${{ runner.temp }}/gitbot-fleet/bots/seambot - + # Clone BEFORE the rust-cache step: rust-cache needs the workspace + # (Cargo.lock) to exist to key the cache, and cloning into a + # cache-created directory fails with `destination path ... already + # exists and is not an empty directory` (exit 128). - name: Fetch gitbot-fleet at pinned ref if: steps.check-seam.outputs.has_seam == 'true' run: | + rm -rf "$RUNNER_TEMP/gitbot-fleet" git clone --no-checkout --filter=tree:0 \ https://github.com/hyperpolymath/gitbot-fleet.git \ "$RUNNER_TEMP/gitbot-fleet" git -C "$RUNNER_TEMP/gitbot-fleet" checkout "$GITBOT_FLEET_REF" + - name: Cache dependencies + if: steps.check-seam.outputs.has_seam == 'true' + uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2 + with: + workspaces: ${{ runner.temp }}/gitbot-fleet/bots/seambot + - name: Build seambot if: steps.check-seam.outputs.has_seam == 'true' working-directory: ${{ runner.temp }}/gitbot-fleet/bots/seambot @@ -65,9 +70,13 @@ jobs: id: seambot continue-on-error: true run: | + # A non-zero check is the intended signal; capture it without + # letting `set -e` abort before the exit-code file is written. + rc=0 "$RUNNER_TEMP/gitbot-fleet/bots/seambot/target/release/seambot" check \ - > seambot-results.txt 2>&1 - echo $? > seambot-exit-code.txt + > seambot-results.txt 2>&1 || rc=$? + echo "$rc" > seambot-exit-code.txt + exit "$rc" - name: Display results if: always() && steps.check-seam.outputs.has_seam == 'true' @@ -78,7 +87,7 @@ jobs: cat seambot-results.txt >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY - exit_code=$(cat seambot-exit-code.txt) + exit_code=$(cat seambot-exit-code.txt 2>/dev/null || echo unknown) if [ "$exit_code" = "0" ]; then echo "✅ All seam checks passed" >> $GITHUB_STEP_SUMMARY else