Skip to content
Draft
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
198 changes: 198 additions & 0 deletions .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
name: Deploy to Staging

on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to deploy (default: main)'
required: false
type: string
default: 'main'
service_name:
description: 'GCP App Engine service name to deploy to (default: wildebackyard-web-staging)'
required: false
type: string
default: 'wildebackyard-web-staging'

env:
GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
GCP_REGION: us-central1
PYTHON_VERSION: '3.12'
SERVICE_NAME: ${{ inputs.service_name || 'wildebackyard-web-staging' }}

jobs:
test:
name: Run Tests
runs-on: ubuntu-latest

permissions:
contents: read

env:
DJANGO_SECRET_KEY: test-secret-key-for-ci
DJANGO_SETTINGS_MODULE: config.settings.local
DJANGO_ADMIN_URL: admin/
BACKEND_API_URL: https://wildebackyard-api-dot-wildepod-339517.wl.r.appspot.com

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ inputs.branch || 'main' }}

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Install uv
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.cargo/bin" >> $GITHUB_PATH

- name: Install dependencies
run: |
uv sync
uv pip install -r requirements-dev.txt

- name: Run tests
run: |
uv run pytest --verbose --tb=short

build:
name: Build Validation
runs-on: ubuntu-latest
needs: test

permissions:
contents: read

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ inputs.branch || 'main' }}

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt

- name: Validate GCP credentials secret
env:
GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }}
run: |
if [ -z "$GCP_SA_KEY" ]; then
echo "Error: GCP_SA_KEY secret is not set or is empty"
echo "Please configure the GCP_SA_KEY secret in your repository settings:"
echo "1. Go to Settings → Secrets and variables → Actions"
echo "2. Add a new secret named 'GCP_SA_KEY'"
echo "3. Paste the contents of your service account JSON key"
exit 1
fi

- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}

- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2

- name: Validate app.yaml
run: |
if [ ! -f "app.yaml" ]; then
echo "Error: app.yaml not found"
exit 1
fi
python -c "import yaml; yaml.safe_load(open('app.yaml'))"
echo "✓ app.yaml is valid"

deploy:
name: Deploy to App Engine Staging
runs-on: ubuntu-latest
needs: [test, build]
environment:
name: staging

permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ inputs.branch || 'main' }}

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}

- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Update version.py with deployment commit hash
shell: bash
run: |
SHORT_HASH=$(git rev-parse --short HEAD)
RELEASE_TAG=$(git describe --tags --exact-match 2>/dev/null || echo "staging")
export SHORT_HASH RELEASE_TAG
python3 << 'PYTHON'
import os
short_hash = os.environ.get('SHORT_HASH', 'unknown')
release_tag = os.environ.get('RELEASE_TAG', 'unknown')
with open('config/version.py', 'w') as f:
f.write('"""\n')
f.write('Version information for the application.\n')
f.write('This file is automatically updated by the GitHub Actions workflow during deployment.\n')
f.write('"""\n')
f.write('\n')
f.write('VERSION = {\n')
f.write(f' "commit_hash": "{short_hash}",\n')
f.write(f' "release_tag": "{release_tag}",\n')
f.write('}\n')
print(f'✓ Updated version.py with commit hash: {short_hash} and release tag: {release_tag}')
PYTHON

- name: Collect static files
continue-on-error: true
env:
DJANGO_SECRET_KEY: ${{ secrets.DJANGO_SECRET_KEY }}
CLOUD_SQL_DATABASE_URL_STAGING: ${{ secrets.CLOUD_SQL_DATABASE_URL_STAGING }}
run: |
uv run python manage.py collectstatic --noinput --settings=config.settings.staging || echo "Static collection skipped"

- name: Deploy to App Engine
run: |
gcloud app deploy \
--project=${{ env.GCP_PROJECT_ID }} \
--verbosity=info \
--no-promote \
--version=$(echo $GITHUB_SHA | cut -c1-7) \
--appyaml=app.yaml

- name: Get deployment info
id: deployment
run: |
VERSION=$(echo $GITHUB_SHA | cut -c1-7)
URL="https://${VERSION}-dot-${{ env.SERVICE_NAME }}-dot-${{ env.GCP_PROJECT_ID }}.appspot.com"
echo "url=$URL" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "✓ Deployed version ${VERSION} to ${{ env.SERVICE_NAME }}"
echo "✓ URL: ${URL}"
Loading