Skip to content

fix(gitea): resolve target SHA from after field on tag push - #2997

Open
sdlarsen wants to merge 1 commit into
tektoncd:mainfrom
Midas-Energy:fix/forgejo-tag-push-sha
Open

sdlarsen wants to merge 1 commit into
tektoncd:mainfrom
Midas-Energy:fix/forgejo-tag-push-sha

Conversation

@sdlarsen

@sdlarsen sdlarsen commented Sep 23, 2026 •

Copy link
Copy Markdown

📝 Description of the Change

When a tag is pushed without commits, Forgejo/Gitea provides head_commit=nil, before=0000000000000000000000000000000000000000, and after=<commit/tag SHA>. Using 'before' resulted in querying commit 0000000000000000000000000000000000000000, failing with 'could not find commit info'.

In addition:

  • Reject and skip push events for deleted refs (where 'after' is zero SHA).
  • Resolve annotated tag objects to their peeled commit SHA via the Forgejo tag API.

🔗 Linked GitHub Issue

Fixes #2983

🧪 Testing Strategy

  • Unit tests
  • Integration tests
  • End-to-end tests
  • Manual testing (running in my pipeline)
  • Not Applicable

🤖 AI Assistance

  • I have not used any AI assistance for this PR.
  • [X ] I have used AI assistance for this PR.

✅ Submitter Checklist

  • 📝 My commit messages are clear, informative, and follow the project's How to write a git commit message guide. The Gitlint linter ensures in CI it's properly validated
  • ✨ I have ensured my commit message prefix (e.g., fix:, feat:) matches the "Type of Change" I selected above.
  • ♽ I have run make test and make lint locally to check for and fix any
    issues. For an efficient workflow, I have considered installing
    pre-commit and running pre-commit install to
    automate these checks.
  • 📖 I have added or updated documentation for any user-facing changes.
  • 🧪 I have added sufficient unit tests for my code changes.
  • 🎁 I have added end-to-end tests where feasible. See README for more details.
  • 🔎 I have addressed any CI test flakiness or provided a clear reason to bypass it.
  • If adding a provider feature, I have filled in the following and updated the provider documentation:
    • GitHub App
    • GitHub Webhook
    • Gitea/Forgejo
    • GitLab
    • Bitbucket Cloud
    • Bitbucket Data Center

@linux-foundation-easycla

linux-foundation-easycla Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: sdlarsen / name: Søren Dalby Larsen (2cf04fc)

@chmouel

chmouel commented Sep 23, 2026

Copy link
Copy Markdown
Member

/ok-to-test

@chmouel

chmouel commented Sep 23, 2026

Copy link
Copy Markdown
Member

/paco review

@pipelines-as-code

Copy link
Copy Markdown

Paco Review 🔍

This PR adds tag push support to the Gitea provider. It introduces logic to detect refs/tags/ prefixes in BaseBranch/HeadBranch and resolve annotated tags to their peeled commit SHA via the Gitea API. It also fixes a bug where deleted-ref push events (after SHA is all zeros) were not being skipped, and improves the fallback SHA selection to use gitEvent.After instead of gitEvent.Before when the head commit is missing.

Review difficulty: 3/5 (Moderate) — Moderate complexity: touches parsing logic, commit resolution, and tests across multiple files with subtle edge cases around zero SHAs and tag vs branch resolution.

2 new inline comment(s) found.

Reviewed commit: 2cf04fc

@pipelines-as-code pipelines-as-code Bot added the paco/review-moderate Paco review difficulty label Sep 23, 2026

@pipelines-as-code pipelines-as-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Paco inline comments -- see the Paco Review summary comment for the overview.


