Goals
Conscious Deployment
Recognize Production migrations as “non-routine separate tasks”
Force Option
Can force proceed without approval (with reason logged)
Duplicate Prevention
Skip re-request if same migration combination already approved
Failure Handling
Comment out config to restore original behavior during Slack outages
Configuration
sonamu.config.ts
Environment Variables
Commenting out the
slackConfirm block will restore the original behavior (immediate execution without approval).Slack App Setup
1. Create App
- Slack API → Create New App
- Select “From scratch”
- App Name: “Sonamu Migration” (or your preferred name)
- Select Workspace
2. Add Bot Token Scopes
Go to OAuth & Permissions → Scopes → Bot Token Scopes and add:| Scope | Purpose |
|---|---|
chat:write | Send messages, post reasons in threads |
reactions:read | Check emojis |
reactions:write | Add ✅ on force |
3. Install and Configure
- Click Install to Workspace
- Copy Bot User OAuth Token (
xoxb-...) - In your channel, run
/invite @botname - Get Channel ID (right-click channel name → “Copy link” →
C...part in URL)
Approval Flow
Approval Request Message
Usage
Normal Approval
- Click Apply for Production target migration in Sonamu UI
- Approval request message sent to Slack channel
- Manager clicks ✅ emoji
- Migration executes automatically
Force Proceed
When you need to proceed without waiting for approval:- Click “Force Proceed” button while waiting
- Enter reason
- Migration executes (force reason logged to Slack)
Rejection Handling
When manager clicks ❌ emoji, the migration is rejected.Local File Storage
Approval request information is stored locally to prevent re-requests for the same migration combination.Storage Location
Filename Convention
{hash}= MD5 hash of sorted migration names (12 characters)- Example:
.slack-confirm-a1b2c3d4e5f6
File Contents
C01234567:1705412345.000100
Slack API Reference
APIs Used
| API | Purpose |
|---|---|
chat.postMessage | Send approval request message |
reactions.get | Check emojis (Tier 3, 50+/min) |
reactions.add | Add ✅ on force |
chat.postMessage (thread_ts) | Log to thread |
Rate Limit
reactions.getis a Tier 3 API allowing 50+ calls per minute- When limit is exceeded, responses are delayed rather than blocked
- Polling interval is set to 2 seconds, which is safe
Test Scenarios
| Scenario | Behavior |
|---|---|
| Normal flow | Apply → Slack message → Wait → ✅ → Execute |
| Existing approval | Apply → Check existing ts → ✅ exists → Execute immediately |
| Rejection | Apply → Wait → ❌ → Rejection message |
| Force | Apply → Wait → Force → Enter reason → Execute |
| No config | Same as original behavior (immediate execution) |
| Non-target DB | DBs not in targets execute without approval |