{
  "id": "b5b82f5d-8220-44e2-b23a-f1b63ed042a4",
  "name": "GitHub Actions Failure Review",
  "nodes": [
    {
      "parameters": {
        "content": "# Reviewed Harshith.com template\n\nReads one bounded page of public GitHub Actions runs and prepares completed failures for human review. API errors are surfaced explicitly. It does not rerun jobs, comment, or change a repository.\n\nThis export is inactive and contains no credentials, deployment IDs, webhook IDs, or pinned data. Review the visible repository before each run.",
        "height": 300,
        "width": 430,
        "color": 7
      },
      "id": "98231ba0-3382-4608-9289-df864ec9bdd9",
      "name": "Read Me First",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -760,
        -300
      ]
    },
    {
      "parameters": {},
      "id": "8c6fc1c4-1d50-4bdc-8f26-21c7f6af9fdf",
      "name": "Run Manually",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -620,
        80
      ]
    },
    {
      "parameters": {
        "jsCode": "return [{ json: { repository: 'n8n-io/n8n', perPage: 30 } }];"
      },
      "id": "d0da6cf3-cac3-40ac-802d-3ef9fb2d9993",
      "name": "Set Public Repository",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -380,
        80
      ]
    },
    {
      "parameters": {
        "url": "=https://api.github.com/repos/{{ $json.repository }}/actions/runs?per_page={{ $json.perPage }}",
        "options": {
          "timeout": 10000,
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "response": {
            "response": {
              "fullResponse": true,
              "neverError": true,
              "responseFormat": "text"
            }
          }
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/vnd.github+json"
            },
            {
              "name": "X-GitHub-Api-Version",
              "value": "2022-11-28"
            }
          ]
        }
      },
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 1000,
      "id": "cc91c4f2-094e-4b50-b6f5-652e61cb281b",
      "name": "Read Workflow Runs",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -100,
        80
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const response = $json;\nconst raw = response.body ?? response.data ?? response;\nlet payload = raw;\nlet parseError = '';\nif (typeof raw === 'string') {\n  try { payload = JSON.parse(raw || '{}'); }\n  catch (error) { payload = {}; parseError = error.message || 'invalid_json'; }\n}\nconst source = $('Set Public Repository').first().json;\nconst statusCode = Number(response.statusCode || 0);\nconst apiOk = statusCode === 200 && Array.isArray(payload.workflow_runs);\nconst runs = apiOk ? payload.workflow_runs : [];\nconst completedNonSuccess = runs.filter((run) => run.status === 'completed' && run.conclusion && run.conclusion !== 'success');\nconst reviewRuns = completedNonSuccess.filter((run) => run.conclusion !== 'skipped');\nconst failures = reviewRuns.slice(0, 20).map((run) => ({ name: run.name || '', conclusion: run.conclusion, branch: run.head_branch || '', url: run.html_url || '', completedAt: run.updated_at || '' }));\nconst error = apiOk ? '' : String(payload.message || parseError || 'Unexpected GitHub API response');\nconst headers = response.headers || {};\nconst totalCount = apiOk && Number.isFinite(Number(payload.total_count)) ? Number(payload.total_count) : null;\nconst pageMayBeIncomplete = apiOk && (totalCount === null ? runs.length >= source.perPage : totalCount > runs.length);\nconst status = !apiOk ? 'api_error' : reviewRuns.length > 0 ? 'review_before_action' : 'clear';\nreturn { json: { repository: source.repository, statusCode, apiOk, error, rateLimitRemaining: String(headers['x-ratelimit-remaining'] || headers['X-RateLimit-Remaining'] || ''), totalCount, inspected: runs.length, nonSuccessCountOnPage: completedNonSuccess.length, skippedCountOnPage: completedNonSuccess.length - reviewRuns.length, reviewCountOnPage: reviewRuns.length, returnedReviewCount: failures.length, failures, resultTruncated: reviewRuns.length > failures.length, pageLimit: source.perPage, pageMayBeIncomplete, needsReview: !apiOk || reviewRuns.length > 0, status, checkedAt: new Date().toISOString() } };"
      },
      "id": "98924732-4171-4f25-8078-161cf82d376f",
      "name": "Build Failure Review",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        180,
        80
      ]
    }
  ],
  "connections": {
    "Run Manually": {
      "main": [
        [
          {
            "node": "Set Public Repository",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Public Repository": {
      "main": [
        [
          {
            "node": "Read Workflow Runs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Workflow Runs": {
      "main": [
        [
          {
            "node": "Build Failure Review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "saveDataErrorExecution": "none",
    "saveDataSuccessExecution": "none",
    "saveManualExecutions": false,
    "executionTimeout": 60
  },
  "tags": []
}
