Skip to content

feat(sdk): detect PR context on Jenkins multibranch builds (#234) - #238

Merged
xping-admin merged 4 commits into
mainfrom
feat/234-jenkins-pr-context
Oct 5, 2026
Merged

xping-admin merged 4 commits into
mainfrom
feat/234-jenkins-pr-context

Conversation

@xping-admin

@xping-admin xping-admin commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #234.

Jenkins Branch Source PR builds now carry a PullRequestContext.

How the PR head commit is found

No Jenkins env var holds the PR head under the merge strategy (the default). Jenkins checks out the PR head and merges the target into it, so:

  • Read refs/remotes/origin/$BRANCH_NAME from $WORKSPACE/.git (loose ref, then packed-refs).
  • Use it only if it equals GIT_COMMIT (head strategy, or the merge fast-forwarded) or GIT_COMMIT's first parent (merge strategy).
  • Anything else returns null. For example, the ref moved past the built commit, or .git is a file.

Changes

  • JenkinsPullRequestDetector: gated on CHANGE_ID. Platform, owner and name come from CHANGE_URL: github.com, gitlab.com (nested groups), and Azure DevOps Services (dev.azure.com and *.visualstudio.com). Owner/name match the Azure Pipelines and GitLab detectors. If the PR number in the URL ≠ CHANGE_ID, it returns null.
  • GitRepositoryReader: minimal read-only .git access. It reads refs and the first parent of a loose commit (zlib via DeflateStream). There's no pack parsing: a commit packed by git gc --auto (long-lived workspaces) falls back to git rev-parse <sha>^1 with a 5 s timeout, and returns null without git on PATH. It validates ref names and SHAs before building file paths.
  • EnvironmentDetector: CI.IsPullRequest uses the shared IsPullRequestBuild predicate. GHPRB is still flagged.
  • Registered in AddXpingPullRequest.
  • Docs: configuration-reference.md and the Jenkins section and commit table of ci-cd-setup.md.

Tests

  • JenkinsPullRequestDetectorTests:
    • each host, unknown hosts, bad CHANGE_ID, URL/ID mismatch, each required variable missing
    • head / merge / moved-ref / unreadable cases
    • parity with the Azure Pipelines and GitLab detectors
  • GitRepositoryReaderTests: run against real repos built with the git CLI in a temp dir. They cover loose and packed refs, a --no-ff merge's first parent, root and packed objects, a worktree .git file, and unsafe inputs.

Not verified

Not yet run on a real Jenkins. If GIT_COMMIT or the PR-n / MR-n ref names differ from what the plugin source shows, the detector returns null rather than a wrong commit.

🤖 Generated with Claude Code

Jenkins Branch Source PR builds now carry a PullRequestContext for
github.com, gitlab.com and Azure DevOps Services repositories, parsed
from CHANGE_URL. The PR head commit is read from
refs/remotes/origin/$BRANCH_NAME and used only when it is GIT_COMMIT
(head strategy, fast-forward) or GIT_COMMIT's first parent (merge
strategy), so a ref that moved past the built commit yields no context.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.09502% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...vices/PullRequest/Internals/GitRepositoryReader.cs 98.09% 2 Missing ⚠️
Files with missing lines Coverage Δ
...ore/Extensions/XpingServiceCollectionExtensions.cs 96.28% <100.00%> (+0.02%) ⬆️
...vices/Environment/Internals/EnvironmentDetector.cs 72.09% <100.00%> (+1.18%) ⬆️
...ullRequest/Internals/JenkinsPullRequestDetector.cs 100.00% <100.00%> (ø)
...vices/PullRequest/Internals/GitRepositoryReader.cs 98.09% <98.09%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

xping-admin and others added 3 commits October 5, 2026 16:01
git merge runs gc --auto, so on a long-lived workspace the merge commit
Jenkins just made can end up in a pack the reader doesn't parse. Fall
back to `git rev-parse <sha>^1` when the commit isn't a loose object.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
#234)

A background gc --auto can pack refs and delete the loose PR ref between
the existence check and the read. Catch the IOException and fall through
to packed-refs, which pack-refs writes before deleting loose refs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Covers malformed refs, packed-refs and loose objects, the git fallback's
timeout and bad output, and unsupported CHANGE_URL shapes. Reading a
loose object no longer checks File.Exists first, so a gc pruning it
mid-read falls back to git instead of returning null.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@xping-admin
xping-admin merged commit 830c924 into main Oct 5, 2026
2 checks passed
@xping-admin
xping-admin deleted the feat/234-jenkins-pr-context branch October 5, 2026 14:50
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.

PR context detector for Jenkins (multibranch / Branch Source)

1 participant