diff --git a/.gitea/workflows/publish.yaml b/.gitea/workflows/publish.yaml index 84566a7..a8b2cb4 100644 --- a/.gitea/workflows/publish.yaml +++ b/.gitea/workflows/publish.yaml @@ -19,6 +19,16 @@ jobs: token: ${{ secrets.GITEA_TOKEN }} persist-credentials: true + - name: Check release credentials before changing the version + shell: bash + env: + HARBOR_USERNAME: ${{ secrets.HARBOR_USERNAME }} + HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }} + run: | + set -euo pipefail + test -n "$HARBOR_USERNAME" || { echo 'Missing HARBOR_USERNAME action secret'; exit 1; } + test -n "$HARBOR_PASSWORD" || { echo 'Missing HARBOR_PASSWORD action secret'; exit 1; } + - name: Test and lint in the shared builder image shell: bash run: | @@ -115,8 +125,11 @@ jobs: echo 'NATS is not installed yet. The backend release pipeline bootstraps NATS and this Argo Application.' exit 0 fi + if ! kubectl -n argocd get application ai-spel-rule-engine >/dev/null 2>&1; then + echo 'The backend release pipeline owns first-time Argo Application creation; skipping this worker-only rollout.' + exit 0 + fi kubectl -n ai-spel rollout status statefulset/ai-spel-nats --timeout=10m - kubectl -n argocd apply -f deploy/argocd/application.yaml kubectl -n argocd patch application ai-spel-rule-engine --type merge -p "{\"spec\":{\"source\":{\"targetRevision\":\"$version\"}}}" deadline=$((SECONDS + 600)) while (( SECONDS < deadline )); do diff --git a/README.md b/README.md index 218ba06..fc8be68 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,13 @@ For source development, the Rust commands are `cargo fmt --all -- --check`, `cargo test --workspace`, and `cargo clippy --workspace --all-targets -- -D warnings`. Production builds, tests, image builds, and executable verification for this project are run by Gitea Actions on the existing `large` runner and Kubernetes. + +## Release deployment boundary + +The API repository owns first-time NATS and Argo Application provisioning. The +worker release pipeline publishes this repository's versioned image and chart, +then updates the existing `ai-spel-rule-engine` Argo Application. It uses the +`AI_SPEL_TEST_KUBECONFIG` repository action secret, scoped to patch that one +Argo Application and read rollout health in namespace `ai-spel`. The one-time +service-account roles are described in `deploy/ci/namespace-scoped-rbac.yaml`; +they do not grant database, secret, workload-write, or cluster-wide access. diff --git a/deploy/ci/namespace-scoped-rbac.yaml b/deploy/ci/namespace-scoped-rbac.yaml new file mode 100644 index 0000000..7f6086d --- /dev/null +++ b/deploy/ci/namespace-scoped-rbac.yaml @@ -0,0 +1,66 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: ai-spel-rule-engine-deployer + namespace: argocd +--- +apiVersion: v1 +kind: Secret +metadata: + name: ai-spel-rule-engine-deployer-token + namespace: argocd + annotations: + kubernetes.io/service-account.name: ai-spel-rule-engine-deployer +type: kubernetes.io/service-account-token +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: ai-spel-rule-engine-deployer + namespace: argocd +rules: + - apiGroups: [argoproj.io] + resources: [applications] + resourceNames: [ai-spel-rule-engine] + verbs: [get, patch] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ai-spel-rule-engine-deployer + namespace: argocd +subjects: + - kind: ServiceAccount + name: ai-spel-rule-engine-deployer + namespace: argocd +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ai-spel-rule-engine-deployer +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: ai-spel-rule-engine-deployer + namespace: ai-spel +rules: + - apiGroups: [apps] + resources: [deployments, replicasets, statefulsets] + verbs: [get, list, watch] + - apiGroups: [""] + resources: [pods, events] + verbs: [get, list, watch] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ai-spel-rule-engine-deployer + namespace: ai-spel +subjects: + - kind: ServiceAccount + name: ai-spel-rule-engine-deployer + namespace: argocd +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ai-spel-rule-engine-deployer