Skip to content

Use custom status embed to signal workflow status to Discord #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/status-embed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Status Embed

on:
workflow_run:
workflows:
- Test & Lint
types:
- completed

jobs:
status_embed:
if: github.event.workflow_run.conclusion != 'skipped'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is "skipped" what's set if continue on error is triggered? Is this how it tries to prevent itself from running if the artefact upload in the other workflow failed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, if the artifact was not uploaded, it will send an embed for a non-PR workflow. This is just a safeguard as the action currently only supports success/failure/cancelled as workflow conclusions. It's not really important here, but I added it as a safe guard against a future CI redesign suddenly breaking this action unexpectedly.

name: Send a Status Embed to Discord
runs-on: ubuntu-latest

steps:
- name: Get Pull Request Information
id: pr_info
if: github.event.workflow_run.event == 'pull_request'
run: |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes the script safer. e and pipefail I consider essentially for any non-trivial script to get some sane error handling behaviour.

Suggested change
run: |
run: |
set -euo pipefail

Also consider setting x, which will output each command as its executed for debugging purposes.

The || exit ... will no longer be necessary after commands unless you want a custom exit code.

curl -s -H "Authorization: token $GITHUB_TOKEN" ${{ github.event.workflow_run.artifacts_url }} > artifacts.json
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likely a good idea to add these. -S shows errors even when silent. -L follows HTTP 3xx redirects.

Suggested change
curl -s -H "Authorization: token $GITHUB_TOKEN" ${{ github.event.workflow_run.artifacts_url }} > artifacts.json
curl -sSL -H "Authorization: token $GITHUB_TOKEN" ${{ github.event.workflow_run.artifacts_url }} > artifacts.json

DOWNLOAD_URL=$(cat artifacts.json | jq -r '.artifacts[] | select(.name == "pull-request-payload") | .archive_download_url')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cat is unnecessary. jq accepts a filename argument.

Suggested change
DOWNLOAD_URL=$(cat artifacts.json | jq -r '.artifacts[] | select(.name == "pull-request-payload") | .archive_download_url')
DOWNLOAD_URL=$(jq -r '.artifacts[] | select(.name == "pull-request-payload") | .archive_download_url' artifacts.json)

[ -z "$DOWNLOAD_URL" ] && exit 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jq returns the string "null" if a value at a key isn't found, so -z is not an adequate check. You can pass -e to jq to make it set its exit code to 1 when the result is false or null. Since -e is set for the whole script (separate from jq's -e argument), the script will exit when it encounters the exit code of 1. Therefore, this check can be removed unless you still want to check for an empty string (this would mean the API returned an existing key with an empty value).

wget --quiet --header="Authorization: token $GITHUB_TOKEN" -O pull_request_payload.zip $DOWNLOAD_URL || exit 2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
wget --quiet --header="Authorization: token $GITHUB_TOKEN" -O pull_request_payload.zip $DOWNLOAD_URL || exit 2
wget --quiet --header="Authorization: token $GITHUB_TOKEN" -O pull_request_payload.zip "$DOWNLOAD_URL" || exit 2

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit strange to use curl the first time and then switch to wget, but it doesn't really matter.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had some inconsistent results with curl while downloading the zip-file that I couldn't quite explain. I'll see if I can dig them up. wget worked reliable every time.

unzip -p pull_request_payload.zip > pull_request_payload.json
[ -s pull_request_payload.json ] || exit 3
echo "::set-output name=pr_author_login::$(jq -r '.user.login // empty' pull_request_payload.json)"
echo "::set-output name=pr_number::$(jq -r '.number // empty' pull_request_payload.json)"
echo "::set-output name=pr_title::$(jq -r '.title // empty' pull_request_payload.json)"
echo "::set-output name=pr_source::$(jq -r '.head.label // empty' pull_request_payload.json)"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Send an informational status embed to Discord instead of the
# standard embeds that Discord sends. This embed will contain
# more information and we can fine tune when we actually want
# to send an embed.
- name: GitHub Actions Status Embed for Discord
uses: SebastiaanZ/[email protected]
with:
# Our GitHub Actions webhook
webhook_id: '784184528997842985'
webhook_token: ${{ secrets.GHA_WEBHOOK_TOKEN }}

# Workflow information
workflow_name: ${{ github.event.workflow_run.name }}
run_id: ${{ github.event.workflow_run.id }}
run_number: ${{ github.event.workflow_run.run_number }}
status: ${{ github.event.workflow_run.conclusion }}
sha: ${{ github.event.workflow_run.head_sha }}

# Now we can use the information extracted in the previous step:
pr_author_login: ${{ steps.pr_info.outputs.pr_author_login }}
pr_number: ${{ steps.pr_info.outputs.pr_number }}
pr_title: ${{ steps.pr_info.outputs.pr_title }}
pr_source: ${{ steps.pr_info.outputs.pr_source }}
30 changes: 25 additions & 5 deletions .github/workflows/test_and_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
steps:
- uses: actions/checkout@v2
- uses: EgorDm/gha-yarn-node-cache@v1

- name: Install dependencies
run: yarn install

- name: Install dependencies
run: yarn build

Expand All @@ -26,11 +26,31 @@ jobs:
steps:
- uses: actions/checkout@v2
- uses: EgorDm/gha-yarn-node-cache@v1

- name: Install dependencies
run: yarn install

- name: Run tests
run: yarn test



# Prepare the Pull Request Payload artifact. If this fails, we
# we fail silently using the `continue-on-error` option. It's
# nice if this succeeds, but if it fails for any reason, it
# does not mean that our lint-test checks failed.
- name: Prepare Pull Request Payload artifact
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- name: Prepare Pull Request Payload artifact
- name: Prepare Pull Request Payload Artifact

id: prepare-artifact
if: always() && github.event_name == 'pull_request'
continue-on-error: true
run: cat $GITHUB_EVENT_PATH | jq '.pull_request' > pull_request_payload.json
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably an absolute path so it can be quoted. If it relies on globs to expand then it shouldn't be quoted. Setting -e to be safe.

Suggested change
run: cat $GITHUB_EVENT_PATH | jq '.pull_request' > pull_request_payload.json
run: jq -e '.pull_request' "$GITHUB_EVENT_PATH" > pull_request_payload.json


# This only makes sense if the previous step succeeded. To
# get the original outcome of the previous step before the
# `continue-on-error` conclusion is applied, we use the
# `.outcome` value. This step also fails silently.
- name: Upload a Build Artifact
if: always() && steps.prepare-artifact.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@v2
with:
name: pull-request-payload
path: pull_request_payload.json