Skip to content
Open
Show file tree
Hide file tree
Changes from 7 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
71 changes: 66 additions & 5 deletions .github/workflows/deploy-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ jobs:
sync-dev-to-main:
runs-on: ubuntu-latest
if: ${{ contains(fromJson(vars.PROD_DEPLOYMENT_ALLOWED_USERS), github.actor) }}
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand All @@ -33,17 +35,76 @@ jobs:
git merge --ff-only origin/dev || {
echo "❌ Fast-forward merge failed. Manual conflict resolution required."
echo "Please ensure dev branch is ahead of main with no conflicts."
git merge --abort
exit 1
}

- name: Push updated main branch
run: git push origin main

# Bump minor version on main
bump-minor-version:
runs-on: ubuntu-latest
needs: sync-dev-to-main
if: ${{ contains(fromJson(vars.PROD_DEPLOYMENT_ALLOWED_USERS), github.actor) }}
Comment thread
aditeyabaral marked this conversation as resolved.
permissions:
contents: write
steps:
- name: Checkout main
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
ref: main
fetch-depth: 0

- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Bump minor version
run: python3 scripts/bump_version.py minor

- name: Commit and push
run: |
git add pyproject.toml
Comment thread
aditeyabaral marked this conversation as resolved.
Outdated
git diff --cached --quiet && exit 0
git commit -m "chore: bump minor version [skip ci]"
Comment thread
aditeyabaral marked this conversation as resolved.
Comment thread
aditeyabaral marked this conversation as resolved.
git push origin main
Comment thread
aditeyabaral marked this conversation as resolved.

# Sync minor version bump back to dev so dev and main stay on the same commit
sync-minor-to-dev:
runs-on: ubuntu-latest
needs: bump-minor-version
if: ${{ contains(fromJson(vars.PROD_DEPLOYMENT_ALLOWED_USERS), github.actor) }}
permissions:
contents: write
steps:
- name: Checkout dev
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
ref: dev
fetch-depth: 0

- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Fast-forward dev to main
run: |
git fetch origin main
git merge --ff-only origin/main || {
echo "❌ Fast-forward merge of main into dev failed. dev has diverged from main."
echo "Please manually fast-forward dev to main before retrying the production deployment."
exit 1
}
git push origin dev

# Build and push Docker images
push-to-dockerhub:
runs-on: ubuntu-latest
needs: sync-dev-to-main
needs: bump-minor-version
if: ${{ contains(fromJson(vars.PROD_DEPLOYMENT_ALLOWED_USERS), github.actor) }}
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
Expand Down Expand Up @@ -84,7 +145,7 @@ jobs:
# Push to GitHub Container Registry
push-to-ghcr:
runs-on: ubuntu-latest
needs: sync-dev-to-main
needs: bump-minor-version
if: ${{ contains(fromJson(vars.PROD_DEPLOYMENT_ALLOWED_USERS), github.actor) }}
permissions:
contents: read
Expand Down Expand Up @@ -119,7 +180,7 @@ jobs:
# Deploy to Staging
deploy-to-staging:
runs-on: ubuntu-latest
needs: [sync-dev-to-main, push-to-dockerhub, push-to-ghcr]
needs: [bump-minor-version, push-to-dockerhub, push-to-ghcr]
Comment thread
aditeyabaral marked this conversation as resolved.
Outdated
if: ${{ contains(fromJson(vars.PROD_DEPLOYMENT_ALLOWED_USERS), github.actor) }}
env:
RENDER_DEPLOY_HOOK_URL_DEV: ${{ secrets.RENDER_DEPLOY_HOOK_URL_DEV }}
Expand All @@ -143,7 +204,7 @@ jobs:
# Deploy to Production
deploy-to-prod:
runs-on: ubuntu-latest
needs: [sync-dev-to-main, push-to-dockerhub, push-to-ghcr, deploy-to-staging]
needs: [bump-minor-version, push-to-dockerhub, push-to-ghcr, deploy-to-staging, sync-minor-to-dev]
if: ${{ contains(fromJson(vars.PROD_DEPLOYMENT_ALLOWED_USERS), github.actor) }}
env:
RENDER_DEPLOY_HOOK_URL_PROD: ${{ secrets.RENDER_DEPLOY_HOOK_URL_PROD }}
Expand Down
40 changes: 39 additions & 1 deletion .github/workflows/deploy-staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ on:
types:
- completed

