@@ -6,79 +6,80 @@ package actions
66import (
77 "context"
88 "fmt"
9+ "path"
910
1011 actions_model "code.gitea.io/gitea/models/actions"
1112 "code.gitea.io/gitea/models/db"
1213 git_model "code.gitea.io/gitea/models/git"
1314 user_model "code.gitea.io/gitea/models/user"
15+ "code.gitea.io/gitea/modules/log"
1416 api "code.gitea.io/gitea/modules/structs"
1517 webhook_module "code.gitea.io/gitea/modules/webhook"
18+
19+ "github.com/nektos/act/pkg/jobparser"
1620)
1721
18- func CreateCommitStatus (ctx context.Context , job * actions_model.ActionRunJob ) error {
22+ // CreateCommitStatus creates a commit status for the given job.
23+ // It won't return an error failed, but will log it, because it's not critical.
24+ func CreateCommitStatus (ctx context.Context , jobs ... * actions_model.ActionRunJob ) {
25+ for _ , job := range jobs {
26+ if err := createCommitStatus (ctx , job ); err != nil {
27+ log .Error ("Failed to create commit status for job %d: %v" , job .ID , err )
28+ }
29+ }
30+ }
31+
32+ func createCommitStatus (ctx context.Context , job * actions_model.ActionRunJob ) error {
1933 if err := job .LoadAttributes (ctx ); err != nil {
2034 return fmt .Errorf ("load run: %w" , err )
2135 }
2236
2337 run := job .Run
38+
2439 var (
25- sha string
26- creatorID int64
40+ sha string
41+ event string
2742 )
28-
2943 switch run .Event {
3044 case webhook_module .HookEventPush :
45+ event = "push"
3146 payload , err := run .GetPushEventPayload ()
3247 if err != nil {
3348 return fmt .Errorf ("GetPushEventPayload: %w" , err )
3449 }
35-
36- // Since the payload comes from json data, we should check if it's broken, or it will cause panic
37- switch {
38- case payload .Repo == nil :
39- return fmt .Errorf ("repo is missing in event payload" )
40- case payload .Pusher == nil :
41- return fmt .Errorf ("pusher is missing in event payload" )
42- case payload .HeadCommit == nil :
50+ if payload .HeadCommit == nil {
4351 return fmt .Errorf ("head commit is missing in event payload" )
4452 }
45-
4653 sha = payload .HeadCommit .ID
47- creatorID = payload .Pusher .ID
4854 case webhook_module .HookEventPullRequest , webhook_module .HookEventPullRequestSync :
55+ event = "pull_request"
4956 payload , err := run .GetPullRequestEventPayload ()
5057 if err != nil {
5158 return fmt .Errorf ("GetPullRequestEventPayload: %w" , err )
5259 }
53-
54- switch {
55- case payload .PullRequest == nil :
60+ if payload .PullRequest == nil {
5661 return fmt .Errorf ("pull request is missing in event payload" )
57- case payload .PullRequest .Head == nil :
62+ } else if payload .PullRequest .Head == nil {
5863 return fmt .Errorf ("head of pull request is missing in event payload" )
59- case payload .PullRequest .Head .Repository == nil :
60- return fmt .Errorf ("head repository of pull request is missing in event payload" )
61- case payload .PullRequest .Head .Repository .Owner == nil :
62- return fmt .Errorf ("owner of head repository of pull request is missing in evnt payload" )
6364 }
64-
6565 sha = payload .PullRequest .Head .Sha
66- creatorID = payload .PullRequest .Head .Repository .Owner .ID
6766 default :
6867 return nil
6968 }
7069
7170 repo := run .Repo
72- ctxname := job .Name
73- state := toCommitStatus (job .Status )
74- creator , err := user_model .GetUserByID (ctx , creatorID )
75- if err != nil {
76- return fmt .Errorf ("GetUserByID: %w" , err )
71+ // TODO: store workflow name as a field in ActionRun to avoid parsing
72+ runName := path .Base (run .WorkflowID )
73+ if wfs , err := jobparser .Parse (job .WorkflowPayload ); err == nil && len (wfs ) > 0 {
74+ runName = wfs [0 ].Name
7775 }
76+ ctxname := fmt .Sprintf ("%s / %s (%s)" , runName , job .Name , event )
77+ state := toCommitStatus (job .Status )
7878 if statuses , _ , err := git_model .GetLatestCommitStatus (ctx , repo .ID , sha , db.ListOptions {}); err == nil {
7979 for _ , v := range statuses {
8080 if v .Context == ctxname {
8181 if v .State == state {
82+ // no need to update
8283 return nil
8384 }
8485 break
@@ -93,16 +94,36 @@ func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
9394 return fmt .Errorf ("getIndexOfJob: %w" , err )
9495 }
9596
97+ description := ""
98+ switch job .Status {
99+ // TODO: if we want support description in different languages, we need to support i18n placeholders in it
100+ case actions_model .StatusSuccess :
101+ description = fmt .Sprintf ("Successful in %s" , job .Duration ())
102+ case actions_model .StatusFailure :
103+ description = fmt .Sprintf ("Failing after %s" , job .Duration ())
104+ case actions_model .StatusCancelled :
105+ description = "Has been cancelled"
106+ case actions_model .StatusSkipped :
107+ description = "Has been skipped"
108+ case actions_model .StatusRunning :
109+ description = "Has started running"
110+ case actions_model .StatusWaiting :
111+ description = "Waiting to run"
112+ case actions_model .StatusBlocked :
113+ description = "Blocked by required conditions"
114+ }
115+
116+ creator := user_model .NewActionsUser ()
96117 if err := git_model .NewCommitStatus (ctx , git_model.NewCommitStatusOptions {
97118 Repo : repo ,
98119 SHA : sha ,
99120 Creator : creator ,
100121 CommitStatus : & git_model.CommitStatus {
101122 SHA : sha ,
102123 TargetURL : fmt .Sprintf ("%s/jobs/%d" , run .Link (), index ),
103- Description : "" ,
124+ Description : description ,
104125 Context : ctxname ,
105- CreatorID : creatorID ,
126+ CreatorID : creator . ID ,
106127 State : state ,
107128 },
108129 }); err != nil {
@@ -114,9 +135,9 @@ func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
114135
115136func toCommitStatus (status actions_model.Status ) api.CommitStatusState {
116137 switch status {
117- case actions_model .StatusSuccess :
138+ case actions_model .StatusSuccess , actions_model . StatusSkipped :
118139 return api .CommitStatusSuccess
119- case actions_model .StatusFailure , actions_model .StatusCancelled , actions_model . StatusSkipped :
140+ case actions_model .StatusFailure , actions_model .StatusCancelled :
120141 return api .CommitStatusFailure
121142 case actions_model .StatusWaiting , actions_model .StatusBlocked :
122143 return api .CommitStatusPending
0 commit comments