Skip to content

ci: automate safe-settings deployment - #17

Merged
zeyu2001 merged 4 commits into
main-enterprisefrom
agent/automate-safe-settings-deploy
Aug 8, 2026
Merged

ci: automate safe-settings deployment#17
zeyu2001 merged 4 commits into
main-enterprisefrom
agent/automate-safe-settings-deploy

Conversation

@zeyu2001

@zeyu2001 zeyu2001 commented Aug 8, 2026

Copy link
Copy Markdown
Member

Summary

  • replace the stale manual Azure deploy with a gated GCP/GKE workflow
  • test on Node 24, build and push an immutable SHA-tagged image, then deploy with atomic Helm rollback
  • add Hacktron production Helm values that load GitHub App credentials from safe-settings/app-env
  • add a secret-safe bootstrap helper and document both Smee and direct HTTPS webhook modes

Deployment security

  • GitHub OIDC uses safe-settings-deployer@hacktron-462816.iam.gserviceaccount.com, not the broadly privileged infrastructure runner
  • Workload Identity impersonation is limited to HacktronAI/safe-settings
  • image push access is limited to the safe-settings Artifact Registry repository
  • GCP grants only roles/container.clusterViewer for cluster discovery; Kubernetes writes are controlled separately
  • Kubernetes access is isolated to the safe-settings namespace and cannot read Secrets
  • Helm uses the ConfigMap storage driver, --atomic, --wait, immutable image tags, and bounded history
  • the deploy job remains gated by SAFE_SETTINGS_DEPLOY_ENABLED == true; it is currently false

Provisioned prerequisites

  • production environment and both GCP identifier secrets
  • dedicated GCP service account and repository-scoped Workload Identity binding
  • Artifact Registry writer binding and GKE cluster-viewer binding
  • safe-settings namespace with scoped deployer Role/RoleBinding
  • safe-settings/app-env with APP_ID, PRIVATE_KEY, WEBHOOK_SECRET, and WEBHOOK_PROXY_URL

Webhook and cutover state

  • the legacy default/safe-settings deployment is healthy and currently consumes GitHub events through Smee
  • the new release must not overlap it because both instances would consume the same channel
  • after merge, the documented first cutover scales the legacy replica to zero, enables and manually runs this workflow, verifies the replacement, and restores the legacy replica if verification fails

Validation

  • npm run test:unit:ci: 16 suites passed, 137 tests passed
  • actionlint v1.7.12: passed on the original workflow revision
  • Helm lint and template rendering: passed
  • Kubernetes authorization: deploy in safe-settings yes; read Secrets no; modify default no
  • commit secret scan: passed

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Bootstrap drops optional secret keys
    • The bootstrap script now reuses an existing WEBHOOK_PROXY_URL from the current Kubernetes Secret when .env omits or leaves it empty, preventing apply from dropping that key.

Create PR

Or push these changes by commenting:

@cursor push 984b12483c
Preview (984b12483c)
diff --git a/script/bootstrap-k8s-secret b/script/bootstrap-k8s-secret
--- a/script/bootstrap-k8s-secret
+++ b/script/bootstrap-k8s-secret
@@ -36,8 +36,21 @@
   --from-file="WEBHOOK_SECRET=${secret_dir}/WEBHOOK_SECRET"
 )
 
-if [[ -n "${WEBHOOK_PROXY_URL:-}" ]]; then
-  printf '%s' "${WEBHOOK_PROXY_URL}" > "${secret_dir}/WEBHOOK_PROXY_URL"
+existing_webhook_proxy_url=""
+if [[ -z "${WEBHOOK_PROXY_URL:-}" ]]; then
+  encoded_webhook_proxy_url="$(
+    kubectl get secret "${secret_name}" \
+      --namespace "${namespace}" \
+      --output "jsonpath={.data.WEBHOOK_PROXY_URL}" 2>/dev/null || true
+  )"
+  if [[ -n "${encoded_webhook_proxy_url}" ]]; then
+    existing_webhook_proxy_url="$(printf '%s' "${encoded_webhook_proxy_url}" | base64 --decode)"
+  fi
+fi
+
+webhook_proxy_url="${WEBHOOK_PROXY_URL:-${existing_webhook_proxy_url}}"
+if [[ -n "${webhook_proxy_url}" ]]; then
+  printf '%s' "${webhook_proxy_url}" > "${secret_dir}/WEBHOOK_PROXY_URL"
   secret_args+=(--from-file="WEBHOOK_PROXY_URL=${secret_dir}/WEBHOOK_PROXY_URL")
 fi

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 3a9aab4. Configure here.

Comment thread script/bootstrap-k8s-secret
@zeyu2001
zeyu2001 marked this pull request as ready for review August 8, 2026 10:10

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 821519221f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


deploy:
name: Deploy production
if: ${{ vars.SAFE_SETTINGS_DEPLOY_ENABLED == 'true' }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restrict manual deployments to main-enterprise

When this workflow is manually dispatched from a feature branch or tag, the push branch filter does not apply and this condition only checks the repository variable, so the selected ref is checked out, built, and deployed to production. The local gh workflow run --help explicitly documents --ref as accepting a “Branch or tag name,” making it possible to bypass main-enterprise review and branch protection; add a github.ref == 'refs/heads/main-enterprise' guard to the deploy job.

Useful? React with 👍 / 👎.

@zeyu2001
zeyu2001 merged commit 3857ab8 into main-enterprise Aug 8, 2026
8 checks passed
@zeyu2001 zeyu2001 changed the title ci: automate safe-settings deployment ci: automate safe-settings deployment [webhook verification] Aug 8, 2026
@zeyu2001 zeyu2001 changed the title ci: automate safe-settings deployment [webhook verification] ci: automate safe-settings deployment Aug 8, 2026
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