From 5af9b4678cad2d3b65abf829f4334aa6fa7c8e0d Mon Sep 17 00:00:00 2001 From: Wooseong Kim Date: Sun, 26 Jul 2026 04:16:57 +0900 Subject: [PATCH 1/2] ci(pr): run E2E when a PR touches tests/e2e paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regression specs under tests/e2e never ran on PR CI — only schedule and release called e2e.yml — so a red regression test could merge green. Path-filter and workflow_call the E2E suite when E2E-relevant files change. Closes #10518 --- .github/workflows/pr.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index e444a498f0f6..0064911de71d 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -165,3 +165,39 @@ jobs: # temp copy so Node cannot mask missing package deps with repo node_modules. - name: Smoke packaged CLI run: node config/scripts/smoke-packaged-cli.mjs --app-dir=dist/linux-unpacked + + # Why: regression specs under tests/e2e/** used to merge green without ever + # running — e2e.yml only fired on schedule/release (#10518). Path-filter so + # ordinary PRs stay light; any E2E suite change still gets a full shard run. + e2e-paths: + name: detect e2e path changes + runs-on: ubuntu-latest + if: github.event.pull_request.draft != true + outputs: + should_run: ${{ steps.filter.outputs.should_run }} + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Filter E2E-relevant paths + id: filter + run: | + set -euo pipefail + BASE="${{ github.event.pull_request.base.sha }}" + HEAD="${{ github.event.pull_request.head.sha }}" + if git diff --name-only "$BASE" "$HEAD" | grep -E '^(tests/e2e/|playwright\.|\.github/workflows/e2e\.yml$)' >/dev/null; then + echo "should_run=true" >> "$GITHUB_OUTPUT" + echo "E2E path changes detected" + else + echo "should_run=false" >> "$GITHUB_OUTPUT" + echo "No E2E path changes" + fi + + e2e: + name: e2e + needs: e2e-paths + if: needs.e2e-paths.outputs.should_run == 'true' + uses: ./.github/workflows/e2e.yml From 2fd4985cb16146c9978685500baa91ec898901b1 Mon Sep 17 00:00:00 2001 From: Wooseong Kim Date: Sun, 26 Jul 2026 12:09:46 +0900 Subject: [PATCH 2/2] ci(pr): harden E2E path detection after CodeRabbit Use merge-base diffs so base-branch drift does not false-trigger E2E, fail the detector when git diff cannot compute the PR range, and pin least-privilege contents:read on both the detector and reusable E2E workflow. --- .github/workflows/e2e.yml | 4 ++++ .github/workflows/pr.yml | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 0e18d3ca5cd0..29a1679359fe 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -1,5 +1,9 @@ name: E2E +# Why: checkout + artifact upload only; callers can only further restrict. +permissions: + contents: read + on: workflow_call: inputs: diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 0064911de71d..9bc407d3b80d 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -173,6 +173,9 @@ jobs: name: detect e2e path changes runs-on: ubuntu-latest if: github.event.pull_request.draft != true + # Why: detector only needs to read the checkout; do not inherit repo defaults. + permissions: + contents: read outputs: should_run: ${{ steps.filter.outputs.should_run }} steps: @@ -188,7 +191,11 @@ jobs: set -euo pipefail BASE="${{ github.event.pull_request.base.sha }}" HEAD="${{ github.event.pull_request.head.sha }}" - if git diff --name-only "$BASE" "$HEAD" | grep -E '^(tests/e2e/|playwright\.|\.github/workflows/e2e\.yml$)' >/dev/null; then + # Why: capture first so a failed git diff does not look like "no matches" + # (pipeline status in `if` is not aborted by set -e). Three-dot / merge-base + # limits the list to files this PR introduced, not base-branch drift. + CHANGED="$(git diff --name-only --merge-base "$BASE" "$HEAD")" + if printf '%s\n' "$CHANGED" | grep -E '^(tests/e2e/|playwright\.|\.github/workflows/e2e\.yml$)' >/dev/null; then echo "should_run=true" >> "$GITHUB_OUTPUT" echo "E2E path changes detected" else @@ -200,4 +207,7 @@ jobs: name: e2e needs: e2e-paths if: needs.e2e-paths.outputs.should_run == 'true' + # Why: reusable e2e.yml only checkouts, builds, and uploads artifacts. + permissions: + contents: read uses: ./.github/workflows/e2e.yml