This runbook defines how to run Synapse in production with GitHub Actions as runtime and Google Cloud Scheduler as the external trigger.
- Runtime: GitHub Actions workflow
.github/workflows/daily-digest.yml - Trigger: Cloud Scheduler HTTP job calls GitHub
workflow_dispatchAPI - Code path:
npm ci->npm run build->npm start - Secrets/config: GitHub repository Secrets + Variables
Why this setup:
- Avoids hosting a persistent service/container for scheduling.
- Prevents production halts caused by GitHub scheduled workflows being auto-disabled after long inactivity.
Primary trigger:
- Cloud Scheduler invokes
workflow_dispatchdaily.
Fallback trigger:
- Keep the existing
scheduleblock in the workflow as a best-effort backup. - Keep
workflow_dispatchenabled for manual recovery.
- GCP project with Cloud Scheduler API enabled.
- GitHub fine-grained PAT with minimum required permissions for Actions workflow dispatch on this repo.
- Workflow file name:
daily-digest.yml.
Fast path:
- Use
scripts/setup_cloud_scheduler_dispatch.shto create/update the scheduler job with environment-variable placeholders.
Endpoint:
POST https://api.github.com/repos/<OWNER>/<REPO>/actions/workflows/daily-digest.yml/dispatches
Headers:
Accept: application/vnd.github+jsonAuthorization: Bearer <GITHUB_PAT>X-GitHub-Api-Version: 2022-11-28Content-Type: application/json
Body:
{"ref":"main"}Example command:
gcloud scheduler jobs create http synapse-daily-dispatch \
--location=us-central1 \
--schedule="0 13 * * *" \
--time-zone="Etc/UTC" \
--uri="https://api.github.com/repos/<OWNER>/<REPO>/actions/workflows/daily-digest.yml/dispatches" \
--http-method=POST \
--headers="Accept=application/vnd.github+json,X-GitHub-Api-Version=2022-11-28,Content-Type=application/json,Authorization=Bearer <GITHUB_PAT>" \
--message-body='{"ref":"main"}'Notes:
- Prefer provisioning through IaC so token rotation and changes are auditable.
- PAT should be rotated on a fixed cadence.
Required workflow secrets (minimum):
DISCORD_TOKENDISCORD_CHANNELSSLACK_BOT_TOKENSLACK_CHANNEL_IDGEMINI_API_KEYDISCOURSE_API_KEY(if Discourse enabled)DISCOURSE_API_USERNAME(if Discourse enabled)
Required workflow variables (minimum):
DRY_RUN(falsein production)LOG_LEVEL(infodefault)ENABLE_DISCORDENABLE_DISCOURSEDISCOURSE_BASE_URL(if Discourse enabled)GEMINI_MODELMAX_SUMMARY_TOKENSDIGEST_WINDOW_HOURSMIN_MESSAGE_LENGTHEXCLUDE_COMMANDSEXCLUDE_LINK_ONLY
Check these once per day:
- Cloud Scheduler job execution status is successful.
- A corresponding successful run exists in the
Daily Digestworkflow. - Slack digest arrived in the expected channel.
Set up two alerts:
- Trigger failure alert: Cloud Scheduler job failed.
- Digest missing alert: no successful
Daily Digestrun or no Slack post within expected window.
Target response objective:
- Detect failure within 30 minutes of scheduled run.
Likely causes:
- Invalid/expired GitHub PAT.
- Repository/workflow path changed.
Actions:
- Validate Cloud Scheduler HTTP response code and payload.
- Validate PAT permissions and expiration.
- Manually run
workflow_dispatchfrom GitHub UI. - Rotate PAT and update Scheduler headers.
Likely causes:
- Invalid API credentials.
- Upstream API rate limits/outage (Discord/Discourse/Gemini/Slack).
- Config drift in repo variables.
Actions:
- Inspect failing step in Actions logs.
- Validate secrets/variables against
.env.example. - Re-run the workflow once after correction.
- If still failing, set temporary
DRY_RUN=trueto validate end-to-end flow safely.
Likely causes:
- Slack channel ID/token mismatch.
- Filters/window produced no qualifying messages.
Actions:
- Inspect final posting logs in workflow.
- Confirm
SLACK_CHANNEL_ID,DIGEST_WINDOW_HOURS, and filter vars. - Run one manual dispatch with temporary broader window for diagnosis.
If a daily run is missed:
- Resolve root cause.
- Manually dispatch the workflow (
workflow_dispatch). - Confirm Slack post delivery.
- Document incident summary and corrective action.
- Rotate GitHub PAT on a fixed schedule.
- Keep PAT scope minimal.
- Restrict who can edit Cloud Scheduler jobs and repository secrets.
- Quarterly review of workflow variables and external API credentials.
Before changing schedule/time window:
- Validate with one manual
workflow_dispatchrun. - Apply scheduler update in non-peak hours.
- Confirm next scheduled invocation succeeds.