Skip to content

Commit 6671bb3

Browse files
ci: fix e2e-failure-analyzer for positron-builds caller (#13693)
## Summary Three follow-ups to [#13671](#13671) needed before the e2e-failure-analyzer action can run from [posit-dev/positron-builds](https://github.com/posit-dev/positron-builds), where the action lives in a submodule and the test source isn't at `$GITHUB_WORKSPACE`. All in [.github/actions/e2e-failure-analyzer/action.yml](.github/actions/e2e-failure-analyzer/action.yml): - Apply `inputs.repo-root || github.workspace` at all five consumers. #13671 wired the input through to `REPO_ROOT` but left the four helper-script paths hardcoded to `github.workspace`, so positron-builds hit `MODULE_NOT_FOUND` on the first script call. - Change the `repo-root` default from `${{ github.workspace }}` to `""`. Input defaults aren't guaranteed to evaluate expressions reliably across all contexts; falling back at each usage site is the defensive pattern (also flagged by roborev on #13671). - Replace the `REPORT_DIR` pipeline (`grep | grep | head -1`) with a single `awk` pass. Under `set -e -o pipefail`, `head -1` closes its stdin after the first match and upstream `grep` gets SIGPIPE while writing the next line — kills the step on real CI log payloads. The existing positron caller ([analyze-e2e-failures.yml](.github/workflows/analyze-e2e-failures.yml)) doesn't pass `repo-root`, so the `||` fallback resolves to `github.workspace` everywhere — behavior is unchanged for in-repo runs. ## Test plan - [ ] Trigger `Analyze E2E Failures` on positron against a recent failed run; confirm the gather/process/history steps still find the helper scripts at `$GITHUB_WORKSPACE/.claude/skills/...` and the analyzer reads test source as before. - [ ] Once merged, bump positron-builds' submodule pin to this SHA and confirm the end-to-end analyzer run succeeds with `repo-root: ${{ github.workspace }}/positron`.
1 parent aba28d9 commit 6671bb3

1 file changed

Lines changed: 12 additions & 12 deletions

File tree

.github/actions/e2e-failure-analyzer/action.yml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ inputs:
2424
required: false
2525
default: "blob"
2626
repo-root:
27-
description: "Path to the repo workspace whose test/e2e/ source the analyzer should read. Defaults to $GITHUB_WORKSPACE. positron-builds passes $GITHUB_WORKSPACE/positron because the test source lives in the submodule."
27+
description: "Path to the repo workspace whose test/e2e/ source and .claude/skills/ helpers the analyzer should read. Defaults to $GITHUB_WORKSPACE. positron-builds passes $GITHUB_WORKSPACE/positron because both the test source and helper scripts live in the submodule."
2828
required: false
29-
default: ${{ github.workspace }}
29+
default: ""
3030
runs:
3131
using: composite
3232
steps:
@@ -65,7 +65,7 @@ runs:
6565
env:
6666
GH_TOKEN: ${{ github.token }}
6767
run: |
68-
node "${{ github.workspace }}/.claude/skills/e2e-failure-analyzer/scripts/e2e-gather-run-info.js" \
68+
node "${{ inputs.repo-root || github.workspace }}/.claude/skills/e2e-failure-analyzer/scripts/e2e-gather-run-info.js" \
6969
"${{ inputs.run-url }}" > "${{ steps.prep.outputs.work_dir }}/run-info.json"
7070
echo "::group::run-info.json"
7171
cat "${{ steps.prep.outputs.work_dir }}/run-info.json"
@@ -94,7 +94,7 @@ runs:
9494
mkdir -p "$OUT"
9595
echo "::group::Process project $PROJECT"
9696
# cwd = action dir so npx finds @playwright/test from action's node_modules
97-
node "${{ github.workspace }}/.claude/skills/e2e-failure-analyzer/scripts/e2e-process-project.js" \
97+
node "${{ inputs.repo-root || github.workspace }}/.claude/skills/e2e-failure-analyzer/scripts/e2e-process-project.js" \
9898
--download \
9999
--run-id "$RUN_ID" \
100100
--repo "$REPO" \
@@ -156,13 +156,13 @@ runs:
156156
# Resolve REPORT_DIR from the job's logs. The workflow logs both an
157157
# unresolved template line (REPORT_DIR="...-${IDENTIFIER}-${OS_SUFFIX}")
158158
# and the expanded value (REPORT_DIR: playwright-report-<run>-<attempt>-<id>-<os>).
159-
# Filter out lines containing literal ${ to skip the template, then
160-
# extract the first concrete playwright-report-* token.
159+
# Skip the template line, take the first concrete match. Single awk pass
160+
# rather than grep | grep | head -1 to avoid head closing its stdin while
161+
# upstream grep is still writing -- under `set -e -o pipefail` that
162+
# manifests as "grep: write error: Broken pipe" + exit 2 on large logs.
161163
LOGS=$(gh api "repos/$REPO/actions/jobs/$JOB_ID/logs" 2>/dev/null || true)
162164
REPORT_DIR=$(printf '%s' "$LOGS" \
163-
| grep -v '\${' \
164-
| grep -oE 'playwright-report-[A-Za-z0-9_-]+' \
165-
| head -1)
165+
| awk '!/\${/ && match($0, /playwright-report-[A-Za-z0-9_-]+/) { print substr($0, RSTART, RLENGTH); exit }')
166166
167167
if [ -z "$REPORT_DIR" ]; then
168168
echo "Could not resolve REPORT_DIR from logs of job $JOB_ID. Skipping."
@@ -173,7 +173,7 @@ runs:
173173
REPORT_URL="$CDN_BASE/$REPORT_DIR/"
174174
echo "Report URL: $REPORT_URL"
175175
176-
node "${{ github.workspace }}/.claude/skills/e2e-failure-analyzer/scripts/e2e-process-s3.js" \
176+
node "${{ inputs.repo-root || github.workspace }}/.claude/skills/e2e-failure-analyzer/scripts/e2e-process-s3.js" \
177177
--report-url "$REPORT_URL" \
178178
--output-dir "$OUT" \
179179
--cleanup \
@@ -196,7 +196,7 @@ runs:
196196
# The e2e-test-insights API uses a single "positron" repo ID for both
197197
# posit-dev/positron and posit-dev/positron-builds (same tests, same
198198
# storage) -- do not parameterize this on the source GH repo.
199-
node "${{ github.workspace }}/.claude/skills/e2e-failure-analyzer/scripts/e2e-query-history.js" \
199+
node "${{ inputs.repo-root || github.workspace }}/.claude/skills/e2e-failure-analyzer/scripts/e2e-query-history.js" \
200200
--repo positron \
201201
--run-id "$RUN_ID" \
202202
--lookback-days 14 \
@@ -214,7 +214,7 @@ runs:
214214
WORK_DIR: ${{ steps.prep.outputs.work_dir }}
215215
# Repo workspace -- the agent reads test source from $REPO_ROOT/test/e2e
216216
# to understand each failing test's intent (assertions, page-object usage).
217-
REPO_ROOT: ${{ inputs.repo-root }}
217+
REPO_ROOT: ${{ inputs.repo-root || github.workspace }}
218218
MODEL: ${{ inputs.model }}
219219
MAX_TURNS: ${{ inputs.max-turns }}
220220
run: node analyze.mjs

0 commit comments

Comments
 (0)