-
Notifications
You must be signed in to change notification settings - Fork 0
Update deployment SSH key ownership and allow branch-based workflow testing #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
991837d
3f38d00
ea23fd7
2326a0e
9dcb0cc
fa386b8
4e46e5e
bb712b1
2768a2d
118da99
1c8e961
6adc5c3
be9f00d
f2314db
1ee5ba3
b1aca24
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,9 +3,6 @@ name: Create Empty Local DB Manifest | |
| env: | ||
| SPACES_ACCESS_KEY: ${{ secrets.SPACES_ACCESS_KEY }} | ||
| SPACES_SECRET_KEY: ${{ secrets.SPACES_SECRET_KEY }} | ||
| SPACES_REGION: ${{ secrets.SPACES_REGION }} | ||
| SPACES_BUCKET: ${{ secrets.SPACES_BUCKET }} | ||
| SPACES_ENDPOINT: ${{ secrets.SPACES_ENDPOINT }} | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
|
|
@@ -30,12 +27,31 @@ jobs: | |
| keep-env-derivations = true | ||
| keep-outputs = true | ||
|
|
||
| - name: Load encrypted runtime config | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| mkdir -p ~/.ssh | ||
| printf '%s\n' "${{ secrets.SSH_KEY }}" > ~/.ssh/id_ed25519 | ||
| chmod 600 ~/.ssh/id_ed25519 | ||
| nix shell nixpkgs#rage -c sh -c 'rage -d -i ~/.ssh/id_ed25519 config/runtime.env.age > /tmp/local-db-runtime.env' | ||
| set -a | ||
| # shellcheck disable=SC1091 | ||
| source /tmp/local-db-runtime.env | ||
| set +a | ||
| { | ||
| echo "DUMP_BASE_URL=$DUMP_BASE_URL" | ||
| echo "SPACES_REGION=$SPACES_REGION" | ||
| echo "SPACES_BUCKET=$SPACES_BUCKET" | ||
| echo "SPACES_ENDPOINT=$SPACES_ENDPOINT" | ||
| } >> "$GITHUB_ENV" | ||
|
|
||
|
Comment on lines
+30
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Consider extracting the runtime config loading to a reusable composite action. This decryption pattern (SSH key setup + rage decrypt + export to ♻️ Example composite action structureCreate name: Load encrypted runtime config
description: Decrypt and load runtime.env.age into GITHUB_ENV
inputs:
ssh_key:
description: SSH private key for decryption
required: true
runs:
using: composite
steps:
- shell: bash
run: |
set -euo pipefail
mkdir -p ~/.ssh
printf '%s\n' "${{ inputs.ssh_key }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
nix shell nixpkgs#rage -c sh -c 'rage -d -i ~/.ssh/id_ed25519 config/runtime.env.age > /tmp/local-db-runtime.env'
set -a
source /tmp/local-db-runtime.env
set +a
{
echo "DUMP_BASE_URL=$DUMP_BASE_URL"
echo "SPACES_REGION=$SPACES_REGION"
echo "SPACES_BUCKET=$SPACES_BUCKET"
echo "SPACES_ENDPOINT=$SPACES_ENDPOINT"
} >> "$GITHUB_ENV"🤖 Prompt for AI Agents |
||
| - name: Create and upload empty manifest | ||
| id: create_manifest | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| manifest_url="$(nix run .#local-db-create-empty-manifest)" | ||
| manifest_url="$(nix run .#local-db-create-empty-manifest | tail -n 1)" | ||
| echo "manifest_url=$manifest_url" >>"$GITHUB_OUTPUT" | ||
|
|
||
| - name: Summarize manifest URL | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,6 +3,16 @@ name: Deploy | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inputs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| target_ref: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: Git ref to deploy from | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| default: main | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| allow_non_main: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: Allow deployment from a non-main ref | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| default: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: boolean | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| settings_url: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: Settings YAML URL to deploy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -18,22 +28,31 @@ permissions: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| HYPER_RPC_API_TOKEN: ${{ secrets.HYPER_RPC_API_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DUMP_BASE_URL: ${{ secrets.DUMP_BASE_URL }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PUBLIC_WALLETCONNECT_PROJECT_ID: "00000000000000000000000000000000" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SPACES_ACCESS_KEY: ${{ secrets.SPACES_ACCESS_KEY }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SPACES_SECRET_KEY: ${{ secrets.SPACES_SECRET_KEY }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SPACES_REGION: ${{ secrets.SPACES_REGION }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SPACES_BUCKET: ${{ secrets.SPACES_BUCKET }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SPACES_ENDPOINT: ${{ secrets.SPACES_ENDPOINT }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TAILSCALE_HOSTNAME: local-db-remote | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TARGET_REF: ${{ inputs.target_ref }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| deploy: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Validate target ref | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$TARGET_REF" != "main" ] && [ "${{ inputs.allow_non_main }}" != "true" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Set allow_non_main=true to deploy from a non-main ref." >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Free disk space | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: jlumbroso/free-disk-space@v1.3.1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ref: ${{ env.TARGET_REF }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| submodules: recursive | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -54,17 +73,40 @@ jobs: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf '%s\n' "${{ secrets.SSH_KEY }}" > ~/.ssh/id_ed25519 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| chmod 600 ~/.ssh/id_ed25519 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Load encrypted runtime config | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nix shell nixpkgs#rage -c sh -c 'rage -d -i ~/.ssh/id_ed25519 config/runtime.env.age > /tmp/local-db-runtime.env' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -a | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # shellcheck disable=SC1091 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| source /tmp/local-db-runtime.env | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set +a | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "DUMP_BASE_URL=$DUMP_BASE_URL" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "SPACES_REGION=$SPACES_REGION" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "SPACES_BUCKET=$SPACES_BUCKET" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "SPACES_ENDPOINT=$SPACES_ENDPOINT" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } >> "$GITHUB_ENV" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+76
to
+90
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Consider cleaning up the decrypted secrets file. Same as in 🛡️ Suggested cleanup {
echo "DUMP_BASE_URL=$DUMP_BASE_URL"
echo "SPACES_REGION=$SPACES_REGION"
echo "SPACES_BUCKET=$SPACES_BUCKET"
echo "SPACES_ENDPOINT=$SPACES_ENDPOINT"
} >> "$GITHUB_ENV"
+ rm -f /tmp/local-db-runtime.env📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Connect runner to Tailscale | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: tailscale/github-action@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| oauth-secret: ${{ secrets.TS_OAUTH_SECRET }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tags: tag:ci | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Prepare raindex submodule | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: ./prep.sh | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Build local CLI artifact | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: nix run .#build-raindex-cli | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Resolve host IP | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Resolve host over Tailscale | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| host_ip="$(nix run .#resolve-ip)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| host_ip="$(tailscale ip -4 "$TAILSCALE_HOSTNAME")" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "::add-mask::$host_ip" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "HOST_IP=$host_ip" >> "$GITHUB_ENV" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -75,6 +117,8 @@ jobs: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ssh-keyscan -H "$HOST_IP" >> ~/.ssh/known_hosts | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Deploy NixOS configuration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DEPLOY_HOST: ${{ env.HOST_IP }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: nix run .#deploy-nixos | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Upload runtime assets and restart service | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -124,6 +168,7 @@ jobs: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "## Local DB Remote Deployment" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "- Target ref: $TARGET_REF" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "- Host IP: $HOST_IP" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "- Settings URL: ${{ inputs.settings_url }}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "- Timer: local-db-sync.timer" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,16 @@ name: Provision Host | |
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| target_ref: | ||
| description: Git ref to provision from | ||
| required: true | ||
| default: main | ||
| type: string | ||
| allow_non_main: | ||
| description: Allow provisioning from a non-main ref | ||
| required: true | ||
| default: false | ||
| type: boolean | ||
| bootstrap_nixos: | ||
| description: Bootstrap NixOS onto the provisioned droplet | ||
| required: true | ||
|
|
@@ -22,13 +32,14 @@ jobs: | |
| runs-on: ubuntu-latest | ||
| env: | ||
| TF_VAR_do_token: ${{ secrets.DO_TOKEN }} | ||
| TARGET_REF: ${{ inputs.target_ref }} | ||
| steps: | ||
| - name: Require main branch | ||
| - name: Validate target ref | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| if [ "${GITHUB_REF_NAME}" != "main" ]; then | ||
| echo "This workflow must be run from the main branch." >&2 | ||
| if [ "$TARGET_REF" != "main" ] && [ "${{ inputs.allow_non_main }}" != "true" ]; then | ||
| echo "Set allow_non_main=true to provision from a non-main ref." >&2 | ||
| exit 1 | ||
| fi | ||
|
Comment on lines
+37
to
44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Constrain Line 90 assumes 🔧 Suggested hardening - uses: actions/checkout@v4
with:
ref: ${{ env.TARGET_REF }}
submodules: recursive
fetch-depth: 0
+
+ - name: Ensure target_ref is an existing remote branch
+ shell: bash
+ run: |
+ set -euo pipefail
+ if ! git ls-remote --exit-code --heads origin "$TARGET_REF" >/dev/null; then
+ echo "target_ref must be an existing branch name because terraform state is pushed back to it." >&2
+ exit 1
+ fiAlso applies to: 90-90 🤖 Prompt for AI Agents |
||
|
|
||
|
|
@@ -37,7 +48,7 @@ jobs: | |
|
|
||
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: main | ||
| ref: ${{ env.TARGET_REF }} | ||
| submodules: recursive | ||
| fetch-depth: 0 | ||
|
|
||
|
|
@@ -76,7 +87,7 @@ jobs: | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git add infra/terraform.tfstate.age infra/terraform.tfvars.age | ||
| git commit -m "chore: update local-db remote terraform state" | ||
| git push origin HEAD:main | ||
| git push origin HEAD:"$TARGET_REF" | ||
|
|
||
| - name: Resolve host IP | ||
| id: resolve_ip | ||
|
|
@@ -100,6 +111,7 @@ jobs: | |
| { | ||
| echo "## Host Provisioning" | ||
| echo | ||
| echo "- Target ref: $TARGET_REF" | ||
| echo "- Host IP: ${{ steps.resolve_ip.outputs.host_ip }}" | ||
| echo "- Bootstrap NixOS: ${{ inputs.bootstrap_nixos }}" | ||
| echo "- Terraform apply ran successfully" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| DUMP_BASE_URL= | ||
| SPACES_REGION= | ||
| SPACES_BUCKET= | ||
| SPACES_ENDPOINT= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| { | ||
| "runtime.env.age".publicKeys = (import ../keys.nix).roles.infra; | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Consider cleaning up the decrypted secrets file.
The decrypted runtime config at
/tmp/local-db-runtime.envcontains sensitive values and persists after the step completes. Consider adding cleanup for defense in depth.🛡️ Suggested cleanup
{ echo "DUMP_BASE_URL=$DUMP_BASE_URL" echo "SPACES_REGION=$SPACES_REGION" echo "SPACES_BUCKET=$SPACES_BUCKET" echo "SPACES_ENDPOINT=$SPACES_ENDPOINT" } >> "$GITHUB_ENV" + rm -f /tmp/local-db-runtime.env📝 Committable suggestion
🤖 Prompt for AI Agents