From f363088e4b3ec19c719e34c46598b98c6cd773f7 Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Wed, 14 Oct 2026 16:49:32 +0200 Subject: [PATCH 1/3] ci: send Slack notifications through the shared notify-slack action The workflows posted to Slack with inline curl steps and the SLACK_NOTIFICATION_WEBHOOK / SLACK_ERROR_WEBHOOK secrets, which are being retired (Apicurio/apicurio-registry#10380). They now use Apicurio/apicurio-github-actions/notify-slack, routed by whether anyone has to act: - Verify: a failed push goes to the general channel; success says nothing. - Publish, release and website: success to the general channel, failure to the important one, mentioning whoever ran the workflow. A release reports its publishes in one message, so the publishes it calls are quiet; run on their own, they report themselves. Signed-off-by: Jakub Senko --- .github/workflows/npm-publish.yaml | 36 +++++++++++----------- .github/workflows/release.yaml | 44 +++++++++++++-------------- .github/workflows/update-website.yaml | 30 ++++++++---------- .github/workflows/verify.yaml | 33 ++++++++++---------- 4 files changed, 69 insertions(+), 74 deletions(-) diff --git a/.github/workflows/npm-publish.yaml b/.github/workflows/npm-publish.yaml index b38cda2..5a55cc8 100644 --- a/.github/workflows/npm-publish.yaml +++ b/.github/workflows/npm-publish.yaml @@ -11,6 +11,10 @@ on: description: 'Release version to publish' required: true type: string + quiet: + description: 'Leave the Slack notification to the caller' + type: boolean + default: false permissions: id-token: write @@ -50,21 +54,17 @@ jobs: - name: Publish to npm run: npm publish --provenance --access public - - - name: Slack Notification (Always) - if: always() - run: | - MESSAGE="NPM publish for version ${{ inputs.release-version }} completed with status: ${{ job.status }}" - REPO="${{ github.repository }}" - LINK="https://github.com/$REPO/actions/runs/${{ github.run_id }}" - PAYLOAD="{\"workflow\": \"${{ github.workflow }}\", \"status\": \"${{ job.status }}\", \"message\": \"$MESSAGE\", \"link\": \"$LINK\", \"repository\": \"$REPO\"}" - curl -X POST -H "Content-Type: application/json" -d "$PAYLOAD" ${{ secrets.SLACK_NOTIFICATION_WEBHOOK }} - - - name: Slack Notification (Error) - if: failure() - run: | - MESSAGE="NPM publish for version ${{ inputs.release-version }} FAILED!" - REPO="${{ github.repository }}" - LINK="https://github.com/$REPO/actions/runs/${{ github.run_id }}" - PAYLOAD="{\"workflow\": \"${{ github.workflow }}\", \"status\": \"${{ job.status }}\", \"message\": \"$MESSAGE\", \"link\": \"$LINK\", \"repository\": \"$REPO\"}" - curl -X POST -H "Content-Type: application/json" -d "$PAYLOAD" ${{ secrets.SLACK_ERROR_WEBHOOK }} + # Slack, when run on its own: success to the general channel, failure to the + # important one. release.yaml reports the publishes it calls itself. + - name: Notify + if: ${{ !cancelled() && !inputs.quiet }} + uses: Apicurio/apicurio-github-actions/notify-slack@bd19cbe33797325a571cd7ffd58f639b62e128a2 # v2.4.0 + with: + level: ${{ job.status == 'success' && 'general' || 'important' }} + text: "${{ job.status == 'success' && format(':package: {0}: {1} published {2}', github.repository, github.workflow, inputs.release-version) || format(':x: {0}: {1} failed for {2}', github.repository, github.workflow, inputs.release-version) }}" + link: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + mention: ${{ job.status != 'success' && github.actor || '' }} + machine-users: apitomy-ci + user-map: ${{ secrets.SLACK_USER_MAP }} + important-webhook: ${{ secrets.SLACK_IMPORTANT_NOTIFICATION_WEBHOOK }} + general-webhook: ${{ secrets.SLACK_GENERAL_NOTIFICATION_WEBHOOK }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 661887e..3b72b82 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -59,6 +59,7 @@ jobs: uses: ./.github/workflows/npm-publish.yaml with: release-version: ${{ needs.release.outputs.release-version }} + quiet: true secrets: inherit @@ -103,25 +104,24 @@ jobs: fi - - name: Slack Notification (Always) - if: always() - run: | - NPM_STATUS="${{ needs.npm-publish.result }}" - if [[ "$NPM_STATUS" != "success" ]]; then - MESSAGE="Release ${{ needs.release.outputs.release-version }} completed with warnings. NPM: $NPM_STATUS. Manual retry may be needed." - else - MESSAGE="Release ${{ needs.release.outputs.release-version }} completed successfully" - fi - REPO="${{ github.repository }}" - LINK="https://github.com/$REPO/actions/runs/${{ github.run_id }}" - PAYLOAD="{\"workflow\": \"${{ github.workflow }}\", \"status\": \"${{ job.status }}\", \"message\": \"$MESSAGE\", \"link\": \"$LINK\", \"repository\": \"$REPO\"}" - curl -X POST -H "Content-Type: application/json" -d "$PAYLOAD" ${{ secrets.SLACK_NOTIFICATION_WEBHOOK }} - - - name: Slack Notification (Publishing Failures) - if: needs.npm-publish.result != 'success' - run: | - MESSAGE="Release ${{ needs.release.outputs.release-version }}: NPM publish failed (${{ needs.npm-publish.result }}). Retry at https://github.com/${{ github.repository }}/actions/workflows/npm-publish.yaml" - REPO="${{ github.repository }}" - LINK="https://github.com/$REPO/actions/runs/${{ github.run_id }}" - PAYLOAD="{\"workflow\": \"${{ github.workflow }}\", \"status\": \"warning\", \"message\": \"$MESSAGE\", \"link\": \"$LINK\", \"repository\": \"$REPO\"}" - curl -X POST -H "Content-Type: application/json" -d "$PAYLOAD" ${{ secrets.SLACK_ERROR_WEBHOOK }} + # Slack: the outcome of the whole release, publishes included. Success to + # the general channel, a failure to the important one, mentioning whoever + # ran it. A failed publish can be re-run on its own from its workflow. + notify: + name: Notify + needs: [release, npm-publish, finalize] + if: ${{ !cancelled() && github.repository_owner == 'Apitomy' }} + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Notify + uses: Apicurio/apicurio-github-actions/notify-slack@bd19cbe33797325a571cd7ffd58f639b62e128a2 # v2.4.0 + with: + level: ${{ (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) && 'important' || 'general' }} + text: "${{ (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) && format(':x: {0}: release {1} failed (release {2}, npm-publish {3}, finalize {4})', github.repository, needs.release.outputs.release-version, needs.release.result, needs.npm-publish.result, needs.finalize.result) || format(':rocket: {0} {1} released', github.repository, needs.release.outputs.release-version) }}" + link: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + mention: ${{ (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) && github.actor || '' }} + machine-users: apitomy-ci + user-map: ${{ secrets.SLACK_USER_MAP }} + important-webhook: ${{ secrets.SLACK_IMPORTANT_NOTIFICATION_WEBHOOK }} + general-webhook: ${{ secrets.SLACK_GENERAL_NOTIFICATION_WEBHOOK }} diff --git a/.github/workflows/update-website.yaml b/.github/workflows/update-website.yaml index ccf5a87..3653f2b 100644 --- a/.github/workflows/update-website.yaml +++ b/.github/workflows/update-website.yaml @@ -56,20 +56,16 @@ jobs: git commit -m "Automated Update For Apitomy OpenAPI Editor Release Version: ${{ env.RELEASE_VERSION }}" git push - - name: Slack Notification (Always) - if: always() - run: | - MESSAGE="'${{ github.workflow }}/${{ github.job }}' job completed with status: ${{ job.status }}" - REPO="${{ github.repository }}" - LINK="https://github.com/$REPO/actions/runs/${{ github.run_id }}" - PAYLOAD="{\"workflow\": \"${{ github.workflow }}\", \"status\": \"${{ job.status }}\", \"message\": \"$MESSAGE\", \"link\": \"$LINK\", \"repository\": \"$REPO\"}" - curl -X POST -H "Content-Type: application/json" -d "$PAYLOAD" ${{ secrets.SLACK_NOTIFICATION_WEBHOOK }} - - - name: Slack Notification (Error) - if: failure() - run: | - MESSAGE="'${{ github.workflow }}/${{ github.job }}' job FAILED!" - REPO="${{ github.repository }}" - LINK="https://github.com/$REPO/actions/runs/${{ github.run_id }}" - PAYLOAD="{\"workflow\": \"${{ github.workflow }}\", \"status\": \"${{ job.status }}\", \"message\": \"$MESSAGE\", \"link\": \"$LINK\", \"repository\": \"$REPO\"}" - curl -X POST -H "Content-Type: application/json" -d "$PAYLOAD" ${{ secrets.SLACK_ERROR_WEBHOOK }} + # Slack: success to the general channel, failure to the important one. + - name: Notify + if: ${{ !cancelled() }} + uses: Apicurio/apicurio-github-actions/notify-slack@bd19cbe33797325a571cd7ffd58f639b62e128a2 # v2.4.0 + with: + level: ${{ job.status == 'success' && 'general' || 'important' }} + text: "${{ job.status == 'success' && format(':globe_with_meridians: {0}: website updated for {1}', github.repository, env.RELEASE_VERSION) || format(':x: {0}: {1} failed', github.repository, github.workflow) }}" + link: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + mention: ${{ job.status != 'success' && github.actor || '' }} + machine-users: apitomy-ci + user-map: ${{ secrets.SLACK_USER_MAP }} + important-webhook: ${{ secrets.SLACK_IMPORTANT_NOTIFICATION_WEBHOOK }} + general-webhook: ${{ secrets.SLACK_GENERAL_NOTIFICATION_WEBHOOK }} diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 8c1340a..d9fc4a2 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -25,20 +25,19 @@ jobs: npm run lint npm run build - - name: Slack Notification (Always) - if: github.event_name == 'push' && always() - run: | - MESSAGE="'${{ github.workflow }}/${{ github.job }}' job completed with status: ${{ job.status }}" - REPO="${{ github.repository }}" - LINK="https://github.com/$REPO/actions/runs/${{ github.run_id }}" - PAYLOAD="{\"workflow\": \"${{ github.workflow }}\", \"status\": \"${{ job.status }}\", \"message\": \"$MESSAGE\", \"link\": \"$LINK\", \"repository\": \"$REPO\"}" - curl -X POST -H "Content-Type: application/json" -d "$PAYLOAD" ${{ secrets.SLACK_NOTIFICATION_WEBHOOK }} - - - name: Slack Notification (Error) - if: github.event_name == 'push' && failure() - run: | - MESSAGE="'${{ github.workflow }}/${{ github.job }}' job FAILED!" - REPO="${{ github.repository }}" - LINK="https://github.com/$REPO/actions/runs/${{ github.run_id }}" - PAYLOAD="{\"workflow\": \"${{ github.workflow }}\", \"status\": \"${{ job.status }}\", \"message\": \"$MESSAGE\", \"link\": \"$LINK\", \"repository\": \"$REPO\"}" - curl -X POST -H "Content-Type: application/json" -d "$PAYLOAD" ${{ secrets.SLACK_ERROR_WEBHOOK }} + # Slack: a failed push goes to the general channel. Success and PR runs + # say nothing. + notify: + name: Notify + needs: [build-verify] + if: failure() && github.event_name == 'push' + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Notify + uses: Apicurio/apicurio-github-actions/notify-slack@bd19cbe33797325a571cd7ffd58f639b62e128a2 # v2.4.0 + with: + level: general + text: ":x: ${{ github.repository }}: ${{ github.workflow }} failed on ${{ github.ref_name }} at ${{ github.sha }}" + link: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + general-webhook: ${{ secrets.SLACK_GENERAL_NOTIFICATION_WEBHOOK }} From 0b220af1da4fa1fb2846abe87130a3d926fccb6c Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Wed, 14 Oct 2026 17:50:51 +0200 Subject: [PATCH 2/3] ci: post the website update to Slack only when it fails The release already posts one success message for the whole release; a second for the website it triggers told nobody anything new. Signed-off-by: Jakub Senko --- .github/workflows/update-website.yaml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/update-website.yaml b/.github/workflows/update-website.yaml index 3653f2b..b80ceaa 100644 --- a/.github/workflows/update-website.yaml +++ b/.github/workflows/update-website.yaml @@ -56,16 +56,17 @@ jobs: git commit -m "Automated Update For Apitomy OpenAPI Editor Release Version: ${{ env.RELEASE_VERSION }}" git push - # Slack: success to the general channel, failure to the important one. + # Slack, failure only: the release's own message covers the success. + # Runs triggered by the release are apitomy-ci's, so nobody is mentioned + # then; a run started by hand mentions whoever started it. - name: Notify - if: ${{ !cancelled() }} + if: failure() uses: Apicurio/apicurio-github-actions/notify-slack@bd19cbe33797325a571cd7ffd58f639b62e128a2 # v2.4.0 with: - level: ${{ job.status == 'success' && 'general' || 'important' }} - text: "${{ job.status == 'success' && format(':globe_with_meridians: {0}: website updated for {1}', github.repository, env.RELEASE_VERSION) || format(':x: {0}: {1} failed', github.repository, github.workflow) }}" + level: important + text: ":x: ${{ github.repository }}: ${{ github.workflow }} failed" link: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - mention: ${{ job.status != 'success' && github.actor || '' }} + mention: ${{ github.actor }} machine-users: apitomy-ci user-map: ${{ secrets.SLACK_USER_MAP }} important-webhook: ${{ secrets.SLACK_IMPORTANT_NOTIFICATION_WEBHOOK }} - general-webhook: ${{ secrets.SLACK_GENERAL_NOTIFICATION_WEBHOOK }} From a0ba9dd81a677222cc15125ca6f00a26a86a346b Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Wed, 14 Oct 2026 18:03:09 +0200 Subject: [PATCH 3/3] ci: keep a cancelled Verify run quiet in Slack failure() stays true when a run that already failed is cancelled, so the notify job could still post. Signed-off-by: Jakub Senko --- .github/workflows/verify.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index d9fc4a2..97c8502 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -25,12 +25,13 @@ jobs: npm run lint npm run build - # Slack: a failed push goes to the general channel. Success and PR runs - # say nothing. + # Slack: a failed push goes to the general channel. Success, PR runs and a + # run cancelled by hand say nothing (failure() stays true when a run that + # already failed is cancelled). notify: name: Notify needs: [build-verify] - if: failure() && github.event_name == 'push' + if: failure() && !cancelled() && github.event_name == 'push' runs-on: ubuntu-latest timeout-minutes: 5 steps: