Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,25 @@ jobs:
shell: bash
env:
BASE_REF: ${{ github.base_ref }}
# PR event payload exposes the merge-base-equivalent SHA for free.
# Using it avoids the post-checkout `git fetch origin <ref>` that
# intermittently 401s on this runner image — the fetch path was
# the only thing requiring git credentials in this job, and dropping
# it eliminates an entire class of "could not read Username" flake.
BASE_SHA: ${{ github.event.pull_request.base.sha }}
EVENT_NAME: ${{ github.event_name }}
BEFORE_SHA: ${{ github.event.before }}
run: |
set -euo pipefail

case "$EVENT_NAME" in
pull_request)
# No --depth=1: checkout used fetch-depth: 0, so we already
# have full history. A shallow fetch here would truncate
# origin/$BASE_REF to its tip and break the merge-base lookup
# (origin/main...HEAD → "no merge base").
git fetch --no-tags origin "$BASE_REF"
diff_range="origin/$BASE_REF...HEAD"
# base.sha (PR's branch-point on the base ref) is always an
# ancestor of HEAD when checkout uses fetch-depth: 0, so it's
# already in our local object DB — no network fetch needed.
# Three-dot diff range gives merge-base...HEAD semantics
# which is what we want for "files this PR changes".
diff_range="$BASE_SHA...HEAD"
;;
push)
# $BEFORE_SHA is the previous HEAD on this ref; 0..0 means
Expand Down
49 changes: 35 additions & 14 deletions .github/workflows/ecp-pr-analyze.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,39 @@ jobs:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}

- name: Fetch base ref
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: git fetch origin "$BASE_REF:refs/remotes/origin/$BASE_REF"
# No `ref:` override. The default for pull_request events is
# refs/pull/N/merge — a synthetic merge commit GitHub computes
# whose two parents are (^1) PR head and (^2) current base tip.
# fetch-depth: 0 pulls full history reachable from this merge
# ref, which is exactly { PR head ancestors ∪ base tip ancestors }.
# That gives us everything we need locally — no follow-up
# `git fetch origin <base>` (which triggers the runner's
# credential-helper flake: "could not read Username … ENXIO").
#
# If a PR has merge conflicts, GitHub doesn't compute this ref
# and checkout fails — that's correct behavior (a conflicting
# PR can't merge anyway, ecp analysis would be meaningless).

- name: Compute branch point + switch HEAD to PR head
id: refs
run: |
# Branch point = merge-base of PR head and current base tip,
# both available as parents of the merge ref's HEAD commit.
# This is the SAME value `git merge-base origin/<base> <pr-head>`
# would produce — derived purely from local objects, no network.
PR_HEAD=$(git rev-parse HEAD^1)
BASE_TIP=$(git rev-parse HEAD^2)
BRANCH_POINT=$(git merge-base "$PR_HEAD" "$BASE_TIP")
echo "pr-head=$PR_HEAD" >> "$GITHUB_OUTPUT"
echo "branch-point=$BRANCH_POINT" >> "$GITHUB_OUTPUT"
echo "pr head: $PR_HEAD"
echo "base tip: $BASE_TIP"
echo "branch point: $BRANCH_POINT"
# Detach HEAD onto PR head so subsequent steps (cargo build /
# ecp index / pr-analyze) see the PR's actual tree, not the
# synthetic merged tree (which can differ from PR head if any
# merge resolution applied).
git checkout "$PR_HEAD"

- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
Expand Down Expand Up @@ -91,15 +118,9 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BASE_REF: ${{ github.event.pull_request.base.ref }}
BASE: ${{ steps.refs.outputs.branch-point }}
run: |
# Compute merge-base against the PR's actual target branch so the
# diff reflects this PR's delta rather than divergence vs. wherever
# the target branch happens to be right now. Target branch can be
# main / beta / develop / release-* etc. — never hardcode.
# (PR #382 first smoke produced 20+ phantom symbols because raw
# `origin/main` had moved past the PR's branch point.)
BASE=$(git merge-base "origin/$BASE_REF" HEAD)
echo "target: $BASE_REF baseline (merge-base): $BASE"
echo "target: $BASE_REF baseline (branch point): $BASE"
./target/release/ecp \
dev pr-analyze \
--baseline "$BASE" \
Expand Down
Loading