Skip to content

feat(cloudflare): DNS-as-code + reusable Pages deploy for 6 org zones - #362

Merged
seonghobae merged 10 commits into
mainfrom
feat/cloudflare-dns-pages
Jul 10, 2026
Merged

feat(cloudflare): DNS-as-code + reusable Pages deploy for 6 org zones#362
seonghobae merged 10 commits into
mainfrom
feat/cloudflare-dns-pages

Conversation

@seonghobae

@seonghobaeseonghobae commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

What

Declarative Cloudflare DNS + Pages as infrastructure-as-code for the org, using curl + jq (no Terraform for 6 zones). Everything that touches the Cloudflare API runs inside GitHub Actions with the org secrets CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID — the token is never committed and never leaves Actions.

Files

  • infra/cloudflare/zones.json — declarative 6 zones + records (data-driven; records empty until Pages targets exist).
  • infra/cloudflare/reconcile.sh — idempotent reconciler: ensure zone exists (POST /zones in apply mode), upsert records (no destructive delete unless prune=true), print each zone's Cloudflare nameservers + status.
  • .github/workflows/cloudflare-dns.yml — runs the reconciler. Dry-run by default; apply is an explicit workflow_dispatch input. Auto dry-run on same-repo PRs / pushes touching the config.
  • .github/workflows/deploy-pages.ymlreusable (workflow_call) Cloudflare Pages deploy via wrangler + idempotent custom-domain attach. Callers use secrets: inherit.
  • infra/cloudflare/README.md — the model, the one-time Namecheap nameserver step, how to add records / attach domains.

Domain ↔ product map

DomainProduct repo
keyverse.iocwl-idp (Keyverse)
wardnet.iowaf-ids-ai-soc (Wardnet)
inkspan.iocwl-editor (Inkspan)
cloud-erd.apppg-erd-cloud
naruon.netnaruon
naruon.ionaruon

Nameservers / zone status

Pending — GitHub Actions runners are saturated. The dry-run was triggered twice on this branch (a pull_request auto-run and an explicit workflow_dispatch), but all ~37 recent Actions runs in this repo are queued with 0 in_progress — the org's runners are not picking up any jobs (Actions spending cap or an org-wide runner halt; not specific to this PR). The nameserver/status capture below will be filled in as soon as a runner frees up.

To capture the nameservers once a runner is available:

# find the latest Cloudflare DNS run and read its log
gh run list --workflow=cloudflare-dns.yml --limit 1
gh run view <run-id> --log | grep '^NAMESERVERS|'

Each NAMESERVERS|<domain>|<status>|<ns1, ns2> line (also rendered as a table in the run's job summary) tells you exactly which two Cloudflare nameservers to set at Namecheap for each domain. Zones that do not exist yet report not created (dry-run); running the workflow in apply mode (mode = apply) creates them via POST /zones and then reports their assigned nameservers.

DomainZone statusCloudflare nameservers
keyverse.iopending runcaptured on first successful run
wardnet.iopending runcaptured on first successful run
inkspan.iopending runcaptured on first successful run
cloud-erd.apppending runcaptured on first successful run
naruon.netpending runcaptured on first successful run
naruon.iopending runcaptured on first successful run

How to use

  • Create zones + get nameservers: run Actions → Cloudflare DNS → Run workflow → mode = apply. It creates missing zones and prints the two assigned Cloudflare nameservers per domain.
  • Point Namecheap → Cloudflare: set those nameservers as Custom DNS at Namecheap (one-time). Zone flips pending → active.
  • Deploy a product site: call deploy-pages.yml from the product repo with secrets: inherit.

Do not merge yet — this is for review + capturing nameservers.

🤖 Generated with Claude Code

…ones
Declarative Cloudflare DNS and Pages hosting for the org, curl+jq (no Terraform):
- infra/cloudflare/zones.json: 6 zones (keyverse.io, wardnet.io, inkspan.io,
cloud-erd.app, naruon.net, naruon.io) mapped to product repos; data-driven,
records start empty until Pages targets exist.
- infra/cloudflare/reconcile.sh: idempotent reconciler — ensures each zone
exists (POST /zones in apply mode), upserts records (no destructive delete
unless prune=true), prints each zone's Cloudflare nameservers + status.
- .github/workflows/cloudflare-dns.yml: runs the reconciler with org secrets
CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID. Dry-run by default; apply is an
explicit input. Auto dry-run on same-repo PRs and pushes touching the config.
- .github/workflows/deploy-pages.yml: reusable (workflow_call) Cloudflare Pages
deploy via wrangler + idempotent custom-domain attach; callers use
secrets: inherit.
- infra/cloudflare/README.md: the model (Cloudflare = DNS + Pages host),
the one-time Namecheap nameserver step, and how to add records / attach domains.
No secrets committed; the token only ever runs inside GitHub Actions.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RTAMs4bpSZS77Xe3RQjv9P
Comment thread.github/workflows/cloudflare-dns.yml Fixed
Comment thread.github/workflows/deploy-pages.yml Fixed
Comment thread.github/workflows/deploy-pages.yml Fixed
seonghobaeand others added 7 commits July 8, 2026 21:52
Resolve 3 code-scanning Pinned-Dependencies alerts (#74, #75, #76):
pin actions/checkout and cloudflare/wrangler-action by full commit SHA
with a version comment, matching the org convention.
- actions/checkout@v4 -> @9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- cloudflare/wrangler-action@v3 -> @9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RTAMs4bpSZS77Xe3RQjv9P
@opencode-agent

opencode-agentBot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: 95747957e2f182c447ae44952e9ed1b5093b10f3
  • Workflow run: 29085579508
  • Workflow attempt: 1
  • Gate result: APPROVE (approval step)

Pull request overview

OpenCode reviewed the current-head bounded evidence and found no blocking issues.

Findings

No blocking findings.

Summary

Approval sufficiency: bounded evidence supplied affirmative approval evidence for changed files, coverage/docstring posture, risk surfaces, and current-head verification; approval is not based merely on the absence of known blockers.
Verification posture: CodeGraph evidence was initialized and bounded current-head evidence reviewed for changed-file evidence including .github/workflows/cloudflare-dns.yml, .github/workflows/deploy-pages.yml, infra/cloudflare/README.md, infra/cloudflare/reconcile.sh, infra/cloudflare/zones.json.
Linter/static: workflow/static review evidence is bounded by the current-head GitHub Checks gate and changed-file evidence.
TDD/regression: coverage execution evidence and focused changed hunks were reviewed from bounded-review-evidence.md.
Coverage: coverage execution evidence reports test coverage as not applicable because no supported changed source files or package manifests were found.
Docstring coverage: coverage execution evidence reports docstring coverage as not applicable because no supported changed source files or package manifests were found.
DAG: CodeGraph/source-backed behavior map connects .github/workflows/cloudflare-dns.yml to the affected review, runtime, or workflow path and required checks.
PoC/execution: coverage-evidence job executed on the current head and reported PASS.
DDD/domain: workflow and repository-governance invariants were reviewed against changed files in bounded evidence.
CDD/context: CodeGraph evidence, changed-file history, and focused hunks were reviewed from bounded-review-evidence.md.
Similar issues: changed-file history evidence was reviewed for comparable local precedents.
Claim/concept check: bounded evidence, repository source, current-head workflow evidence, and, where numeric, scientific, statistical, or literature-backed claims are affected, original-paper/formula evidence and parameter-recovery expectations were used for claims.
Standards search: standards and external-source checks are delegated to configured OpenCode web_search/Context7/DeepWiki sources when applicable; no evidence-backed standards blocker is present in bounded evidence.
Compatibility/convention: changed workflow/script conventions, object naming, and reserved-word safety for schema/API/config/code surfaces were checked in bounded evidence.
Breaking-change/backcompat: deployment evidence and changed-file history were checked for backward-compatibility risk.
Performance: changed surfaces were checked for performance risk in bounded evidence.
Developer experience: changed automation, review, test, setup, and maintenance surfaces were checked for helpful or obstructive DX impact in bounded evidence.
User experience: connected user, operator, API, CLI, documentation, review-comment, status-check, rendering, and workflow-reader behavior was checked for contradictions against code, docs, and tests in bounded evidence.
Visual/DOM: Playwright visual, DOM locator, ARIA snapshot, console, and responsive evidence were checked when a web UI surface was present; for non-web surfaces, API/CLI/log/docs/workflow interaction evidence was reviewed instead.
Accessibility/i18n: accessibility, localization, and human-readable text surfaces were checked where UI, CLI, API message, docs, logs, or review text changed.
Supply-chain/license: dependency, package, model, container, and external-tool changes were checked in bounded evidence.
Packaging: package, build, test, lint, and security contracts were checked in bounded evidence.
Security/privacy: workflow-token, review-gate, and repository-automation security/privacy boundaries were checked in bounded evidence.

  • Result: APPROVE
  • Reason: No blocking issues found in the current-head bounded evidence.
  • Head SHA: 95747957e2f182c447ae44952e9ed1b5093b10f3
  • Workflow run: 29085579508
  • Workflow attempt: 1

Changed-File Evidence Map

flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Workflow (2 files)"]
S1 --> I1["GitHub Actions review job"]
I1 --> R1["Review risk: Workflow (2 files)"]
R1 --> V1["actionlint plus required checks"]
Evidence --> S2["Changed file (3 files)"]
S2 --> I2["repository behavior"]
I2 --> R2["Review risk: Changed file (3 files)"]
R2 --> V2["required checks"]
Loading

@opencode-agentopencode-agentBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode reviewed the current-head bounded evidence and found no blocking issues.

Findings

No blocking findings.

Summary

Approval sufficiency: bounded evidence supplied affirmative approval evidence for changed files, coverage/docstring posture, risk surfaces, and current-head verification; approval is not based merely on the absence of known blockers.
Verification posture: CodeGraph evidence was initialized and bounded current-head evidence reviewed for changed-file evidence including .github/workflows/cloudflare-dns.yml, .github/workflows/deploy-pages.yml, infra/cloudflare/README.md, infra/cloudflare/reconcile.sh, infra/cloudflare/zones.json.
Linter/static: workflow/static review evidence is bounded by the current-head GitHub Checks gate and changed-file evidence.
TDD/regression: coverage execution evidence and focused changed hunks were reviewed from bounded-review-evidence.md.
Coverage: coverage execution evidence reports test coverage as not applicable because no supported changed source files or package manifests were found.
Docstring coverage: coverage execution evidence reports docstring coverage as not applicable because no supported changed source files or package manifests were found.
DAG: CodeGraph/source-backed behavior map connects .github/workflows/cloudflare-dns.yml to the affected review, runtime, or workflow path and required checks.
PoC/execution: coverage-evidence job executed on the current head and reported PASS.
DDD/domain: workflow and repository-governance invariants were reviewed against changed files in bounded evidence.
CDD/context: CodeGraph evidence, changed-file history, and focused hunks were reviewed from bounded-review-evidence.md.
Similar issues: changed-file history evidence was reviewed for comparable local precedents.
Claim/concept check: bounded evidence, repository source, current-head workflow evidence, and, where numeric, scientific, statistical, or literature-backed claims are affected, original-paper/formula evidence and parameter-recovery expectations were used for claims.
Standards search: standards and external-source checks are delegated to configured OpenCode web_search/Context7/DeepWiki sources when applicable; no evidence-backed standards blocker is present in bounded evidence.
Compatibility/convention: changed workflow/script conventions, object naming, and reserved-word safety for schema/API/config/code surfaces were checked in bounded evidence.
Breaking-change/backcompat: deployment evidence and changed-file history were checked for backward-compatibility risk.
Performance: changed surfaces were checked for performance risk in bounded evidence.
Developer experience: changed automation, review, test, setup, and maintenance surfaces were checked for helpful or obstructive DX impact in bounded evidence.
User experience: connected user, operator, API, CLI, documentation, review-comment, status-check, rendering, and workflow-reader behavior was checked for contradictions against code, docs, and tests in bounded evidence.
Visual/DOM: Playwright visual, DOM locator, ARIA snapshot, console, and responsive evidence were checked when a web UI surface was present; for non-web surfaces, API/CLI/log/docs/workflow interaction evidence was reviewed instead.
Accessibility/i18n: accessibility, localization, and human-readable text surfaces were checked where UI, CLI, API message, docs, logs, or review text changed.
Supply-chain/license: dependency, package, model, container, and external-tool changes were checked in bounded evidence.
Packaging: package, build, test, lint, and security contracts were checked in bounded evidence.
Security/privacy: workflow-token, review-gate, and repository-automation security/privacy boundaries were checked in bounded evidence.

  • Result: APPROVE
  • Reason: New Cloudflare DNS and Pages workflows are well-documented and secure.
  • Head SHA: 7b8879182c811e8a73dd088fa5bffd98a98a1069
  • Workflow run: 29080948110
  • Workflow attempt: 1

Changed-File Evidence Map

flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Workflow (2 files)"]
S1 --> I1["GitHub Actions review job"]
I1 --> R1["Review risk: Workflow (2 files)"]
R1 --> V1["actionlint plus required checks"]
Evidence --> S2["Changed file (3 files)"]
S2 --> I2["repository behavior"]
I2 --> R2["Review risk: Changed file (3 files)"]
R2 --> V2["required checks"]
Loading

@seonghobae
seonghobae enabled auto-merge (squash) July 10, 2026 09:00

@opencode-agentopencode-agentBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode reviewed the current-head bounded evidence and found no blocking issues.

Findings

No blocking findings.

Summary

Approval sufficiency: bounded evidence supplied affirmative approval evidence for changed files, coverage/docstring posture, risk surfaces, and current-head verification; approval is not based merely on the absence of known blockers.
Verification posture: CodeGraph evidence was initialized and bounded current-head evidence reviewed for changed-file evidence including .github/workflows/cloudflare-dns.yml, .github/workflows/deploy-pages.yml, infra/cloudflare/README.md, infra/cloudflare/reconcile.sh, infra/cloudflare/zones.json.
Linter/static: workflow/static review evidence is bounded by the current-head GitHub Checks gate and changed-file evidence.
TDD/regression: coverage execution evidence and focused changed hunks were reviewed from bounded-review-evidence.md.
Coverage: coverage execution evidence reports test coverage as not applicable because no supported changed source files or package manifests were found.
Docstring coverage: coverage execution evidence reports docstring coverage as not applicable because no supported changed source files or package manifests were found.
DAG: CodeGraph/source-backed behavior map connects .github/workflows/cloudflare-dns.yml to the affected review, runtime, or workflow path and required checks.
PoC/execution: coverage-evidence job executed on the current head and reported PASS.
DDD/domain: workflow and repository-governance invariants were reviewed against changed files in bounded evidence.
CDD/context: CodeGraph evidence, changed-file history, and focused hunks were reviewed from bounded-review-evidence.md.
Similar issues: changed-file history evidence was reviewed for comparable local precedents.
Claim/concept check: bounded evidence, repository source, current-head workflow evidence, and, where numeric, scientific, statistical, or literature-backed claims are affected, original-paper/formula evidence and parameter-recovery expectations were used for claims.
Standards search: standards and external-source checks are delegated to configured OpenCode web_search/Context7/DeepWiki sources when applicable; no evidence-backed standards blocker is present in bounded evidence.
Compatibility/convention: changed workflow/script conventions, object naming, and reserved-word safety for schema/API/config/code surfaces were checked in bounded evidence.
Breaking-change/backcompat: deployment evidence and changed-file history were checked for backward-compatibility risk.
Performance: changed surfaces were checked for performance risk in bounded evidence.
Developer experience: changed automation, review, test, setup, and maintenance surfaces were checked for helpful or obstructive DX impact in bounded evidence.
User experience: connected user, operator, API, CLI, documentation, review-comment, status-check, rendering, and workflow-reader behavior was checked for contradictions against code, docs, and tests in bounded evidence.
Visual/DOM: Playwright visual, DOM locator, ARIA snapshot, console, and responsive evidence were checked when a web UI surface was present; for non-web surfaces, API/CLI/log/docs/workflow interaction evidence was reviewed instead.
Accessibility/i18n: accessibility, localization, and human-readable text surfaces were checked where UI, CLI, API message, docs, logs, or review text changed.
Supply-chain/license: dependency, package, model, container, and external-tool changes were checked in bounded evidence.
Packaging: package, build, test, lint, and security contracts were checked in bounded evidence.
Security/privacy: workflow-token, review-gate, and repository-automation security/privacy boundaries were checked in bounded evidence.

  • Result: APPROVE
  • Reason: No blocking issues found in the current-head evidence
  • Head SHA: 8a867263c2cd0a2f362863de1105d7fb2ade1758
  • Workflow run: 29081902503
  • Workflow attempt: 1

Changed-File Evidence Map

flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Workflow (2 files)"]
S1 --> I1["GitHub Actions review job"]
I1 --> R1["Review risk: Workflow (2 files)"]
R1 --> V1["actionlint plus required checks"]
Evidence --> S2["Changed file (3 files)"]
S2 --> I2["repository behavior"]
I2 --> R2["Review risk: Changed file (3 files)"]
R2 --> V2["required checks"]
Loading

@opencode-agentopencode-agentBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode reviewed the current-head bounded evidence and found no blocking issues.

Findings

No blocking findings.

Summary

Approval sufficiency: bounded evidence supplied affirmative approval evidence for changed files, coverage/docstring posture, risk surfaces, and current-head verification; approval is not based merely on the absence of known blockers.
Verification posture: CodeGraph evidence was initialized and bounded current-head evidence reviewed for changed-file evidence including .github/workflows/cloudflare-dns.yml, .github/workflows/deploy-pages.yml, infra/cloudflare/README.md, infra/cloudflare/reconcile.sh, infra/cloudflare/zones.json.
Linter/static: workflow/static review evidence is bounded by the current-head GitHub Checks gate and changed-file evidence.
TDD/regression: coverage execution evidence and focused changed hunks were reviewed from bounded-review-evidence.md.
Coverage: coverage execution evidence reports test coverage as not applicable because no supported changed source files or package manifests were found.
Docstring coverage: coverage execution evidence reports docstring coverage as not applicable because no supported changed source files or package manifests were found.
DAG: CodeGraph/source-backed behavior map connects .github/workflows/cloudflare-dns.yml to the affected review, runtime, or workflow path and required checks.
PoC/execution: coverage-evidence job executed on the current head and reported PASS.
DDD/domain: workflow and repository-governance invariants were reviewed against changed files in bounded evidence.
CDD/context: CodeGraph evidence, changed-file history, and focused hunks were reviewed from bounded-review-evidence.md.
Similar issues: changed-file history evidence was reviewed for comparable local precedents.
Claim/concept check: bounded evidence, repository source, current-head workflow evidence, and, where numeric, scientific, statistical, or literature-backed claims are affected, original-paper/formula evidence and parameter-recovery expectations were used for claims.
Standards search: standards and external-source checks are delegated to configured OpenCode web_search/Context7/DeepWiki sources when applicable; no evidence-backed standards blocker is present in bounded evidence.
Compatibility/convention: changed workflow/script conventions, object naming, and reserved-word safety for schema/API/config/code surfaces were checked in bounded evidence.
Breaking-change/backcompat: deployment evidence and changed-file history were checked for backward-compatibility risk.
Performance: changed surfaces were checked for performance risk in bounded evidence.
Developer experience: changed automation, review, test, setup, and maintenance surfaces were checked for helpful or obstructive DX impact in bounded evidence.
User experience: connected user, operator, API, CLI, documentation, review-comment, status-check, rendering, and workflow-reader behavior was checked for contradictions against code, docs, and tests in bounded evidence.
Visual/DOM: Playwright visual, DOM locator, ARIA snapshot, console, and responsive evidence were checked when a web UI surface was present; for non-web surfaces, API/CLI/log/docs/workflow interaction evidence was reviewed instead.
Accessibility/i18n: accessibility, localization, and human-readable text surfaces were checked where UI, CLI, API message, docs, logs, or review text changed.
Supply-chain/license: dependency, package, model, container, and external-tool changes were checked in bounded evidence.
Packaging: package, build, test, lint, and security contracts were checked in bounded evidence.
Security/privacy: workflow-token, review-gate, and repository-automation security/privacy boundaries were checked in bounded evidence.

  • Result: APPROVE
  • Reason: No blocking issues found in the current-head bounded evidence.
  • Head SHA: 95747957e2f182c447ae44952e9ed1b5093b10f3
  • Workflow run: 29085579508
  • Workflow attempt: 1

Changed-File Evidence Map

flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Workflow (2 files)"]
S1 --> I1["GitHub Actions review job"]
I1 --> R1["Review risk: Workflow (2 files)"]
R1 --> V1["actionlint plus required checks"]
Evidence --> S2["Changed file (3 files)"]
S2 --> I2["repository behavior"]
I2 --> R2["Review risk: Changed file (3 files)"]
R2 --> V2["required checks"]
Loading

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants

@seonghobae@github-advanced-security