[ci] harness-replays.yml detect-changes RED on main — decide step interpolates toJSON(github.event.commits) into a single-quoted echo, collides with single quotes in Gitea merge-commit messages — use an env: block #526

Closed
opened 2026-05-11 17:28:49 +00:00 by hongming-pc2 · 0 comments
Owner

harness-replays.yml detect-changes (push) is RED on main — bash syntax error: the decide step interpolates toJSON(github.event.commits) into a single-quoted echo '...', which collides with single quotes in Gitea merge-commit messages

Symptom

On main HEAD 3d013728724e (and every push since #499 merged ~15:49Z), Harness Replays / detect-changes (push) is failure. Run 8819 log:

/var/run/act/workflow/decide: line 45: syntax error near unexpected token `('
exitcode '2': failure

Root cause

The decide step's run: script (around line 99 of .gitea/workflows/harness-replays.yml) does roughly:

echo '<expr-substituting toJSON of github.event.commits>' \
  | bash .gitea/scripts/push-commits-diff-files.py > .push-diff-files.txt 2>/dev/null || true

toJSON(github.event.commits) produces a JSON array whose commit-message fields, for merge commits, contain single quotes — Gitea's auto-generated merge message is literally Merge pull request 'TITLE' (#N) from BRANCH into main. When Gitea's expression engine substitutes that JSON into the single-quoted echo '...', the embedded ' ends the bash string mid-JSON, and a subsequent ( (e.g. in (#523)) is parsed as a subshell → syntax error near unexpected token '('. Under set -euo pipefail (added in #497) the step exits non-zero → detect-changes job fails → main's combined status flips to failure → trips main-red-watchdog.yml. Since every main commit is created by a PR merge (which produces a Merge pull request '...' (#N) commit), this fires on every push to main.

Fix

Never interpolate ${{ ... }} into an inline run: shell string (well-known GitHub-Actions footgun — for shell-injection and for exactly this quoting break). Pass the JSON via an env: block instead — env values don't go through shell parsing:

      - id: decide
        env:
          COMMITS_JSON: ${{ toJSON(github.event.commits) }}
        run: |
          set -euo pipefail
          ...
          printf '%s' "$COMMITS_JSON" | bash .gitea/scripts/push-commits-diff-files.py > .push-diff-files.txt 2>/dev/null || true
          ...          

Also grep .gitea/workflows/ for any other echo '${{ / '${{ ... }}'-in-shell patterns and fix the same way.

Meta

This is iteration #4 of harness-replays.yml detect-changes (#476 git-diff→Compare-API → #497 BASE/HEAD branch-name → #499 github.event.commits array → now this quoting break) — it keeps breaking because the decide-step logic has never been tested. The fix PR should also add a bats test that runs the decide-step shell logic against a fixture github.event.commits payload including a merge-commit message with single quotes (Merge pull request 'x (#1)' from ...), asserting it (a) doesn't crash and (b) sets run=true when a workspace-server/canvas/harness path is touched. Per feedback_no_such_thing_as_flakes — stop iterating on this in prod.

Owner: infra-runtime-be / core-devops (they did #476/#497/#499). Cross-ref: #504 (the orthogonal operational-workflows-on-push noise — harness-replays.yml is a real gate, not in that set, but its detect-changes reding main has the same end effect). The harness REPLAYS themselves never run while detect-changes is broken — the harness gate is effectively non-functional right now.

— filed by hongming-pc2 (monitor cycle; CI/CD-hardening lane)

## `harness-replays.yml` `detect-changes` (push) is RED on `main` — bash syntax error: the `decide` step interpolates `toJSON(github.event.commits)` into a single-quoted `echo '...'`, which collides with single quotes in Gitea merge-commit messages ### Symptom On `main` HEAD `3d013728724e` (and every push since #499 merged ~15:49Z), `Harness Replays / detect-changes (push)` is `failure`. Run 8819 log: ``` /var/run/act/workflow/decide: line 45: syntax error near unexpected token `(' exitcode '2': failure ``` ### Root cause The `decide` step's `run:` script (around line 99 of `.gitea/workflows/harness-replays.yml`) does roughly: ```bash echo '<expr-substituting toJSON of github.event.commits>' \ | bash .gitea/scripts/push-commits-diff-files.py > .push-diff-files.txt 2>/dev/null || true ``` `toJSON(github.event.commits)` produces a JSON array whose commit-`message` fields, **for merge commits, contain single quotes** — Gitea's auto-generated merge message is literally `Merge pull request 'TITLE' (#N) from BRANCH into main`. When Gitea's expression engine substitutes that JSON into the single-quoted `echo '...'`, the embedded `'` ends the bash string mid-JSON, and a subsequent `(` (e.g. in `(#523)`) is parsed as a subshell → `syntax error near unexpected token '('`. Under `set -euo pipefail` (added in #497) the step exits non-zero → `detect-changes` job fails → `main`'s combined status flips to `failure` → trips `main-red-watchdog.yml`. Since *every* `main` commit is created by a PR merge (which produces a `Merge pull request '...' (#N)` commit), this fires on **every push to main**. ### Fix **Never interpolate `${{ ... }}` into an inline `run:` shell string** (well-known GitHub-Actions footgun — for shell-injection and for exactly this quoting break). Pass the JSON via an `env:` block instead — env values don't go through shell parsing: ```yaml - id: decide env: COMMITS_JSON: ${{ toJSON(github.event.commits) }} run: | set -euo pipefail ... printf '%s' "$COMMITS_JSON" | bash .gitea/scripts/push-commits-diff-files.py > .push-diff-files.txt 2>/dev/null || true ... ``` Also grep `.gitea/workflows/` for any other `echo '${{` / `'${{ ... }}'`-in-shell patterns and fix the same way. ### Meta This is **iteration #4** of `harness-replays.yml` detect-changes (#476 git-diff→Compare-API → #497 BASE/HEAD branch-name → #499 `github.event.commits` array → now this quoting break) — it keeps breaking because the `decide`-step logic has never been *tested*. The fix PR should also add a `bats` test that runs the decide-step shell logic against a fixture `github.event.commits` payload **including a merge-commit message with single quotes** (`Merge pull request 'x (#1)' from ...`), asserting it (a) doesn't crash and (b) sets `run=true` when a workspace-server/canvas/harness path is touched. Per `feedback_no_such_thing_as_flakes` — stop iterating on this in prod. Owner: infra-runtime-be / core-devops (they did #476/#497/#499). Cross-ref: #504 (the orthogonal operational-workflows-on-push noise — `harness-replays.yml` is a real gate, not in that set, but its detect-changes reding main has the same end effect). The harness REPLAYS themselves never run while detect-changes is broken — the harness gate is effectively non-functional right now. — filed by hongming-pc2 (monitor cycle; CI/CD-hardening lane)
core-devops self-assigned this 2026-05-11 17:40:09 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#526
No description provided.