Repository navigation
Add manual API release workflow for production and staging - #632
Merged
Merged
Conversation
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes in commit 62bc3052 across the manual release workflow, staging Terraform resources, and deployment guidance.
- Release workflow: Selects production or staging, validates the requested branch and commit, and verifies the Render deployment before recording its GitHub Deployment.
- Staging infrastructure: Disables API auto deploy, preserves release selected branches, and provisions a landing static site with its service ID output.
- Documentation: Describes the release inputs, Terraform apply precautions, and repository variable setup.
GPT Sol | 𝕏
|
thomasluizon
added a commit
to thomasluizon/orbit-landing-page
that referenced
this pull request
Sep 28, 2026
## Summary - Replace the production-only deploy workflow with a manual release workflow dispatched from `main`. - Keep production fixed to the `main` branch and its existing Render site and public domain checks. - Set the staging Render site's tracked branch before deploying its resolved head commit, verify the `orbit-build` marker, and record a staging GitHub Deployment. Related: thomasluizon/orbit-tickets#818 ## Assumptions - The `branch` input names a branch head; accepting a tag or arbitrary commit ID was rejected. - Staging verification and its Deployment URL use the Render service URL; checking the production public domain for staging was rejected. ## Manual steps - Apply the Terraform change in thomasluizon/orbit-api#632. In Render Dashboard > Static Sites > `orbit-landing-staging` > Settings > Auto-Deploy, confirm it shows Off; a read-only service API response with `autoDeploy: no` proves the setting took effect. - In GitHub > `thomasluizon/orbit-landing-page` > Settings > Secrets and variables > Actions > Variables, set `RENDER_LANDING_STAGING_SERVICE_ID` to the new staging site's service ID. A staging release that records a Deployment for the selected branch head proves it took effect. - In the same GitHub Variables screen, set `RENDER_LANDING_SERVICE_ID` to the production `orbit-landing` service ID. A production release that records a Deployment for `main` proves it took effect. - In GitHub > `thomasluizon/orbit-landing-page` > Settings > Secrets and variables > Actions > Secrets, confirm `RENDER_API_KEY` can access both Render sites. Successful service reads and deploys for both environments prove access. ## Verification - `npm test`: 30 passed. - `npm run build`: build and sitemap test passed. - `npm run lint`, `npm run format:check`, `npm run check`, and `npm audit --audit-level=moderate`: passed. - Focused workflow checks passed for dispatch inputs, embedded JavaScript syntax, five release selection cases, and mocked production and staging request sequences.
thomasluizon
added a commit
that referenced
this pull request
Sep 28, 2026
…) (#635) * Guard web service Terraform plans before apply (#631) * Guard Terraform web service updates before apply * Guard Terraform web service replacement and deletion (cherry picked from commit 7a1e26a) * Add manual API release workflow for production and staging (#632) (cherry picked from commit 498015a) * Add Amazon SES delivery and signed event handling (#628) * Add SES identities, DNS, and delivery infrastructure * Add SES sender and signed SNS event handling * Classify SES webhook and clarify email contract * Fix SES cutover controls and webhook verification * Extract shared email composition for SES and Resend * Isolate staging SES events and sender credentials * Escape interpolated names in the SES isolation test patterns CodeQL js/incomplete-hostname-regexp flagged the tuple values flowing into new RegExp; every interpolated value is now escaped as a literal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit f770b47) * Keep staging awake and reseed its free database (#626) * Add staging keepalive and database reseed lifecycle * Document and strengthen staging seed command * Keep Terraform plan details out of workflow logs * Require successful health responses in staging workflows * Parse Render creation time portably * Isolate staging database state and gate reseed on deploy * Read the staging database id from the main state before moving it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Correlate staging reseed deploy with live commit --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit ee40ae9) * fix: point apex DNS at Render landing site (#634) (cherry picked from commit 65d355f) * Move uploads to private S3 with stable read links (#625) * Add configurable S3 upload signing * Provision private S3 upload buckets and scoped credentials * Expose storage provider cutover as Terraform variables * Add stable read redirects for private S3 uploads * Map public upload reads in agent catalog * Fix upload read validation and S3 bucket safeguards * Keep S3 upload reads available across provider rollback * Bound anonymous upload reads per client IP (cherry picked from commit 395239f) * Fix Render database names in API connection strings (#633) * fix: derive Render database names from connection URLs * Generate the staging database name pattern with a match timeout SonarCloud S6444 and SYSLIB1045 on the seed target check: the pattern is now a GeneratedRegex with a one second timeout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 0fd416f) * Complete carried error copy and generated gating matrix * Keep SES event notifications recoverable (#746) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Closes thomasluizon/orbit-tickets#816
Change
.github/workflows/deploy-api.ymlwith.github/workflows/release.yml. It runs only by manual dispatch frommain, rejects a production branch other thanmainbefore checkout, checks that the checkout matches the selected branch head, and serializes releases per environment. The production Render deploy, health check, live commit check, and GitHub Deployment behavior carry forward. Staging sets its tracked branch and disables auto-deploy before triggering the selected commit, then checks staging health and records its Deployment.infra/staging.tfto disable staging API auto-deploy, preserve its workflow-selected branch across Terraform applies, create the staging landing site with the production landing build and delivery settings, and outputlanding_staging_service_id.README.md,infra/README.md, andCLAUDE.mdwith the manual release path and Terraform apply caution.The workflow uses one release path for both environments so commit resolution, Render polling, health verification, and GitHub Deployment recording stay aligned. No Render service was changed by this PR branch.
Assumptions
mainand copies production landing headers and routes; the alternative was a staging-specific initial branch or delivery settings.mainon every apply.Manual steps
infraTerraform workspace, review a refreshed saved plan with the approved web image digests and apply it. Cancel the Render Dashboard deploy started by the staging API setting change unless that branch head is the intended release. ConfirmGET https://api.render.com/v1/services/srv-dasotg8473hc739a5gjgreportsautoDeploy: no, and confirm the neworbit-landing-stagingsite exists in the Render Staging environment.thomasluizon/orbit-landing-page, open Settings > Secrets and variables > Actions > Variables and setRENDER_LANDING_STAGING_SERVICE_IDto thelanding_staging_service_idTerraform output. Read the variable back in that screen and compare it with the output before the landing release workflow runs.The
RENDER_STAGING_SERVICE_IDvariable is already set inthomasluizon/orbit-apitosrv-dasotg8473hc739a5gjgand was read back withgh variable list. The existingRENDER_API_KEYsecret is present in the repository.Test evidence
actionlint .github/workflows/release.yml: passed.terraform fmt -check -recursive infra: passed.terraform -chdir=infra validate: passed.-refresh=falsebecause no Cloudflare API token is available in this worker:render_web_service.staging_apiupdates onlyauto_deployfromtruetofalse;render_web_service.staging_webandrender_web_service.production_apihave no change;render_web_service.production_webis a create, not an in-place update;render_static_site.staging_landingis a create. The plan was not applied.dotnet build Orbit.slnx: 0 errors.dotnet test: 6,813 passed, 0 failed.External interface evidence
GET https://api.render.com/v1/services/srv-dasotg8473hc739a5gjgwithRENDER_MCP_TOKENreturned the projection{ "id": "srv-dasotg8473hc739a5gjg", "branch": "redesign/main", "autoDeploy": "yes" }. Reproduce withcurl -fsS -H "Authorization: Bearer $RENDER_MCP_TOKEN" https://api.render.com/v1/services/srv-dasotg8473hc739a5gjg | jq '{id, branch, autoDeploy}'. The Render update service reference confirmsPATCHacceptsbranchandautoDeployand returns both fields. No mutating Render API call was made here.GET https://api.render.com/v1/services/srv-dasotg8473hc739a5gjg/deploys?limit=1returned the projection{ "deploy": { "id": "dep-dass32bl550s739k9cq0", "status": "live", "commit": { "id": "e1bbb37ad1bfb2030764da256d589f9393cec78c" } } }. Reproduce with the same authorization header andjq '.[0] | {deploy: {id: .deploy.id, status: .deploy.status, commit: {id: .deploy.commit.id}}}'. The Render trigger deploy reference, retrieve deploy reference, and list deploys reference confirm the request and response fields. The workflow sets the tracked branch before passingcommitId; cross-branch POST behavior was not tested against a live service.gh api repos/thomasluizon/orbit-api/branches/redesign/main --jq '{name: .name, sha: .commit.sha}'returned{ "name": "redesign/main", "sha": "e1bbb37ad1bfb2030764da256d589f9393cec78c" }. The GitHub branch reference confirmscommit.sha.gh api repos/thomasluizon/orbit-api/deployments --jq '.[0] | {id: .id, ref: .ref, environment: .environment}'returned an existing deployment withid,ref, andenvironment; the GitHub Deployment reference confirms the create responseid. A read-only status GET returnedstate,environment,log_url, andenvironment_urlfor that deployment.