Repository navigation
Publish releases on Gitea and Forgejo, and run on Gitea Actions and Forgejo Actions - #411
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Just report it as information, like the other Git host clients do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Although similar to Gitea, Forgejo is its own platform and gets its own API client and support classes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Gitea and Forgejo hosts are now properly configurable (although yet seen as unknown hosts). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Now `bv release` can publish a release on a Gitea host. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Those lines predate GiteaHost and did not follow the 140-character guideline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Now `bv release` can publish a release on a Forgejo host. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Now `bv release` recognizes Gitea and Forgejo runners and deals with them properly. Previously they were incorrectly recognized as GitHub runners. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Now that we have it, support for Gitea and Forgejo deserves to be documented. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #411 +/- ##
==========================================
+ Coverage 86.82% 87.28% +0.45%
==========================================
Files 307 321 +14
Lines 9055 9514 +459
Branches 1749 1793 +44
==========================================
+ Hits 7862 8304 +442
- Misses 905 911 +6
- Partials 288 299 +11 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
rdeago
commented
Oct 26, 2026
rdeago
left a comment
Member
Author
There was a problem hiding this comment.
Review by Claude. Self-review.
👍 Approved.
No blocking findings.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist of related issues / discussions
Proposed changes
GitHost.Createmade anUnknownHostfor every Gitea and Forgejo repository, sobv releasecreated no release page there. A Gitea or Forgejo runner setsGITHUB_ACTIONS=true, sobvalso took it for GitHub Actions. This PR adds Gitea and Forgejo as Git hosts, and Gitea Actions and Forgejo Actions as CI platforms.The hosts:
GiteaApiClientandForgejoApiClientreach the REST API athttps://<host>/api/v1, withAuthorization: token <token>.GiteaHostandForgejoHostbuild the release and file URLs.GetFileUrlputstag,branch, orcommitbefore the ref, after the kind ofGitRef.GiteaReleasePublisherandForgejoReleasePublishercheck the token, create and publish the release, and undo it on a rollback.buildvana.jsoncacceptsgiteaandforgejoinrepository.host.hosts.gitea.tokenEnvdefaults toGITEA_TOKEN, andhosts.forgejo.tokenEnvtoFORGEJO_TOKEN.GitHost.DetectKindtakesgitea.comfor Gitea andcodeberg.orgfor Forgejo on every CI platform. On its own runners, a self-hosted instance is recognized throughCIPlatform.ServerKind.The release, on both hosts:
BeginAsyncreadsGET /repos/{owner}/{repo}. It refuses a repository whosehas_releasesis false, or whosepermissions.pushis false.PublishAsyncruns after the push of the tag. It creates a draft on the tag, withtarget_commitishset to the release commit.PublishAsyncthen uploads each asset as multipart fieldattachment, with?name=<file name>. Last, it sendsPATCHwithname,body,prerelease, anddraftfalse.CHANGELOG.mdon the release branch.UndoAsyncdeletes the release, then sendsDELETE /repos/{owner}/{repo}/tags/{tag}. Each deletion tolerates a 404.CheckAssetsrefuses two assets with the same file name.The platforms:
ForgejoActionsPlatformis detected onFORGEJO_ACTIONS. It readsFORGEJO_SERVER_URL, and writes the step outputs to the fileFORGEJO_OUTPUTnames.GiteaActionsPlatformis detected onGITEA_ACTIONS. It readsGITHUB_SERVER_URL, and writes the step outputs to the fileGITHUB_OUTPUTnames.GITEA_ACTIONStoo.GitHubActionsStepOutputWriter. Both runners parse its format.gitea-actions <gitea-actions@noreply.<host>>andforgejo-actions <noreply@forgejo.org>. The Gitea Actions user has no email, so the address names the host ofGITHUB_SERVER_URL. Forgejo states its own address.release.mdhas a "Publishing on Gitea" and a "Publishing on Forgejo" section. Each states the token kinds, the scope and the access the token needs, the token of an Actions job, and the attachments.environment-variables.mddescribes the platform variables and the token variables.introduction.mdhas a row for each host and each platform.configuration-file.mdlists the two values ofrepository.host, andhosts.gitea.tokenEnvandhosts.forgejo.tokenEnv.Where the code differs from the issue
The facts below come from Gitea v28.2.0, Forgejo v17.0.0, and the runners of both.
forgejoselectGiteaHost, with nohosts.forgejosection. Forgejo has its ownHostKind, host, client, publisher, configuration, and platform. The Gitea and Forgejo types share no code beyondHostApiClient, so that each follows its own server. The two APIs already differ: Forgejo hashide_archive_linksand notag_message, and itscreateTaghas no default-branch fallback.token, where the issue reads the login of the token owner. Basic authentication ignores the username when the password is an access token or an Actions token, on both hosts. The Git HTTP routes authenticate through the same code.BeginAsynccreates nothing, where the issue creates a draft there. When Gitea or Forgejo processes the push of a tag, it publishes a draft on the same tag name. A draft created before the push would be published without its attachments.BeginAsyncreadspermissions.pushandhas_releasesof the repository instead. A token without thewrite:repositoryscope also fails at the push of the release commit, before anything is published.PATCH. The update sends notag_nameand notarget_commitish, which the issue lists. The draft already carries both, and aPATCHwithdraftfalse keeps the tag of the release.UndoAsyncalso deletes the record of the tag. A rollback deletes the tag beforeUndoAsync, which turns the release into a draft. Deleting a release keeps the record of its tag, which then shows in the tag list.DeleteReleaseAsyncreturnsfalseon a 404, andUndoAsyncreports it at Info level. A throw there would skip the deletion of the tag record.IsPrivateRepositoryAsync. It is true whenprivateis true orowner.visibilityis notpublic. The issue readsprivatealone, which misses a public repository of a limited or private owner.release.mdsays so.Risks
push_updatequeue. A slow queue can publish the draft before the assets are uploaded. The release ends complete either way.ForgejoActionsPlatformreadsFORGEJO_OUTPUT, which exists from Forgejo Runner 9.0.0. An older runner failsbv releasewith a message that names the variable.introduction.mdstates the minimum version.introduction.mdsay "Supported (untested)" for both hosts and both platforms.Additional changes
GitHubApiClient.DeleteReleaseAsync. It threw on a 404, so a rollback that found the release gone stopped with an error. It returnsfalseinstead, andGitHubReleasePublisher.UndoAsyncreports the missing release at Info level, asGitLabReleasePublisherdoes. On GitHub, the 404 happens only when someone deletes the release by hand. No changelog bullet, becauseGitHubApiClientdid not exist in the last stable release.GitHostTests.csandReleaseHarness.cshad lines over 140 characters, which predate this PR. They are wrapped, in their own commit.terminology.md. The "CI platform" row listed the platforms in its first cell. The list moves below the table, with Gitea Actions and Forgejo Actions.Types of changes
This pull request introduces the following types of changes:
.gitattributes,.gitignore)Breaking changes
This pull request introduces breaking changes:
Checklist
🤖 Generated with Claude Code