Payload
{
"action": "created",
"comment": {
"url": "https://api.github.com/repos/darkmatter/infra/pulls/comments/3405038594",
"pull_request_review_id": 4487716952,
"id": 3405038594,
"node_id": "PRRC_kwDOPq3Cd87K9MQC",
"diff_hunk": "@@ -0,0 +1,212 @@\n+# discover-services — multi-source HTTP service discovery for Uptime Kuma.\n+#\n+# Run with: `nix run .#discover-services`\n+#\n+# Queries several sources of truth, cross-references them by hostname, and\n+# emits a JSON array of HTTP-reachable services in the same shape AutoKuma\n+# consumes (see render-uptime-kuma-config), enriched with `discovered_by`\n+# (which sources saw the hostname) and `backend` (the in-cluster service the\n+# cloudflared tunnel routes to, when known).\n+#\n+# Sources:\n+# 1. Cloudflare Workers custom domains (GET .../workers/domains)\n+# 2. Cloudflare Workers scripts (GET .../workers/scripts — names)\n+# 3. Cloudflare DNS records per zone (proxied / tunnel-pointing A,CNAME)\n+# 4. cloudflared tunnel ConfigMap (hostname → k8s backend mappings)\n+# 5. Tailscale tailnet devices (optional, best-effort, HTTP-tagged)\n+#\n+# Only HTTP endpoints on monitored domains (plus any Worker custom domain) are\n+# emitted. Tailscale/TCP-only hosts are intentionally dropped.\n+#\n+# Output: $REPO_ROOT/config/discovered-services.json\n+# (override with $DISCOVERED_SERVICES_OUT)\n+#\n+# Env:\n+# CLOUDFLARE_API_TOKEN — required (himitsu read cloudflare-api-token)\n+# CLOUDFLARE_ACCOUNT_ID — default 57637f68fc95064ca667662b05784e27\n+# TAILSCALE_API_KEY — optional (skip Tailscale discovery if unset)\n+# TAILSCALE_TAILNET — default tail6277a6.ts.net\n+# GITOPS_DIR — gitops checkout (default: sibling ../gitops)\n+# INFRA_REPO_ROOT — infra repo root (default: git toplevel)\n+# DISCOVERED_SERVICES_OUT — output path (default: above)\n+{ pkgs, ... }:\n+let\n+ app = pkgs.writeShellApplication {\n+ name = \"discover-services\";\n+ runtimeInputs = with pkgs; [ curl jq yq-go coreutils git ];\n+ # SC2016: jq filters contain literal $foo — not shell expansions.\n+ excludeShellChecks = [ \"SC2016\" ];\n+ text = ''\n+ set -euo pipefail\n+\n+ # ── Env ────────────────────────────────────────────────────────────────\n+ : \"''${CLOUDFLARE_API_TOKEN:?CLOUDFLARE_API_TOKEN is required. Run: himitsu read cloudflare-api-token}\"\n+ CLOUDFLARE_ACCOUNT_ID=\"''${CLOUDFLARE_ACCOUNT_ID:-57637f68fc95064ca667662b05784e27}\"\n+ TAILSCALE_TAILNET=\"''${TAILSCALE_TAILNET:-tail6277a6.ts.net}\"\n+\n+ REPO_ROOT=\"''${INFRA_REPO_ROOT:-$(git rev-parse --show-toplevel)}\"\n+ GITOPS_DIR=\"''${GITOPS_DIR:-$REPO_ROOT/../gitops}\"\n+ OUT=\"''${DISCOVERED_SERVICES_OUT:-$REPO_ROOT/config/discovered-services.json}\"\n+ CF_CONFIGMAP=\"$GITOPS_DIR/manifests/cloudflared/configmap.yaml\"\n+\n+ CF_API=\"https://api.cloudflare.com/client/v4\"\n+ auth_header=\"Authorization: Bearer $CLOUDFLARE_API_TOKEN\"\n+\n+ # ── Zone IDs (public identifiers, mirror alchemy/lib/config.ts) ─────────\n+ ZONES='[\n+ {\"zone\":\"darkmatter.io\",\"id\":\"57637f68fc95064ca667662b05784e27\"},\n+ {\"zone\":\"drkmttr.dev\",\"id\":\"8ad909e93cb74b806fd4051565b7195e\"},\n+ {\"zone\":\"dm.sh\",\"id\":\"5be8144b791486e24966f7577ab2d41b\"},\n+ {\"zone\":\"blockvalue.ai\",\"id\":\"4769a143074f30d7fff85f5d4070fcaf\"},\n+ {\"zone\":\"iridium.sh\",\"id\":\"fb65511be6f1da21b732550aec252658\"}\n+ ]'\n+\n+ # ── Generic Cloudflare paginated GET ────────────────────────────────────\n+ # $1 = path under CF_API (no query string); $2 = per_page (default 50).\n+ # Always echoes a JSON array (empty \"[]\" on failure — fail gracefully).\n+ cf_get_all() {\n+ local path=\"$1\" per=\"''${2:-50}\"\n+ local page=1 all=\"[]\"\n+ while :; do\n+ local resp result total\n+ if ! resp=\"$(curl -sf \"$CF_API/$path?per_page=$per&page=$page\" -H \"$auth_header\")\"; then\n+ echo \"WARNING: Cloudflare API call failed: $path (page $page)\" >&2\n+ break\n+ fi\n+ result=\"$(echo \"$resp\" | jq '.result // []')\"\n+ all=\"$(jq -n --argjson a \"$all\" --argjson b \"$result\" '$a + $b')\"\n+ total=\"$(echo \"$resp\" | jq -r '.result_info.total_pages // 1')\"\n+ if [[ \"$page\" -ge \"$total\" ]]; then break; fi\n+ page=$((page + 1))\n+ done\n+ echo \"$all\"\n+ }\n+\n+ # ── 1. Worker custom domains ────────────────────────────────────────────\n+ worker_domains_raw=\"$(cf_get_all \"accounts/$CLOUDFLARE_ACCOUNT_ID/workers/domains\")\"\n+ worker_records=\"$(echo \"$worker_domains_raw\" | jq '\n+ [ .[] | select(.hostname) | {hostname: .hostname, source: \"worker\", worker_name: (.service // null)} ]\n+ ')\"\n+ n_workers=\"$(echo \"$worker_records\" | jq 'length')\"\n+ echo \"Worker custom domains: $n_workers\" >&2\n+\n+ # ── 2. Worker scripts (names, informational) ────────────────────────────\n+ worker_scripts_raw=\"$(cf_get_all \"accounts/$CLOUDFLARE_ACCOUNT_ID/workers/scripts\")\"\n+ n_scripts=\"$(echo \"$worker_scripts_raw\" | jq 'length')\"\n+ echo \"Worker scripts: $n_scripts\" >&2\n+\n+ # ── 3. cloudflared tunnel ConfigMap (hostname → backend) ────────────────\n+ tunnel_records=\"[]\"\n+ if [[ -f \"$CF_CONFIGMAP\" ]]; then\n+ cf_config=\"$(yq -r '.data.\"config.yaml\"' \"$CF_CONFIGMAP\")\"\n+ tunnel_uuid=\"$(echo \"$cf_config\" | yq -r '.tunnel')\"\n+ echo \"Tunnel: $tunnel_uuid\" >&2\n+ tunnel_records=\"$(echo \"$cf_config\" \\\n+ | yq -o=json '.ingress' \\\n+ | jq '\n+ [ .[] | select(.hostname) | {\n+ hostname: .hostname,\n+ source: \"tunnel\",\n+ backend: (\n+ try ( (.service | capture(\"https?://(?<svc>[^.]+)\\\\.(?<ns>[^.]+)\\\\.svc\\\\.cluster\\\\.local\\\\.?:(?<port>[0-9]+)\"))\n+ | \"\\(.ns)/\\(.svc):\\(.port)\" )\n+ catch null\n+ )\n+ } ]\n+ ')\"\n+ else\n+ echo \"WARNING: cloudflared configmap not found at $CF_CONFIGMAP — skipping tunnel discovery\" >&2\n+ fi\n+ n_tunnel=\"$(echo \"$tunnel_records\" | jq 'length')\"\n+ echo \"Tunnel routes: $n_tunnel\" >&2\n+\n+ # ── 4. DNS records per controlled zone (proxied or tunnel-pointing) ─────\n+ dns_records=\"[]\"\n+ while IFS=' ' read -r _zone zone_id; do\n+ [[ -z \"$zone_id\" ]] && continue\n+ recs=\"$(cf_get_all \"zones/$zone_id/dns_records\" 100)\"\n+ filtered=\"$(echo \"$recs\" | jq '\n+ [ .[]\n+ | select((.type == \"A\" or .type == \"CNAME\")\n+ and (.proxied == true or ((.content // \"\") | test(\"cfargotunnel\\\\.com$\"))))\n+ | {hostname: .name, source: \"dns\", record_type: .type} ]\n+ ')\"\n+ dns_records=\"$(jq -n --argjson a \"$dns_records\" --argjson b \"$filtered\" '$a + $b')\"\n+ done < <(echo \"$ZONES\" | jq -r '.[] | \"\\(.zone) \\(.id)\"')\n+ n_dns=\"$(echo \"$dns_records\" | jq 'length')\"\n+ echo \"DNS records (proxied/tunnel): $n_dns\" >&2\n+\n+ # ── 5. Tailscale devices (optional, best-effort, HTTP-tagged only) ──────\n+ tailscale_records=\"[]\"\n+ if [[ -n \"''${TAILSCALE_API_KEY:-}\" ]]; then\n+ if ts_resp=\"$(curl -sf \"https://api.tailscale.com/api/v2/tailnet/$TAILSCALE_TAILNET/devices\" -u \"$TAILSCALE_API_KEY:\")\"; then\n+ tailscale_records=\"$(echo \"$ts_resp\" | jq '\n+ [ .devices[]?\n+ | select(((.tags // []) | any(test(\"http|web\"))))\n+ | {hostname: ((.name // \"\") | sub(\"\\\\.$\"; \"\")), source: \"tailscale\"}\n+ | select(.hostname != \"\") ]\n+ ')\"\n+ n_ts=\"$(echo \"$tailscale_records\" | jq 'length')\"\n+ echo \"Tailscale HTTP-tagged devices: $n_ts\" >&2\n+ else\n+ echo \"WARNING: Tailscale API call failed — skipping Tailscale discovery\" >&2\n+ fi\n+ else\n+ echo \"TAILSCALE_API_KEY not set — skipping Tailscale discovery\" >&2\n+ fi\n+\n+ # ── Merge, dedupe, filter, tag ──────────────────────────────────────────\n+ all_records=\"$(jq -n \\\n+ --argjson worker \"$worker_records\" \\\n+ --argjson dns \"$dns_records\" \\\n+ --argjson tunnel \"$tunnel_records\" \\\n+ --argjson tailscale \"$tailscale_records\" \\\n+ '$worker + $dns + $tunnel + $tailscale')\"\n+\n+ # Group by hostname. Keep the richest entry: union discovered_by, take the\n+ # tunnel-derived backend when present. Include a hostname only if it lives\n+ # on a monitored domain OR is a Worker custom domain (Workers may be on\n+ # domains we don't control DNS for). Tailscale/TCP-only hosts fall away.\n+ services_json=\"$(echo \"$all_records\" | jq '\n+ group_by(.hostname)\n+ | map(\n+ .[0].hostname as $host\n+ | (map(.source) | unique) as $by\n+ | (map(.backend // empty) | first) as $backend\n+ | (($by | index(\"worker\")) != null) as $is_worker\n+ | ($host | test(\"(^|\\\\.)(darkmatter\\\\.io|drkmttr\\\\.dev|dm\\\\.sh|nixmac\\\\.com|iridium\\\\.sh|stackpanel\\\\.com|blockvalue\\\\.ai)$\")) as $monitored\n+ | select($monitored or $is_worker)\n+ | (if ($host | test(\"(^|\\\\.)darkmatter\\\\.io$\")) then \"production\" else \"staging\" end) as $env\n+ | (if $host == \"status.darkmatter.io\" then 60 else 300 end) as $interval\n+ | {\n+ name: $host,\n+ type: \"http\",\n+ url: (\"https://\" + $host),\n+ interval: $interval,\n+ tag_names: [{ name: $env }],\n+ discovered_by: $by\n+ }\n+ + (if $backend != null then { backend: $backend } else {} end)\n+ )\n+ | sort_by(.name)\n+ | [{ name: \"production\", color: \"#5cdd8b\", type: \"tag\" }, { name: \"staging\", color: \"#f8a306\", type: \"tag\" }] + .\n+ ')\"",
"path": "nix/flake/apps/discover-services.nix",
"commit_id": "1a3bc877897166e5a4759226a8bf57c6d94ce7b7",
"original_commit_id": "1a3bc877897166e5a4759226a8bf57c6d94ce7b7",
"user": {
"login": "Copilot",
"id": 175728472,
"node_id": "BOT_kgDOCnlnWA",
"avatar_url": "https://avatars.githubusercontent.com/in/946600?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Copilot",
"html_url": "https://github.com/apps/copilot-pull-request-reviewer",
"followers_url": "https://api.github.com/users/Copilot/followers",
"following_url": "https://api.github.com/users/Copilot/following{/other_user}",
"gists_url": "https://api.github.com/users/Copilot/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Copilot/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Copilot/subscriptions",
"organizations_url": "https://api.github.com/users/Copilot/orgs",
"repos_url": "https://api.github.com/users/Copilot/repos",
"events_url": "https://api.github.com/users/Copilot/events{/privacy}",
"received_events_url": "https://api.github.com/users/Copilot/received_events",
"type": "Bot",
"user_view_type": "public",
"site_admin": false
},
"body": "`discover-services` currently prepends tag definitions (`production`/`staging`) to `config/discovered-services.json`. But `render-uptime-kuma-config` already prepends those tags and expects the discovered file to be an array of monitor objects. Including tag objects here will cause the merge/dedup logic to treat tags as monitors and may emit duplicate/misordered tag entries in the final ConfigMap.",
"created_at": "2026-06-12T17:12:47Z",
"updated_at": "2026-06-12T17:12:47Z",
"html_url": "https://github.com/darkmatter/infra/pull/24#discussion_r3405038594",
"pull_request_url": "https://api.github.com/repos/darkmatter/infra/pulls/24",
"_links": {
"self": {
"href": "https://api.github.com/repos/darkmatter/infra/pulls/comments/3405038594"
},
"html": {
"href": "https://github.com/darkmatter/infra/pull/24#discussion_r3405038594"
},
"pull_request": {
"href": "https://api.github.com/repos/darkmatter/infra/pulls/24"
}
},
"reactions": {
"url": "https://api.github.com/repos/darkmatter/infra/pulls/comments/3405038594/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"start_line": 189,
"original_start_line": 189,
"start_side": "RIGHT",
"line": 193,
"original_line": 193,
"side": "RIGHT",
"author_association": "NONE",
"original_position": 193,
"position": 193,
"subject_type": "line"
},
"pull_request": {
"url": "https://api.github.com/repos/darkmatter/infra/pulls/24",
"id": 3856308142,
"node_id": "PR_kwDOPq3Cd87l2peu",
"html_url": "https://github.com/darkmatter/infra/pull/24",
"diff_url": "https://github.com/darkmatter/infra/pull/24.diff",
"patch_url": "https://github.com/darkmatter/infra/pull/24.patch",
"issue_url": "https://api.github.com/repos/darkmatter/infra/issues/24",
"number": 24,
"state": "open",
"locked": false,
"title": "feat: multi-source service discovery for Uptime Kuma",
"user": {
"login": "czxtm",
"id": 1325802,
"node_id": "MDQ6VXNlcjEzMjU4MDI=",
"avatar_url": "https://avatars.githubusercontent.com/u/1325802?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/czxtm",
"html_url": "https://github.com/czxtm",
"followers_url": "https://api.github.com/users/czxtm/followers",
"following_url": "https://api.github.com/users/czxtm/following{/other_user}",
"gists_url": "https://api.github.com/users/czxtm/gists{/gist_id}",
"starred_url": "https://api.github.com/users/czxtm/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/czxtm/subscriptions",
"organizations_url": "https://api.github.com/users/czxtm/orgs",
"repos_url": "https://api.github.com/users/czxtm/repos",
"events_url": "https://api.github.com/users/czxtm/events{/privacy}",
"received_events_url": "https://api.github.com/users/czxtm/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"body": "Add discover-services Nix app + extend render-uptime-kuma-config to merge discovered services + CI workflow.\n\n**New:**\n- `nix/flake/apps/discover-services.nix` — queries Cloudflare Workers API, DNS records (5 zones), cloudflared tunnel ConfigMap, and Tailscale API\n- `.github/workflows/discover-services.yml` — daily cron + on-push\n\n**Modified:**\n- `nix/flake/apps/render-uptime-kuma-config.nix` — merges discovered-services.json with service-catalog.nix (catalog wins on conflict)\n- `nix/flake/apps.nix` — registered discover-services for both platforms\n\nRun manually: `CLOUDFLARE_API_TOKEN=$(himitsu read cloudflare-api-token) nix run .#discover-services`",
"created_at": "2026-06-12T17:07:16Z",
"updated_at": "2026-06-12T17:12:47Z",
"closed_at": null,
"merged_at": null,
"merge_commit_sha": "9f7d4d5f7915925ccdd5c4403c1649cf7f74ae0d",
"assignees": [],
"requested_reviewers": [],
"requested_teams": [],
"labels": [],
"milestone": null,
"draft": false,
"commits_url": "https://api.github.com/repos/darkmatter/infra/pulls/24/commits",
"review_comments_url": "https://api.github.com/repos/darkmatter/infra/pulls/24/comments",
"review_comment_url": "https://api.github.com/repos/darkmatter/infra/pulls/comments{/number}",
"comments_url": "https://api.github.com/repos/darkmatter/infra/issues/24/comments",
"statuses_url": "https://api.github.com/repos/darkmatter/infra/statuses/1a3bc877897166e5a4759226a8bf57c6d94ce7b7",
"head": {
"label": "darkmatter:feat/add-gluon-inventory",
"ref": "feat/add-gluon-inventory",
"sha": "1a3bc877897166e5a4759226a8bf57c6d94ce7b7",
"user": {
"login": "darkmatter",
"id": 17834193,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE3ODM0MTkz",
"avatar_url": "https://avatars.githubusercontent.com/u/17834193?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/darkmatter",
"html_url": "https://github.com/darkmatter",
"followers_url": "https://api.github.com/users/darkmatter/followers",
"following_url": "https://api.github.com/users/darkmatter/following{/other_user}",
"gists_url": "https://api.github.com/users/darkmatter/gists{/gist_id}",
"starred_url": "https://api.github.com/users/darkmatter/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/darkmatter/subscriptions",
"organizations_url": "https://api.github.com/users/darkmatter/orgs",
"repos_url": "https://api.github.com/users/darkmatter/repos",
"events_url": "https://api.github.com/users/darkmatter/events{/privacy}",
"received_events_url": "https://api.github.com/users/darkmatter/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"repo": {
"id": 1051574903,
"node_id": "R_kgDOPq3Cdw",
"name": "infra",
"full_name": "darkmatter/infra",
"private": true,
"owner": {
"login": "darkmatter",
"id": 17834193,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE3ODM0MTkz",
"avatar_url": "https://avatars.githubusercontent.com/u/17834193?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/darkmatter",
"html_url": "https://github.com/darkmatter",
"followers_url": "https://api.github.com/users/darkmatter/followers",
"following_url": "https://api.github.com/users/darkmatter/following{/other_user}",
"gists_url": "https://api.github.com/users/darkmatter/gists{/gist_id}",
"starred_url": "https://api.github.com/users/darkmatter/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/darkmatter/subscriptions",
"organizations_url": "https://api.github.com/users/darkmatter/orgs",
"repos_url": "https://api.github.com/users/darkmatter/repos",
"events_url": "https://api.github.com/users/darkmatter/events{/privacy}",
"received_events_url": "https://api.github.com/users/darkmatter/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"html_url": "https://github.com/darkmatter/infra",
"description": "Versioned infra repo",
"fork": false,
"url": "https://api.github.com/repos/darkmatter/infra",
"forks_url": "https://api.github.com/repos/darkmatter/infra/forks",
"keys_url": "https://api.github.com/repos/darkmatter/infra/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/darkmatter/infra/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/darkmatter/infra/teams",
"hooks_url": "https://api.github.com/repos/darkmatter/infra/hooks",
"issue_events_url": "https://api.github.com/repos/darkmatter/infra/issues/events{/number}",
"events_url": "https://api.github.com/repos/darkmatter/infra/events",
"assignees_url": "https://api.github.com/repos/darkmatter/infra/assignees{/user}",
"branches_url": "https://api.github.com/repos/darkmatter/infra/branches{/branch}",
"tags_url": "https://api.github.com/repos/darkmatter/infra/tags",
"blobs_url": "https://api.github.com/repos/darkmatter/infra/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/darkmatter/infra/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/darkmatter/infra/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/darkmatter/infra/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/darkmatter/infra/statuses/{sha}",
"languages_url": "https://api.github.com/repos/darkmatter/infra/languages",
"stargazers_url": "https://api.github.com/repos/darkmatter/infra/stargazers",
"contributors_url": "https://api.github.com/repos/darkmatter/infra/contributors",
"subscribers_url": "https://api.github.com/repos/darkmatter/infra/subscribers",
"subscription_url": "https://api.github.com/repos/darkmatter/infra/subscription",
"commits_url": "https://api.github.com/repos/darkmatter/infra/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/darkmatter/infra/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/darkmatter/infra/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/darkmatter/infra/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/darkmatter/infra/contents/{+path}",
"compare_url": "https://api.github.com/repos/darkmatter/infra/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/darkmatter/infra/merges",
"archive_url": "https://api.github.com/repos/darkmatter/infra/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/darkmatter/infra/downloads",
"issues_url": "https://api.github.com/repos/darkmatter/infra/issues{/number}",
"pulls_url": "https://api.github.com/repos/darkmatter/infra/pulls{/number}",
"milestones_url": "https://api.github.com/repos/darkmatter/infra/milestones{/number}",
"notifications_url": "https://api.github.com/repos/darkmatter/infra/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/darkmatter/infra/labels{/name}",
"releases_url": "https://api.github.com/repos/darkmatter/infra/releases{/id}",
"deployments_url": "https://api.github.com/repos/darkmatter/infra/deployments",
"created_at": "2025-09-06T09:28:59Z",
"updated_at": "2026-06-12T15:18:35Z",
"pushed_at": "2026-06-12T17:07:01Z",
"git_url": "git://github.com/darkmatter/infra.git",
"ssh_url": "git@github.com:darkmatter/infra.git",
"clone_url": "https://github.com/darkmatter/infra.git",
"svn_url": "https://github.com/darkmatter/infra",
"homepage": null,
"size": 59381,
"stargazers_count": 0,
"watchers_count": 0,
"language": "Nix",
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": true,
"has_discussions": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 2,
"license": null,
"allow_forking": false,
"is_template": false,
"web_commit_signoff_required": false,
"has_pull_requests": true,
"pull_request_creation_policy": "all",
"topics": [],
"visibility": "private",
"forks": 0,
"open_issues": 2,
"watchers": 0,
"default_branch": "main",
"allow_squash_merge": true,
"allow_merge_commit": true,
"allow_rebase_merge": true,
"allow_auto_merge": false,
"delete_branch_on_merge": false,
"allow_update_branch": false,
"use_squash_pr_title_as_default": false,
"squash_merge_commit_message": "COMMIT_MESSAGES",
"squash_merge_commit_title": "COMMIT_OR_PR_TITLE",
"merge_commit_message": "PR_TITLE",
"merge_commit_title": "MERGE_MESSAGE"
}
},
"base": {
"label": "darkmatter:main",
"ref": "main",
"sha": "454fcc8682817388e9eaafd24b964e1717362406",
"user": {
"login": "darkmatter",
"id": 17834193,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE3ODM0MTkz",
"avatar_url": "https://avatars.githubusercontent.com/u/17834193?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/darkmatter",
"html_url": "https://github.com/darkmatter",
"followers_url": "https://api.github.com/users/darkmatter/followers",
"following_url": "https://api.github.com/users/darkmatter/following{/other_user}",
"gists_url": "https://api.github.com/users/darkmatter/gists{/gist_id}",
"starred_url": "https://api.github.com/users/darkmatter/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/darkmatter/subscriptions",
"organizations_url": "https://api.github.com/users/darkmatter/orgs",
"repos_url": "https://api.github.com/users/darkmatter/repos",
"events_url": "https://api.github.com/users/darkmatter/events{/privacy}",
"received_events_url": "https://api.github.com/users/darkmatter/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"repo": {
"id": 1051574903,
"node_id": "R_kgDOPq3Cdw",
"name": "infra",
"full_name": "darkmatter/infra",
"private": true,
"owner": {
"login": "darkmatter",
"id": 17834193,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE3ODM0MTkz",
"avatar_url": "https://avatars.githubusercontent.com/u/17834193?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/darkmatter",
"html_url": "https://github.com/darkmatter",
"followers_url": "https://api.github.com/users/darkmatter/followers",
"following_url": "https://api.github.com/users/darkmatter/following{/other_user}",
"gists_url": "https://api.github.com/users/darkmatter/gists{/gist_id}",
"starred_url": "https://api.github.com/users/darkmatter/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/darkmatter/subscriptions",
"organizations_url": "https://api.github.com/users/darkmatter/orgs",
"repos_url": "https://api.github.com/users/darkmatter/repos",
"events_url": "https://api.github.com/users/darkmatter/events{/privacy}",
"received_events_url": "https://api.github.com/users/darkmatter/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"html_url": "https://github.com/darkmatter/infra",
"description": "Versioned infra repo",
"fork": false,
"url": "https://api.github.com/repos/darkmatter/infra",
"forks_url": "https://api.github.com/repos/darkmatter/infra/forks",
"keys_url": "https://api.github.com/repos/darkmatter/infra/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/darkmatter/infra/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/darkmatter/infra/teams",
"hooks_url": "https://api.github.com/repos/darkmatter/infra/hooks",
"issue_events_url": "https://api.github.com/repos/darkmatter/infra/issues/events{/number}",
"events_url": "https://api.github.com/repos/darkmatter/infra/events",
"assignees_url": "https://api.github.com/repos/darkmatter/infra/assignees{/user}",
"branches_url": "https://api.github.com/repos/darkmatter/infra/branches{/branch}",
"tags_url": "https://api.github.com/repos/darkmatter/infra/tags",
"blobs_url": "https://api.github.com/repos/darkmatter/infra/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/darkmatter/infra/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/darkmatter/infra/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/darkmatter/infra/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/darkmatter/infra/statuses/{sha}",
"languages_url": "https://api.github.com/repos/darkmatter/infra/languages",
"stargazers_url": "https://api.github.com/repos/darkmatter/infra/stargazers",
"contributors_url": "https://api.github.com/repos/darkmatter/infra/contributors",
"subscribers_url": "https://api.github.com/repos/darkmatter/infra/subscribers",
"subscription_url": "https://api.github.com/repos/darkmatter/infra/subscription",
"commits_url": "https://api.github.com/repos/darkmatter/infra/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/darkmatter/infra/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/darkmatter/infra/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/darkmatter/infra/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/darkmatter/infra/contents/{+path}",
"compare_url": "https://api.github.com/repos/darkmatter/infra/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/darkmatter/infra/merges",
"archive_url": "https://api.github.com/repos/darkmatter/infra/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/darkmatter/infra/downloads",
"issues_url": "https://api.github.com/repos/darkmatter/infra/issues{/number}",
"pulls_url": "https://api.github.com/repos/darkmatter/infra/pulls{/number}",
"milestones_url": "https://api.github.com/repos/darkmatter/infra/milestones{/number}",
"notifications_url": "https://api.github.com/repos/darkmatter/infra/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/darkmatter/infra/labels{/name}",
"releases_url": "https://api.github.com/repos/darkmatter/infra/releases{/id}",
"deployments_url": "https://api.github.com/repos/darkmatter/infra/deployments",
"created_at": "2025-09-06T09:28:59Z",
"updated_at": "2026-06-12T15:18:35Z",
"pushed_at": "2026-06-12T17:07:01Z",
"git_url": "git://github.com/darkmatter/infra.git",
"ssh_url": "git@github.com:darkmatter/infra.git",
"clone_url": "https://github.com/darkmatter/infra.git",
"svn_url": "https://github.com/darkmatter/infra",
"homepage": null,
"size": 59381,
"stargazers_count": 0,
"watchers_count": 0,
"language": "Nix",
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": true,
"has_discussions": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 2,
"license": null,
"allow_forking": false,
"is_template": false,
"web_commit_signoff_required": false,
"has_pull_requests": true,
"pull_request_creation_policy": "all",
"topics": [],
"visibility": "private",
"forks": 0,
"open_issues": 2,
"watchers": 0,
"default_branch": "main",
"allow_squash_merge": true,
"allow_merge_commit": true,
"allow_rebase_merge": true,
"allow_auto_merge": false,
"delete_branch_on_merge": false,
"allow_update_branch": false,
"use_squash_pr_title_as_default": false,
"squash_merge_commit_message": "COMMIT_MESSAGES",
"squash_merge_commit_title": "COMMIT_OR_PR_TITLE",
"merge_commit_message": "PR_TITLE",
"merge_commit_title": "MERGE_MESSAGE"
}
},
"_links": {
"self": {
"href": "https://api.github.com/repos/darkmatter/infra/pulls/24"
},
"html": {
"href": "https://github.com/darkmatter/infra/pull/24"
},
"issue": {
"href": "https://api.github.com/repos/darkmatter/infra/issues/24"
},
"comments": {
"href": "https://api.github.com/repos/darkmatter/infra/issues/24/comments"
},
"review_comments": {
"href": "https://api.github.com/repos/darkmatter/infra/pulls/24/comments"
},
"review_comment": {
"href": "https://api.github.com/repos/darkmatter/infra/pulls/comments{/number}"
},
"commits": {
"href": "https://api.github.com/repos/darkmatter/infra/pulls/24/commits"
},
"statuses": {
"href": "https://api.github.com/repos/darkmatter/infra/statuses/1a3bc877897166e5a4759226a8bf57c6d94ce7b7"
}
},
"author_association": "MEMBER",
"auto_merge": null,
"assignee": null,
"active_lock_reason": null
},
"repository": {
"id": 1051574903,
"node_id": "R_kgDOPq3Cdw",
"name": "infra",
"full_name": "darkmatter/infra",
"private": true,
"owner": {
"login": "darkmatter",
"id": 17834193,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE3ODM0MTkz",
"avatar_url": "https://avatars.githubusercontent.com/u/17834193?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/darkmatter",
"html_url": "https://github.com/darkmatter",
"followers_url": "https://api.github.com/users/darkmatter/followers",
"following_url": "https://api.github.com/users/darkmatter/following{/other_user}",
"gists_url": "https://api.github.com/users/darkmatter/gists{/gist_id}",
"starred_url": "https://api.github.com/users/darkmatter/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/darkmatter/subscriptions",
"organizations_url": "https://api.github.com/users/darkmatter/orgs",
"repos_url": "https://api.github.com/users/darkmatter/repos",
"events_url": "https://api.github.com/users/darkmatter/events{/privacy}",
"received_events_url": "https://api.github.com/users/darkmatter/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"html_url": "https://github.com/darkmatter/infra",
"description": "Versioned infra repo",
"fork": false,
"url": "https://api.github.com/repos/darkmatter/infra",
"forks_url": "https://api.github.com/repos/darkmatter/infra/forks",
"keys_url": "https://api.github.com/repos/darkmatter/infra/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/darkmatter/infra/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/darkmatter/infra/teams",
"hooks_url": "https://api.github.com/repos/darkmatter/infra/hooks",
"issue_events_url": "https://api.github.com/repos/darkmatter/infra/issues/events{/number}",
"events_url": "https://api.github.com/repos/darkmatter/infra/events",
"assignees_url": "https://api.github.com/repos/darkmatter/infra/assignees{/user}",
"branches_url": "https://api.github.com/repos/darkmatter/infra/branches{/branch}",
"tags_url": "https://api.github.com/repos/darkmatter/infra/tags",
"blobs_url": "https://api.github.com/repos/darkmatter/infra/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/darkmatter/infra/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/darkmatter/infra/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/darkmatter/infra/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/darkmatter/infra/statuses/{sha}",
"languages_url": "https://api.github.com/repos/darkmatter/infra/languages",
"stargazers_url": "https://api.github.com/repos/darkmatter/infra/stargazers",
"contributors_url": "https://api.github.com/repos/darkmatter/infra/contributors",
"subscribers_url": "https://api.github.com/repos/darkmatter/infra/subscribers",
"subscription_url": "https://api.github.com/repos/darkmatter/infra/subscription",
"commits_url": "https://api.github.com/repos/darkmatter/infra/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/darkmatter/infra/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/darkmatter/infra/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/darkmatter/infra/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/darkmatter/infra/contents/{+path}",
"compare_url": "https://api.github.com/repos/darkmatter/infra/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/darkmatter/infra/merges",
"archive_url": "https://api.github.com/repos/darkmatter/infra/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/darkmatter/infra/downloads",
"issues_url": "https://api.github.com/repos/darkmatter/infra/issues{/number}",
"pulls_url": "https://api.github.com/repos/darkmatter/infra/pulls{/number}",
"milestones_url": "https://api.github.com/repos/darkmatter/infra/milestones{/number}",
"notifications_url": "https://api.github.com/repos/darkmatter/infra/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/darkmatter/infra/labels{/name}",
"releases_url": "https://api.github.com/repos/darkmatter/infra/releases{/id}",
"deployments_url": "https://api.github.com/repos/darkmatter/infra/deployments",
"created_at": "2025-09-06T09:28:59Z",
"updated_at": "2026-06-12T15:18:35Z",
"pushed_at": "2026-06-12T17:07:01Z",
"git_url": "git://github.com/darkmatter/infra.git",
"ssh_url": "git@github.com:darkmatter/infra.git",
"clone_url": "https://github.com/darkmatter/infra.git",
"svn_url": "https://github.com/darkmatter/infra",
"homepage": null,
"size": 59381,
"stargazers_count": 0,
"watchers_count": 0,
"language": "Nix",
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": true,
"has_discussions": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 2,
"license": null,
"allow_forking": false,
"is_template": false,
"web_commit_signoff_required": false,
"has_pull_requests": true,
"pull_request_creation_policy": "all",
"topics": [],
"visibility": "private",
"forks": 0,
"open_issues": 2,
"watchers": 0,
"default_branch": "main",
"custom_properties": {}
},
"organization": {
"login": "darkmatter",
"id": 17834193,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE3ODM0MTkz",
"url": "https://api.github.com/orgs/darkmatter",
"repos_url": "https://api.github.com/orgs/darkmatter/repos",
"events_url": "https://api.github.com/orgs/darkmatter/events",
"hooks_url": "https://api.github.com/orgs/darkmatter/hooks",
"issues_url": "https://api.github.com/orgs/darkmatter/issues",
"members_url": "https://api.github.com/orgs/darkmatter/members{/member}",
"public_members_url": "https://api.github.com/orgs/darkmatter/public_members{/member}",
"avatar_url": "https://avatars.githubusercontent.com/u/17834193?v=4",
"description": ""
},
"enterprise": {
"id": 469843,
"slug": "darkmatter",
"name": "darkmatter",
"node_id": "E_kgDOAAcrUw",
"avatar_url": "https://avatars.githubusercontent.com/b/469843?v=4",
"description": "",
"website_url": "darkmatter.io",
"html_url": "https://github.com/enterprises/darkmatter",
"created_at": "2025-09-07T16:01:00Z",
"updated_at": "2026-06-07T16:53:26Z"
},
"sender": {
"login": "Copilot",
"id": 175728472,
"node_id": "BOT_kgDOCnlnWA",
"avatar_url": "https://avatars.githubusercontent.com/in/946600?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Copilot",
"html_url": "https://github.com/apps/copilot-pull-request-reviewer",
"followers_url": "https://api.github.com/users/Copilot/followers",
"following_url": "https://api.github.com/users/Copilot/following{/other_user}",
"gists_url": "https://api.github.com/users/Copilot/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Copilot/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Copilot/subscriptions",
"organizations_url": "https://api.github.com/users/Copilot/orgs",
"repos_url": "https://api.github.com/users/Copilot/repos",
"events_url": "https://api.github.com/users/Copilot/events{/privacy}",
"received_events_url": "https://api.github.com/users/Copilot/received_events",
"type": "Bot",
"user_view_type": "public",
"site_admin": false
},
"installation": {
"id": 131074261,
"node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMTMxMDc0MjYx"
}
}