Skip to content

Use the merge-base of a PR when comparing SASS changes, not the instantaneous main - #11191

Open
Jacobfaib wants to merge 1 commit into
NVIDIA:mainfrom
Jacobfaib:jacobf/2026-09-03/sass-diff-use-merge-base
Open

Use the merge-base of a PR when comparing SASS changes, not the instantaneous main#11191
Jacobfaib wants to merge 1 commit into
NVIDIA:mainfrom
Jacobfaib:jacobf/2026-09-03/sass-diff-use-merge-base

Conversation

@Jacobfaib

Copy link
Copy Markdown
Contributor

Description

closes #11190

As mentioned in the issue, the root problem here is that the current sass diff checker will compare the branch against current main. If your branch is behind main (and it almost always is), and main itself made changes to SASS, then to the checker it will appear as if it undid those changes, effectively producing a diff.

made changes to SASS
        V
        C -- D <- main
       /
A -- B -- E <- branch

The checker would compare D vs E and erroneously think that E undid C.

There are 2 ways to solve this:

  1. Use the merge-base of the PR and main (the commit of main from which the PR was split from) as the baseline. Instead of comparing E vs D, we now compare E vs B which only includes the changes on the branch.
  2. Use a synthetic merge commit between main and the PR as the PRs "current" state. So create a new commit or rebase:
made changes to SASS
        V
        C -- D <- main
       /      \
A -- B -- E ... F <- "HEAD" as seen by the sass diff checker 
          ^     ^
actual HEAD     |
                |
New, synthetic commit created by the sass diff checker by merging main
into the current branch

This also has the same effect as 1. but from the other angle. Instead of ignoring C we now merge it into our branch for the purposes of SASS diffing, and effectively only compare our own commits against main.

There are pros and cons of either approach:

Merge-base:

Pro: Always works
Con: If the combination of main + PR would actually produce diffs, then the checker wouldn't catch it. Similar to how merging a PR prior to clang-tidy updates may cause main to be broken for a bit until a follow-up fixes the issues.

Synthetic merge:

Pro: The most correct answer at all times
Con: Brittle, and doesn't work if there are merge failures
Con: Not clear how this should be handled when the script is run standalone since a new commit is actually made.

So this PR implements option 1

Checklist

  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

@Jacobfaib Jacobfaib self-assigned this Sep 3, 2026
@Jacobfaib
Jacobfaib requested a review from a team as a code owner September 3, 2026 22:09
@Jacobfaib
Jacobfaib requested a review from jrhemstad September 3, 2026 22:09
@github-project-automation github-project-automation Bot moved this to Todo in CCCL Sep 3, 2026
@cccl-authenticator-app cccl-authenticator-app Bot moved this from Todo to In Review in CCCL Sep 3, 2026
@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 9d7482f6-0f62-4351-9947-00bb68a8c35a

📥 Commits

Reviewing files that changed from the base of the PR and between 3b12964 and 0e3d34c.

📒 Files selected for processing (1)
  • .github/workflows/ci-workflow-pull-request.yml

Included review availability: Your plan provides up to 12 included reviews per hour; 11 remain after this review.


📝 Summary

Summary by CodeRabbit

  • Chores
    • Improved pull request workflow handling for merge-base calculation.
    • Updated change detection and style checks to use the computed merge base for more accurate comparisons.

Walkthrough

The pull-request workflow now computes and exports merge_base_sha from complete repository history. Branch-notes detection and SASS diff dispatch use this shared SHA instead of independently derived or raw PR base references.

Changes

SASS merge-base handling

Layer / File(s) Summary
Compute and consume merge base
.github/workflows/ci-workflow-pull-request.yml
The workflow exports merge_base_sha, computes it from the PR base and workflow SHA, and passes it to branch-notes detection.
Use merge base for SASS diff
.github/workflows/ci-workflow-pull-request.yml
SASS diff dispatch uses the shared merge-base SHA as base_ref.

