Deploy and Test Your Bot
Your bot is built. Now let’s make it run automatically every morning using GitHub Actions.What Is GitHub Actions?
GitHub Actions is a built-in automation service that runs tasks for you. You tell it when to run (e.g. every weekday at 9 am) and what to do (e.g. run your bot script), and it handles the rest — no server needed.How does it work under the hood?
How does it work under the hood?
When you push a workflow file (a YAML file in
.github/workflows/), GitHub watches for the trigger you defined. When the trigger fires — a scheduled time, a push, or a manual button press — GitHub spins up a virtual machine, checks out your code, installs dependencies, and runs your commands. It’s like having a free computer in the cloud that does one job and shuts down.Prompt 7: Create the GitHub Actions Workflow
Ask Claude Code to create the automation:Your prompt to Claude Code
About cron timing: GitHub Actions cron uses UTC. New Zealand is UTC+12 (or UTC+13 during daylight saving). The schedule
0 20 * * 1-5 means “8 PM UTC, Monday to Friday” which is approximately 9 AM NZST. Cron triggers can be delayed by up to 15 minutes during busy periods — this is normal.What does [skip ci] mean?
What does [skip ci] mean?
When the bot commits the updated
state.json, the commit message includes [skip ci]. This tells GitHub Actions not to trigger another workflow run for that commit — otherwise you’d get an infinite loop of the bot triggering itself.Why fetch-depth: 0?
Why fetch-depth: 0?
By default, GitHub Actions checks out only the latest commit (shallow clone). Your bot needs to read the full git history to find recent commits. Setting
fetch-depth: 0 ensures the entire history is available.View the generated workflow
View the generated workflow
Configure GitHub Secrets
Your bot needs three secrets. Never commit these to your code — store them in GitHub’s encrypted secrets.- Using the command line (gh CLI)
- Using the GitHub website
Push and Deploy
Test the Workflow
Dry run (no Slack post)
Trigger the workflow manually with a dry run to check everything works without posting to Slack:Or on the GitHub website: Actions → Daily Report Bot → Run workflow.Check the logs to see the output. You should see the commit collection, banking, and summary steps complete successfully.
Real test (post to test channel)
If the dry run looks good, trigger a real run that posts to your test Slack channel. Check the
SLACK_CHANNEL environment variable is set to test in the workflow file, then trigger again.Go to your test Slack channel — you should see a message like this:Prompt 8: Troubleshoot
Things don’t always work on the first try. Here’s the pattern for debugging with Claude Code:Your prompt to Claude Code
Common Issues
Workflow not triggering
Workflow not triggering
Possible causes:
- The workflow file isn’t on the default branch (usually
main). Scheduled workflows only run from the default branch. - The cron schedule is in UTC, not your local time. Double-check the conversion.
- GitHub Actions can delay cron triggers by up to 15 minutes during busy periods.
Slack webhook returns 403 or 404
Slack webhook returns 403 or 404
Possible causes:
- The webhook URL has been revoked or is incorrect. Go to your Slack app settings and check.
- The secret name in your workflow doesn’t match what you set in GitHub Secrets.
- You’re using the test webhook URL but the environment variable points to prod (or vice versa).
Empty commit messages or garbled output
Empty commit messages or garbled output
Possible cause: The git log separator conflicts with shell operators. Using
|| or && as separators will break because the shell interprets them. Use a safe separator like <SEP> instead.State push conflicts
State push conflicts
Possible cause: If someone pushes to the repository at the same time as the bot tries to commit
state.json, you’ll get a conflict. The [skip ci] tag prevents cascading runs, but timing conflicts can still happen. This is rare in practice.No commits found
No commits found
Possible causes:
- The time window is too short. The default is 24 hours, but if the workflow runs at a slightly different time, some commits might fall outside the window.
fetch-depth: 0is missing from the checkout step, so the git history isn’t available.
Switch to Production
Once you’re happy with the test output, switch to the production channel:- In your workflow file (
.github/workflows/daily-report.yml), changeSLACK_CHANNEL: testtoSLACK_CHANNEL: prod - Commit and push
Your prompt to Claude Code
Your bot is deployed and running! Head to What’s next for ideas to extend it, lessons learned, and reflection questions.