fix(gitlab): handle branch creation without commits - #2875
Conversation
Paco Review 🔍This PR adds support for GitLab "branch creation" push webhooks that arrive with an empty commits array (only before/after SHAs), by detecting the pattern, deferring skip-CI evaluation until commit metadata is fetched via API and SHA-verified, and pinning PipelineRun/file resolution to the immutable webhook SHA (or default branch) via a new shared Review difficulty: 4/5 (Hard) — The change spans webhook parsing, skip-CI decisioning, and revision resolution across several interdependent files with subtle edge cases (SHA casing, branch-creation detection, call-order coupling) that require careful tracing to validate. 1 new inline comment(s) found. Reviewed commit: dae8edb |
a28ee30 to
7abd479
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2875 +/- ##
==========================================
+ Coverage 68.23% 68.44% +0.20%
==========================================
Files 197 197
Lines 16680 16761 +81
==========================================
+ Hits 11382 11472 +90
+ Misses 4432 4417 -15
- Partials 866 872 +6
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
d2b86ad to
04d8cc9
Compare
| if branchCreate { | ||
| // Pin branch creation to the webhook SHA so a later push cannot change the matched definitions. | ||
| revision = event.SHA | ||
| } |
There was a problem hiding this comment.
I think not only on branchCreate we can use event.SHA for every event as it is available all the time and good for security...
There was a problem hiding this comment.
Sorry, I missed this comment earlier.
I think you are right: for source provenance, we should use event.SHA across all supported GitLab event types.
I originally added the branchCreate guard to keep this fix narrowly scoped and avoid changing the existing behavior for other events. At that point, I had not verified the meaning of event.SHA for every GitLab event type, so I did not want to assume that it was always a valid and reachable commit SHA. In particular, I was concerned that some event types might carry a zero SHA such as 0000000000000000000000000000000000000000. For branch creation, we explicitly validate gitEvent.After, so overriding revision in that case was the conservative choice.
I reviewed how processedEvent.SHA is populated in pkg/provider/gitlab/parse_payload.go (code), together with how runevent.SHA is resolved by GetCommitInfo (code). I do not see such an exception in the supported event paths: they either provide an actual commit SHA or resolve one before the PipelineRun definitions are loaded.
I’ll open a follow-up PR to use event.SHA consistently for GitLab source provenance. I’ll also make sure that both the .tekton definitions and repository-local Task/Pipeline references are pinned to the same revision.
Thanks for pointing this out.
|
overall PR looks good to me! just address the comment and squash your commits |
|
fine by me as well just need to have the squashed commit please |
Accept branch-creation push payloads that omit the commits array and resolve the created branch from the immutable after SHA. Keep PipelineRun definitions, repository-local references, and commit metadata pinned to the same event revision. Add regression coverage for payload validation, skip-CI handling, and source revision selection. Signed-off-by: qingliu <qingliu@alauda.io> Assisted-by: OpenAI Codex (GPT-5)
04d8cc9 to
85a3913
Compare
Thanks — done. |
Use the immutable event SHA for PipelineRun definitions and repository-local Task and Pipeline references across GitLab events. Fall back to the source branch only when the event SHA is empty or all zeros. This follows up on tektoncd#2875 after its source-provenance review comment was noticed after merge. It prevents later branch updates from changing the repository revision selected for an existing event. Signed-off-by: qingliu <qingliu@alauda.io>
Use the immutable event SHA for PipelineRun definitions and repository-local Task and Pipeline references across GitLab events. Fall back to the source branch only when the event SHA is empty or all zeros. This follows up on tektoncd#2875 after its source-provenance review comment was noticed after merge. It prevents later branch updates from changing the repository revision selected for an existing event. Signed-off-by: qingliu <qingliu@alauda.io>
Use the immutable event SHA for PipelineRun definitions and repository-local Task and Pipeline references across GitLab events. Fall back to the source branch only when the event SHA is empty or all zeros. This follows up on #2875 after its source-provenance review comment was noticed after merge. It prevents later branch updates from changing the repository revision selected for an existing event. Signed-off-by: qingliu <qingliu@alauda.io>
📝 Description of the Change
GitLab can send a Push Hook with an empty
commitsarray when a new branch iscreated at an existing commit. Pipelines as Code currently rejects every such
payload with
no commits attached to this push event, so the new branch nevertriggers a PipelineRun.
This change:
refs/heads/<branch>ref, an all-zero
beforeSHA, and a valid non-zero 40-character hexadecimalafterSHA.afteras the authoritative immutable revision and fetches commitmetadata for that exact SHA instead of a mutable branch head.
on the same selected source revision, including
default_branchprovenance.removing the ordering dependency between
GetTektonDirandGetFileInsideRepo.webhook omits commit metadata.
names, and unrelated empty-commit push events.
🔍 Root Cause and Code Location
The links below use the fixed pre-change
mainrevision3bbaf67f5042b852f9acebc59758eeb38e0ee870.ParsePayloadrejected every push with an emptycommitsarray.A valid GitLab branch-creation payload has an all-zero
beforeSHA, anon-zero
afterSHA containing the created branch tip, and arefs/heads/...ref, but no entry incommits. The unconditional rejectiontherefore discarded a valid event before matching could begin.
GetTektonDir,while the GitLab provider selected the mutable branch ref.
If another push moved the branch after webhook delivery, matching could read
definitions from a different commit than the event's
afterSHA.chain:
getPipelineRunsFromRepocalledresolve.Resolve,ResolvecreatedRemoteTaskswithout a selected revision,and
RemoteTaskspassed an empty target to the provider.The GitLab implementation then always fetched from
HeadBranch,so repository-local references could drift independently of the PipelineRun
definitions.
SHATitle.Branch-creation payloads do not provide that commit metadata, so the exact
aftercommit must be queried before checking its full message.The fix classifies only genuine branch-creation payloads, records
afteras animmutable event-scoped source revision, and queries commit metadata by that SHA.
For source provenance,
.tektondefinitions use the same SHA. Fordefault_branchprovenance, the default branch is selected explicitly. Thechosen revision is then passed through
resolve.OptsandRemoteTasksintoGetFileInsideRepo, so repository-local references use the same source withoutrequiring
GetTektonDirto mutate shared event state first. If a caller does notprovide an explicit target, GitLab branch creation safely falls back to the
immutable event SHA.
📦 Release Notes
GitLab branch creation events can now trigger Pipelines as Code when GitLab
omits the
commitsarray from the Push Hook payload.🔗 Linked GitHub Issue
Fixes #2874
🧪 Testing Strategy
The tests cover payload classification, exact-SHA metadata lookup, invalid and
deletion payload rejection, source/default-branch revision selection, explicit
repository-revision propagation, repository-local references, skip-CI
handling, and the adapter event flow.
make testpasses all 3162 tests. Go, gofumpt, and YAML lint checks pass. Thecomplete local
make lintcould not run its Markdown/grammar stage because thelocal environment does not have
markdownlintorvale; this PR does notchange Markdown files, and CI remains the authoritative complete lint run.
🤖 AI Assistance
OpenAI Codex (GPT-5) assisted with implementation and test development. The
submitter reviewed and understood the changes, validated the behavior, and ran
the test and available lint suites. The commits include an
Assisted-bytrailer.
✅ Submitter Checklist
fix:,feat:) matches the "Type of Change" I selected above.make testandmake lintlocally to check for and fix any issues.make testand all available lint stages pass; the missing local Markdown tools are documented above.