@@ -6,79 +6,80 @@ package actions
6
6
import (
7
7
"context"
8
8
"fmt"
9
+ "path"
9
10
10
11
actions_model "code.gitea.io/gitea/models/actions"
11
12
"code.gitea.io/gitea/models/db"
12
13
git_model "code.gitea.io/gitea/models/git"
13
14
user_model "code.gitea.io/gitea/models/user"
15
+ "code.gitea.io/gitea/modules/log"
14
16
api "code.gitea.io/gitea/modules/structs"
15
17
webhook_module "code.gitea.io/gitea/modules/webhook"
18
+
19
+ "github.com/nektos/act/pkg/jobparser"
16
20
)
17
21
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 {
19
33
if err := job .LoadAttributes (ctx ); err != nil {
20
34
return fmt .Errorf ("load run: %w" , err )
21
35
}
22
36
23
37
run := job .Run
38
+
24
39
var (
25
- sha string
26
- creatorID int64
40
+ sha string
41
+ event string
27
42
)
28
-
29
43
switch run .Event {
30
44
case webhook_module .HookEventPush :
45
+ event = "push"
31
46
payload , err := run .GetPushEventPayload ()
32
47
if err != nil {
33
48
return fmt .Errorf ("GetPushEventPayload: %w" , err )
34
49
}
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 {
43
51
return fmt .Errorf ("head commit is missing in event payload" )
44
52
}
45
-
46
53
sha = payload .HeadCommit .ID
47
- creatorID = payload .Pusher .ID
48
54
case webhook_module .HookEventPullRequest , webhook_module .HookEventPullRequestSync :
55
+ event = "pull_request"
49
56
payload , err := run .GetPullRequestEventPayload ()
50
57
if err != nil {
51
58
return fmt .Errorf ("GetPullRequestEventPayload: %w" , err )
52
59
}
53
-
54
- switch {
55
- case payload .PullRequest == nil :
60
+ if payload .PullRequest == nil {
56
61
return fmt .Errorf ("pull request is missing in event payload" )
57
- case payload .PullRequest .Head == nil :
62
+ } else if payload .PullRequest .Head == nil {
58
63
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" )
63
64
}
64
-
65
65
sha = payload .PullRequest .Head .Sha
66
- creatorID = payload .PullRequest .Head .Repository .Owner .ID
67
66
default :
68
67
return nil
69
68
}
70
69
71
70
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
77
75
}
76
+ ctxname := fmt .Sprintf ("%s / %s (%s)" , runName , job .Name , event )
77
+ state := toCommitStatus (job .Status )
78
78
if statuses , _ , err := git_model .GetLatestCommitStatus (ctx , repo .ID , sha , db.ListOptions {}); err == nil {
79
79
for _ , v := range statuses {
80
80
if v .Context == ctxname {
81
81
if v .State == state {
82
+ // no need to update
82
83
return nil
83
84
}
84
85
break
@@ -93,16 +94,36 @@ func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
93
94
return fmt .Errorf ("getIndexOfJob: %w" , err )
94
95
}
95
96
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 ()
96
117
if err := git_model .NewCommitStatus (ctx , git_model.NewCommitStatusOptions {
97
118
Repo : repo ,
98
119
SHA : sha ,
99
120
Creator : creator ,
100
121
CommitStatus : & git_model.CommitStatus {
101
122
SHA : sha ,
102
123
TargetURL : fmt .Sprintf ("%s/jobs/%d" , run .Link (), index ),
103
- Description : "" ,
124
+ Description : description ,
104
125
Context : ctxname ,
105
- CreatorID : creatorID ,
126
+ CreatorID : creator . ID ,
106
127
State : state ,
107
128
},
108
129
}); err != nil {
@@ -114,9 +135,9 @@ func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
114
135
115
136
func toCommitStatus (status actions_model.Status ) api.CommitStatusState {
116
137
switch status {
117
- case actions_model .StatusSuccess :
138
+ case actions_model .StatusSuccess , actions_model . StatusSkipped :
118
139
return api .CommitStatusSuccess
119
- case actions_model .StatusFailure , actions_model .StatusCancelled , actions_model . StatusSkipped :
140
+ case actions_model .StatusFailure , actions_model .StatusCancelled :
120
141
return api .CommitStatusFailure
121
142
case actions_model .StatusWaiting , actions_model .StatusBlocked :
122
143
return api .CommitStatusPending
0 commit comments