concurrency:
group: deploy-staging-${{ github.event.workflow_run.head_branch }}
cancel-in-progress: false

jobs:
# Deploy to staging environment
deploy-staging:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'dev' }}
if: "${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'dev' && !startsWith(github.event.workflow_run.head_commit.message, 'chore: bump') }}"
permissions:
contents: write
env:
RENDER_DEPLOY_HOOK_URL_DEV: ${{ secrets.RENDER_DEPLOY_HOOK_URL_DEV }}
steps:
Expand All @@ -21,6 +27,38 @@ jobs:
exit 1
fi

- name: Checkout validated commit
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
ref: ${{ github.event.workflow_run.head_sha }}
fetch-depth: 0

- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Verify dev HEAD matches validated SHA
run: |
git fetch origin dev
DEV_HEAD=$(git rev-parse origin/dev)
VALIDATED_SHA="${{ github.event.workflow_run.head_sha }}"
if [ "$DEV_HEAD" != "$VALIDATED_SHA" ]; then
echo "⚠️ dev has advanced to $DEV_HEAD beyond the validated SHA $VALIDATED_SHA. Skipping."
exit 0
fi
Comment thread
aditeyabaral marked this conversation as resolved.
Comment thread
aditeyabaral marked this conversation as resolved.

- name: Bump patch version
run: python3 scripts/bump_version.py patch

- name: Commit and push
run: |
git add pyproject.toml
Comment thread
aditeyabaral marked this conversation as resolved.
Outdated
git diff --cached --quiet && exit 0
git commit -m "chore: bump patch version [skip ci]"
Comment thread
aditeyabaral marked this conversation as resolved.
git push origin HEAD:dev
Comment thread
aditeyabaral marked this conversation as resolved.
Comment thread
aditeyabaral marked this conversation as resolved.

- name: Deploy to Staging Environment
Comment thread
aditeyabaral marked this conversation as resolved.
run: |
echo "🚀 Deploying to Staging..."
Expand Down
35 changes: 35 additions & 0 deletions scripts/bump_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env python3

Check failure on line 1 in scripts/bump_version.py

View workflow job for this annotation

GitHub Actions / lint (3.13)

ruff (D100)

scripts/bump_version.py:1:1: D100 Missing docstring in public module

Check failure on line 1 in scripts/bump_version.py

View workflow job for this annotation

GitHub Actions / lint (3.12)

ruff (D100)

scripts/bump_version.py:1:1: D100 Missing docstring in public module
import re
import sys

if len(sys.argv) != 2 or sys.argv[1] not in ("patch", "minor"):
raise SystemExit("Usage: bump_version.py [patch|minor]")

bump_type = sys.argv[1]

with open("pyproject.toml") as f:
content = f.read()

match = re.search(r'^version = "(\d+)\.(\d+)\.(\d+)"', content, re.MULTILINE)
if not match:
raise SystemExit('version = "x.y.z" not found in pyproject.toml')

major, minor, patch = int(match.group(1)), int(match.group(2)), int(match.group(3))

if bump_type == "patch":
new_version = f"{major}.{minor}.{patch + 1}"
else:
new_version = f"{major}.{minor + 1}.0"

new_content = re.sub(
r'^version = "\d+\.\d+\.\d+"',
f'version = "{new_version}"',
content,
count=1,
flags=re.MULTILINE,
)

with open("pyproject.toml", "w") as f:
f.write(new_content)
Comment thread
aditeyabaral marked this conversation as resolved.

print(f"Bumped: {major}.{minor}.{patch} -> {new_version}")
Loading