feat: scheduled GitHub Actions workflow to fire Claude Code routine 4x daily

This commit is contained in:
2026-04-24 15:24:47 +07:00
commit deb3428cfb
4 changed files with 149 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
name: Trigger Claude Code Routine
on:
schedule:
# UTC+7 (Asia/Ho_Chi_Minh) → UTC
- cron: '0 22 * * *' # 05:00 UTC+7
- cron: '0 3 * * *' # 10:00 UTC+7
- cron: '0 8 * * *' # 15:00 UTC+7
- cron: '0 13 * * *' # 20:00 UTC+7
workflow_dispatch:
inputs:
text:
description: 'Optional context text passed to the routine'
required: false
default: ''
concurrency:
group: claude-code-routine-trigger
cancel-in-progress: false
jobs:
fire:
name: Fire routine
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: POST /fire
env:
ROUTINE_FIRE_URL: ${{ secrets.ROUTINE_FIRE_URL }}
ROUTINE_FIRE_TOKEN: ${{ secrets.ROUTINE_FIRE_TOKEN }}
INPUT_TEXT: ${{ inputs.text }}
run: |
set -euo pipefail
if [ -z "${ROUTINE_FIRE_URL:-}" ] || [ -z "${ROUTINE_FIRE_TOKEN:-}" ]; then
echo "::error::Missing secrets ROUTINE_FIRE_URL and/or ROUTINE_FIRE_TOKEN"
exit 1
fi
LOCAL_NOW=$(TZ=Asia/Ho_Chi_Minh date '+%Y-%m-%d %H:%M %Z')
if [ -n "${INPUT_TEXT}" ]; then
TEXT="${INPUT_TEXT}"
else
TEXT="Scheduled trigger at ${LOCAL_NOW} (run ${GITHUB_RUN_ID})"
fi
PAYLOAD=$(jq -n --arg text "$TEXT" '{text: $text}')
RESPONSE=$(curl -sS -w "\n%{http_code}" -X POST "$ROUTINE_FIRE_URL" \
-H "Authorization: Bearer $ROUTINE_FIRE_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: experimental-cc-routine-2026-04-01" \
-H "Content-Type: application/json" \
-d "$PAYLOAD")
HTTP_CODE=$(printf '%s' "$RESPONSE" | tail -n1)
BODY=$(printf '%s' "$RESPONSE" | sed '$d')
echo "HTTP ${HTTP_CODE}"
echo "${BODY}"
if [ "$HTTP_CODE" != "200" ]; then
echo "::error::Routine fire failed with HTTP ${HTTP_CODE}"
exit 1
fi
SESSION_URL=$(printf '%s' "$BODY" | jq -r '.claude_code_session_url // empty')
if [ -n "$SESSION_URL" ]; then
echo "### Claude Code session" >> "$GITHUB_STEP_SUMMARY"
echo "- Triggered at: ${LOCAL_NOW}" >> "$GITHUB_STEP_SUMMARY"
echo "- Session: ${SESSION_URL}" >> "$GITHUB_STEP_SUMMARY"
fi
+5
View File
@@ -0,0 +1,5 @@
.DS_Store
*.log
.env
.env.*
!.env.example
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 tiennm99
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+51
View File
@@ -0,0 +1,51 @@
# claude-code-routine-trigger
GitHub Actions workflow that fires a [Claude Code routine](https://code.claude.com/docs/en/routines) four times a day via the [`/fire` API](https://platform.claude.com/docs/en/api/claude-code/routines-fire).
Schedule (UTC+7, `Asia/Ho_Chi_Minh`):
| Local time | UTC cron |
| ---------- | ------------- |
| 05:00 | `0 22 * * *` |
| 10:00 | `0 3 * * *` |
| 15:00 | `0 8 * * *` |
| 20:00 | `0 13 * * *` |
Manual `workflow_dispatch` is supported with an optional `text` input for ad-hoc runs.
## Setup
1. Create a routine at <https://claude.ai/code/routines> (requires a Pro/Max/Team/Enterprise plan with Claude Code on the web enabled).
2. In the routine editor, add an **API** trigger and generate a token. Copy both the fire URL and the token — the token is shown once.
3. Add two repository secrets (`Settings → Secrets and variables → Actions`):
- `ROUTINE_FIRE_URL` — e.g. `https://api.anthropic.com/v1/claude_code/routines/trig_01ABo4hmfydBLFDgRMnKwEKy/fire`
- `ROUTINE_FIRE_TOKEN` — e.g. `sk-ant-oat01-...`
4. Enable Actions for the repo. Scheduled runs start on the next matching UTC tick.
## Manual run
`Actions → Trigger Claude Code Routine → Run workflow`. Leave `text` blank to get a timestamped default, or pass custom context (alert body, log line, etc.).
## Request shape
```bash
curl -X POST "$ROUTINE_FIRE_URL" \
-H "Authorization: Bearer $ROUTINE_FIRE_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: experimental-cc-routine-2026-04-01" \
-H "Content-Type: application/json" \
-d '{"text": "Scheduled trigger ..."}'
```
Beta header pinned to `experimental-cc-routine-2026-04-01`. Two previous dated beta versions keep working while migrating — bump when Anthropic ships a new one.
## Notes
- GitHub cron runs can lag 515 min under load and are best-effort — acceptable for housekeeping-style routines, not for precise timing.
- Token is scoped to a single routine; a leak can only fire that one routine.
- Each POST creates a new session (no idempotency). Avoid retry loops that would multiply sessions.
- 429 responses include `Retry-After`; the workflow fails loud rather than retrying silently.
## License
MIT