@@ -422,6 +422,72 @@ jobs:
422422 projects-path : ${{ runner.temp }}/fly-projects/fly-projects.json
423423 token : ${{ steps.generate-token.outputs.token }}
424424
425+ notify :
426+ needs : [pre-deploy, deploy]
427+ if : >-
428+ always() &&
429+ needs.deploy.result != 'skipped'
430+ runs-on : ubuntu-latest
431+ steps :
432+ - name : Resolve PR number
433+ id : resolve-pr
434+ env :
435+ WR_PRS : ${{ toJSON(github.event.workflow_run.pull_requests) }}
436+ DIRECT_PR : ${{ github.event.number }}
437+ run : |
438+ PR=$(echo "$WR_PRS" | jq -r 'first | .number // empty')
439+ echo "number=${PR:-$DIRECT_PR}" >> "$GITHUB_OUTPUT"
440+
441+ - name : Download projects artifact
442+ uses : actions/download-artifact@v4
443+ with :
444+ name : fly-deployed-projects-${{ github.run_id }}
445+ path : ${{ runner.temp }}/fly-projects
446+ continue-on-error : true
447+
448+ - name : Build Slack payload
449+ env :
450+ ENVIRONMENT : ${{ needs.pre-deploy.outputs.environment }}
451+ DEPLOY_RESULT : ${{ needs.deploy.result }}
452+ PR_NUMBER : ${{ steps.resolve-pr.outputs.number }}
453+ RUN_URL : ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
454+ PROJECTS_FILE : ${{ runner.temp }}/fly-projects/fly-projects.json
455+ run : |
456+ STATUS_EMOJI=$([ "$DEPLOY_RESULT" = "success" ] && echo "✅" || echo "❌")
457+ ENV_LABEL=$([ "$ENVIRONMENT" = "production" ] && echo "Production" || echo "Preview")
458+ PR_SUFFIX=$([ -n "$PR_NUMBER" ] && echo " · PR #${PR_NUMBER}" || echo "")
459+ HEADER="${STATUS_EMOJI} ${ENV_LABEL} Deployment${PR_SUFFIX}"
460+
461+ APPS_TEXT=""
462+ if [ -f "$PROJECTS_FILE" ]; then
463+ APPS_TEXT=$(jq -r '
464+ .[] |
465+ if .action == "deploy" then "✅ *" + .name + "* — <" + .url + "|" + .url + ">"
466+ elif .action == "failed" then "❌ *" + .appOrProject + "* — " + .error
467+ else empty
468+ end
469+ ' "$PROJECTS_FILE")
470+ fi
471+
472+ jq -n \
473+ --arg header "$HEADER" \
474+ --arg apps "$APPS_TEXT" \
475+ --arg run_url "$RUN_URL" \
476+ '{
477+ "blocks": (
478+ [{"type":"header","text":{"type":"plain_text","text":$header,"emoji":true}}]
479+ + (if ($apps | length) > 0 then [{"type":"section","text":{"type":"mrkdwn","text":$apps}}] else [] end)
480+ + [{"type":"context","elements":[{"type":"mrkdwn","text":("<" + $run_url + "|View workflow run>")}]}]
481+ )
482+ }' > "${{ runner.temp }}/slack-payload.json"
483+
484+ - name : Send Slack notification
485+ uses : slackapi/slack-github-action@v2
486+ with :
487+ webhook : ${{ secrets.SLACK_WEBHOOK }}
488+ webhook-type : incoming-webhook
489+ payload-file-path : ${{ runner.temp }}/slack-payload.json
490+
425491 destroy :
426492 needs : pre-deploy
427493 if : >-
@@ -468,7 +534,16 @@ jobs:
468534 token : ${{ steps.generate-token.outputs.token }}
469535
470536 summary :
471- needs : [analyze-conditions, pre-deploy, build, deploy, destroy, pr-comment]
537+ needs :
538+ [
539+ analyze-conditions,
540+ pre-deploy,
541+ build,
542+ deploy,
543+ destroy,
544+ pr-comment,
545+ notify
546+ ]
472547 if : always()
473548 runs-on : ubuntu-latest
474549 steps :
0 commit comments