mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-26 21:39:42 +09:00
fix(actions): keep distinct commit statuses for workflows sharing a name (#37834)
## Summary Two Gitea Actions workflow files that share the same `name:` and same job name produced identical commit-status `Context` strings. Because `GetLatestCommitStatus` groups by `context_hash` (derived from `Context`), only one row was shown on the PR page — see #35699. GitHub displays both rows even though they look identical. This change does the same: the displayed `Context` is unchanged, but `ContextHash` now mixes in the workflow file path so the two statuses remain distinct in the dedupe query. ## Notes - Workflows that omit `name:` now use the workflow file name in the `Context` (e.g. `ci.yaml / build (push)`) instead of an empty `/ build (push)`. This changes the `Context` string for unnamed workflows, so any required-status-check rule that referenced the old string must be updated after upgrade. - For statuses created before this change (hashed from `Context` alone), `createCommitStatus` reuses that legacy hash when a matching row is still present, so in-flight pending statuses are superseded rather than orphaned on upgrade. Fixes #35699 --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
co-authored by
Claude Opus 4.7
silverwind
parent
5fe77ad309
commit
63df886ba8
@@ -139,10 +139,24 @@ func getCommitStatusEventNameAndCommitID(run *actions_model.ActionRun) (event, c
|
||||
func createCommitStatus(ctx context.Context, repo *repo_model.Repository, event, commitID string, run *actions_model.ActionRun, job *actions_model.ActionRunJob) error {
|
||||
// TODO: store workflow name as a field in ActionRun to avoid parsing
|
||||
runName := path.Base(run.WorkflowID)
|
||||
// fall back to the file name when the workflow has no non-blank `name:`
|
||||
if wfs, err := jobparser.Parse(job.WorkflowPayload); err == nil && len(wfs) > 0 {
|
||||
runName = wfs[0].Name
|
||||
if name := strings.TrimSpace(wfs[0].Name); name != "" {
|
||||
runName = name
|
||||
}
|
||||
}
|
||||
ctxName := strings.TrimSpace(fmt.Sprintf("%s / %s (%s)", runName, job.Name, event)) // git_model.NewCommitStatus also trims spaces
|
||||
// Mix the workflow file path into the hash so two workflow files that
|
||||
// share the same `name:` and job name produce distinct commit statuses
|
||||
// even though they render identically — matching GitHub's behavior
|
||||
// (issue #35699).
|
||||
ctxHash := git_model.HashCommitStatusContext(ctxName + "\x00" + run.WorkflowID)
|
||||
// Pre-fix rows were hashed from Context alone. If a pre-existing row with
|
||||
// the legacy hash is still the "latest" for this SHA, reuse that hash so
|
||||
// the new row supersedes it; otherwise the old pending status would stay
|
||||
// stuck forever (it lives in its own dedupe group). Only relevant for
|
||||
// in-flight workflows at upgrade time.
|
||||
legacyHash := git_model.HashCommitStatusContext(ctxName)
|
||||
state := toCommitStatus(job.Status)
|
||||
targetURL := fmt.Sprintf("%s/jobs/%d", run.Link(), job.ID)
|
||||
description := toCommitStatusDescription(job)
|
||||
@@ -152,7 +166,13 @@ func createCommitStatus(ctx context.Context, repo *repo_model.Repository, event,
|
||||
return fmt.Errorf("GetLatestCommitStatus: %w", err)
|
||||
}
|
||||
for _, v := range statuses {
|
||||
if v.Context == ctxName {
|
||||
if v.ContextHash == legacyHash && v.Context == ctxName {
|
||||
ctxHash = legacyHash
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, v := range statuses {
|
||||
if v.ContextHash == ctxHash {
|
||||
if v.State == state && v.TargetURL == targetURL && v.Description == description {
|
||||
return nil
|
||||
}
|
||||
@@ -166,6 +186,7 @@ func createCommitStatus(ctx context.Context, repo *repo_model.Repository, event,
|
||||
TargetURL: targetURL,
|
||||
Description: description,
|
||||
Context: ctxName,
|
||||
ContextHash: ctxHash,
|
||||
State: state,
|
||||
CreatorID: creator.ID,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user