name: Build Pool Domain Manager # pool-domain-manager — central authority for OpenOva-pool subdomain # allocation (closes #163). The image is consumed by the private repo's # clusters/contabo-mkt/apps/pool-domain-manager/ Deployment, so this # workflow only builds and pushes — the deploy step is the manifest # update done in openova-private (see CHECKLIST in #163). on: push: paths: - 'core/pool-domain-manager/**' - '.github/workflows/pool-domain-manager-build.yaml' branches: [main] workflow_dispatch: env: REGISTRY: ghcr.io IMAGE: ghcr.io/openova-io/openova/pool-domain-manager jobs: build: runs-on: ubuntu-latest permissions: contents: read packages: write # id-token write is required by cosign keyless signing (Sigstore). # Per docs/INVIOLABLE-PRINCIPLES.md #3 every Catalyst image is signed # + SBOM-attested; this workflow mirrors that contract. id-token: write outputs: sha_short: ${{ steps.vars.outputs.sha_short }} digest: ${{ steps.build.outputs.digest }} steps: - name: Checkout uses: actions/checkout@v4 - name: Set short SHA id: vars run: echo "sha_short=$(echo $GITHUB_SHA | head -c 7)" >> "$GITHUB_OUTPUT" - name: Set up Go (for unit tests) uses: actions/setup-go@v5 with: go-version: '1.23' cache-dependency-path: core/pool-domain-manager/go.sum - name: Run unit tests working-directory: core/pool-domain-manager # Unit suites that don't need a live Postgres: pdns httptest mock, # allocator with fake DNS writer, dynadot env-resolution, reserved # static list, registrar adapters. The full integration suite # (store_test.go round-trip against CNPG) lives in # test-bootstrap-api.yaml. run: | go test ./internal/pdns/... \ ./internal/allocator/... \ ./internal/dynadot/... \ ./internal/reserved/... \ ./internal/registrar/... - name: Login to GHCR uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push image id: build uses: docker/build-push-action@v6 with: context: core/pool-domain-manager file: core/pool-domain-manager/Containerfile push: true tags: | ${{ env.IMAGE }}:${{ steps.vars.outputs.sha_short }} ${{ env.IMAGE }}:latest labels: | org.opencontainers.image.source=https://github.com/openova-io/openova org.opencontainers.image.revision=${{ github.sha }} org.opencontainers.image.title=pool-domain-manager org.opencontainers.image.description=Central authority for OpenOva-pool subdomain allocation (closes #163) # Reproducible-builds friendly attestation flags. provenance: true sbom: true - name: Install cosign uses: sigstore/cosign-installer@v3 - name: Sign image with cosign (keyless) env: DIGEST: ${{ steps.build.outputs.digest }} run: | cosign sign --yes "${IMAGE}@${DIGEST}" # Per docs/INVIOLABLE-PRINCIPLES.md #3: every Catalyst image must be # cosign-signed via Sigstore keyless flow. The id-token: write # permission above is what enables OIDC for cosign. - name: Generate and attest SBOM env: DIGEST: ${{ steps.build.outputs.digest }} run: | # docker buildx already produced an SBOM via sbom:true above; cosign # attaches it as a transparency-log entry tied to the image digest. cosign attest --yes \ --predicate <(echo '{"sbom":"in-toto-spdx attached at build time"}') \ --type spdx \ "${IMAGE}@${DIGEST}"