Skip to content

build(ci): baseline the Jenkins .claude/ filter on the PR target branch - #1850

Merged
lukaszlenart merged 1 commit into
mainfrom
build/jenkins-pr-change-baseline
Aug 14, 2026
Merged

build(ci): baseline the Jenkins .claude/ filter on the PR target branch#1850
lukaszlenart merged 1 commit into
mainfrom
build/jenkins-pr-change-baseline

Conversation

@lukaszlenart

Copy link
Copy Markdown
Member

Follow-up to #1846 and #1849. The GitHub Actions side is fixed; Jenkins still ran a full Maven round trip on a docs-only PR.

What happens

#1846 guards the two JDK stages on a diff against GIT_PREVIOUS_SUCCESSFUL_COMMIT. For a branch build that is the right baseline. For a PR build it is not — the pointer is the previous head of the same PR, so once the PR is rebased (or the target branch merged into it), everything the target absorbed in between looks like a change of the PR's own.

PR-1848 build #2 is the case. That PR touches only .claude/skills/releasing-struts/, but it had been rebased across the maven.yml fix, and Jenkins computed:

+ base=b633817af047afaa80948404e2e6f1eb78e02b7a
+ git diff --name-only b633817af... HEAD
+ outside=.github/workflows/maven.yml
+ echo true
Changes outside .claude/: true

Both JDK stages then ran in full for a documentation-only change. Since main almost always carries code, this makes the filter useless for any PR that is ever brought up to date — which is most of them.

The fix

Use the merge base with the target branch when CHANGE_TARGET is set. The multibranch checkout already fetches it:

git fetch ... +refs/pull/1848/head:refs/remotes/origin/PR-1848 +refs/heads/main:refs/remotes/origin/main

so origin/$CHANGE_TARGET resolves in the workspace. Branch builds have no target and keep the previous-successful-commit baseline, unchanged.

Fail-open is preserved and now covers the new path too: an unresolvable merge base (target branch absent) leaves base empty and reports true.

Verification

Ran the stage's shell logic against the real commits of #1848 either side of its rebase, and against synthetic heads off main:

case baseline result
PR #1848 post-rebase (58a9a013a) 7411024c9 false — was true
PR #1848 pre-rebase (b633817af) 81b34c295 false
PR: code only 7411024c9 true
PR: .claude only 7411024c9 false
PR: .claude + code 7411024c9 true
PR: .claudefoo/ near miss 7411024c9 true
PR: target branch not fetched none true (fail open)
branch: no previous successful none true (fail open)
branch: previous = origin/main 7411024c9 false
branch: unreachable previous none true (fail open)

Not verifiable locally: that Jenkins exports CHANGE_TARGET into the sh step. It is a standard multibranch variable and GIT_PREVIOUS_SUCCESSFUL_COMMIT reaches the same script the same way, so the risk is low — and if it were ever unset, the branch-build path takes over and behaviour is exactly today's. Worth a glance at the Detect changes trace on this PR's own build to confirm.

Only the 7.x line is changed here; support/struts-6-x-x carries none of this.

🤖 Generated with Claude Code

#1846 guarded the two JDK stages on a diff against
GIT_PREVIOUS_SUCCESSFUL_COMMIT. On a branch build that is the right
baseline. On a pull request build it is not: the pointer is the previous
head of the same PR, so once the PR is rebased - or the target branch is
merged into it - everything the target absorbed in between shows up as a
change of the PR's own.

PR-1848 build #2 is the case. The pull request touches only
.claude/skills/releasing-struts/, but it had been rebased across the
maven.yml fix, and Jenkins computed:

  + base=b633817af047afaa80948404e2e6f1eb78e02b7a
  + git diff --name-only b633817... HEAD
  + outside=.github/workflows/maven.yml
  Changes outside .claude/: true

so both JDK stages ran a full Maven round trip for a documentation-only
change. Since main almost always carries code, this made the filter
useless for any pull request that is ever brought up to date.

Use the merge base with the target branch as the baseline when
CHANGE_TARGET is set. The multibranch checkout already fetches it -

  git fetch ... +refs/heads/main:refs/remotes/origin/main

- so origin/$CHANGE_TARGET resolves in the workspace. Branch builds have
no target and keep the previous-successful-commit baseline.

Fail-open is unchanged and still covers the new path: an unresolvable
merge base (target branch absent) yields an empty base and reports true.

Exercised against the real commits of #1848 either side of its rebase,
and against synthetic heads for: code only, .claude only, mixed, a
.claudefoo/ near miss, a missing target branch, and the three branch
build baselines. All ten behave as intended.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@lukaszlenart
lukaszlenart merged commit 791d1e3 into main Aug 14, 2026
13 checks passed
@lukaszlenart
lukaszlenart deleted the build/jenkins-pr-change-baseline branch August 14, 2026 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant