From bc038ff9a37021a89688110fce02e368ff0a5692 Mon Sep 17 00:00:00 2001 From: Tore Martin Hagen Date: Fri, 3 Oct 2025 10:25:08 +0200 Subject: [PATCH 1/5] Added reusable actions for slack notification on failure in CI run --- .../send-ci-failure-slack-message/action.yml | 40 +++++++++++++++++++ .github/actions/send-slack-message/action.yml | 40 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 .github/actions/send-ci-failure-slack-message/action.yml create mode 100644 .github/actions/send-slack-message/action.yml diff --git a/.github/actions/send-ci-failure-slack-message/action.yml b/.github/actions/send-ci-failure-slack-message/action.yml new file mode 100644 index 000000000..e65c1be83 --- /dev/null +++ b/.github/actions/send-ci-failure-slack-message/action.yml @@ -0,0 +1,40 @@ +name: "Send CI failure slack message" +description: "Send slack message on failed CI run" +author: "Tore Hagen" + +inputs: + slack_url: + description: "Slack webhook URL" + required: true + +runs: + using: "composite" + steps: + - name: Set short SHA + id: short_sha + shell: bash + run: echo "sha=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT + + - name: Get failed jobs + id: failed_jobs + shell: bash + run: | + jobs=$(gh api repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/jobs \ + --jq '.jobs[] | select(.conclusion=="failure") | "- "' \ + | paste -sd "\n" -) + echo "jobs<> $GITHUB_OUTPUT + echo "$jobs" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Slack Notification on Failure + uses: .github/actions/send-slack-message + with: + slack_url: ${{ inputs.slack_url }} + plain_text_preview: ${{ github.workflow }} faild in ${GITHUB_REPOSITORY} + message: | + failed in ${{ github.workflow }} + + Failed jobs: + ${{ steps.failed_jobs.outputs.jobs }} diff --git a/.github/actions/send-slack-message/action.yml b/.github/actions/send-slack-message/action.yml new file mode 100644 index 000000000..0837bce69 --- /dev/null +++ b/.github/actions/send-slack-message/action.yml @@ -0,0 +1,40 @@ +name: Send Slack Message +description: Send Slack Message to a SLACK URL + +inputs: + plain_text_preview: + description: Plain text preview (on mobile devices for instance) + required: true + message: + description: Slack message to send + required: true + slack_url: + description: Slack URL to send message to + required: true + +runs: + using: "composite" + steps: + - name: Send Slack Message + shell: bash + run: | + MESSAGE=$(cat < Date: Fri, 3 Oct 2025 13:59:37 +0200 Subject: [PATCH 2/5] Use workflow in reusable-actions repo --- .../send-ci-failure-slack-message/action.yml | 40 ------------------- .github/actions/send-slack-message/action.yml | 40 ------------------- .github/workflows/test.yml | 12 +++--- 3 files changed, 5 insertions(+), 87 deletions(-) delete mode 100644 .github/actions/send-ci-failure-slack-message/action.yml delete mode 100644 .github/actions/send-slack-message/action.yml diff --git a/.github/actions/send-ci-failure-slack-message/action.yml b/.github/actions/send-ci-failure-slack-message/action.yml deleted file mode 100644 index e65c1be83..000000000 --- a/.github/actions/send-ci-failure-slack-message/action.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: "Send CI failure slack message" -description: "Send slack message on failed CI run" -author: "Tore Hagen" - -inputs: - slack_url: - description: "Slack webhook URL" - required: true - -runs: - using: "composite" - steps: - - name: Set short SHA - id: short_sha - shell: bash - run: echo "sha=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT - - - name: Get failed jobs - id: failed_jobs - shell: bash - run: | - jobs=$(gh api repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/jobs \ - --jq '.jobs[] | select(.conclusion=="failure") | "- "' \ - | paste -sd "\n" -) - echo "jobs<> $GITHUB_OUTPUT - echo "$jobs" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Slack Notification on Failure - uses: .github/actions/send-slack-message - with: - slack_url: ${{ inputs.slack_url }} - plain_text_preview: ${{ github.workflow }} faild in ${GITHUB_REPOSITORY} - message: | - failed in ${{ github.workflow }} - - Failed jobs: - ${{ steps.failed_jobs.outputs.jobs }} diff --git a/.github/actions/send-slack-message/action.yml b/.github/actions/send-slack-message/action.yml deleted file mode 100644 index 0837bce69..000000000 --- a/.github/actions/send-slack-message/action.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Send Slack Message -description: Send Slack Message to a SLACK URL - -inputs: - plain_text_preview: - description: Plain text preview (on mobile devices for instance) - required: true - message: - description: Slack message to send - required: true - slack_url: - description: Slack URL to send message to - required: true - -runs: - using: "composite" - steps: - - name: Send Slack Message - shell: bash - run: | - MESSAGE=$(cat < Date: Fri, 3 Oct 2025 14:02:15 +0200 Subject: [PATCH 3/5] Use reusable workflow and make integration test fail --- .github/workflows/test.yml | 37 ++++++++++++-------------------- cmd/kosli/assertApproval_test.go | 2 +- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 97c55d7b5..84ec908bb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -176,13 +176,10 @@ jobs: - name: Slack Notification on Failure if: ${{ failure() }} - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_CHANNEL: ${{ secrets.slack_channel }} - SLACK_COLOR: ${{ job.status }} - SLACK_TITLE: Test Failed in CLI repository - SLACK_USERNAME: GithubActions - SLACK_WEBHOOK: ${{ secrets.slack_webhook }} + uses: kosli-dev/reusable-actions/.github/actions/send-ci-failure-slack-message@debug + with: + slack_url: ${{ secrets.slack_webhook }} + github_token: ${{ secrets.GITHUB_TOKEN }} snyk-code-test: if: ${{ inputs.run_snyk }} @@ -220,16 +217,13 @@ jobs: # --trail ${{ inputs.TRAIL_NAME }} # --scan-results snyk-code.json # --org ${{ inputs.KOSLI_ORG }} - + # - name: Slack Notification on Failure # if: ${{ failure() }} - # uses: rtCamp/action-slack-notify@v2 - # env: - # SLACK_CHANNEL: ${{ secrets.slack_channel }} - # SLACK_COLOR: ${{ job.status }} - # SLACK_TITLE: Snyk Code Failed in CLI repository - # SLACK_USERNAME: GithubActions - # SLACK_WEBHOOK: ${{ secrets.slack_webhook }} + # uses: kosli-dev/reusable-actions/.github/actions/send-ci-failure-slack-message@debug + # with: + # slack_url: ${{ secrets.slack_webhook }} + # github_token: ${{ secrets.GITHUB_TOKEN }} snyk-dependency-test: if: ${{ inputs.run_snyk }} @@ -267,13 +261,10 @@ jobs: # --trail ${{ inputs.TRAIL_NAME }} # --scan-results snyk-dependency.json # --org ${{ inputs.KOSLI_ORG }} - + # - name: Slack Notification on Failure # if: ${{ failure() }} - # uses: rtCamp/action-slack-notify@v2 - # env: - # SLACK_CHANNEL: ${{ secrets.slack_channel }} - # SLACK_COLOR: ${{ job.status }} - # SLACK_TITLE: Snyk Test Failed in CLI repository - # SLACK_USERNAME: GithubActions - # SLACK_WEBHOOK: ${{ secrets.slack_webhook }} + # uses: kosli-dev/reusable-actions/.github/actions/send-ci-failure-slack-message@debug + # with: + # slack_url: ${{ secrets.slack_webhook }} + # github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/cmd/kosli/assertApproval_test.go b/cmd/kosli/assertApproval_test.go index a4b1369e6..045daec63 100644 --- a/cmd/kosli/assertApproval_test.go +++ b/cmd/kosli/assertApproval_test.go @@ -29,7 +29,7 @@ func (suite *AssertApprovalCommandTestSuite) SetupTest() { suite.artifactName = "arti" suite.artifactPath = "testdata/folder1/hello.txt" global = &GlobalOpts{ - ApiToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6ImNkNzg4OTg5In0.e8i_lA_QrEhFncb05Xw6E_tkCHU9QfcY4OLTVUCHffY", + ApiToken: "XXeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6ImNkNzg4OTg5In0.e8i_lA_QrEhFncb05Xw6E_tkCHU9QfcY4OLTVUCHffY", Org: "docs-cmd-test-user", Host: "http://localhost:8001", } From d2b7513c8ea8cfff9d7379761d3dce21ab171cb7 Mon Sep 17 00:00:00 2001 From: Tore Martin Hagen Date: Fri, 3 Oct 2025 14:25:43 +0200 Subject: [PATCH 4/5] Separate job for slack notification in each workflow --- .github/workflows/daily-cli-tests.yml | 18 +++++++++++++++++ .github/workflows/main.yml | 20 ++++++++++++++++++ .github/workflows/release.yml | 28 ++++++++++++++++++++++++++ .github/workflows/test.yml | 29 +-------------------------- cmd/kosli/assertApproval_test.go | 2 +- 5 files changed, 68 insertions(+), 29 deletions(-) diff --git a/.github/workflows/daily-cli-tests.yml b/.github/workflows/daily-cli-tests.yml index 3ca488a01..fc2ff7f74 100644 --- a/.github/workflows/daily-cli-tests.yml +++ b/.github/workflows/daily-cli-tests.yml @@ -48,3 +48,21 @@ jobs: kosli_reporting_api_token: ${{ secrets.KOSLI_PUBLIC_API_TOKEN }} kosli_querying_api_token: ${{ secrets.KOSLI_API_TOKEN_PROD }} sonarqube_token: ${{ secrets.KOSLI_SONARQUBE_TOKEN }} + + slack-notification-on-failure: + runs-on: ubuntu-24.04 + permissions: + actions: read + contents: read + needs: + [ + set-trail-name, + test, + ] + if: ${{ always() && contains(join(needs.*.result, ','), 'failure') && github.ref == 'refs/heads/master' }} + steps: + - name: Slack Notification on Failure + uses: kosli-dev/reusable-actions/.github/actions/send-ci-failure-slack-message@main + with: + slack_url: ${{ secrets.MERKELY_SLACK_CI_FAILURES_WEBHOOK }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c5bbe68df..6788a9479 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -88,3 +88,23 @@ jobs: slack_channel: ci-failures kosli_api_token: ${{ secrets.KOSLI_PUBLIC_API_TOKEN }} snyk_token: ${{ secrets.SNYK_TOKEN }} + + slack-notification-on-failure: + runs-on: ubuntu-24.04 + permissions: + actions: read + contents: read + needs: + [ + pre-build, + init-kosli, + test, + docker + ] + if: ${{ always() && contains(join(needs.*.result, ','), 'failure') && github.ref == 'refs/heads/master' }} + steps: + - name: Slack Notification on Failure + uses: kosli-dev/reusable-actions/.github/actions/send-ci-failure-slack-message@main + with: + slack_url: ${{ secrets.MERKELY_SLACK_CI_FAILURES_WEBHOOK }} + github_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bfe84fe6e..529078e35 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -250,3 +250,31 @@ jobs: tag: ${{ needs.pre-build.outputs.tag }} AWS_ACCOUNT_ID: 585008075785 AWS_REGION: eu-central-1 + + slack-notification-on-failure: + runs-on: ubuntu-24.04 + permissions: + actions: read + contents: read + needs: + [ + pre-build, + init-kosli, + never-alone-trail, + test, + docker, + goreleaser, + binary-provenance, + homebrew-pr, + docs-gen, + evidence-reporter-upload-package-and-deploy, + environment-reporter-upload-package-and-deploy, + environment-reporter-upload-layer + ] + if: ${{ always() && contains(join(needs.*.result, ','), 'failure') && github.ref == 'refs/heads/master' }} + steps: + - name: Slack Notification on Failure + uses: kosli-dev/reusable-actions/.github/actions/send-ci-failure-slack-message@main + with: + slack_url: ${{ secrets.MERKELY_SLACK_CI_FAILURES_WEBHOOK }} + github_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 84ec908bb..87ab715de 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -98,14 +98,7 @@ jobs: --flow ${{ inputs.FLOW_NAME }} --trail ${{ inputs.TRAIL_NAME }} --org ${{ inputs.KOSLI_ORG }} - --compliant=${{ steps.lint.outcome == 'success' }} - - - name: Slack Notification on Failure - if: ${{ failure() }} - uses: kosli-dev/reusable-actions/.github/actions/send-ci-failure-slack-message@debug - with: - slack_url: ${{ secrets.slack_webhook }} - github_token: ${{ secrets.GITHUB_TOKEN }} + --compliant=${{ steps.lint.outcome == 'success' }} test: name: Test @@ -174,13 +167,6 @@ jobs: if: ${{ inputs.report_results }} uses: codecov/codecov-action@v4 - - name: Slack Notification on Failure - if: ${{ failure() }} - uses: kosli-dev/reusable-actions/.github/actions/send-ci-failure-slack-message@debug - with: - slack_url: ${{ secrets.slack_webhook }} - github_token: ${{ secrets.GITHUB_TOKEN }} - snyk-code-test: if: ${{ inputs.run_snyk }} name: Snyk Code Test @@ -218,13 +204,6 @@ jobs: # --scan-results snyk-code.json # --org ${{ inputs.KOSLI_ORG }} - # - name: Slack Notification on Failure - # if: ${{ failure() }} - # uses: kosli-dev/reusable-actions/.github/actions/send-ci-failure-slack-message@debug - # with: - # slack_url: ${{ secrets.slack_webhook }} - # github_token: ${{ secrets.GITHUB_TOKEN }} - snyk-dependency-test: if: ${{ inputs.run_snyk }} name: Snyk Dependency Test @@ -262,9 +241,3 @@ jobs: # --scan-results snyk-dependency.json # --org ${{ inputs.KOSLI_ORG }} - # - name: Slack Notification on Failure - # if: ${{ failure() }} - # uses: kosli-dev/reusable-actions/.github/actions/send-ci-failure-slack-message@debug - # with: - # slack_url: ${{ secrets.slack_webhook }} - # github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/cmd/kosli/assertApproval_test.go b/cmd/kosli/assertApproval_test.go index 045daec63..a4b1369e6 100644 --- a/cmd/kosli/assertApproval_test.go +++ b/cmd/kosli/assertApproval_test.go @@ -29,7 +29,7 @@ func (suite *AssertApprovalCommandTestSuite) SetupTest() { suite.artifactName = "arti" suite.artifactPath = "testdata/folder1/hello.txt" global = &GlobalOpts{ - ApiToken: "XXeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6ImNkNzg4OTg5In0.e8i_lA_QrEhFncb05Xw6E_tkCHU9QfcY4OLTVUCHffY", + ApiToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6ImNkNzg4OTg5In0.e8i_lA_QrEhFncb05Xw6E_tkCHU9QfcY4OLTVUCHffY", Org: "docs-cmd-test-user", Host: "http://localhost:8001", } From 6fffcf1b3c2eb52387812cc2f3220f4e41175f76 Mon Sep 17 00:00:00 2001 From: Tore Martin Hagen Date: Fri, 3 Oct 2025 14:26:46 +0200 Subject: [PATCH 5/5] Removed unnecessary permission --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 87ab715de..19e71a19c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -65,7 +65,6 @@ jobs: name: Lint runs-on: ubuntu-latest permissions: - actions: read id-token: write contents: write steps: