A faster scheduler
GitHub delays scheduled workflow runs when its infrastructure is busy. A cron set to 15 minutes commonly fires every 30 to 40 minutes, and worse at peak times.
For queues measured in hours this is fine and you should skip this page. If you want tighter timing, a Cloudflare Worker can wake the workflow on its own schedule instead. The free tier covers it.
The Worker only wakes the workflow. All of Qoffee's logic still runs inside GitHub Actions. That means you can remove the Worker at any time and change nothing about Qoffee.
1. Create a Cloudflare Worker
- Sign in to Cloudflare.
- Navigate to Workers & Pages.
- Create a new Worker.
- Replace the default code with the Worker below.
- Deploy the Worker.
2. Add Worker Secrets
Under Settings → Variables and Secrets, create the following secrets.
| Secret | Value |
|---|---|
GITHUB_REPO | your-username/your-repository |
GITHUB_TOKEN | A GitHub Fine-Grained Personal Access Token with Actions: Read & Write permission for your Qoffee repository. |
3. Worker Code
export default {
async scheduled(event, env, ctx) {
console.log("☕ Qoffee scheduler triggered");
ctx.waitUntil(triggerWorkflow(env));
},
async fetch(request, env, ctx) {
return new Response("☕ Qoffee scheduler alive");
}
};
async function triggerWorkflow(env) {
const url =
`https://api.github.com/repos/${env.GITHUB_REPO}/actions/workflows/watch.yml/dispatches`;
console.log("Dispatch URL:", url);
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${env.GITHUB_TOKEN}`,
"Accept": "application/vnd.github+json",
"User-Agent": "qoffee-cloudflare-scheduler"
},
body: JSON.stringify({
ref: "main"
})
});
const text = await response.text();
console.log("GitHub status:", response.status);
console.log("GitHub response:", text);
if (!response.ok) {
console.log("✗ GitHub workflow dispatch failed");
} else {
console.log("✓ GitHub workflow dispatched");
}
}
4. Configure the Cron Trigger
From the Worker dashboard:
Settings → Triggers → Cron Triggers
Create a cron schedule such as:
*/5 * * * *
This runs the scheduler every five minutes.
Cloudflare cron expressions use UTC time and changes may take several minutes to propagate globally after being saved.
5. Generate a GitHub Token
Create a Fine-Grained Personal Access Token with access only to your selected Qoffee repository.
Required repository permissions:
- Actions: Read and Write
- Metadata: Read (automatically included)
Copy the token into the Cloudflare GITHUB_TOKEN secret.
6. Test the Scheduler
After deployment, you should see logs similar to:
☕ Qoffee scheduler triggered
Dispatch URL: https://api.github.com/repos/your-name/your-repo/actions/workflows/watch.yml/dispatches
GitHub status: 204
GitHub response:
✓ GitHub workflow dispatched
An HTTP 204 No Content response is the expected success response from GitHub when a workflow dispatch request is accepted.
7. Verify the Workflow
Open your repository's Actions tab.
Every time the Cloudflare cron fires, a new Qoffee Watcher workflow run should appear.
And that's it. You are done.