Skip to content

feat: Add support for gerrit changes for download Jenkins file and support custom refspec in lightweight checkout#3969

Open
panicking wants to merge 16 commits into
jenkinsci:masterfrom
panicking:feat/add-jenkins-gerrit-change-support
Open

feat: Add support for gerrit changes for download Jenkins file and support custom refspec in lightweight checkout#3969
panicking wants to merge 16 commits into
jenkinsci:masterfrom
panicking:feat/add-jenkins-gerrit-change-support

Conversation

@panicking

@panicking panicking commented May 27, 2026

Copy link
Copy Markdown

[JENKINS-71506] Support custom refspec in lightweight checkout

Let user specify a custom refspec to fetch.
Add support for branch names FETCH_HEAD or a commit hash.

This allows to use lightweight checkout for:

  • Fetch the pipeline from a Gerrit change (refspec:
    refs/changes/*/change/patchset and branch: FETCH_HEAD).

  • Fetch the pipeline from a fixed commit of a branch, instead of head (refspec: branch and branch: commit hash).

Checklist

  • I have read the CONTRIBUTING doc
  • I have referenced the Jira issue related to my changes in one or more commit messages
  • I have added tests that verify my changes
  • Unit tests pass locally with my changes
  • I have added documentation as necessary
  • No Javadoc warnings were introduced with my changes
  • No spotbugs warnings were introduced with my changes
  • Documentation in README has been updated as necessary
  • Online help has been added and reviewed for any new or modified fields
  • I have interactively tested my changes
  • Any dependent changes have been merged and published in upstream modules (like git-client-plugin)

Types of changes

  • New feature (non-breaking change which adds functionality)

@panicking panicking requested a review from a team as a code owner May 27, 2026 18:14
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label May 27, 2026
@panicking panicking force-pushed the feat/add-jenkins-gerrit-change-support branch from 98b5da4 to 5ce95e2 Compare May 27, 2026 18:23
@github-actions github-actions Bot added the tests Automated test addition or improvement label May 27, 2026
@panicking panicking force-pushed the feat/add-jenkins-gerrit-change-support branch from 5ce95e2 to 45f8fbd Compare May 27, 2026 18:30
@panicking

Copy link
Copy Markdown
Author

@jenkinsci/git-plugin-developers Anytime to take a look on it?

panicking and others added 15 commits June 27, 2026 09:24
We want to support the verification pipeline when the Jenkinsfile
is part of the modification itself. This allow to test the
pipeline on any project and test it. The change should address
JENKINS-66599

Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
Allow users to specify a custom refspec for fetching in lightweight
checkout mode via GitSCMFileSystem. This enables SCMFileSystem to
fetch specific revisions rather than always fetching the branch tip.

Add support for:
- Custom refspec from UserRemoteConfig.getRefspec()
- FETCH_HEAD as a valid branch specification
- Raw commit hashes as branch specification
- refs/changes/* prefix for Gerrit change refs

These changes enable lightweight checkout to be used for:
- Gerrit changes using refs/changes/* refspecs with FETCH_HEAD
- Checking out a specific commit instead of branch HEAD
Centralize branch name resolution, prefix detection, commit hash
matching, and refspec construction inside HeadNameResult.calculate().
Previously this logic was split between the BuilderImpl.build() method
and HeadNameResult, making the flow hard to follow.

- Add remoteName parameter for constructing remote-tracking refs
- Add remoteHeadName, refspec, and rev fields to HeadNameResult
- Move FETCH_HEAD detection from build() into calculate()
- Move commit hash matching from build() into calculate()
- Move refspec construction from build() into calculate()
- Simplify build() to delegate entirely to HeadNameResult.calculate()
- Add unit tests for head name calculation with refspecs, commits,
  and FETCH_HEAD
Replace reference equality (==) with value equality (.equals()) when
comparing the prefix against Constants.R_HEADS and Constants.R_TAGS.
The == operator may fail for string values that are equal but not
the same object instance.
The prefix variable can be null when the branch specification is
FETCH_HEAD or a raw commit hash. Add a null check before calling
.equals() to prevent a NullPointerException.
Replace the hardcoded "FETCH_HEAD" string literal with the JGit
constant Constants.FETCH_HEAD in both production code and tests.
This improves maintainability and ensures consistency if the
constant value ever changes.
Extract a getFileContent() helper method to reduce duplication
in the file tree traversal assertions across multiple test methods.
Move createRepoListWithRefspec() helper adjacent to it.

Add new test methods:
- create_SCMFileSystem_from_commit: verify checkout at a specific
  commit revision
- create_SCMFileSystem_from_FETCH_HEAD: verify checkout using a
  custom refspec with FETCH_HEAD
Add static import for GitSCMFileSystem.BuilderImpl.HeadNameResult
and use the short name throughout calculate_head_name_with_env().
This reduces line length and improves readability of the test
assertions.
The headName field in HeadNameResult is reported as unread by
spotbugs (URF_UNREAD_FIELD). Suppress this warning temporarily
while investigating the proper resolution.

Note: This exclusion is removed in a subsequent commit once the
field is properly used in logging output.
Rename the local variable headName to calculatedHeadName inside
HeadNameResult.calculate() to avoid confusion with the
HeadNameResult.headName field. This makes the code easier to
understand by distinguishing the temporary local value from the
result object's field of the same name.
Include the remote name and resolved head name in the "Done." log
message so users can see which branch or commit was actually used
during the fetch operation.

Also remove the spotbugs URF_UNREAD_FIELD exclusion for
HeadNameResult.headName, which is now properly accessed through
the logging statement.
Update the refSpec parameter annotation in HeadNameResult.calculate()
from @nonnull to @checkfornull. The existing tests pass null for this
parameter, and the implementation already handles null correctly by
constructing a default refspec when none is provided.
Extend the static import of HeadNameResult to cover
calculate_head_name(), calculate_head_name_with_refspec_commit(),
calculate_head_name_with_refspec_FETCH_HEAD(), and
calculate_revision_head_name() test methods. This completes the
cleanup started in an earlier commit.
Fix the refspec calculation for tag branches. Previously a lightweight
checkout of a tag would generate a refspec mapping the tag to
refs/remotes/origin/<tag>, which places the tag reference in the
wrong namespace.

Now tag refspecs use +refs/tags/<name>:refs/tags/<name>, keeping tag
references in the correct refs/tags/ namespace. The remoteHeadName
for tags is also corrected to use just the tag name instead of the
remote-tracking path.

Additionally add a null guard when expanding refspec environment
variables to prevent NPE when refspecExpandedName is null.
The headName field in HeadNameResult was only used internally for
constructing the remoteHeadName. Since remoteHeadName is now always
a fully qualified reference (either refs/remotes/<remote>/<name>
for branches or the raw name for tags/commits/FETCH_HEAD), the
separate headName field is no longer needed.

- Remove headName from HeadNameResult constructor and fields
- Update callers to use remoteHeadName instead of headName
- Update test assertions to verify remoteHeadName directly
@panicking panicking force-pushed the feat/add-jenkins-gerrit-change-support branch from 45f8fbd to 66f2650 Compare June 27, 2026 16:40
@panicking

panicking commented Jun 27, 2026

Copy link
Copy Markdown
Author

@MarkEWaite and @ckullabosch I have rebased #1468 and added to my change, I'm going to test but would be nice to get reviewed

Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
@panicking panicking changed the title feat: Add support for gerrit changes for download Jenkins file feat: Add support for gerrit changes for download Jenkins file and support custom refspec in lightweight checkout Jun 27, 2026
private HeadNameResult(String headName, String prefix) {
this.headName = headName;
this.prefix = prefix;
final String remoteHeadName;

@rsandell rsandell Jun 28, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm trying to remember if this class gets stored somewhere on disk, like the project config or pipeline context/program.
I don't think so, but if that's the case then an upgrade would break those builds currently running. That might be ok though.

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

Labels

documentation Improvements or additions to documentation tests Automated test addition or improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants