Skip to content

Commit 2a001d8

Browse files
authored
Slack alerts (#19716)
### Overview Implements automated Slack notifications for tagged build failures. Currently we manually check GitHub Actions for build status - this adds immediate alerts when any tagged app build fails, with smart channel routing based on tag type. ### Test Plan and Hands on Testing ✅ Created and tested simple-build-alert action ✅ Updated app-test-build-deploy.yaml with notification jobs 🧪 Need: Test with real tags to verify Slack notifications work 🧪 Need: Verify webhook secrets are configured ### Changelog ### Added * New action: .github/actions/simple-build-alert/ - Slack notifications for tagged builds * Auto routing: v/ot3@ → #release-cycle, component tags → #builds * App workflow notifications: Success/failure/cancelled alerts for tagged builds ### Removed * Complex action: Removed over-engineered build-notifications system * Outdated docs: Cleaned up old setup guides ### Review requests * Verify Slack webhook secrets are available in repo settings * Confirm #release-cycle and #builds are correct channels * Should we extend to other workflows (PD, LL, etc.)? ### Risk assessment Risk Level: 🟡 Medium - New notification system ### Risks * Notification spam: Misconfigured webhooks could flood channels * Missing alerts: Action failure could miss critical build failures ### Mitigation * Simple design: Minimal complexity reduces failure points * Fallback routing: Unknown tags default to #release-cycle * Easy rollback: Can disable by removing notification jobs ### Side Effects * No breaking changes: Only adds notifications, doesn't modify build logic * Minimal coupling: Self-contained action, doesn't affect other workflows
1 parent a3dec90 commit 2a001d8

File tree

8 files changed

+714
-0
lines changed

8 files changed

+714
-0
lines changed
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
# Simple Build Alert
2+
3+
A lightweight GitHub Action that sends Slack notifications for tagged build failures with automatic channel routing.
4+
5+
## Features
6+
7+
-**Automatic channel routing** based on tag patterns
8+
-**Clear failure information** with direct workflow links
9+
-**Simple configuration** with just 4 optional inputs
10+
-**Smart defaults** for different release types
11+
12+
## Usage
13+
14+
```yaml
15+
- name: 'Send build alert'
16+
uses: ./.github/actions/simple-build-alert
17+
with:
18+
status: 'failure' # success, failure, or cancelled
19+
workflow_name: 'App test, build, and deploy'
20+
failed_jobs: 'js-unit-test,build-app' # optional
21+
channel_override: '#custom-channel' # optional
22+
```
23+
24+
## Inputs
25+
26+
| Input | Required | Description |
27+
| ------------------ | -------- | -------------------------------------------------------------------- |
28+
| `status` | ✅ | Build status: `success`, `failure`, or `cancelled` |
29+
| `workflow_name` | ✅ | Name of the workflow that triggered the alert |
30+
| `failed_jobs` | ❌ | Comma-separated list of failed jobs (e.g., `js-unit-test,build-app`) |
31+
| `channel_override` | ❌ | Override automatic channel selection (e.g., `#custom-channel`) |
32+
33+
## Automatic Channel Routing
34+
35+
The action automatically routes notifications to different Slack channels based on the tag pattern:
36+
37+
### Main Releases → `#release-cycle`
38+
39+
- `v*` - Version releases (v7.2.0, v8.0.0, etc.)
40+
- `ot3@*` - OT3 releases ([email protected], [email protected], etc.)
41+
42+
### Component Releases → `#builds`
43+
44+
- `protocol-designer*` - Protocol Designer releases
45+
- `labware-library*` - Labware Library releases
46+
- `components*` - Components releases
47+
- `shared-data*` - Shared Data releases
48+
49+
### AI Releases → `#builds`
50+
51+
- `ai-client@*` - AI Client releases
52+
- `ai-server@*` - AI Server releases
53+
54+
### Documentation Releases → `#builds`
55+
56+
- `docs@*` - Documentation releases
57+
- `MKDOCS*` - MkDocs releases
58+
- `staging-docs@*` - Documentation staging
59+
- `staging-MKDOCS*` - MkDocs staging
60+
- `staging-mkdocs*` - MkDocs staging (lowercase)
61+
62+
### Default → `#release-cycle`
63+
64+
- Any other tag pattern defaults to the release cycle channel
65+
66+
## Required Secrets
67+
68+
You need to set up these repository secrets:
69+
70+
### 1. Release Cycle Webhook
71+
72+
- **Secret Name**: `OT_APP_RELEASE_SLACK_NOTIFICATION_WEBHOOK_URL`
73+
- **Channel**: `#release-cycle`
74+
- **Used for**: Main releases (v*, ot3@*)
75+
76+
### 2. Builds Channel Webhook
77+
78+
- **Secret Name**: `OT_APP_ROBOTSTACK_SLACK_NOTIFICATION_WEBHOOK_URL`
79+
- **Channel**: `#builds`
80+
- **Used for**: Component, AI, and documentation releases
81+
82+
## Setup Instructions
83+
84+
### 1. Create Slack Webhooks
85+
86+
#### For #release-cycle channel:
87+
88+
1. Go to your Slack workspace
89+
2. Create a new app or use existing one
90+
3. Go to "Incoming Webhooks"
91+
4. Create webhook for `#release-cycle` channel
92+
5. Copy the webhook URL
93+
94+
#### For #builds channel:
95+
96+
1. Create another webhook for `#builds` channel
97+
2. Copy the webhook URL
98+
99+
### 2. Add Repository Secrets
100+
101+
1. Go to your repository settings: `https://github.com/YourOrg/YourRepo/settings/secrets/actions`
102+
2. Add these secrets:
103+
- `OT_APP_RELEASE_SLACK_NOTIFICATION_WEBHOOK_URL` → Your #release-cycle webhook URL
104+
- `OT_APP_ROBOTSTACK_SLACK_NOTIFICATION_WEBHOOK_URL` → Your #builds webhook URL
105+
106+
### 3. Add to Workflows
107+
108+
Add these notification jobs to any workflow:
109+
110+
```yaml
111+
# Success notification
112+
notify-success:
113+
name: 'Notify Build Success'
114+
runs-on: 'ubuntu-latest'
115+
needs: [job1, job2, job3] # Replace with your job names
116+
if: always() && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && needs.job1.result == 'success' && needs.job2.result == 'success' && needs.job3.result == 'success'
117+
steps:
118+
- name: 'Send success alert'
119+
uses: ./.github/actions/simple-build-alert
120+
with:
121+
status: 'success'
122+
workflow_name: 'Your Workflow Name'
123+
124+
# Failure notification
125+
notify-failure:
126+
name: 'Notify Build Failure'
127+
runs-on: 'ubuntu-latest'
128+
needs: [job1, job2, job3] # Replace with your job names
129+
if: always() && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && (needs.job1.result == 'failure' || needs.job2.result == 'failure' || needs.job3.result == 'failure')
130+
steps:
131+
- name: 'Determine failed jobs'
132+
id: failed-jobs
133+
shell: bash
134+
run: |
135+
failed_jobs=()
136+
if [[ "${{ needs.job1.result }}" == "failure" ]]; then
137+
failed_jobs+=("job1")
138+
fi
139+
if [[ "${{ needs.job2.result }}" == "failure" ]]; then
140+
failed_jobs+=("job2")
141+
fi
142+
if [[ "${{ needs.job3.result }}" == "failure" ]]; then
143+
failed_jobs+=("job3")
144+
fi
145+
146+
IFS=','
147+
echo "failed_jobs=${failed_jobs[*]}" >> $GITHUB_OUTPUT
148+
149+
- name: 'Send failure alert'
150+
uses: ./.github/actions/simple-build-alert
151+
with:
152+
status: 'failure'
153+
workflow_name: 'Your Workflow Name'
154+
failed_jobs: ${{ steps.failed-jobs.outputs.failed_jobs }}
155+
156+
# Cancelled notification
157+
notify-cancelled:
158+
name: 'Notify Build Cancelled'
159+
runs-on: 'ubuntu-latest'
160+
needs: [job1, job2, job3] # Replace with your job names
161+
if: always() && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && (needs.job1.result == 'cancelled' || needs.job2.result == 'cancelled' || needs.job3.result == 'cancelled')
162+
steps:
163+
- name: 'Send cancelled alert'
164+
uses: ./.github/actions/simple-build-alert
165+
with:
166+
status: 'cancelled'
167+
workflow_name: 'Your Workflow Name'
168+
```
169+
170+
## Example Notifications
171+
172+
### Success Notification
173+
174+
```
175+
✅ Build Success
176+
Tag: v7.2.0
177+
Workflow: App test, build, and deploy
178+
Status: success
179+
View Details: [Open Workflow]
180+
```
181+
182+
### Failure Notification
183+
184+
```
185+
❌ Build Failed
186+
Tag: protocol-designer-v1.0.0
187+
Workflow: Protocol Designer test, build, and deploy
188+
Status: failure
189+
Failed Jobs: js-unit-test, build-app
190+
View Details: [Open Workflow]
191+
```
192+
193+
### Cancelled Notification
194+
195+
```
196+
⚠️ Build Cancelled
197+
Tag: v7.2.0
198+
Workflow: App test, build, and deploy
199+
Status: cancelled
200+
View Details: [Open Workflow]
201+
```
202+
203+
## Testing
204+
205+
### Test with Real Tags
206+
207+
```bash
208+
# Test main release (goes to #release-cycle)
209+
git tag v7.2.0-test && git push origin v7.2.0-test
210+
211+
# Test component release (goes to #builds)
212+
git tag protocol-designer-v1.0.0-test && git push origin protocol-designer-v1.0.0-test
213+
214+
# Test AI release (goes to #builds)
215+
git tag [email protected] && git push origin [email protected]
216+
```
217+
218+
### Test with Channel Override
219+
220+
```yaml
221+
- name: 'Send alert to custom channel'
222+
uses: ./.github/actions/simple-build-alert
223+
with:
224+
status: 'failure'
225+
workflow_name: 'Test Workflow'
226+
channel_override: '#alerts'
227+
```
228+
229+
## Customization
230+
231+
### Adding New Tag Patterns
232+
233+
To add support for new tag patterns, edit the channel detection logic in `action.yml`:
234+
235+
```bash
236+
elif [[ "${{ github.ref_name }}" =~ ^your-new-pattern ]]; then
237+
echo "channel=#your-channel" >> $GITHUB_OUTPUT
238+
echo "webhook_secret=YOUR_WEBHOOK_SECRET" >> $GITHUB_OUTPUT
239+
```
240+
241+
### Custom Channel Override
242+
243+
You can override the automatic channel selection for any workflow:
244+
245+
```yaml
246+
- name: 'Send to custom channel'
247+
uses: ./.github/actions/simple-build-alert
248+
with:
249+
status: 'failure'
250+
workflow_name: 'Special Workflow'
251+
channel_override: '#special-alerts'
252+
```
253+
254+
## Benefits
255+
256+
- 🎯 **Focused**: Does exactly what you need, nothing more
257+
- 🔧 **Maintainable**: Easy to understand and modify
258+
- ⚡ **Fast**: No complex logic or multiple steps
259+
- 🛡️ **Reliable**: Fewer moving parts = fewer failure points
260+
- 📈 **Scalable**: Easy to copy to other workflows
261+
- 🎨 **Smart**: Automatic channel routing based on tag patterns
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: 'Simple Build Alert'
2+
description: 'Sends Slack alerts for tagged build failures with clear links'
3+
4+
inputs:
5+
status:
6+
description: 'Build status: success, failure, or cancelled'
7+
required: true
8+
workflow_name:
9+
description: 'Name of the workflow'
10+
required: true
11+
failed_jobs:
12+
description: 'Comma-separated list of failed jobs (optional)'
13+
required: false
14+
channel_override:
15+
description: 'Override default channel (optional)'
16+
required: false
17+
18+
runs:
19+
using: 'composite'
20+
steps:
21+
- name: 'Determine channel and webhook'
22+
id: channel-config
23+
shell: bash
24+
run: |
25+
# Use override if provided, otherwise default to release cycle
26+
if [[ -n "${{ inputs.channel_override }}" ]]; then
27+
echo "channel=${{ inputs.channel_override }}" >> $GITHUB_OUTPUT
28+
echo "webhook_secret=OT_APP_RELEASE_SLACK_NOTIFICATION_WEBHOOK_URL" >> $GITHUB_OUTPUT
29+
else
30+
# All tagged builds go to release cycle by default
31+
echo "channel=#release-cycle" >> $GITHUB_OUTPUT
32+
echo "webhook_secret=OT_APP_RELEASE_SLACK_NOTIFICATION_WEBHOOK_URL" >> $GITHUB_OUTPUT
33+
fi
34+
35+
- name: 'Send Slack Alert'
36+
uses: slackapi/[email protected]
37+
with:
38+
payload: |
39+
{
40+
"channel": "${{ steps.channel-config.outputs.channel }}",
41+
"username": "GitHub Actions",
42+
"icon_emoji": ":robot_face:",
43+
"attachments": [
44+
{
45+
"color": "${{ inputs.status == 'success' && 'good' || inputs.status == 'failure' && 'danger' || 'warning' }}",
46+
"blocks": [
47+
{
48+
"type": "header",
49+
"text": {
50+
"type": "plain_text",
51+
"text": "${{ inputs.status == 'success' && '✅ Build Success' || inputs.status == 'failure' && '❌ Build Failed' || '⚠️ Build Cancelled' }}"
52+
}
53+
},
54+
{
55+
"type": "section",
56+
"fields": [
57+
{
58+
"type": "mrkdwn",
59+
"text": "*Tag:* `${{ github.ref_name }}`"
60+
},
61+
{
62+
"type": "mrkdwn",
63+
"text": "*Workflow:* `${{ inputs.workflow_name }}`"
64+
},
65+
{
66+
"type": "mrkdwn",
67+
"text": "*Status:* `${{ inputs.status }}`"
68+
},
69+
{
70+
"type": "mrkdwn",
71+
"text": "*View Details:* <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Open Workflow>"
72+
}
73+
${{ inputs.failed_jobs && format(',{{ "type": "mrkdwn", "text": "*Failed Jobs:* `{0}`" }}', inputs.failed_jobs) || '' }}
74+
]
75+
}
76+
]
77+
}
78+
]
79+
}
80+
env:
81+
SLACK_WEBHOOK_URL: ${{ secrets[steps.channel-config.outputs.webhook_secret] }}

0 commit comments

Comments
 (0)