This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/struts.git
The following commit(s) were added to refs/heads/main by this push:
new 791d1e3db build(ci): baseline the Jenkins .claude/ filter on the PR
target branch (#1850)
791d1e3db is described below
commit 791d1e3dbd582b43179b00826790ad6c701d73ee
Author: Lukasz Lenart <[email protected]>
AuthorDate: Fri Aug 14 19:30:28 2026 +0200
build(ci): baseline the Jenkins .claude/ filter on the PR target branch
(#1850)
#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 b633817af... 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 <[email protected]>
---
Jenkinsfile | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index 105625d5d..3611fbaae 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -44,13 +44,28 @@ pipeline {
stage('Detect changes') {
steps {
script {
- // Skip the build when a push only touched .claude/ - agent
+ // Skip the build when a change only touched .claude/ - agent
// instructions, not code. Fails open: anything unexpected (no
- // previous successful build, an unreachable commit, a git error)
- // reports true and the build runs as before.
+ // baseline, an unreachable commit, a git error) reports true and
+ // the build runs as before.
+ //
+ // On a pull request the baseline is the merge base with the
+ // target branch, NOT GIT_PREVIOUS_SUCCESSFUL_COMMIT. That
pointer
+ // is the previous head of this same PR, so once the PR is
rebased
+ // (or the target is merged into it) everything the target branch
+ // absorbed in the meantime looks like a change of the PR's own.
+ // The multibranch checkout already fetches the target branch, so
+ // origin/$CHANGE_TARGET resolves here. On a branch build there
is
+ // no target and the previous successful commit is the only
+ // baseline available.
env.CODE_CHANGED = sh(returnStdout: true, script: '''
set -u
- base="${GIT_PREVIOUS_SUCCESSFUL_COMMIT:-}"
+ target="${CHANGE_TARGET:-}"
+ if [ -n "$target" ]; then
+ base=$(git merge-base "origin/${target}" HEAD 2>/dev/null ||
true)
+ else
+ base="${GIT_PREVIOUS_SUCCESSFUL_COMMIT:-}"
+ fi
if [ -z "$base" ] || ! git cat-file -e "${base}^{commit}"
2>/dev/null; then
echo true
exit 0