if sha == "" {
switch {
case runevent.HeadBranch != "":

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[HIGH] When the tag API call succeeds and updates sha/runevent.SHA to the peeled commit SHA, the code then falls into the if sha == "" block — which it won't enter since sha is now set. That's correct. However, if the tag API call fails (err != nil), the error is silently swallowed. runevent.SHA was already set to the original tag object SHA before this function was called (tagobjectsha999 in the test). In that case, sha retains the original value passed in (runevent.SHA before the function), and GetSingleCommit is called with the tag object SHA rather than the peeled commit SHA. This may silently produce wrong commit info instead of surfacing the API error. At minimum the error should be logged via v.Logger.

sha = branchinfo.Commit.ID
case runevent.PullRequestNumber != 0:
pr, _, err := v.Client().GetPullRequest(runevent.Organization, runevent.Repository, int64(runevent.PullRequestNumber))
if err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[MEDIUM] After the tag resolution block sets sha to the peeled commit SHA, the if sha == "" block is skipped entirely. However runevent.HeadBranch still contains refs/tags/v1.0.0. Later, when GetRepoBranch is used as a fallback (for non-tag, non-PR events where SHA is empty), runevent.HeadBranch would be passed as-is. This is fine for the current logic, but note that in the tag case, runevent.HeadBranch is never cleared of the refs/tags/ prefix, which could affect callers that assume HeadBranch is a plain branch name. Consider stripping the refs/tags/ prefix from HeadBranch when a tag is detected, similar to how PR resolution updates HeadBranch.

@codecov

codecov Bot commented Sep 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.62500% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.56%. Comparing base (8ed3d29) to head (2cf04fc).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
pkg/provider/gitea/gitea.go 88.88% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2997      +/-   ##
==========================================
- Coverage   91.57%   91.56%   -0.01%     
==========================================
  Files         164      164              
  Lines       12532    12546      +14     
==========================================
+ Hits        11476    11488      +12     
- Misses       1055     1057       +2     
  Partials        1        1              
Flag Coverage Δ
unit-tests 91.56% <90.62%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

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

@sdlarsen
sdlarsen force-pushed the fix/forgejo-tag-push-sha branch from 2cf04fc to 9a4a40c Compare September 23, 2026 08:04
branchinfo, _, err := v.Client().GetRepoBranch(runevent.Organization, runevent.Repository, runevent.HeadBranch)
if err != nil {
return err
var tagName string

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'd rather do this tag fetching in parse_payload.go, as you can see something similar is done for github in its ParsePayload func

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks you for taking the time for the review @zakisk!

I looked into doing this in gitea/parse_payload.go, but if I get it right, there is a lifecycle constraint with Gitea compared to GitHub:

  1. GitHub can make API calls in parse_payload.go because it runs as a GitHub App and mints an installation token up front from the controller credentials (github/parse_payload.go:312).
  2. Gitea/Forgejo uses per-repository tokens stored in the Kubernetes Repository CR. When s.vcx.ParsePayload() is called in sinker.go, the Repository CR hasn't been matched yet (matching depends on event.URL from ParsePayload), so v.giteaClient is nil throughout parse_payload.go.
  3. GetCommitInfo is called after SetClient initializes v.giteaClient. In fact, GetCommitInfo in gitea.go already handles other ref-to-commit API lookups for the exact same reason (e.g. v.Client().GetRepoBranch for branches and v.Client().GetPullRequest for PRs).

Resolving the annotated tag in GetCommitInfo keeps parse_payload.go purely as a payload parser and reuses the authenticated client once initialized. To me, it looks like github is the exception? Let me know if that makes sense, or I missed the point.

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.

we can continue with what you've implemented and it would be a follow-up task to not make this complext.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That would be great @zakisk , I'd love to get this upstream.

When a tag is pushed without commits, Forgejo/Gitea provides head_commit=nil,
before=0000000000000000000000000000000000000000, and after=<commit/tag SHA>.
Using 'before' resulted in querying zero SHA
0000000000000000000000000000000000000000, failing with 'could not find commit
info'.

In addition:
- Reject and skip push events for deleted refs (where 'after' is zero SHA).
- Resolve annotated tag objects to their peeled commit SHA via the
  Forgejo tag API.
- Strip refs/tags/ prefix from HeadBranch for clean branch naming.
- Return error if tag lookup fails or cannot resolve commit SHA.

Fixes tektoncd#2983

Co-authored-by: Gemini <noreply@google.com>
Signed-off-by: Søren Dalby Larsen <sdl@midas-energy.com>
@sdlarsen
sdlarsen force-pushed the fix/forgejo-tag-push-sha branch from 9a4a40c to fa62c5e Compare September 25, 2026 11:37
@sdlarsen

Copy link
Copy Markdown
Author

Good catch, thanks! If GetTag fails or returns an empty commit SHA for an annotated tag, falling through leaves the SHA pointing to a tag object which GetSingleCommit cannot resolve anyway.
I have updated GetCommitInfo to propagate the error directly (consistent with how branch and PR lookups fail fast) and updated the unit tests accordingly.

This branch has not been deployed

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

Labels

paco/review-moderate Paco review difficulty

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Gitea/Forgejo] Tag push webhooks fail with 'could not find commit info: 0000000000000000000000000000000000000000'

4 participants