The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "bizOS GitHub Actions Poll",
"active": false,
"nodes": [
{
"parameters": {
"content": "## Poll GitHub Actions for bizOS failures\n\nRuns every 15 minutes. Requires `GITHUB_TOKEN` in n8n env (fine-grained PAT or classic token with `actions:read` on pmwasim/bizOS).\n\nWorks with **localhost n8n** \u2014 no inbound webhook from GitHub required.\n\nDedupes by workflow run id in workflow static data. Replace **Log Route** with Slack/email before activation.",
"height": 200,
"width": 480
},
"id": "sticky-note-bizos-gh-poll",
"name": "Setup Notes",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
80,
-120
]
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "*/15 * * * *"
}
]
}
},
"id": "schedule-bizos-gh-poll",
"name": "Every 15 Minutes",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
260,
0
]
},
{
"parameters": {
"jsCode": "const token = $env.GITHUB_TOKEN;\nif (!token) {\n throw new Error('GITHUB_TOKEN is not configured in n8n environment');\n}\n\nconst url = new URL('https://api.github.com/repos/pmwasim/bizOS/actions/runs');\nurl.searchParams.set('status', 'completed');\nurl.searchParams.set('per_page', '10');\n\nconst response = await fetch(url, {\n headers: {\n Accept: 'application/vnd.github+json',\n Authorization: `Bearer ${token}`,\n 'X-GitHub-Api-Version': '2022-11-28',\n },\n});\n\nif (!response.ok) {\n throw new Error(`GitHub API ${response.status}: ${await response.text()}`);\n}\n\nreturn [{ json: await response.json() }];"
},
"id": "code-fetch-github-runs",
"name": "Fetch Recent Runs",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
520,
0
]
},
{
"parameters": {
"jsCode": "const runs = $input.first().json.workflow_runs ?? [];\nconst staticData = $getWorkflowStaticData('global');\nif (!staticData.notifiedRunIds) {\n staticData.notifiedRunIds = {};\n}\n\nconst failures = runs.filter((run) => {\n if (run.conclusion !== 'failure' && run.conclusion !== 'cancelled') {\n return false;\n }\n if (staticData.notifiedRunIds[String(run.id)]) {\n return false;\n }\n return true;\n});\n\nreturn failures.map((run) => ({\n json: {\n event: 'ci.failure',\n source: 'github-actions-poll',\n idempotencyKey: `gh-run-${run.id}`,\n repo: 'pmwasim/bizOS',\n workflow: run.name,\n runId: run.id,\n runUrl: run.html_url,\n branch: run.head_branch,\n sha: run.head_sha?.slice(0, 7),\n conclusion: run.conclusion,\n actor: run.actor?.login ?? 'unknown',\n createdAt: run.created_at,\n },\n}));"
},
"id": "code-filter-failures",
"name": "Filter New Failures",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
780,
0
]
},
{
"parameters": {
"values": {
"string": [
{
"name": "workflow",
"value": "bizos-github-actions-poll"
},
{
"name": "channel",
"value": "ops-ci"
},
{
"name": "title",
"value": "=[bizOS] GitHub failure: {{ $json.workflow }}"
},
{
"name": "message",
"value": "=Branch {{ $json.branch }} \u00b7 {{ $json.conclusion }} \u00b7 {{ $json.runUrl }}"
},
{
"name": "routedAt",
"value": "={{ $now.toISO() }}"
}
]
},
"options": {}
},
"id": "set-gh-poll-notification",
"name": "Build Notification",
"type": "n8n-nodes-base.set",
"typeVersion": 3,
"position": [
1040,
0
]
},
{
"parameters": {
"jsCode": "const staticData = $getWorkflowStaticData('global');\nif (!staticData.notifiedRunIds) {\n staticData.notifiedRunIds = {};\n}\nstaticData.notifiedRunIds[String($json.runId)] = $now.toISO();\n\n// Keep map bounded\nconst keys = Object.keys(staticData.notifiedRunIds);\nif (keys.length > 200) {\n for (const key of keys.slice(0, keys.length - 200)) {\n delete staticData.notifiedRunIds[key];\n }\n}\n\nreturn [{ json: { ...$json, status: 'routed' } }];"
},
"id": "code-mark-notified",
"name": "Mark Notified",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1300,
0
]
},
{
"parameters": {
"values": {
"string": [
{
"name": "status",
"value": "routed"
}
]
},
"options": {}
},
"id": "set-gh-poll-log",
"name": "Log Route",
"type": "n8n-nodes-base.set",
"typeVersion": 3,
"position": [
1560,
0
]
}
],
"connections": {
"Every 15 Minutes": {
"main": [
[
{
"node": "Fetch Recent Runs",
"type": "main",
"index": 0
}
]
]
},
"Fetch Recent Runs": {
"main": [
[
{
"node": "Filter New Failures",
"type": "main",
"index": 0
}
]
]
},
"Filter New Failures": {
"main": [
[
{
"node": "Build Notification",
"type": "main",
"index": 0
}
]
]
},
"Build Notification": {
"main": [
[
{
"node": "Mark Notified",
"type": "main",
"index": 0
}
]
]
},
"Mark Notified": {
"main": [
[
{
"node": "Log Route",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"saveManualExecutions": true,
"callerPolicy": "workflowsFromSameOwner"
},
"meta": {
"templateCredsSetupCompleted": false,
"description": "Polls GitHub Actions for new bizOS failures. Configure GitHub API Token credential before activation."
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
bizOS GitHub Actions Poll. Scheduled trigger; 7 nodes.
Source: https://github.com/pmwasim/bizOS/blob/main/docs/operations/n8n-workflows/github-actions-poll.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Create An Issue On Gitlab On Every Github Release. Uses github, gitlab. Scheduled trigger; 6 nodes.
Create an issue on GitLab on every GitHub release. Uses github, gitlab. Scheduled trigger; 6 nodes.
The Docker Immich WHMCS module uses a specially designed workflow for n8n to automate deployment processes. The workflow provides an API interface for the module, receives specific commands, and conne
The Docker n8n WHMCS module uses a specially designed workflow for n8n to automate deployment processes. The workflow provides an API interface for the module, receives specific commands, and connects