## # A reusable workflow for posting messages to the Making WordPress # Core Slack Instance by submitting data to Slack webhook URLs # received by Slack Workflows. ## name: Slack Notifications on: workflow_call: inputs: calling_status: description: 'The status of the calling workflow' type: string required: true secrets: SLACK_GHA_SUCCESS_WEBHOOK: description: 'The Slack webhook URL for a successful build.' required: true SLACK_GHA_CANCELLED_WEBHOOK: description: 'The Slack webhook URL for a cancelled build.' required: true SLACK_GHA_FIXED_WEBHOOK: description: 'The Slack webhook URL for a fixed build.' required: true SLACK_GHA_FAILURE_WEBHOOK: description: 'The Slack webhook URL for a failed build.' required: true env: CURRENT_BRANCH: ${{ github.ref_name }} jobs: # Gathers the details needed for Slack notifications. # # These details are passed as outputs to the subsequent, dependant jobs that # submit data to Slack webhook URLs configured to post messages. # # Performs the following steps: # - Retrieves the current workflow run. # - Determines the conclusion of the previous workflow run or run attempt. # - Sets the previous conclusion as an output. # - Prepares the commit message. # - Constructs and stores a message payload as an output. prepare: name: Prepare notifications runs-on: ubuntu-latest timeout-minutes: 5 if: ${{ github.repository == 'WordPress/wordpress-develop' && github.event.workflow_run.event != 'pull_request' }} outputs: previous_conclusion: ${{ steps.previous-conclusion.outputs.previous_conclusion }} payload: ${{ steps.create-payload.outputs.payload }} steps: - name: Determine the status of the previous attempt id: previous-attempt-result uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 # v6.4.0 with: retries: 2 retry-exempt-status-codes: 418 script: | const workflow_run = await github.rest.actions.getWorkflowRun({ owner: context.repo.owner, repo: context.repo.repo, run_id: ${{ github.run_id }}, }); // When a workflow has been restarted to fix a failure, check the previous run attempt. if ( workflow_run.data.run_attempt > 1 ) { const previous_run = await github.rest.actions.getWorkflowRunAttempt({ owner: context.repo.owner, repo: context.repo.repo, run_id: ${{ github.run_id }}, attempt_number: workflow_run.data.run_attempt - 1 }); return previous_run.data.conclusion; } // Otherwise, check the previous workflow run. const previous_runs = await github.rest.actions.listWorkflowRuns({ owner: context.repo.owner, repo: context.repo.repo, workflow_id: workflow_run.data.workflow_id, branch: '${{ env.CURRENT_BRANCH }}', exclude_pull_requests: true, }); // This is the first workflow run for this branch or tag. if ( previous_runs.data.workflow_runs.length < 2 ) { return 'none'; } const expected_events = new Array( 'push', 'schedule', 'workflow_dispatch' ); // Find the workflow run for the commit that immediately preceded this one. for ( let i = 0; i < previous_runs.data.workflow_runs.length; i++ ) { if ( previous_runs.data.workflow_runs[ i ].run_number == workflow_run.data.run_number ) { let next_index = i; do { next_index++; // Protects against a false notification when contributors use the trunk branch as the pull request head_ref. if ( expected_events.indexOf( previous_runs.data.workflow_runs[ next_index ].event ) == -1 ) { continue; } return previous_runs.data.workflow_runs[ next_index ].conclusion; } while ( next_index < previous_runs.data.workflow_runs.length ); } } // Can't determine previous workflow conclusion. return 'unknown'; - name: Store previous conclusion as an output id: previous-conclusion run: echo "previous_conclusion=${{ steps.previous-attempt-result.outputs.result }}" >> $GITHUB_OUTPUT - name: Get the commit message id: current-commit-message uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 # v6.4.0 if: ${{ github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' }} with: retries: 2 retry-exempt-status-codes: 418 script: | const commit_details = await github.rest.repos.getCommit({ owner: context.repo.owner, repo: context.repo.repo, ref: '${{ github.sha }}' }); return commit_details.data.commit.message; - name: Prepare commit message. id: commit-message run: | COMMIT_MESSAGE=$(cat <<'EOF' | awk 'NR==1' | sed 's/`/\\`/g' | sed 's/\"/\\\\\\"/g' | sed 's/\$/\\$/g' ${{ ( github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) && fromJson( steps.current-commit-message.outputs.result ) || github.event.head_commit.message }} EOF ) echo "commit_message_escaped=${COMMIT_MESSAGE}" >> $GITHUB_OUTPUT - name: Construct payload and store as an output id: create-payload run: echo "payload={\"workflow_name\":\"${{ github.workflow }}\",\"ref_name\":\"${{ env.CURRENT_BRANCH }}\",\"run_url\":\"https://github.com/WordPress/wordpress-develop/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }}\",\"commit_message\":\"${{ steps.commit-message.outputs.commit_message_escaped }}\"}" >> $GITHUB_OUTPUT # Posts notifications when a workflow fails. failure: name: Failure notifications runs-on: ubuntu-latest timeout-minutes: 5 needs: [ prepare ] if: ${{ inputs.calling_status == 'failure' || failure() }} steps: - name: Post failure notifications to Slack uses: slackapi/slack-github-action@007b2c3c751a190b6f0f040e47ed024deaa72844 # v1.23.0 with: payload: ${{ needs.prepare.outputs.payload }} env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} # Posts notifications the first time a workflow run succeeds after previously failing. fixed: name: Fixed notifications runs-on: ubuntu-latest timeout-minutes: 5 needs: [ prepare ] if: ${{ contains( fromJson( '["failure", "cancelled", "none"]' ), needs.prepare.outputs.previous_conclusion ) && inputs.calling_status == 'success' && success() }} steps: - name: Post failure notifications to Slack uses: slackapi/slack-github-action@007b2c3c751a190b6f0f040e47ed024deaa72844 # v1.23.0 with: payload: ${{ needs.prepare.outputs.payload }} env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} # Posts notifications when a workflow is successful. success: name: Success notifications runs-on: ubuntu-latest timeout-minutes: 5 needs: [ prepare ] if: ${{ inputs.calling_status == 'success' && success() }} steps: - name: Post success notifications to Slack uses: slackapi/slack-github-action@007b2c3c751a190b6f0f040e47ed024deaa72844 # v1.23.0 with: payload: ${{ needs.prepare.outputs.payload }} env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_GHA_SUCCESS_WEBHOOK }} # Posts notifications when a workflow is cancelled. cancelled: name: Cancelled notifications runs-on: ubuntu-latest timeout-minutes: 5 needs: [ prepare ] if: ${{ inputs.calling_status == 'cancelled' || cancelled() }} steps: - name: Post cancelled notifications to Slack uses: slackapi/slack-github-action@007b2c3c751a190b6f0f040e47ed024deaa72844 # v1.23.0 with: payload: ${{ needs.prepare.outputs.payload }} env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }}