Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Deploy

on:
push:
branches: [main]
workflow_dispatch:
inputs:
tag:
description: "Existing image tag to (re)deploy; empty = build current SHA"
required: false

# default token is read-only; only the deploy job is granted id-token for WIF
permissions:
contents: read

concurrency:
group: deploy-production
cancel-in-progress: false

jobs:
test:
uses: ./.github/workflows/go.yml

deploy:
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v6
Comment thread
coderabbitai[bot] marked this conversation as resolved.
with:
# the workflow never pushes git; don't leave the token in .git/config
persist-credentials: false

- name: Resolve and validate image tag
id: tag
env:
# pass untrusted input through the environment, never interpolate it
# into the script body — a value like $(cmd) would otherwise run
# before the regex check below
RAW_TAG: ${{ inputs.tag }}
SHA: ${{ github.sha }}
run: |
tag="${RAW_TAG:-$SHA}"
# tag flows into shell commands below and a docker reference; allow
# only the characters valid in a docker tag so it cannot inject.
if ! printf '%s' "$tag" | grep -Eq '^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$'; then
echo "refusing unsafe image tag: $tag" >&2
exit 1
fi
echo "tag=$tag" >> "$GITHUB_OUTPUT"
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- uses: google-github-actions/auth@v3
with:
workload_identity_provider: ${{ vars.GCP_WIF_PROVIDER }}
service_account: ${{ vars.GCP_DEPLOYER_SA }}

- uses: google-github-actions/setup-gcloud@v3

- name: Build and push image
if: inputs.tag == ''
env:
IMAGE: ${{ vars.GCP_IMAGE }}
TAG: ${{ steps.tag.outputs.tag }}
run: |
gcloud auth configure-docker us-west1-docker.pkg.dev --quiet
docker build -t "${IMAGE}:${TAG}" .
docker push "${IMAGE}:${TAG}"

- name: Deploy to VM over IAP
env:
ZONE: ${{ vars.GCP_ZONE }}
VM: ${{ vars.GCP_VM }}
TAG: ${{ steps.tag.outputs.tag }}
run: |
gcloud compute ssh "$VM" --zone "$ZONE" --tunnel-through-iap \
--command='mkdir -p /tmp/planner-deploy'
gcloud compute scp deploy/docker-compose.prod.yml deploy/Caddyfile \
deploy/env.production deploy/deploy.sh \
"$VM":/tmp/planner-deploy/ --zone "$ZONE" --tunnel-through-iap
gcloud compute ssh "$VM" --zone "$ZONE" --tunnel-through-iap \
--command="sudo bash -c 'cp /tmp/planner-deploy/* /opt/planner/ && bash /opt/planner/deploy.sh ${TAG}'"
1 change: 1 addition & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches: [main]
pull_request:
branches: [main]
workflow_call:

jobs:
golangci:
Expand Down