-
-
Save imZack/5184491747611364e5a514bcf189617f to your computer and use it in GitHub Desktop.
Notify slack about Github Actions workflow and its jobs status. `notify` job must be the last job in the workflow and it must depend on all other jobs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
notify: | |
if: always() | |
name: Notify | |
needs: | |
- job1 | |
- job2 | |
- job11 | |
- job3 | |
- job4 | |
runs-on: ubuntu-latest | |
steps: | |
- name: Prepare Slack message | |
id: status | |
uses: actions/[email protected] | |
with: | |
script: | | |
//////////////////////////////////// | |
// retrieve workflow run data | |
//////////////////////////////////// | |
console.log("get workflow run") | |
const wf_run = await github.actions.getWorkflowRun({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
run_id: ${{ github.run_id }} | |
}) | |
console.log(wf_run.data) | |
console.log("get jobs for workflow run:", wf_run.data.jobs_url) | |
const jobs_response = await github.request(wf_run.data.jobs_url) | |
//////////////////////////////////// | |
// build slack notification message | |
//////////////////////////////////// | |
// some utility functions | |
var date_diff_func = function(start, end) { | |
var duration = end - start | |
// format the duration | |
var delta = duration / 1000 | |
var days = Math.floor(delta / 86400) | |
delta -= days * 86400 | |
var hours = Math.floor(delta / 3600) % 24 | |
delta -= hours * 3600 | |
var minutes = Math.floor(delta / 60) % 60 | |
delta -= minutes * 60 | |
var seconds = Math.floor(delta % 60) | |
var format_func = function(v, text, check) { | |
if (v <= 0 && check) { | |
return "" | |
} else { | |
return v + text | |
} | |
} | |
return format_func(days, "d", true) + format_func(hours, "h", true) + format_func(minutes, "m", true) + format_func(seconds, "s", false) | |
} | |
var status_icon_func = function(s) { | |
switch (s) { | |
case "w_success": | |
return ":white_check_mark:" | |
case "w_failure": | |
return ":no_entry:" | |
case "w_cancelled": | |
return ":warning:" | |
case "success": | |
return "\u2713" | |
case "failure": | |
return "\u2717" | |
default: | |
return "\u20e0" | |
} | |
} | |
const commit = "${{ github.sha }}".substr(0, 6) | |
var pr = "" | |
for (p of wf_run.data.pull_requests) { | |
pr += ",<"+ p.url + "|#" + p.number + ">" | |
} | |
if (pr != "") { | |
pr = "for " + pr.substr(1) | |
} | |
// build the message | |
var fields = [] | |
var is_wf_success = true | |
var is_wf_failure = false | |
for (j of jobs_response.data.jobs) { | |
console.log(j.name, ":", j.status, j.conclusion, j.started_at, j.completed_at) | |
// ignore the current job running this script | |
if (j.status != "completed") { | |
continue | |
} | |
if (j.conclusion != "success") { | |
is_wf_success = false | |
} | |
if (j.conclusion == "failure") { | |
is_wf_failure = true | |
} | |
fields.push({ | |
type: "mrkdwn", | |
text: status_icon_func(j.conclusion) + " <" + j.html_url + "|" + j.name + ">\n \u21b3 completed in " + date_diff_func(new Date(j.started_at), new Date(j.completed_at)) | |
}) | |
} | |
var workflow_status = "w_cancelled" | |
if (is_wf_success) { | |
workflow_status = "w_success" | |
} else if (is_wf_failure) { | |
workflow_status = "w_failure" | |
} | |
var slack_msg = { | |
blocks: [ | |
{ | |
type: "section", | |
text: { | |
type: "mrkdwn", | |
text: "<https://github.com/${{ github.repository }}|*${{ github.repository }}*>\nfrom *${{ github.ref }}@" + commit + "*" | |
} | |
}, | |
{ | |
type: "section", | |
text: { | |
type: "mrkdwn", | |
text: status_icon_func(workflow_status) + " *${{ github.workflow }}* " + pr + "\nWorkflow run <" + wf_run.data.html_url + "|#${{ github.run_number }}> completed in " + date_diff_func(new Date(wf_run.data.created_at), new Date(wf_run.data.updated_at)) | |
} | |
}, | |
{ | |
type: "divider" | |
}, | |
{ | |
type: "section", | |
fields: fields | |
} | |
] | |
} | |
return slack_msg | |
- name: Send to Slack | |
if: success() | |
run: | | |
curl -X POST ${{ secrets.SLACK_WEBHOOK_URL}} -H "Content-type: application/json" --data '${{ steps.status.outputs.result }}' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment