1
1
import * as core from '@actions/core'
2
2
import * as github from '@actions/github'
3
3
import * as axios from 'axios'
4
+ import * as fs from 'fs'
5
+ import { Template } from 'adaptivecards-templating'
4
6
5
7
async function sleep ( ms : number ) : Promise < unknown > {
6
8
return new Promise ( resolve => {
@@ -24,107 +26,114 @@ enum StepStatus {
24
26
COMPLETED = 'completed'
25
27
}
26
28
27
- async function run ( ) : Promise < unknown > {
28
- try {
29
- const token = core . getInput ( 'github-token' )
30
- if ( ! token ) {
31
- core . setFailed ( "'github-token' input can't be empty" )
32
- return
33
- }
29
+ enum TextBlockColor {
30
+ Good = 'good' ,
31
+ Attention = 'attention' ,
32
+ Warning = 'warning'
33
+ }
34
34
35
- const webhookUri = core . getInput ( 'webhook-uri' )
36
- if ( ! webhookUri ) {
37
- core . setFailed ( "'webhook-uri' input can't be empty" )
38
- return
39
- }
40
- const ctx = github . context
41
- const o = github . getOctokit ( token )
42
-
43
- core . debug ( JSON . stringify ( ctx ) )
44
-
45
- await sleep ( 5000 )
46
-
47
- const jobList = await o . actions . listJobsForWorkflowRun ( {
48
- repo : ctx . repo . repo ,
49
- owner : ctx . repo . owner ,
50
- run_id : ctx . runId
51
- } )
52
-
53
- const jobs = jobList . data . jobs
54
- core . debug ( JSON . stringify ( jobs ) )
55
-
56
- const job = jobs . find ( j => j . name . startsWith ( ctx . job ) )
57
-
58
- const stoppedStep = job ?. steps . find (
59
- s =>
60
- s . conclusion === Conclusions . FAILURE ||
61
- s . conclusion === Conclusions . TIMED_OUT ||
62
- s . conclusion === Conclusions . TIMED_OUT ||
63
- s . conclusion === Conclusions . ACTION_REQUIRED
64
- )
65
- const lastStep = stoppedStep
66
- ? stoppedStep
67
- : job ?. steps . reverse ( ) . find ( s => s . status === StepStatus . COMPLETED )
68
-
69
- const wr = await o . actions . getWorkflowRun ( {
70
- owner : ctx . repo . owner ,
71
- repo : ctx . repo . repo ,
72
- run_id : ctx . runId
73
- } )
74
-
75
- core . debug ( JSON . stringify ( wr . data ) )
76
-
77
- const repository_url = ctx . payload . repository ?. html_url
78
- const commit_author = ctx . actor
79
-
80
- const themeColor =
81
- lastStep ?. conclusion === Conclusions . SUCCESS
82
- ? '90C978'
83
- : lastStep ?. conclusion === Conclusions . CANCELLED
84
- ? 'FFF175'
85
- : 'C23B23'
86
- const conclusion =
87
- lastStep ?. conclusion === Conclusions . SUCCESS
88
- ? 'SUCCEEDED'
89
- : lastStep ?. conclusion === Conclusions . CANCELLED
90
- ? 'CANCELLED'
91
- : 'FAILED'
92
-
93
- const webhookBody = {
94
- '@type' : 'MessageCard' ,
95
- '@context' : 'http://schema.org/extensions' ,
96
- themeColor : `${ themeColor } ` ,
97
- summary : `${ commit_author } commited new changes` ,
98
- sections : [
99
- {
100
- activityTitle : `Workflow '${ ctx . workflow } ' #${ ctx . runNumber } ${ conclusion } ` ,
101
- activitySubtitle : `on [${ ctx . payload . repository ?. full_name } ](${ repository_url } )` ,
102
- facts : [
103
- {
104
- name : 'Commit' ,
105
- value : `[${ wr . data . head_commit . message } ](${ wr . data . repository . html_url } /commit/${ wr . data . head_sha } ) by [${ ctx . payload . sender ?. login } ](${ ctx . payload . sender ?. html_url } )`
106
- } ,
107
- {
108
- name :
109
- ctx . eventName === 'pull_request' ? 'Pull request' : 'Branch' ,
110
- value :
111
- ctx . eventName === 'pull_request'
112
- ? `[${ ctx . payload . pull_request ?. html_url } ](${ ctx . payload . pull_request ?. html_url } )`
113
- : `[${ ctx . payload . repository ?. html_url } /tree/${ ctx . ref } ](${ ctx . payload . repository ?. html_url } /tree/${ ctx . ref } )`
114
- } ,
115
- {
116
- name : 'Workflow run details' ,
117
- value : `[${ wr . data . html_url } ](${ wr . data . html_url } )`
118
- }
119
- ] ,
120
- markdown : true
121
- }
122
- ]
35
+ const send = async ( ) => {
36
+ await sleep ( 5000 )
37
+ const token = core . getInput ( 'github-token' )
38
+ const webhookUri = core . getInput ( 'webhook-uri' )
39
+ const o = github . getOctokit ( token )
40
+ const ctx = github . context
41
+ const jobList = await o . actions . listJobsForWorkflowRun ( {
42
+ repo : ctx . repo . repo ,
43
+ owner : ctx . repo . owner ,
44
+ run_id : ctx . runId
45
+ } )
46
+
47
+ const jobs = jobList . data . jobs
48
+
49
+ const job = jobs . find ( j => j . name . startsWith ( ctx . job ) )
50
+
51
+ const stoppedStep = job ?. steps . find (
52
+ s =>
53
+ s . conclusion === Conclusions . FAILURE ||
54
+ s . conclusion === Conclusions . TIMED_OUT ||
55
+ s . conclusion === Conclusions . TIMED_OUT ||
56
+ s . conclusion === Conclusions . ACTION_REQUIRED
57
+ )
58
+ const lastStep = stoppedStep
59
+ ? stoppedStep
60
+ : job ?. steps . reverse ( ) . find ( s => s . status === StepStatus . COMPLETED )
61
+
62
+ const wr = await o . actions . getWorkflowRun ( {
63
+ owner : ctx . repo . owner ,
64
+ repo : ctx . repo . repo ,
65
+ run_id : ctx . runId
66
+ } )
67
+
68
+ const conclusion =
69
+ lastStep ?. conclusion === Conclusions . SUCCESS
70
+ ? 'SUCCEEDED'
71
+ : lastStep ?. conclusion === Conclusions . CANCELLED
72
+ ? 'CANCELLED'
73
+ : 'FAILED'
74
+
75
+ const conclusion_color =
76
+ lastStep ?. conclusion === Conclusions . SUCCESS
77
+ ? TextBlockColor . Good
78
+ : lastStep ?. conclusion === Conclusions . CANCELLED
79
+ ? TextBlockColor . Warning
80
+ : TextBlockColor . Attention
81
+
82
+ const rawdata = fs . readFileSync ( './ac.json' ) . toString ( )
83
+ const template = new Template ( rawdata )
84
+ const content = template . expand ( {
85
+ $root : {
86
+ repository : {
87
+ name : ctx . payload . repository ?. full_name ,
88
+ html_url : ctx . payload . repository ?. html_url
89
+ } ,
90
+ commit : {
91
+ message : wr . data . head_commit . message ,
92
+ html_url : `${ wr . data . repository . html_url } /commit/${ wr . data . head_sha } `
93
+ } ,
94
+ workflow : {
95
+ name : ctx . workflow ,
96
+ conclusion,
97
+ conclusion_color,
98
+ run_number : ctx . runNumber ,
99
+ run_html_url : wr . data . html_url
100
+ } ,
101
+ event : {
102
+ type : ctx . eventName === 'pull_request' ? 'Pull request' : 'Branch' ,
103
+ html_url :
104
+ ctx . eventName === 'pull_request'
105
+ ? ctx . payload . pull_request ?. html_url
106
+ : `${ ctx . payload . repository ?. html_url } /tree/${ ctx . ref } `
107
+ } ,
108
+ author : {
109
+ username : ctx . payload . sender ?. login ,
110
+ html_url : ctx . payload . sender ?. html_url ,
111
+ avatar_url : ctx . payload . sender ?. avatar_url
112
+ }
123
113
}
124
- const response = await axios . default . post ( webhookUri , webhookBody )
125
- core . debug ( JSON . stringify ( response . data ) )
126
- // TODO: check response status, if not succesful, mark workflow as failed
114
+ } )
115
+
116
+ const webhookBody = {
117
+ type : 'message' ,
118
+ attachments : [
119
+ {
120
+ contentType : 'application/vnd.microsoft.card.adaptive' ,
121
+ content : JSON . parse ( content )
122
+ }
123
+ ]
124
+ }
125
+
126
+ core . info ( JSON . stringify ( webhookBody ) )
127
+
128
+ const response = await axios . default . post ( webhookUri , webhookBody )
129
+ core . info ( JSON . stringify ( response . data ) )
130
+ }
131
+
132
+ async function run ( ) {
133
+ try {
134
+ await send ( )
127
135
} catch ( error ) {
136
+ core . error ( error )
128
137
core . setFailed ( error . message )
129
138
}
130
139
}
0 commit comments