diff --git a/.github/actions/slack-alert/action.yml b/.github/actions/slack-alert/action.yml new file mode 100644 index 00000000..9f4c1d6b --- /dev/null +++ b/.github/actions/slack-alert/action.yml @@ -0,0 +1,51 @@ +--- +# See the "workflow builder" approach in https://github.com/slackapi/slack-github-action/. +name: Slack alert +description: Send an alert to a Slack channel using workflow builder +inputs: + inputs: + description: Textual representation of workflow inputs + required: false + default: "N/A" + type: string + message: + description: Slack alert message + required: false + default: "${{ github.workflow }}/${{ github.job }} GitHub Actions workflow failed :sob:" + type: string + results-url: + description: URL for workflow results + required: false + default: "N/A" + type: string + # Typically this would be a secret. + slack-webhook-url: + description: Slack workflow builder webhook URL + required: true + type: string + # Typically this would be a secret or variable. + slack-channel-id: + description: ID of Slack channel to send alert to + required: true + type: string +runs: + using: composite + steps: + - name: Send message to Slack via Workflow Builder + uses: slackapi/slack-github-action@v1.26.0 + with: + payload: | + { + "channel-id": "${{ env.SLACK_CHANNEL_ID }}", + "inputs": "${{ env.INPUTS }}", + "message": "${{ env.MESSAGE }}", + "results-url": "${{ env.RESULTS_URL }}", + "workflow-url": "${{ env.WORKFLOW_URL }}" + } + env: + SLACK_WEBHOOK_URL: ${{ inputs.slack-webhook-url }} + SLACK_CHANNEL_ID: ${{ inputs.slack-channel-id }} + INPUTS: ${{ inputs.inputs }} + MESSAGE: ${{ inputs.message }} + RESULTS_URL: ${{ inputs.results-url }} + WORKFLOW_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" diff --git a/.github/workflows/container-promote.yml b/.github/workflows/container-promote.yml index 1a88fb01..363cfe99 100644 --- a/.github/workflows/container-promote.yml +++ b/.github/workflows/container-promote.yml @@ -56,3 +56,14 @@ jobs: env: FILTER: ${{ github.event.inputs.filter }} CHECK_MODE: ${{ inputs.check_mode }} + + - name: Send message to Slack via Workflow Builder + uses: ./.github/actions/slack-alert + with: + inputs: >- + filter: ${{ inputs.filter }}\n + kayobe_config_branch: ${{ inputs.kayobe_config_branch }}\n + check_mode: ${{ inputs.check_mode }}\n + slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} + slack-channel-id: ${{ vars.SLACK_CHANNEL_ID }} + if: failure() diff --git a/.github/workflows/container-publish.yml b/.github/workflows/container-publish.yml index 14131aa3..d30e1458 100644 --- a/.github/workflows/container-publish.yml +++ b/.github/workflows/container-publish.yml @@ -46,3 +46,13 @@ jobs: env: FILTER: ${{ github.event.inputs.filter }} DISTROS: ${{ github.event.inputs.distros }} + + - name: Send message to Slack via Workflow Builder + uses: ./.github/actions/slack-alert + with: + inputs: >- + filter: ${{ inputs.filter }}\n + distros: ${{ inputs.distros }}\n + slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} + slack-channel-id: ${{ vars.SLACK_CHANNEL_ID }} + if: failure() && github.event_name == 'push' diff --git a/.github/workflows/container-sync.yml b/.github/workflows/container-sync.yml index 4c198ffd..cc1ac39d 100644 --- a/.github/workflows/container-sync.yml +++ b/.github/workflows/container-sync.yml @@ -87,3 +87,16 @@ jobs: DISTROS: ${{ github.event.inputs.distros }} SYNC_OLD_IMAGES: ${{ github.event.inputs.sync-old-images }} SYNC_NEW_IMAGES: ${{ github.event.inputs.sync-new-images }} + + - name: Send message to Slack via Workflow Builder + uses: ./.github/actions/slack-alert + with: + inputs: >- + filter: ${{ inputs.filter }}\n + distros: ${{ inputs.distros }}\n + sync-old-images: ${{ inputs.sync-old-images }}\n + sync-new-images: ${{ inputs.sync-new-images }}\n + sync-test-pulp: ${{ inputs.sync-test-pulp }}\n + slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} + slack-channel-id: ${{ vars.SLACK_CHANNEL_ID }} + if: failure() diff --git a/.github/workflows/docs-publish.yml b/.github/workflows/docs-publish.yml index 333abf1d..da8b63cc 100644 --- a/.github/workflows/docs-publish.yml +++ b/.github/workflows/docs-publish.yml @@ -15,3 +15,10 @@ jobs: python-version: 3.x - run: pip install -r docs-requirements.txt - run: mkdocs gh-deploy --force + + - name: Send message to Slack via Workflow Builder + uses: ./.github/actions/slack-alert + with: + slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} + slack-channel-id: ${{ vars.SLACK_CHANNEL_ID }} + if: failure() diff --git a/.github/workflows/package-promote.yml b/.github/workflows/package-promote.yml index b22d58e5..c63d8c8a 100644 --- a/.github/workflows/package-promote.yml +++ b/.github/workflows/package-promote.yml @@ -58,3 +58,14 @@ jobs: env: FILTER: ${{ github.event.inputs.filter }} CHECK_MODE: ${{ inputs.check_mode }} + + - name: Send message to Slack via Workflow Builder + uses: ./.github/actions/slack-alert + with: + inputs: >- + filter: ${{ inputs.filter }}\n + kayobe_config_branch: ${{ inputs.kayobe_config_branch }}\n + check_mode: ${{ inputs.check_mode }}\n + slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} + slack-channel-id: ${{ vars.SLACK_CHANNEL_ID }} + if: failure() diff --git a/.github/workflows/package-sync.yml b/.github/workflows/package-sync.yml index 4e7f2f9c..483723dd 100644 --- a/.github/workflows/package-sync.yml +++ b/.github/workflows/package-sync.yml @@ -71,6 +71,18 @@ jobs: FILTER: ${{ inputs.filter }} PACKAGE_SYNC_GROUP: ${{ inputs.package_sync_group }} + - name: Send message to Slack via Workflow Builder + uses: ./.github/actions/slack-alert + with: + inputs: >- + filter: ${{ inputs.filter }}\n + sync_ark: ${{ inputs.sync_ark }}\n + sync_test: ${{ inputs.sync_test }}\n + package_sync_group: ${{ inputs.package_sync_group }}\n + slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} + slack-channel-id: ${{ vars.SLACK_CHANNEL_ID }} + if: failure() + package-sync-test: name: Sync package repositories in test runs-on: arc-release-train-runner @@ -105,3 +117,15 @@ jobs: env: FILTER: ${{ inputs.filter }} PACKAGE_SYNC_GROUP: ${{ inputs.package_sync_group }} + + - name: Send message to Slack via Workflow Builder + uses: ./.github/actions/slack-alert + with: + inputs: >- + filter: ${{ inputs.filter }}\n + sync_ark: ${{ inputs.sync_ark }}\n + sync_test: ${{ inputs.sync_test }}\n + package_sync_group: ${{ inputs.package_sync_group }}\n + slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} + slack-channel-id: ${{ vars.SLACK_CHANNEL_ID }} + if: failure() diff --git a/.github/workflows/source-repo-sync.yml b/.github/workflows/source-repo-sync.yml index edea2a85..3e4e3724 100644 --- a/.github/workflows/source-repo-sync.yml +++ b/.github/workflows/source-repo-sync.yml @@ -30,3 +30,10 @@ jobs: env: ANSIBLE_FORCE_COLOR: True GITHUB_TOKEN: ${{secrets.repository_configuration_token}} + + - name: Send message to Slack via Workflow Builder + uses: ./.github/actions/slack-alert + with: + slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} + slack-channel-id: ${{ vars.SLACK_CHANNEL_ID }} + if: failure() && github.event_name == 'push' diff --git a/.github/workflows/terraform-github.yml b/.github/workflows/terraform-github.yml index 144116d3..d309464d 100644 --- a/.github/workflows/terraform-github.yml +++ b/.github/workflows/terraform-github.yml @@ -115,3 +115,10 @@ jobs: - name: Terraform Apply if: github.ref == 'refs/heads/main' && github.event_name == 'push' run: terraform apply -auto-approve -input=false + + - name: Send message to Slack via Workflow Builder + uses: ./.github/actions/slack-alert + with: + slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} + slack-channel-id: ${{ vars.SLACK_CHANNEL_ID }} + if: failure() && github.ref == 'refs/heads/main' && github.event_name == 'push' diff --git a/docs/usage/notifications.md b/docs/usage/notifications.md new file mode 100644 index 00000000..1c22ab39 --- /dev/null +++ b/docs/usage/notifications.md @@ -0,0 +1,16 @@ +# Notifications + +Much of the functionality of StackHPC Release Train is built around GitHub Actions workflows. +Some of these are triggered automatically based on an event such as pushing to a branch in a GitHub repository. +Others are triggered manually, such as using a "workflow dispatch" from GitHub's web UI or API. + +Failure of a manually triggered workflow will result in an email being sent to the user who triggered the workflow. +Failure of an automatically triggered workflow will result in an email being sent to the user who *created* the workflow file. +This is not ideal, and makes that person a bottleneck and single point of failure. +To make failures of automatically triggered workflows more visible, notifications are sent to the `#release-train-alerts` Slack channel. + +These notifications are implemented in the [slack-alert](https://github.com/stackhpc/stackhpc-release-train/tree/main/.github/actions/slack-alert/) GitHub action. +The `slack-alert` action uses the "workflow builder" approach described in [slack-github-action](https://github.com/slackapi/slack-github-action/). +Slack's [workflow builder](https://slack.com/intl/en-gb/help/articles/360035692513-Guide-to-Slack-Workflow-Builder) feature allows for flexible integration of Slack with various other services, based on various events. +The [Release train status](https://slack.com/shortcuts/Ft07L987AQ91/1f20fd53512385abf199c9357071cb02) workflow has a webhook URL event trigger, with a single action that sends a message to the `#release-train-alerts` Slack channel. +The Slack webhook URL is set in the `SLACK_WEBHOOK_URL` GitHub Actions secret, and the `#release-train-alerts` channel ID is set in the `SLACK_CHANNEL_ID` GitHub Actions variable. diff --git a/mkdocs.yml b/mkdocs.yml index e9fd6ca3..528cde4e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -26,6 +26,7 @@ nav: Access control: usage/access.md Source code CI: usage/source-code-ci.md GitHub Organisation Management: usage/github-organisation-management.md + Notifications: usage/notifications.md - Operations: Ark: operations/ark.md Test Pulp: operations/test-pulp.md