Use api.staging.st0x.io for preview#111
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughStandardize the preview hostname to preview.api.st0x.io across docs and scripts; add a Nix tfImport task and tfSecret wiring; add preview bootstrap SSH variable and example; update Terraform preview resources for lifecycle/user_data/depends_on; and run imports plus conditional replace in the preview CI workflow. ChangesPreview Hostname Update & Preview Infra
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
How to use the Graphite Merge QueueAdd the label add-to-gt-merge-queue to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
6d5a8da to
19a27bf
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
infra/variables.tf (1)
49-53: ⚡ Quick winAdd format validation for
preview_bootstrap_ssh_public_key.This currently accepts any string; a malformed key won’t fail until much later. Add a variable
validationblock to fail early during plan/apply.Suggested diff
variable "preview_bootstrap_ssh_public_key" { description = "Public SSH key authorized on the preview droplet before NixOS bootstrap" type = string default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTd2zKSwHgWegi290EiK5nYp1Wp4+x2fDYqFxbd0WLN" + + validation { + condition = can(regex("^ssh-(ed25519|rsa)\\s+[A-Za-z0-9+/=]+(?:\\s+.+)?$", var.preview_bootstrap_ssh_public_key)) + error_message = "preview_bootstrap_ssh_public_key must be a valid SSH public key." + } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@infra/variables.tf` around lines 49 - 53, The variable preview_bootstrap_ssh_public_key currently accepts any string; add a Terraform variable validation block on preview_bootstrap_ssh_public_key to assert the value matches a valid SSH public key pattern (e.g., starts with a known key type like "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", etc., followed by the base64 blob and optional comment) and provide a clear error_message on failure; update the variable block in infra/variables.tf to include the validation rule so plan/apply fails fast for malformed keys.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/deploy-preview.yaml:
- Around line 79-81: The current commands using "nix run .#tfImport -- -var
preview_enabled=true 'digitalocean_volume.preview_data[0]' ..." (and the similar
calls for digitalocean_droplet.preview_nixos[0] and
digitalocean_reserved_ip.preview_nixos[0]) swallow all errors via "|| true";
change this so the tfImport invocation runs normally and only treats the run as
successful if its stdout/stderr indicates the specific “already in
state”/“already managed” message, otherwise propagate a non‑zero exit (fail the
step). Implement this by removing the trailing "|| true", capturing the command
output/exit code for each nix run .#tfImport call, checking the output for the
known Terraform import-already-in-state text, and exit 0 only when that text is
present; for any other errors, exit non-zero so the workflow fails. Ensure the
logic applies to all three tfImport invocations referenced above.
---
Nitpick comments:
In `@infra/variables.tf`:
- Around line 49-53: The variable preview_bootstrap_ssh_public_key currently
accepts any string; add a Terraform variable validation block on
preview_bootstrap_ssh_public_key to assert the value matches a valid SSH public
key pattern (e.g., starts with a known key type like "ssh-ed25519", "ssh-rsa",
"ecdsa-sha2-nistp256", etc., followed by the base64 blob and optional comment)
and provide a clear error_message on failure; update the variable block in
infra/variables.tf to include the validation rule so plan/apply fails fast for
malformed keys.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: aa272070-0b3d-4a9b-b723-f38824a09f97
📒 Files selected for processing (10)
.github/workflows/deploy-preview.yamlDEPLOY.mddocs/ops.mdflake.nixinfra/default.nixinfra/main.tfinfra/terraform.tfvars.exampleinfra/variables.tfscripts/smoke.shscripts/uptimerobot-setup.sh
✅ Files skipped from review due to trivial changes (4)
- DEPLOY.md
- docs/ops.md
- infra/terraform.tfvars.example
- scripts/smoke.sh
42a41f4 to
b48bc36
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
.github/workflows/deploy-preview.yaml (1)
84-86:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDon't swallow all
tfImportfailures with|| true.
|| truemasks every failure mode (bad ID, auth errors, API throttling), not only the benign "already in state" case. Capture stderr and only treat the "already managed by Terraform" message as success; otherwise fail the step.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/deploy-preview.yaml around lines 84 - 86, The workflow currently appends "|| true" to every nix run .#tfImport invocation which masks all failures; instead run each tfImport command and capture its stderr/stdout, then if it exits non‑zero examine the output for the specific Terraform message that indicates the resource is "already managed by Terraform" and treat only that case as success (exit 0); for any other error (bad ID, auth, rate limit, etc.) re‑exit non‑zero so the step fails. Apply this change to the tfImport invocations (the three nix run .#tfImport lines for digitalocean_volume.preview_data[0], digitalocean_droplet.preview_nixos[0], and digitalocean_reserved_ip.preview_nixos[0]) so they inspect stderr for the benign message before deciding to ignore the error.
🧹 Nitpick comments (2)
infra/terraform.tfvars.example (1)
9-10: 💤 Low valueUse a placeholder in the example tfvars rather than a real-looking key.
Examples are often copied verbatim. Shipping a real ed25519 key here makes it likely that an operator will end up with a working bootstrap key that isn't theirs, instead of being prompted to supply one. A placeholder makes the intent explicit.
Proposed change
# Public key authorized during first preview bootstrap. -preview_bootstrap_ssh_public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTd2zKSwHgWegi290EiK5nYp1Wp4+x2fDYqFxbd0WLN" +preview_bootstrap_ssh_public_key = "ssh-ed25519 AAAA... your-operator-key"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@infra/terraform.tfvars.example` around lines 9 - 10, Replace the real-looking ed25519 key assigned to the Terraform variable preview_bootstrap_ssh_public_key in the example tfvars with a clear placeholder so users are forced to supply their own key; update the value for preview_bootstrap_ssh_public_key to a descriptive token such as a labelled placeholder (e.g. REPLACE_WITH_YOUR_SSH_PUBLIC_KEY) or an empty/obvious dummy value and add a short inline comment clarifying that operators must replace it with their own public key.infra/variables.tf (1)
49-53: 💤 Low valueAvoid hardcoding a specific operator's public key as the variable default.
Defaulting
preview_bootstrap_ssh_public_keyto a specific developer's public key means the bootstrap-time access is implicitly tied to whoever holds that private key. While public keys aren't secret, baking one operator's identity into the module default is fragile: anyone provisioning fresh preview infra from this module (CI, another dev, or after rotating laptops) gets that operator's access by default instead of being forced to think about it.Consider either dropping the default (forcing the caller to provide it) or defaulting to
""and validating against empty in the resource that consumes it.Proposed change
variable "preview_bootstrap_ssh_public_key" { description = "Public SSH key authorized on the preview droplet before NixOS bootstrap" type = string - default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTd2zKSwHgWegi290EiK5nYp1Wp4+x2fDYqFxbd0WLN" }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@infra/variables.tf` around lines 49 - 53, The variable preview_bootstrap_ssh_public_key currently hardcodes an operator SSH key; remove that default (or set default to an empty string "") in the variable declaration (variable "preview_bootstrap_ssh_public_key") and require callers to supply a key, and add validation where it’s consumed (or add a validation block on the variable) to fail when the value is empty so provisioning cannot proceed without an explicit SSH key.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In @.github/workflows/deploy-preview.yaml:
- Around line 84-86: The workflow currently appends "|| true" to every nix run
.#tfImport invocation which masks all failures; instead run each tfImport
command and capture its stderr/stdout, then if it exits non‑zero examine the
output for the specific Terraform message that indicates the resource is
"already managed by Terraform" and treat only that case as success (exit 0); for
any other error (bad ID, auth, rate limit, etc.) re‑exit non‑zero so the step
fails. Apply this change to the tfImport invocations (the three nix run
.#tfImport lines for digitalocean_volume.preview_data[0],
digitalocean_droplet.preview_nixos[0], and
digitalocean_reserved_ip.preview_nixos[0]) so they inspect stderr for the benign
message before deciding to ignore the error.
---
Nitpick comments:
In `@infra/terraform.tfvars.example`:
- Around line 9-10: Replace the real-looking ed25519 key assigned to the
Terraform variable preview_bootstrap_ssh_public_key in the example tfvars with a
clear placeholder so users are forced to supply their own key; update the value
for preview_bootstrap_ssh_public_key to a descriptive token such as a labelled
placeholder (e.g. REPLACE_WITH_YOUR_SSH_PUBLIC_KEY) or an empty/obvious dummy
value and add a short inline comment clarifying that operators must replace it
with their own public key.
In `@infra/variables.tf`:
- Around line 49-53: The variable preview_bootstrap_ssh_public_key currently
hardcodes an operator SSH key; remove that default (or set default to an empty
string "") in the variable declaration (variable
"preview_bootstrap_ssh_public_key") and require callers to supply a key, and add
validation where it’s consumed (or add a validation block on the variable) to
fail when the value is empty so provisioning cannot proceed without an explicit
SSH key.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cac36086-71a0-4761-824b-e9851e57ed88
📒 Files selected for processing (10)
.github/workflows/deploy-preview.yamlDEPLOY.mddocs/ops.mdflake.nixinfra/default.nixinfra/main.tfinfra/terraform.tfvars.exampleinfra/variables.tfscripts/smoke.shscripts/uptimerobot-setup.sh
✅ Files skipped from review due to trivial changes (3)
- scripts/smoke.sh
- DEPLOY.md
- docs/ops.md
b48bc36 to
c2fa4be
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@infra/variables.tf`:
- Around line 49-53: The variable preview_bootstrap_ssh_public_key currently
contains a hardcoded default; remove the concrete default value and require
explicit provisioning of the key (e.g., set no default or default = null and
mark sensitive), and add a validation that fails fast when preview_enabled is
true but preview_bootstrap_ssh_public_key is empty — reference the variable name
preview_bootstrap_ssh_public_key and the flag preview_enabled to implement a
validation block that checks length(var.preview_bootstrap_ssh_public_key) > 0
(or var.preview_bootstrap_ssh_public_key != null &&
var.preview_bootstrap_ssh_public_key != "") and returns a clear error
instructing users to provide the key via per-environment tfvars/CI secret.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 62b2b1f1-9055-4491-be45-8da3b422e7b6
📒 Files selected for processing (10)
.github/workflows/deploy-preview.yamlDEPLOY.mddocs/ops.mdflake.nixinfra/default.nixinfra/main.tfinfra/terraform.tfvars.exampleinfra/variables.tfscripts/smoke.shscripts/uptimerobot-setup.sh
✅ Files skipped from review due to trivial changes (3)
- DEPLOY.md
- docs/ops.md
- scripts/smoke.sh
| variable "preview_bootstrap_ssh_public_key" { | ||
| description = "Public SSH key authorized on the preview droplet before NixOS bootstrap" | ||
| type = string | ||
| default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTd2zKSwHgWegi290EiK5nYp1Wp4+x2fDYqFxbd0WLN" | ||
| } |
There was a problem hiding this comment.
Avoid a shared bootstrap SSH key default.
Line 52 hardcodes a concrete bootstrap key as the default. That creates an insecure access default for preview host provisioning if overrides are missed.
Suggested change
variable "preview_bootstrap_ssh_public_key" {
description = "Public SSH key authorized on the preview droplet before NixOS bootstrap"
type = string
- default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTd2zKSwHgWegi290EiK5nYp1Wp4+x2fDYqFxbd0WLN"
+ default = ""
}Use an explicit per-environment value (for example via encrypted tfvars/CI secret), and fail fast when preview_enabled=true but this value is empty.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| variable "preview_bootstrap_ssh_public_key" { | |
| description = "Public SSH key authorized on the preview droplet before NixOS bootstrap" | |
| type = string | |
| default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTd2zKSwHgWegi290EiK5nYp1Wp4+x2fDYqFxbd0WLN" | |
| } | |
| variable "preview_bootstrap_ssh_public_key" { | |
| description = "Public SSH key authorized on the preview droplet before NixOS bootstrap" | |
| type = string | |
| default = "" | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@infra/variables.tf` around lines 49 - 53, The variable
preview_bootstrap_ssh_public_key currently contains a hardcoded default; remove
the concrete default value and require explicit provisioning of the key (e.g.,
set no default or default = null and mark sensitive), and add a validation that
fails fast when preview_enabled is true but preview_bootstrap_ssh_public_key is
empty — reference the variable name preview_bootstrap_ssh_public_key and the
flag preview_enabled to implement a validation block that checks
length(var.preview_bootstrap_ssh_public_key) > 0 (or
var.preview_bootstrap_ssh_public_key != null &&
var.preview_bootstrap_ssh_public_key != "") and returns a clear error
instructing users to provide the key via per-environment tfvars/CI secret.
c2fa4be to
256b854
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (2)
config/preview.toml (1)
3-3: ⚡ Quick winAdd provenance metadata for the inline registry blob.
This value is hard to review safely in-place. Please add a short comment with source/provenance and how it is regenerated so future updates don’t drift.
♻️ Suggested minimal change
+# Inline registry payload (base64 data URL). +# Keep provenance + regeneration steps documented here for maintainability. registry_url = "data:text/plain;base64,..."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@config/preview.toml` at line 3, The inline base64 registry blob assigned to registry_url should include provenance and regeneration instructions; update the config/preview.toml near the registry_url entry to add a concise comment describing the original source URL(s), the date/timestamp of generation, the tool/command used to produce the base64 blob, and the steps to regenerate (e.g., fetch raw file(s) and base64-encode) so future reviewers can verify or update the blob without guessing.infra/main.tf (1)
70-72: ⚡ Quick winConsider adding
user_datatoignore_changes.Since this is a bootstrap SSH key intended for initial provisioning only, changes to
var.preview_bootstrap_ssh_public_keywould currently trigger droplet recreation. Addinguser_datato the ignore list prevents accidental recreation after NixOS bootstrap completes.♻️ Suggested change
lifecycle { - ignore_changes = [ssh_keys, volume_ids] + ignore_changes = [ssh_keys, volume_ids, user_data] }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@infra/main.tf` around lines 70 - 72, The lifecycle ignore_changes currently lists ssh_keys and volume_ids, which causes changes to var.preview_bootstrap_ssh_public_key to trigger droplet recreation; update the lifecycle block in the resource that contains ignore_changes (the one with ignore_changes = [ssh_keys, volume_ids]) to also include user_data so that bootstrap provisioning data is ignored after NixOS bootstrap completes and accidental recreation is prevented.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@config/preview.toml`:
- Line 3: The inline base64 registry blob assigned to registry_url should
include provenance and regeneration instructions; update the config/preview.toml
near the registry_url entry to add a concise comment describing the original
source URL(s), the date/timestamp of generation, the tool/command used to
produce the base64 blob, and the steps to regenerate (e.g., fetch raw file(s)
and base64-encode) so future reviewers can verify or update the blob without
guessing.
In `@infra/main.tf`:
- Around line 70-72: The lifecycle ignore_changes currently lists ssh_keys and
volume_ids, which causes changes to var.preview_bootstrap_ssh_public_key to
trigger droplet recreation; update the lifecycle block in the resource that
contains ignore_changes (the one with ignore_changes = [ssh_keys, volume_ids])
to also include user_data so that bootstrap provisioning data is ignored after
NixOS bootstrap completes and accidental recreation is prevented.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: abfdb228-0ce0-4551-89fa-eb90e9c372d5
📒 Files selected for processing (11)
.github/workflows/deploy-preview.yamlDEPLOY.mdconfig/preview.tomldocs/ops.mdflake.nixinfra/default.nixinfra/main.tfinfra/terraform.tfvars.exampleinfra/variables.tfscripts/smoke.shscripts/uptimerobot-setup.sh
✅ Files skipped from review due to trivial changes (4)
- scripts/smoke.sh
- DEPLOY.md
- docs/ops.md
- flake.nix
| if [ "${{ inputs.recreate_host }}" = "true" ]; then | ||
| nix run .#tfPlan -- -var preview_enabled=true -replace='digitalocean_droplet.preview_nixos[0]' | ||
| else | ||
| nix run .#tfPlan -- -var preview_enabled=true | ||
| fi | ||
| nix run .#tfApply | ||
| nix run .#tfRekey |
There was a problem hiding this comment.
i'd also pull out all of this logic into a single nix run command instead of spreading scripts over both github actions and those tfInit/Import/Plan/Apply/Rekey
| ''; | ||
| }; | ||
|
|
||
| tfImport = rainix.mkTask.${system} { |
There was a problem hiding this comment.
why not put all the new logic here instead of taking a bunch of extra args passed via the preview github action?
b0b84fb to
d41526b
Compare
Merge activity
|
## Summary - switch the preview NixOS virtual host to `api.staging.st0x.io` - update preview docs and helper script defaults to use the same hostname - keep production `api.st0x.io` untouched ## Context The preview environment now uses `api.staging.st0x.io`, backed by the staging reserved IP. Production deployment and production hostname configuration are unchanged. ## Validation - verified no remaining `api.preview.st0x.io` or `preview.api.st0x.io` references in preview config/docs/scripts - deployed preview successfully - verified `https://api.staging.st0x.io/health` returns HTTP 200 - verified an authenticated `/v1/tokens` request against staging returns HTTP 200 with a staging-only temporary key, then deleted that key
d41526b to
249f3f6
Compare

Summary
api.staging.st0x.ioapi.st0x.iountouchedContext
The preview environment now uses
api.staging.st0x.io, backed by the staging reserved IP. Production deployment and production hostname configuration are unchanged.Validation
api.preview.st0x.ioorpreview.api.st0x.ioreferences in preview config/docs/scriptshttps://api.staging.st0x.io/healthreturns HTTP 200/v1/tokensrequest against staging returns HTTP 200 with a staging-only temporary key, then deleted that key