From be46b6c42ddcbd71a59a06eff7cc908d6bf974b2 Mon Sep 17 00:00:00 2001 From: Charles Sibbald Date: Sat, 18 Jul 2026 15:14:32 +0300 Subject: [PATCH 1/9] ci: consume the reusable Octopilot pipeline (meta workflow) Collapse the generic build DAG (detect/lint/test/integration-validate/ integration-artifacts) to a call of octopilot/actions/.github/workflows/ pipeline.yml@main; keep the app-specific integration-deploy + release jobs locally, consuming the reusable build's integration-* artifacts. The nested DAG visualization is preserved. --- .github/workflows/octopilot-ci.yml | 123 ++++------------------------- 1 file changed, 15 insertions(+), 108 deletions(-) diff --git a/.github/workflows/octopilot-ci.yml b/.github/workflows/octopilot-ci.yml index 882ea49..d7b5aa5 100644 --- a/.github/workflows/octopilot-ci.yml +++ b/.github/workflows/octopilot-ci.yml @@ -1,10 +1,9 @@ name: Octopilot CI -# Octopilot-driven pipeline. The application "shape" is auto-detected from -# skaffold.yaml (source of truth): 3 container services (api/dnsd/edgehub) via -# the octopilot/rust buildpack, plus the fleetingdns Helm chart. CLI tools -# (edf-cli, fleetingdns-ctl, slot-setter) are NOT containers — they ship as -# GitHub Release binaries via the release-binaries job on tags. +# The generic build DAG (detect → lint → test → integration-validate → +# integration-artifacts) comes from the shared reusable pipeline in +# octopilot/actions — this repo only declares its app-specific deploy + release. +# Adopting the build DAG in a new repo is just the `build` job below. on: push: @@ -14,106 +13,18 @@ on: branches: [main] workflow_dispatch: -env: - CARGO_TERM_COLOR: always - RUST_BACKTRACE: 1 - jobs: - # ── 1. Auto-detect languages and versions from skaffold.yaml ─────────────── - detect: - name: Detect Contexts - runs-on: ubuntu-latest - outputs: - pipeline-context: ${{ steps.detect.outputs.pipeline-context }} - steps: - - uses: actions/checkout@v4 - - name: Detect Contexts - id: detect - uses: octopilot/actions/detect-contexts@main - - # ── 2. Lint (pre-commit, language-aware) ─────────────────────────────────── - lint: - needs: detect - if: toJSON(fromJson(needs.detect.outputs.pipeline-context).languages) != '[]' - name: Lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: octopilot/actions/lint@main - with: - pipeline-context: ${{ needs.detect.outputs.pipeline-context }} - - # ── 3. Test (matrix per detected language context) ───────────────────────── - test: - needs: detect - if: toJSON(fromJson(needs.detect.outputs.pipeline-context).matrix) != '[]' - name: Test - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.detect.outputs.pipeline-context).matrix }} - steps: - - uses: actions/checkout@v4 - - uses: octopilot/actions/test@main - with: - pipeline-context: ${{ toJson(matrix) }} - - # ── 4a. Integration validate (release build + UUID for ttl.sh artifacts) ─── - integration-validate: - name: Integration (validate) - needs: [detect, lint, test] - runs-on: ubuntu-latest - outputs: - uuid: ${{ steps.validate.outputs.uuid }} - steps: - - uses: actions/checkout@v4 - - name: Validate primary build and generate UUID - id: validate - uses: octopilot/actions/integration-validate@main - with: - pipeline-context: ${{ needs.detect.outputs.pipeline-context }} - # Smoke run omitted: the primary artifacts are long-running servers - # (they block waiting on Redis/Postgres), so a no-arg smoke would hang. - # The release build itself is the compile gate. - - # ── 4b. Integration artifacts (matrix from skaffold build.artifacts + chart) ─ - integration-artifacts: - name: Integration (${{ matrix.suffix || matrix.output_key }}) - needs: [detect, integration-validate] - if: toJSON(fromJson(needs.detect.outputs.pipeline-context).integration_matrix) != '[]' - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.detect.outputs.pipeline-context).integration_matrix }} - steps: - - uses: actions/checkout@v4 - - - name: Build and push artifact - id: build - uses: octopilot/actions/integration-build-artifact@main - with: - artifact: ${{ toJson(matrix) }} - ttl-uuid: ${{ needs.integration-validate.outputs.uuid }} - op_version: v1.0.17 - - - name: Upload artifact outputs - run: | - mkdir -p artifact-out - mv outputs.txt "artifact-out/${{ matrix.output_key }}.txt" 2>/dev/null || true - [ -f build_result.json ] && cp build_result.json artifact-out/ || true - - - uses: actions/upload-artifact@v4 - with: - name: integration-${{ matrix.output_key }} - path: artifact-out - retention-days: 1 - - # ── 4c. Integration deploy (Kind + SOPS secret + ci-deps + Flux HelmRelease) ─ + # ── Generic Octopilot build DAG (reusable; renders nested in the graph) ───── + build: + uses: octopilot/actions/.github/workflows/pipeline.yml@main + secrets: inherit + + # ── Integration deploy (Kind + SOPS secret + ci-deps + Flux HelmRelease) ──── + # App-specific: consumes the integration-* artifacts the reusable build + # uploaded (build_result.json) and stands the stack up in Kind. integration-deploy: name: Integration (deploy) - needs: integration-artifacts + needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -258,11 +169,7 @@ jobs: exit 1 fi - # ── 5. Release binaries (CLI tools → GitHub Release; tags only) ───────────── - # Octopilot has no first-class "release binary" concept — it treats every - # skaffold artifact as a container. The CLIs (edf-cli, fleetingdns-ctl, - # slot-setter) are deliberately excluded from skaffold.yaml and shipped here - # as attached release assets alongside the container images. + # ── Release binaries (CLI tools → GitHub Release; tags only) ──────────────── release-binaries: name: Release CLI Binaries needs: [integration-deploy] @@ -294,7 +201,7 @@ jobs: dist/*.tar.gz dist/SHA256SUMS.txt - # ── 6. Release notes (on tag: generate and publish to GitHub Release) ────── + # ── Release notes (on tag: generate and publish to GitHub Release) ────────── release-notes: name: Release Notes needs: [integration-deploy] From a231f054122831e4f07398dfcef2c54e1fb7d542 Mon Sep 17 00:00:00 2001 From: Charles Sibbald Date: Sat, 18 Jul 2026 15:20:48 +0300 Subject: [PATCH 2/9] ci: brand the reusable build node as 'Octopilot' in the DAG Set the caller job's display name so nested jobs render 'Octopilot / Detect Contexts', 'Octopilot / Test', etc. instead of 'build / ...'. --- .github/workflows/octopilot-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/octopilot-ci.yml b/.github/workflows/octopilot-ci.yml index d7b5aa5..26ff800 100644 --- a/.github/workflows/octopilot-ci.yml +++ b/.github/workflows/octopilot-ci.yml @@ -15,7 +15,10 @@ on: jobs: # ── Generic Octopilot build DAG (reusable; renders nested in the graph) ───── + # The job's display name becomes the prefix on every nested job in the graph, + # so they read "Octopilot / Detect Contexts", "Octopilot / Test", etc. build: + name: Octopilot uses: octopilot/actions/.github/workflows/pipeline.yml@main secrets: inherit From 6342a84a81608cd6743cdb9de9317077ed0586b3 Mon Sep 17 00:00:00 2001 From: Charles Sibbald Date: Sat, 18 Jul 2026 15:48:32 +0300 Subject: [PATCH 3/9] ci: adopt generic integration deploy (integration: true) Drop the repo-specific integration-deploy job; the reusable pipeline now runs it generically when integration: true. HelmRelease consumes the generic IMG_fleetingdns_{api,dnsd,edgehub} image vars the meta injects. --- .github/workflows/octopilot-ci.yml | 170 ++--------------------------- k8s/deployment/helmrelease.yaml | 8 +- 2 files changed, 16 insertions(+), 162 deletions(-) diff --git a/.github/workflows/octopilot-ci.yml b/.github/workflows/octopilot-ci.yml index 26ff800..3062f26 100644 --- a/.github/workflows/octopilot-ci.yml +++ b/.github/workflows/octopilot-ci.yml @@ -1,9 +1,11 @@ name: Octopilot CI -# The generic build DAG (detect → lint → test → integration-validate → -# integration-artifacts) comes from the shared reusable pipeline in -# octopilot/actions — this repo only declares its app-specific deploy + release. -# Adopting the build DAG in a new repo is just the `build` job below. +# The entire build + integration DAG (detect → lint → test → validate → +# artifacts → deploy) comes from the shared reusable pipeline in +# octopilot/actions. integration: true opts in to the generic Kind + Flux +# deploy, which discovers this repo's shape from its chart/, k8s/env/ci overlay, +# hack/ci-deps and deployment-configuration SOPS profile. This repo only adds +# its tag-time release jobs. on: push: @@ -14,168 +16,18 @@ on: workflow_dispatch: jobs: - # ── Generic Octopilot build DAG (reusable; renders nested in the graph) ───── - # The job's display name becomes the prefix on every nested job in the graph, - # so they read "Octopilot / Detect Contexts", "Octopilot / Test", etc. + # ── Generic Octopilot pipeline (reusable; nested + branded in the graph) ──── build: name: Octopilot uses: octopilot/actions/.github/workflows/pipeline.yml@main + with: + integration: true secrets: inherit - # ── Integration deploy (Kind + SOPS secret + ci-deps + Flux HelmRelease) ──── - # App-specific: consumes the integration-* artifacts the reusable build - # uploaded (build_result.json) and stands the stack up in Kind. - integration-deploy: - name: Integration (deploy) - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Download artifact outputs - uses: actions/download-artifact@v4 - with: - pattern: integration-* - path: artifact-outputs - - - name: Merge build_result.json from all integration jobs - uses: octopilot/actions/merge-build-results@main - with: - directory: artifact-outputs - output-path: build_result.json - - - name: Resolve deploy image refs - id: artifacts - run: | - set -e - IMAGE_API="$(jq -r '.builds[] | select(.imageName | test("fleetingdns-api$")) | .tag' build_result.json 2>/dev/null | head -1)" - IMAGE_DNSD="$(jq -r '.builds[] | select(.imageName | test("fleetingdns-dnsd$")) | .tag' build_result.json 2>/dev/null | head -1)" - IMAGE_EDGEHUB="$(jq -r '.builds[] | select(.imageName | test("fleetingdns-edgehub$")) | .tag' build_result.json 2>/dev/null | head -1)" - IMAGE_CHART="$(jq -r '.builds[] | select(.imageName | test("-chart$")) | .tag' build_result.json 2>/dev/null | head -1)" - - # Chart ref must be Helm OCI shape: registry/repo/chartname:version[@digest]. - CHART_NAME="$(grep -E '^name:' chart/fleetingdns/Chart.yaml 2>/dev/null | sed 's/^name:[[:space:]]*//;s/[[:space:]]*$//' || echo fleetingdns)" - if ! echo "$IMAGE_CHART" | grep -qE "/${CHART_NAME}:"; then - if echo "$IMAGE_CHART" | grep -qE -- '-chart:[^@]+'; then - IMAGE_CHART="$(echo "$IMAGE_CHART" | sed "s|-chart:|-chart/${CHART_NAME}:|")" - echo "Normalized chart ref to Helm OCI form: ${IMAGE_CHART}" - else - echo "::error::Chart ref missing chart name segment: expected .../${CHART_NAME}:version[@digest], got: ${IMAGE_CHART}" - exit 1 - fi - fi - if echo "$IMAGE_CHART" | grep -q '@sha256:'; then - CHART_REF="oci://$(echo "$IMAGE_CHART" | sed 's/:[^@]*@/@/')" - else - CHART_REF="oci://${IMAGE_CHART}" - fi - - echo "api_image=${IMAGE_API}" >> "$GITHUB_OUTPUT" - echo "dnsd_image=${IMAGE_DNSD}" >> "$GITHUB_OUTPUT" - echo "edgehub_image=${IMAGE_EDGEHUB}" >> "$GITHUB_OUTPUT" - echo "chart_ref=${CHART_REF}" >> "$GITHUB_OUTPUT" - - echo "=== build_result.json (merged) ===" - jq . build_result.json - echo "=== Resolved deploy outputs ===" - echo "api=${IMAGE_API}" - echo "dnsd=${IMAGE_DNSD}" - echo "edgehub=${IMAGE_EDGEHUB}" - echo "chart_ref=${CHART_REF}" - if [ -z "$IMAGE_API" ] || [ -z "$IMAGE_DNSD" ] || [ -z "$IMAGE_EDGEHUB" ] || [ -z "$IMAGE_CHART" ]; then - echo "::error::Missing builds: api=${IMAGE_API:+set} dnsd=${IMAGE_DNSD:+set} edgehub=${IMAGE_EDGEHUB:+set} chart=${IMAGE_CHART:+set}" - jq -r '.builds[]? | "\(.imageName): \(.tag)"' build_result.json 2>/dev/null || true - exit 1 - fi - - - name: Decrypt runtime DB secret (SOPS + age) - id: sops - uses: octopilot/actions/sops-decrypt@main - with: - file: deployment-configuration/profiles/dev/fleetingdns/core/runtime/application.secrets.env - age_key: ${{ secrets.SOPS_AGE_KEY }} - output_type: dotenv - - - name: Create Kind cluster (Kubernetes 1.34.3) - uses: helm/kind-action@v1 - with: - version: v0.31.0 - node_image: kindest/node:v1.34.3 - cluster_name: fleetingdns - wait: 120s - - - name: Setup kubectl - uses: octopilot/actions/setup-tools@main - with: - kubectl_version: "1.34.3" - - - name: Create namespace, DB secret and ephemeral deps (redis + postgres) - env: - SECRET_DOTENV: ${{ steps.sops.outputs.data }} - run: | - set -e - kubectl create namespace fleetingdns --dry-run=client -o yaml | kubectl apply -f - - # DB credentials Secret consumed by the api (keys: FDNS_DB_PASSWORD, DATABASE_URL) - printf '%s\n' "$SECRET_DOTENV" > /tmp/db.env - kubectl create secret generic fleetingdns-db-credentials \ - -n fleetingdns --from-env-file=/tmp/db.env \ - --dry-run=client -o yaml | kubectl apply -f - - rm -f /tmp/db.env - kubectl apply -n fleetingdns -f hack/ci-deps/ - kubectl rollout status deploy/postgres -n fleetingdns --timeout=180s - kubectl rollout status deploy/redis -n fleetingdns --timeout=120s - - - name: Setup Flux in Kind - uses: octopilot/actions/setup-flux@main - with: - export_path: k8s/deployment/flux-system/gotk-components.yaml - - - name: Deploy fleetingdns via Flux (OCI chart + HelmRelease) - env: - CHART_REF: ${{ steps.artifacts.outputs.chart_ref }} - API_IMAGE: ${{ steps.artifacts.outputs.api_image }} - DNSD_IMAGE: ${{ steps.artifacts.outputs.dnsd_image }} - EDGEHUB_IMAGE: ${{ steps.artifacts.outputs.edgehub_image }} - run: | - set -e - RECONCILE_FAILED=0 - CHART_OCI_URL="$(echo "$CHART_REF" | sed 's|^oci://||' | cut -d'@' -f1)" - CHART_DIGEST="$(echo "$CHART_REF" | sed 's|^oci://||' | cut -d'@' -f2)" - export CHART_OCI_URL API_IMAGE DNSD_IMAGE EDGEHUB_IMAGE - export CHART_REF_TYPE=digest - export CHART_REF_VALUE="$CHART_DIGEST" - kubectl kustomize k8s/env/ci | envsubst | kubectl apply -f - - flux reconcile source oci fleetingdns-chart -n fleetingdns --timeout=2m || RECONCILE_FAILED=1 - # 8m covers the pre-install migration hook, the three Deployments - # becoming ready, and the Helm test hook (spec.test.enable: true). - flux reconcile helmrelease fleetingdns -n fleetingdns --timeout=8m || RECONCILE_FAILED=1 - kubectl get all -n fleetingdns - flux get helmrelease -n fleetingdns - if [ "$RECONCILE_FAILED" -ne 0 ]; then - echo "::group::Flux controller logs and events (reconcile failed)" - kubectl logs -n flux-system -l app=source-controller --tail=300 --all-containers=true 2>/dev/null || true - kubectl logs -n flux-system -l app=helm-controller --tail=300 --all-containers=true 2>/dev/null || true - kubectl get events -n fleetingdns --sort-by='.lastTimestamp' 2>/dev/null | tail -80 || true - kubectl describe pods -n fleetingdns 2>/dev/null | tail -160 || true - echo "=== migration hook Job logs ===" - kubectl logs -n fleetingdns job/fleetingdns-migrate --tail=100 2>/dev/null || true - echo "=== Helm test Pod logs ===" - kubectl logs -n fleetingdns fleetingdns-api-smoke --tail=100 2>/dev/null || true - echo "=== api/dnsd/edgehub pod logs ===" - for app in api dnsd edgehub; do - echo "--- $app ---" - kubectl logs -n fleetingdns -l app=$app --tail=60 --all-containers=true 2>/dev/null || true - done - flux get source oci -n fleetingdns 2>/dev/null || true - flux get helmrelease -n fleetingdns 2>/dev/null || true - echo "::endgroup::" - exit 1 - fi - # ── Release binaries (CLI tools → GitHub Release; tags only) ──────────────── release-binaries: name: Release CLI Binaries - needs: [integration-deploy] + needs: [build] if: startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest permissions: @@ -207,7 +59,7 @@ jobs: # ── Release notes (on tag: generate and publish to GitHub Release) ────────── release-notes: name: Release Notes - needs: [integration-deploy] + needs: [build] if: startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest permissions: diff --git a/k8s/deployment/helmrelease.yaml b/k8s/deployment/helmrelease.yaml index 9ff8a5d..aaf7c5f 100644 --- a/k8s/deployment/helmrelease.yaml +++ b/k8s/deployment/helmrelease.yaml @@ -30,9 +30,11 @@ spec: namespace: fleetingdns image: pullPolicy: Always + # Injected by the generic Octopilot integration deploy: IMG_ + # (ghcr.io/.../fleetingdns-api -> IMG_fleetingdns_api). api: - image: ${API_IMAGE} + image: ${IMG_fleetingdns_api} dnsd: - image: ${DNSD_IMAGE} + image: ${IMG_fleetingdns_dnsd} edgehub: - image: ${EDGEHUB_IMAGE} + image: ${IMG_fleetingdns_edgehub} From c5934454ce68dc2bc1140173ff56c0602d9dad15 Mon Sep 17 00:00:00 2001 From: Charles Sibbald Date: Sat, 18 Jul 2026 15:52:01 +0300 Subject: [PATCH 4/9] ci: re-run with fixed reusable pipeline From 75861cce00275bb1c001afd03d6556ec33ed017f Mon Sep 17 00:00:00 2001 From: Charles Sibbald Date: Sat, 18 Jul 2026 16:18:55 +0300 Subject: [PATCH 5/9] ci: re-run with fixed generic deploy (IMG vars + SOPS gating) From a51ffb4f3ba45e2d4adc64b6bc1a975cb6c25506 Mon Sep 17 00:00:00 2001 From: Charles Sibbald Date: Sat, 18 Jul 2026 16:49:43 +0300 Subject: [PATCH 6/9] config: flatten deployment-configuration profile + set profile: dev Flatten deployment-configuration/profiles/dev/fleetingdns/core/runtime -> deployment-configuration/profiles/dev (RERP's app/core depth isn't needed for a single-app repo). Move bootstrap out to deployment-configuration/bootstrap/dev. The generic integration deploy walks the first kustomization.yaml under the profile and applies it, so this is now the single customization entry point. Broaden the SOPS rule to cover both trees; caller pins profile: dev. --- .github/workflows/octopilot-ci.yml | 1 + .sops.yaml | 5 +++-- .../core/bootstrap => bootstrap/dev}/application.properties | 0 .../core/bootstrap => bootstrap/dev}/application.secrets.env | 0 .../core/bootstrap => bootstrap/dev}/database-job.yaml | 0 .../core/bootstrap => bootstrap/dev}/kustomization.yaml | 0 .../{fleetingdns/core/runtime => }/application.properties | 0 .../{fleetingdns/core/runtime => }/application.secrets.env | 0 .../profiles/dev/fleetingdns/core/kustomization.yaml | 5 ----- .../dev/{fleetingdns/core/runtime => }/kustomization.yaml | 0 10 files changed, 4 insertions(+), 7 deletions(-) rename deployment-configuration/{profiles/dev/fleetingdns/core/bootstrap => bootstrap/dev}/application.properties (100%) rename deployment-configuration/{profiles/dev/fleetingdns/core/bootstrap => bootstrap/dev}/application.secrets.env (100%) rename deployment-configuration/{profiles/dev/fleetingdns/core/bootstrap => bootstrap/dev}/database-job.yaml (100%) rename deployment-configuration/{profiles/dev/fleetingdns/core/bootstrap => bootstrap/dev}/kustomization.yaml (100%) rename deployment-configuration/profiles/dev/{fleetingdns/core/runtime => }/application.properties (100%) rename deployment-configuration/profiles/dev/{fleetingdns/core/runtime => }/application.secrets.env (100%) delete mode 100644 deployment-configuration/profiles/dev/fleetingdns/core/kustomization.yaml rename deployment-configuration/profiles/dev/{fleetingdns/core/runtime => }/kustomization.yaml (100%) diff --git a/.github/workflows/octopilot-ci.yml b/.github/workflows/octopilot-ci.yml index 3062f26..cf6899c 100644 --- a/.github/workflows/octopilot-ci.yml +++ b/.github/workflows/octopilot-ci.yml @@ -22,6 +22,7 @@ jobs: uses: octopilot/actions/.github/workflows/pipeline.yml@main with: integration: true + profile: dev secrets: inherit # ── Release binaries (CLI tools → GitHub Release; tags only) ──────────────── diff --git a/.sops.yaml b/.sops.yaml index faaa0b3..35b54e0 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -3,11 +3,12 @@ # Encrypt only on ms02 with: # SOPS_AGE_KEY_FILE=~/.config/sops/age/flux-shared-gitops sops --encrypt --in-place creation_rules: - - path_regex: deployment-configuration/profiles/.*/.*\.secrets\.env$ + # Covers both the flattened profile (profiles//) and bootstrap//. + - path_regex: deployment-configuration/.*\.secrets\.env$ key_groups: - age: - age1lh3s2uyxrqu0u7hqgulnd43q3v0xvktukq3fcxuu6gw97uye59rqgjsd07 - - path_regex: deployment-configuration/profiles/.*/.*\.secret\.yaml$ + - path_regex: deployment-configuration/.*\.secret\.yaml$ encrypted_regex: ^(data|stringData)$ key_groups: - age: diff --git a/deployment-configuration/profiles/dev/fleetingdns/core/bootstrap/application.properties b/deployment-configuration/bootstrap/dev/application.properties similarity index 100% rename from deployment-configuration/profiles/dev/fleetingdns/core/bootstrap/application.properties rename to deployment-configuration/bootstrap/dev/application.properties diff --git a/deployment-configuration/profiles/dev/fleetingdns/core/bootstrap/application.secrets.env b/deployment-configuration/bootstrap/dev/application.secrets.env similarity index 100% rename from deployment-configuration/profiles/dev/fleetingdns/core/bootstrap/application.secrets.env rename to deployment-configuration/bootstrap/dev/application.secrets.env diff --git a/deployment-configuration/profiles/dev/fleetingdns/core/bootstrap/database-job.yaml b/deployment-configuration/bootstrap/dev/database-job.yaml similarity index 100% rename from deployment-configuration/profiles/dev/fleetingdns/core/bootstrap/database-job.yaml rename to deployment-configuration/bootstrap/dev/database-job.yaml diff --git a/deployment-configuration/profiles/dev/fleetingdns/core/bootstrap/kustomization.yaml b/deployment-configuration/bootstrap/dev/kustomization.yaml similarity index 100% rename from deployment-configuration/profiles/dev/fleetingdns/core/bootstrap/kustomization.yaml rename to deployment-configuration/bootstrap/dev/kustomization.yaml diff --git a/deployment-configuration/profiles/dev/fleetingdns/core/runtime/application.properties b/deployment-configuration/profiles/dev/application.properties similarity index 100% rename from deployment-configuration/profiles/dev/fleetingdns/core/runtime/application.properties rename to deployment-configuration/profiles/dev/application.properties diff --git a/deployment-configuration/profiles/dev/fleetingdns/core/runtime/application.secrets.env b/deployment-configuration/profiles/dev/application.secrets.env similarity index 100% rename from deployment-configuration/profiles/dev/fleetingdns/core/runtime/application.secrets.env rename to deployment-configuration/profiles/dev/application.secrets.env diff --git a/deployment-configuration/profiles/dev/fleetingdns/core/kustomization.yaml b/deployment-configuration/profiles/dev/fleetingdns/core/kustomization.yaml deleted file mode 100644 index 292905a..0000000 --- a/deployment-configuration/profiles/dev/fleetingdns/core/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - runtime - - bootstrap diff --git a/deployment-configuration/profiles/dev/fleetingdns/core/runtime/kustomization.yaml b/deployment-configuration/profiles/dev/kustomization.yaml similarity index 100% rename from deployment-configuration/profiles/dev/fleetingdns/core/runtime/kustomization.yaml rename to deployment-configuration/profiles/dev/kustomization.yaml From d8997781735aa5f35083b0f3961da1486c290062 Mon Sep 17 00:00:00 2001 From: Charles Sibbald Date: Sat, 18 Jul 2026 16:58:33 +0300 Subject: [PATCH 7/9] config: drop app prefix from k8s secret/configmap names The namespace already scopes them, so fleetingdns-db-credentials -> db-credentials and fleetingdns-database-config -> database-config (chart values + the profile kustomization that generates them). GCP Secret Manager IDs (k8s-tilt) are a separate global namespace and unchanged. --- chart/fleetingdns/values.yaml | 2 +- deployment-configuration/profiles/dev/kustomization.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chart/fleetingdns/values.yaml b/chart/fleetingdns/values.yaml index 17351db..d8e5cf1 100644 --- a/chart/fleetingdns/values.yaml +++ b/chart/fleetingdns/values.yaml @@ -17,7 +17,7 @@ config: # SOPS-encrypted deployment-configuration runtime profile). database: urlSecret: - name: fleetingdns-db-credentials + name: db-credentials key: DATABASE_URL api: diff --git a/deployment-configuration/profiles/dev/kustomization.yaml b/deployment-configuration/profiles/dev/kustomization.yaml index e8e1d7f..3414d2a 100644 --- a/deployment-configuration/profiles/dev/kustomization.yaml +++ b/deployment-configuration/profiles/dev/kustomization.yaml @@ -2,11 +2,11 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: fleetingdns configMapGenerator: - - name: fleetingdns-database-config + - name: database-config envs: - application.properties secretGenerator: - - name: fleetingdns-db-credentials + - name: db-credentials envs: - application.secrets.env generatorOptions: From 760894bcf18fd080060c20ebd8a5777e3e1d6a01 Mon Sep 17 00:00:00 2001 From: Charles Sibbald Date: Sat, 18 Jul 2026 17:30:52 +0300 Subject: [PATCH 8/9] ci: re-run with declared workflow_call secrets From 6845c396200119578f45e5916ef2c797c7ddfae7 Mon Sep 17 00:00:00 2001 From: Charles Sibbald Date: Sat, 18 Jul 2026 20:31:48 +0300 Subject: [PATCH 9/9] ci: pass secrets explicitly to reusable pipeline (inherit fails cross-org) secrets: inherit did not propagate SOPS_AGE_KEY from microscaler/fleetingdns to octopilot/actions across the org boundary, so the profile never decrypted. Pass SOPS_AGE_KEY / ANTHROPIC_API_KEY explicitly to the workflow's declared secrets. --- .github/workflows/octopilot-ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/octopilot-ci.yml b/.github/workflows/octopilot-ci.yml index cf6899c..ee6b8f8 100644 --- a/.github/workflows/octopilot-ci.yml +++ b/.github/workflows/octopilot-ci.yml @@ -23,7 +23,11 @@ jobs: with: integration: true profile: dev - secrets: inherit + # Pass explicitly (not `inherit`): inherit does not reliably cross the + # org boundary to octopilot/actions. Maps to the workflow's declared secrets. + secrets: + SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }} + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} # ── Release binaries (CLI tools → GitHub Release; tags only) ──────────────── release-binaries: