Skip to content

feat(ci): push-to-main deploy via self-hosted ARC runner - #1

Merged
dustfeather merged 3 commits into
mainfrom
feat/github-actions-deploy
May 25, 2026
Merged

feat(ci): push-to-main deploy via self-hosted ARC runner#1
dustfeather merged 3 commits into
mainfrom
feat/github-actions-deploy

Conversation

@dustfeather

Copy link
Copy Markdown
Member

Summary

  • Push to main now triggers .github/workflows/deploy.yml on the in-cluster ARC scale set arc-itguys-ro-nextcloud (asus-pinned).
  • Runner pod auth = own SA bound to namespaced Roles only (nextcloud-deployer in ns nextcloud, cf-token-writer in ns cert-manager narrowed to resourceNames: [cloudflare-api-token]). RBAC at manifests/bootstrap/11-ci-deployer-rbac.yaml.
  • Path-filtered jobs: secrets always; manifests if manifests/*.yaml changed; helm if helm/** changed. workflow_dispatch reconcile_all=true forces full reconcile.
  • manifests/60-nginx-tls-proxy.yaml explicitly excluded from CI — live proxy is shared :443 for headlamp/degoog/searxng/degoog-mcp with extra vhosts + /tls-warp cert mount not in repo.
  • 8 GitHub Actions Secrets render into 5 k8s Secrets at apply time (no plaintext in git).
  • Bootstrap manifests (namespace, ClusterIssuer, deployer RBAC) split into manifests/bootstrap/; not CI-applied.

Design doc: docs/superpowers/specs/2026-05-25-nextcloud-ci-deployment-design.md.

Test plan

  • Pre-flight kubectl diff -f manifests/* clean (only nginx-tls-proxy drifted; resolved by exclusion).
  • ARC scale set arc-itguys-ro-nextcloud installed, listener pod Running.
  • RBAC bootstrap applied; kubectl auth can-i smoke tests pass for the runner SA.
  • All 8 GH Actions Secrets populated.
  • PR check (pr-checks.yml) green.
  • After rebase-merge: deploy.yml no-op against live (helm release moves to next revision but resources unchanged; manifests are already current).

Replace manual `helm upgrade` / `kubectl apply` loop with GitHub Actions
running on in-cluster ARC scale set `arc-itguys-ro-nextcloud`. Push to
main triggers path-filtered jobs: secrets always; manifests if
`manifests/*.yaml` changed; helm if `helm/**` changed. PRs run server-side
dry-run via `pr-checks.yml`.

Runner pod auth = its own SA bound to Role `nextcloud-deployer` (ns
nextcloud, broad CRUD) and Role `cf-token-writer` (ns cert-manager,
narrow update of Secret `cloudflare-api-token` only). 5 k8s Secrets
rendered at apply time from 8 GitHub Actions Secrets.

`manifests/60-nginx-tls-proxy.yaml` is excluded from the CI path filter:
the live proxy is a shared :443 ingress that also fronts headlamp /
degoog / searxng / degoog-mcp with vhosts and a /tls-warp cert mount
not declared in this repo. Repo copy retained as historical baseline
with a DO-NOT-APPLY header.

Bootstrap manifests (namespace, ClusterIssuer, deployer RBAC) split
into `manifests/bootstrap/`; cluster-admin applies once.

Design: docs/superpowers/specs/2026-05-25-nextcloud-ci-deployment-design.md
kubectl apply --dry-run=server defaulted to the runner pod's
namespace (arc-runners) where the deployer SA has no rights,
failing with 'forbidden: cannot get resource services in
namespace arc-runners'. Pass -n nextcloud explicitly.
The fallback called /api/v1/namespaces/nextcloud which needs
cluster-scoped 'namespaces get' that the deployer SA lacks
(intentionally — Role is ns-scoped only). Rely on auth can-i
SelfSubjectAccessReview which needs no RBAC.
@dustfeather
dustfeather merged commit 567378d into main May 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant