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 — say this or paste it:Say this or copy this prompt
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
If you have the GitHub CLI installed:Each command will prompt you to paste the value.
Copy this command
Push and Deploy
1
Stage and commit your code
Copy this command
2
Push to GitHub
Copy this command
3
Verify on GitHub
Go to your repository on GitHub → Actions tab. You should see the “Daily Report Bot” workflow listed. It will run automatically on the next scheduled time, or you can trigger it manually.
Test the Workflow
1
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.
Copy this command
2
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:3
Celebrate
Your bot works! It will now run automatically every weekday morning.
Prompt 8: Troubleshoot
Things don’t always work on the first try. Here’s the pattern for debugging with Claude Code:Say this or copy this prompt
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
Say this or copy this prompt
Your bot is deployed and running! Head to What’s next for ideas to extend it, lessons learned, and reflection questions.