1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-31 06:38:37 +00:00

Keeping consistent between UI and API about combined commit status state and fix some bugs (#34562)

Extract from #34531 

## Move Commit status state to a standalone package

Move the state from `structs` to `commitstatus` package. It also
introduce `CommitStatusStates` so that the combine function could be
used from UI and API logic.

## Combined commit status Changed

This PR will follow Github's combined commit status. Before this PR,
every commit status could be a combined one.
According to
https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#get-the-combined-status-for-a-specific-reference
> Additionally, a combined state is returned. The state is one of:
> failure if any of the contexts report as error or failure
> pending if there are no statuses or a context is pending
> success if the latest status for all contexts is success

This PR will follow that rule and remove the `NoBetterThan` logic. This
also fixes the inconsistent between UI and API. In the API convert
package, it has implemented this which is different from the UI. It also
fixed the missing `URL` and `CommitURL` in the API.

## `CalcCommitStatus` return nil if there is no commit statuses

The behavior of `CalcCommitStatus` is changed. If the parameter commit
statuses is empty, it will return nil. The reference places should check
the returned value themselves.
This commit is contained in:
Lunny Xiao
2025-06-09 12:05:33 +08:00
committed by GitHub
parent f6041441ee
commit 6d0b24064a
21 changed files with 482 additions and 281 deletions

View File

@@ -5,6 +5,7 @@ package convert
import (
"context"
"net/url"
git_model "code.gitea.io/gitea/models/git"
user_model "code.gitea.io/gitea/models/user"
@@ -32,39 +33,29 @@ func ToCommitStatus(ctx context.Context, status *git_model.CommitStatus) *api.Co
return apiStatus
}
func ToCommitStatuses(ctx context.Context, statuses []*git_model.CommitStatus) []*api.CommitStatus {
apiStatuses := make([]*api.CommitStatus, len(statuses))
for i, status := range statuses {
apiStatuses[i] = ToCommitStatus(ctx, status)
}
return apiStatuses
}
// ToCombinedStatus converts List of CommitStatus to a CombinedStatus
func ToCombinedStatus(ctx context.Context, statuses []*git_model.CommitStatus, repo *api.Repository) *api.CombinedStatus {
if len(statuses) == 0 {
return nil
}
retStatus := &api.CombinedStatus{
SHA: statuses[0].SHA,
combinedStatus := git_model.CalcCommitStatus(statuses)
return &api.CombinedStatus{
State: combinedStatus.State,
Statuses: ToCommitStatuses(ctx, statuses),
SHA: combinedStatus.SHA,
TotalCount: len(statuses),
Repository: repo,
URL: "", // never set or used?
State: api.CommitStatusSuccess,
CommitURL: repo.URL + "/commits/" + url.PathEscape(combinedStatus.SHA),
URL: repo.URL + "/commits/" + url.PathEscape(combinedStatus.SHA) + "/status",
}
retStatus.Statuses = make([]*api.CommitStatus, 0, len(statuses))
for _, status := range statuses {
retStatus.Statuses = append(retStatus.Statuses, ToCommitStatus(ctx, status))
if status.State.HasHigherPriorityThan(retStatus.State) {
retStatus.State = status.State
}
}
// According to https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#get-the-combined-status-for-a-specific-reference
// > Additionally, a combined state is returned. The state is one of:
// > failure if any of the contexts report as error or failure
// > pending if there are no statuses or a context is pending
// > success if the latest status for all contexts is success
switch retStatus.State {
case api.CommitStatusSkipped:
retStatus.State = api.CommitStatusSuccess // all skipped means success
case api.CommitStatusPending, api.CommitStatusSuccess:
// use the current state for pending or success
default:
retStatus.State = api.CommitStatusFailure // otherwise, it is a failure
}
return retStatus
}