Assessment against linked issues

Objective Addressed Explanation
Use a merge-base-based comparison for out-of-date PR branches [#11190]

Merge Risk: ⚪ Minimal · up to 0e3d3

The workflow now uses a shared merge-base SHA for pull-request SASS comparisons, avoiding attribution of later main-branch changes to the pull request. No current merge-blocking risk remains.


Comment @coderabbitai help to get the list of available commands.

@github-actions

This comment has been minimized.

@miscco miscco left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a fail

echo "base_sha=${BASE_SHA}" | tee -a "${GITHUB_OUTPUT}"
echo "pr_number=${{ fromJSON(steps.get-pr-info.outputs.pr-info).number }}" | tee -a "${GITHUB_OUTPUT}"
git fetch origin "${BASE_SHA}" -q
echo "merge_base_sha=$(git merge-base "${BASE_SHA}" "${GITHUB_SHA}")" | tee -a "${GITHUB_OUTPUT}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a fail early for PRs that do not merge cleanly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The merge-base path does not merge the PRs. merge-base is the first common commit between 2 branches, so in the diagrams above it asks for commit B. Since every branch is some descendant of main it is infallible.

@bernhardmgruber bernhardmgruber left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic LGTM, but claude thinks we should add an additional check (my knowledge on github workflows is close to zero):

echo "base_sha=${{ fromJSON(steps.get-pr-info.outputs.pr-info).base.sha }}" | tee -a "${GITHUB_OUTPUT}"
echo "base_sha=${BASE_SHA}" | tee -a "${GITHUB_OUTPUT}"
echo "pr_number=${{ fromJSON(steps.get-pr-info.outputs.pr-info).number }}" | tee -a "${GITHUB_OUTPUT}"
git fetch origin "${BASE_SHA}" -q

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, claude is telling me that this line should be guarded:

  • runs git fetch/git merge-base on BASE_SHA with no guard.
  • The step it replaces (branch-notes-dirt, introduced in Add .branch_notes. #7238) explicitly guarded this exact computation with:
    if [[ -z "${BASE_SHA}" ]]; then
    echo "branch_notes_dirt=" >> "${GITHUB_OUTPUT}"
    exit 0
    fi
  • This guard exists because BASE_SHA (fromJSON(get-pr-info.outputs.pr-info).base.sha) can genuinely be empty — this workflow also triggers on push to pull-request/[0-9]+ branches, where get-pr-info may not resolve a linked PR.
  • Since the whole workflow runs under defaults.run.shell: bash --noprofile --norc -euo pipefail, an empty BASE_SHA will now make git fetch origin "" (or git merge-base "" "$GITHUB_SHA") fail with -e, aborting the entire build-workflow job — not just gracefully degrading the .branch_notes check as before. This is a behavior change/regression for the exact edge case the original guard was written to handle.
  • Suggestion: wrap the fetch/merge-base computation in the same if [[ -z "${BASE_SHA}" ]]; then ... fi guard (emitting an empty merge_base_sha in that branch), and keep the downstream consumers (dispatch-sass-diff, branch-notes-dirt) tolerant of an empty value, matching prior behavior.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BASE_SHA (fromJSON(get-pr-info.outputs.pr-info).base.sha) can genuinely be empty — this workflow also triggers on push to pull-request/[0-9]+ branches, where get-pr-info may not resolve a linked PR.

I don't think it's possible for get-pr-info to ever return an empty base sha. Any pull-request created against CCCL should always create a pull-request/1234 pointing to the original PR courtesy of the nv-copy-pr bot.

But could be wrong, @trxcllnt to confirm the above ^^.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@trxcllnt gentle reminder on the above

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

🥳 CI Workflow Results

🟩 Finished in 13h 55m: Pass: 100%/501 | Total: 6d 16h | Max: 2h 09m | Hits: 89%/880320

See results here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

Fix SASS diff for out-of-date PR branches

4 participants