Module 6: Deployment Pipelines
7. Deploy Notifications
Overview
Your pipeline deploys automatically to staging, waits for approval, and deploys to production with an automatic rollback. It works. But who finds out? If the deploy to production succeeded, does the team know? If it failed and rolled back, did anyone get an alert? If the pipeline is paused waiting for approval, does the reviewer know?
Without notifications, the deployment pipeline operates in silence. The team has to go to the Actions tab to find out what happened. That doesn't scale — nobody checks Actions proactively. Notifications turn your pipeline from a silent process into a communicative one.
In this capsule you implement notifications with the tools available in GitHub Actions: job summaries, deployment status on PRs, error/warning annotations, and echo/log patterns. Integration with Slack, email, and external services is covered in Module 7 — here you build the pipeline's communication foundation.
Notification levels
The notification spectrum
Level 1: GitHub Job Summaries
→ Visible in the workflow run's Actions tab
→ Formatted Markdown with the deploy's details
→ It requires going to Actions to see it
Level 2: Deployment Status on PRs
→ An automatic badge on PRs with the deploy's status
→ Visible without going to Actions
→ Generated by GitHub when you use environments
Level 3: Annotations (warnings/errors)
→ Inline messages in the workflow's logs
→ They appear as banners in the Actions UI
→ Useful for highlighting problems
Level 4: GitHub Notifications
→ GitHub's native notifications (email, mobile)
→ Automatic for deployment reviews
→ Configurable per user
Level 5: External Notifications (Module 7)
→ Slack, Teams, Discord, email
→ It requires a webhook or API integration
→ Covered in Module 7
This capsule covers levels 1-4. You'll implement level 5 in Module 7.
Job Summaries — The deploy report
What a Job Summary is
GitHub Actions lets every job generate a Markdown summary that appears in the workflow run's tab. It gets written to the $GITHUB_STEP_SUMMARY file.
- name: Deploy summary
run: |
echo "### Deployment Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Status:** ✅ Success" >> $GITHUB_STEP_SUMMARY
echo "**Environment:** production" >> $GITHUB_STEP_SUMMARY
echo "**Image:** \`sha-abc1234\`" >> $GITHUB_STEP_SUMMARY
The summary appears at the top of the workflow run in the Actions UI. It's the first thing someone sees when they open the run.
A complete summary for a successful deploy
- name: Deploy success summary
if: success()
run: |
echo "### ✅ Deployment Successful" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| **Environment** | production |" >> $GITHUB_STEP_SUMMARY
echo "| **Image** | \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:sha-${{ github.sha }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| **Commit** | [\`$(echo ${{ github.sha }} | cut -c1-7)\`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}) |" >> $GITHUB_STEP_SUMMARY
echo "| **Author** | @${{ github.actor }} |" >> $GITHUB_STEP_SUMMARY
echo "| **URL** | [your-app.com](https://your-app.com) |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Health check:** \`/health\` → 200 OK" >> $GITHUB_STEP_SUMMARY
A summary for a failed deploy with a rollback
- name: Deploy failure summary
if: failure()
run: |
echo "### ❌ Deployment Failed — Rolled Back" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| **Environment** | production |" >> $GITHUB_STEP_SUMMARY
echo "| **Failed image** | \`sha-${{ github.sha }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| **Rolled back to** | \`${{ steps.current.outputs.tag }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| **Commit** | [\`$(echo ${{ github.sha }} | cut -c1-7)\`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}) |" >> $GITHUB_STEP_SUMMARY
echo "| **Author** | @${{ github.actor }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Action required:** Investigate the failure and fix before next deploy." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Logs:** Check the workflow logs for the health check failure." >> $GITHUB_STEP_SUMMARY
A summary of the complete pipeline (multi-job)
Each job can write its own summary. The result is a combined report:
jobs:
test:
steps:
- name: Test summary
if: always()
run: |
echo "### Tests" >> $GITHUB_STEP_SUMMARY
echo "- Lint: ✅" >> $GITHUB_STEP_SUMMARY
echo "- Unit tests: ✅ (42 passed)" >> $GITHUB_STEP_SUMMARY
echo "- Prompt regression: ✅" >> $GITHUB_STEP_SUMMARY
build:
steps:
- name: Build summary
if: always()
run: |
echo "### Docker Build" >> $GITHUB_STEP_SUMMARY
echo "- Image: \`${{ steps.meta.outputs.tags }}\`" >> $GITHUB_STEP_SUMMARY
echo "- Size: $(docker images --format '{{.Size}}' | head -1)" >> $GITHUB_STEP_SUMMARY
echo "- Cache: hit" >> $GITHUB_STEP_SUMMARY
deploy-staging:
steps:
- name: Staging summary
run: |
echo "### Staging Deploy" >> $GITHUB_STEP_SUMMARY
echo "- URL: [staging.your-app.com](https://staging.your-app.com)" >> $GITHUB_STEP_SUMMARY
echo "- Health: ✅ OK" >> $GITHUB_STEP_SUMMARY
deploy-production:
steps:
- name: Production summary
if: always()
run: |
echo "### Production Deploy" >> $GITHUB_STEP_SUMMARY
if [ "${{ steps.verify.outcome }}" = "success" ]; then
echo "- Status: ✅ Deployed" >> $GITHUB_STEP_SUMMARY
else
echo "- Status: ❌ Failed (rolled back)" >> $GITHUB_STEP_SUMMARY
fi
Deployment Status on PRs
An automatic status with environments
When you use environment: in a job, GitHub automatically shows the deployment status on the related PRs:
deploy-staging:
environment:
name: staging
url: https://staging.your-app.com
The result on the PR:
PR #42: "Add embeddings endpoint"
Checks:
✅ test — All tests passed
✅ build — Docker image built
🚀 staging — Deployed (View deployment →)
⏸️ production — Waiting for review
The "View deployment" link leads to the URL you configured in the environment. The reviewer can click and see staging directly.
The deployment status badge
GitHub also shows a badge in the repo's Deployments tab:
GitHub → your-repo → Deployments
staging:
✅ Active — sha-abc1234 — 5 minutes ago
production:
⏸️ Pending — Waiting for review
This history updates automatically. You don't need to configure anything — GitHub does it when the job with environment: runs.
Annotations — Warnings and Errors
What annotations are
GitHub Actions supports special commands that generate annotations visible in the UI:
# An error annotation — a red banner
echo "::error::Deploy failed: health check timeout"
# A warning annotation — a yellow banner
echo "::warning::Deploy succeeded but latency is high (3.2s)"
# A notice annotation — a blue banner
echo "::notice::Deploy to production completed successfully"
Annotations in a deploy context
- name: Health check with annotations
run: |
RESPONSE_TIME=$(curl -sf -w "%{time_total}" -o /dev/null https://your-app.com/health)
HTTP_CODE=$(curl -sf -o /dev/null -w "%{http_code}" https://your-app.com/health)
if [ "$HTTP_CODE" != "200" ]; then
echo "::error title=Deploy Health Check::Health check failed with HTTP $HTTP_CODE"
exit 1
fi
THRESHOLD="3.0"
SLOW=$(echo "$RESPONSE_TIME > $THRESHOLD" | bc -l 2>/dev/null || echo "0")
if [ "$SLOW" = "1" ]; then
echo "::warning title=Slow Response::Health check passed but response time is ${RESPONSE_TIME}s (threshold: ${THRESHOLD}s)"
else
echo "::notice title=Deploy OK::Health check passed in ${RESPONSE_TIME}s"
fi
Annotations with file context
You can associate annotations with specific files:
echo "::error file=docker-compose.yml,line=5::Image tag not found in registry"
echo "::warning file=.github/workflows/deploy.yml,line=42::Consider adding timeout-minutes"
These annotations appear as inline comments on the PR's files, just like code review comments.
The notification pattern for a deploy
The complete pattern
- name: Deploy notification
if: always()
env:
DEPLOY_STATUS: ${{ steps.verify.outcome }}
ENVIRONMENT: production
IMAGE_TAG: sha-${{ github.sha }}
ROLLBACK_TAG: ${{ steps.current.outputs.tag }}
run: |
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
COMMIT_URL="${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}"
RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
if [ "$DEPLOY_STATUS" = "success" ]; then
echo "::notice title=Deploy Success::$ENVIRONMENT deployed sha-$SHORT_SHA successfully"
echo "### ✅ Deploy to $ENVIRONMENT" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Image:** \`$IMAGE_TAG\`" >> $GITHUB_STEP_SUMMARY
echo "**Commit:** [$SHORT_SHA]($COMMIT_URL)" >> $GITHUB_STEP_SUMMARY
echo "**Author:** @${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "**Time:** $(date -u +'%Y-%m-%d %H:%M UTC')" >> $GITHUB_STEP_SUMMARY
else
echo "::error title=Deploy Failed::$ENVIRONMENT deploy failed for sha-$SHORT_SHA — rolled back to $ROLLBACK_TAG"
echo "### ❌ Deploy to $ENVIRONMENT FAILED" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Failed image:** \`$IMAGE_TAG\`" >> $GITHUB_STEP_SUMMARY
echo "**Rolled back to:** \`$ROLLBACK_TAG\`" >> $GITHUB_STEP_SUMMARY
echo "**Commit:** [$SHORT_SHA]($COMMIT_URL)" >> $GITHUB_STEP_SUMMARY
echo "**Logs:** [View workflow run]($RUN_URL)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Next steps:**" >> $GITHUB_STEP_SUMMARY
echo "1. Check workflow logs for the failure reason" >> $GITHUB_STEP_SUMMARY
echo "2. Fix the issue in a new commit" >> $GITHUB_STEP_SUMMARY
echo "3. Push to main to trigger a new deploy" >> $GITHUB_STEP_SUMMARY
fi
GitHub's native Notifications
Configuring Actions notifications
GitHub sends automatic notifications for:
- 📋 Deployment reviews — When a workflow needs approval
- 📋 Workflow failures — When a workflow fails (configurable)
- 📋 Workflow successes — When a workflow that previously failed now passes
To configure:
GitHub → Settings → Notifications → Actions
☑ Send notifications for failed workflows only
☐ Send notifications for all workflow runs (very noisy)
Or more granular:
Repo → Settings → Notifications → Custom routing
→ Watch: Workflow runs
Deployment review notifications
When a workflow reaches an approval gate, GitHub automatically sends:
📧 Email: "Deployment review requested: Deploy Pipeline #42"
🔔 GitHub: "Review requested for production deployment"
📱 Mobile: A push notification
These are automatic — you don't need to configure anything in the workflow.
You only need the environment to have required reviewers.
A preview of Module 7's notifications
What comes next
This capsule covers GitHub's native notifications. Module 7 adds external notifications:
Module 7 will add:
- Slack notifications (a webhook)
- Deployment status in a team channel
- Alert on failure with @channel
- Custom messages with the deploy's details
For now, the native tools are enough: summaries for detailed reports, annotations for visual alerts, deployment status for PRs, and native notifications for email/mobile.
Preparing for Module 7: output as JSON
If you want to prepare your pipeline to integrate external notifications easily later:
- name: Generate deploy event
id: event
if: always()
run: |
EVENT=$(cat <<'PAYLOAD'
{
"environment": "production",
"status": "${{ steps.verify.outcome }}",
"image_tag": "sha-${{ github.sha }}",
"commit_sha": "${{ github.sha }}",
"commit_url": "${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}",
"author": "${{ github.actor }}",
"run_url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"timestamp": "$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
}
PAYLOAD
)
echo "payload=$EVENT" >> $GITHUB_OUTPUT
This JSON can be sent to any webhook in Module 7 without changing the deploy's logic.
Comparisons
Without notifications vs with notifications
| Aspect | Without notifications | With notifications |
|---|---|---|
| Visibility | "Did someone deploy?" | "Deploy v1.2.3 to production ✅" |
| Time to awareness | Minutes to hours | Immediate |
| Debugging | Go to Actions, look for the run | A summary with all the info |
| The team | Only the person who deployed knows | The whole team is informed |
Job Summary vs annotations vs logs
| Aspect | Job Summary | Annotations | Logs (echo) |
|---|---|---|---|
| Visibility | The top of the workflow run | Banners in the UI | Inside the step's log |
| Format | Full Markdown | Simple text | Plain text |
| Persistence | Permanent in the run | Permanent in the run | Permanent in the run |
| Ideal use | A detailed report | Specific alerts | Debug info |
GitHub notifications vs Slack (Module 7)
| Aspect | GitHub native | Slack/external |
|---|---|---|
| Setup | Zero (included) | It requires a webhook/bot |
| Channel | Email + mobile + web | A specific team channel |
| Customization | Limited | Total (custom messages) |
| For this guide | Enough | Module 7 |
Troubleshooting
1. The Job Summary doesn't appear in the UI
Symptom: The step runs but there's no summary in the workflow run's tab.
Cause: A syntax error in the Markdown, or the step failed before writing to the summary.
Solution:
- name: Summary
if: always() # Important: run it always, even if previous steps failed
run: |
echo "### Deploy Report" >> $GITHUB_STEP_SUMMARY
echo "Status: done" >> $GITHUB_STEP_SUMMARY
Verify that you're using >> (append) and not > (overwrite). If you use >, every step overwrites the previous summary.
2. Annotations don't show as banners
Symptom: echo "::error::message" appears in the logs but not as a banner.
Cause: The command's format is wrong, or there are special characters.
Solution:
echo "::error::Simple message without special characters"
echo "::error title=Deploy Failed::Health check returned HTTP 500"
echo "::error file=docker-compose.yml,line=5,col=1::Invalid image reference"
Don't use double quotes inside the message. If you need variables:
echo "::error title=Deploy Failed::Health check failed for $IMAGE_TAG"
3. The deployment status doesn't appear on the PR
Symptom: The job runs but the PR doesn't show the deployment status.
Cause: The job doesn't declare environment:, or the PR isn't associated with the commit that triggered the deploy.
Solution: Verify that:
deploy:
environment:
name: staging # Necessary for deployment tracking
url: https://staging.your-app.com # Optional, but it generates the "View deployment" link
The deployment status only appears on PRs if the commit that triggered the deploy is on the PR's branch.
4. The review notifications don't arrive
Symptom: The workflow is waiting for review but the reviewer doesn't get a notification.
Cause: GitHub's notifications are disabled for the reviewer.
Solution:
The reviewer must go to:
GitHub → Settings → Notifications → Actions
☑ Send notifications for workflow runs requiring my review
And also:
GitHub → Settings → Notifications → Default notification email
Verify that the email is correct
Exercises
Exercise 1: Create a multi-stage Job Summary
Create a step that generates a Job Summary with a table format showing the result of each pipeline stage: test, build, staging, production. Use variables from the previous steps.
See solution
- name: Pipeline summary
if: always()
run: |
echo "### Pipeline Report — $(date -u +'%Y-%m-%d %H:%M UTC')" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Stage | Status | Details |" >> $GITHUB_STEP_SUMMARY
echo "|-------|--------|---------|" >> $GITHUB_STEP_SUMMARY
echo "| Tests | ${{ needs.test.result == 'success' && '✅' || '❌' }} | Lint + pytest |" >> $GITHUB_STEP_SUMMARY
echo "| Build | ${{ needs.build.result == 'success' && '✅' || '❌' }} | Docker image |" >> $GITHUB_STEP_SUMMARY
echo "| Staging | ${{ needs.deploy-staging.result == 'success' && '✅' || '❌' }} | [staging.your-app.com](https://staging.your-app.com) |" >> $GITHUB_STEP_SUMMARY
echo "| Production | ${{ steps.verify.outcome == 'success' && '✅' || '❌' }} | [your-app.com](https://your-app.com) |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Commit:** [\`$(echo ${{ github.sha }} | cut -c1-7)\`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})" >> $GITHUB_STEP_SUMMARY
echo "**Author:** @${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "**Run:** [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_STEP_SUMMARY
Note: To access needs.*.result from a job, you need to declare those jobs in needs::
deploy-production:
needs: [test, build, deploy-staging]
Exercise 2: Conditional annotations by latency
Create a step that measures the health check's response time and generates: ::notice if < 1s, ::warning if 1-3s, ::error if > 3s.
See solution
- name: Health check with latency annotation
run: |
RESPONSE_TIME=$(curl -sf -w "%{time_total}" -o /dev/null https://your-app.com/health 2>/dev/null || echo "999")
if [ "$RESPONSE_TIME" = "999" ]; then
echo "::error title=Health Check Failed::Could not connect to https://your-app.com/health"
exit 1
fi
SECONDS_INT=$(echo "$RESPONSE_TIME" | cut -d. -f1)
MS=$(echo "$RESPONSE_TIME * 1000" | bc | cut -d. -f1)
if [ "$SECONDS_INT" -lt 1 ]; then
echo "::notice title=Health OK::Response time: ${MS}ms (excellent)"
elif [ "$SECONDS_INT" -lt 3 ]; then
echo "::warning title=Slow Response::Response time: ${MS}ms (consider optimizing)"
else
echo "::error title=Very Slow Response::Response time: ${MS}ms (exceeds 3s threshold)"
fi
echo "Health check: HTTP 200, ${MS}ms" >> $GITHUB_STEP_SUMMARY
Key points:
curl -w "%{time_total}"measures the request's total time-o /dev/nulldiscards the body, we only want the timebcdoes decimal arithmetic in bash- The annotations appear as banners in the Actions UI
Exercise 3: Prepare the JSON payload for external notifications
Create a step that generates a JSON with all the deploy's information (environment, status, image, commit, author, timestamp) and saves it as an output for future use (Module 7).
See solution
- name: Generate notification payload
id: notification
if: always()
run: |
STATUS="${{ steps.verify.outcome }}"
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
PAYLOAD=$(python3 -c "
import json, datetime
data = {
'pipeline': 'deploy',
'environment': 'production',
'status': '${STATUS}',
'image_tag': 'sha-${{ github.sha }}',
'commit': {
'sha': '${{ github.sha }}',
'short': '${SHORT_SHA}',
'url': '${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}',
'message': '''${{ github.event.head_commit.message }}'''[:100]
},
'author': '${{ github.actor }}',
'run': {
'id': '${{ github.run_id }}',
'number': ${{ github.run_number }},
'url': '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
},
'timestamp': datetime.datetime.utcnow().isoformat() + 'Z'
}
if '${STATUS}' == 'failure':
data['rollback_to'] = '${{ steps.current.outputs.tag }}'
print(json.dumps(data))
")
echo "payload<<EOF" >> $GITHUB_OUTPUT
echo "$PAYLOAD" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "Notification payload generated:"
echo "$PAYLOAD" | python3 -m json.tool
This payload can be used in Module 7:
- name: Send Slack notification
if: always()
run: |
curl -X POST "${{ secrets.SLACK_WEBHOOK }}" \
-H "Content-Type: application/json" \
-d '${{ steps.notification.outputs.payload }}'
Exercise 4: A summary with the reviewer's checklist
Create a Job Summary for the staging job that includes an interactive checklist for the reviewer, with the verifications they must do before approving the deploy to production.
See solution
- name: Staging review checklist
run: |
echo "### 🔍 Staging Deploy Complete — Review Required" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| | Detail |" >> $GITHUB_STEP_SUMMARY
echo "|---|--------|" >> $GITHUB_STEP_SUMMARY
echo "| **Image** | \`sha-$(echo ${{ github.sha }} | cut -c1-7)\` |" >> $GITHUB_STEP_SUMMARY
echo "| **Staging URL** | [staging.your-app.com](https://staging.your-app.com) |" >> $GITHUB_STEP_SUMMARY
echo "| **Commit** | [\`$(echo ${{ github.sha }} | cut -c1-7)\`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}) — ${{ github.event.head_commit.message }} |" >> $GITHUB_STEP_SUMMARY
echo "| **Smoke tests** | ✅ Passed |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Reviewer Checklist" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Before approving production deploy, verify:" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- [ ] Open [staging.your-app.com](https://staging.your-app.com) and verify it loads" >> $GITHUB_STEP_SUMMARY
echo "- [ ] Test \`/health\` endpoint returns 200" >> $GITHUB_STEP_SUMMARY
echo "- [ ] Test \`/chat\` endpoint with a sample message" >> $GITHUB_STEP_SUMMARY
echo "- [ ] Verify response quality is acceptable" >> $GITHUB_STEP_SUMMARY
echo "- [ ] Check response latency < 5 seconds" >> $GITHUB_STEP_SUMMARY
echo "- [ ] Review commit changes in the PR" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Approve the deployment when all checks pass.**" >> $GITHUB_STEP_SUMMARY
The checkboxes aren't interactive in GitHub Summaries (it's static Markdown), but they serve as a visual reference for the reviewer.
Summary
- ✅ Job Summaries (
$GITHUB_STEP_SUMMARY) generate Markdown reports visible in the Actions UI - ✅ Deployment Status appears automatically on PRs when you use
environment:in the job - ✅ Annotations (
::error::,::warning::,::notice::) generate visual banners for alerts - ✅ GitHub Notifications send email/mobile automatically for deployment reviews
- ✅ The notification pattern includes: status, image tag, commit, author, timestamp, URL
- ✅ Always use
if: always()on notification steps so they run even if the deploy fails - ✅ Prepare a JSON payload to make the integration with Slack/external services in Module 7 easier
- ✅ Progressive levels: summaries → annotations → GitHub native → Slack (Module 7)
Additional resources
- GitHub Actions — Job summaries — Official documentation on $GITHUB_STEP_SUMMARY
- GitHub Actions — Workflow commands — Annotations and other commands
- GitHub — Deployment status — The deployment history
- GitHub Notifications settings — Configuring notifications
- GitHub Actions — Contexts — Variables available for notifications (github.sha, github.actor, etc.)
- Markdown syntax for GitHub — Markdown format for summaries