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
Original file line number Diff line number Diff line change
@@ -1,121 +1,167 @@
name: Deploy
name: Deploy to Production

on:
workflow_run:
workflows: [ "Pre-Commit Checks" ]
types:
- completed
workflow_dispatch:

env:
# Array of usernames allowed to trigger production deploys
ALLOWED_USERS: '["aditeyabaral", "achyu-dev", "ndigvijay"]'

jobs:
# Docker build and push (main only)
# Sync dev branch to main before deployment
sync-dev-to-main:
runs-on: ubuntu-latest
if: ${{ contains(fromJson(env.ALLOWED_USERS), github.actor) }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
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: Fetch all branches
run: |
git fetch origin dev
git fetch origin main
- name: Checkout main branch
run: git checkout main

- name: Merge dev into main
run: |
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

# Build and push Docker images
push-to-dockerhub:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.head_branch == 'main' && github.event.workflow_run.conclusion == 'success' }}
needs: sync-dev-to-main
if: ${{ contains(fromJson(env.ALLOWED_USERS), github.actor) }}
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
steps:
- uses: actions/checkout@v3
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main

- name: Check Docker credentials
run: |
if [ -z "${{ secrets.DOCKER_USERNAME }}" ] || [ -z "${{ secrets.DOCKER_PASSWORD }}" ]; then
echo "Secrets missing, skipping push"
echo "❌ Docker credentials missing, skipping Docker Hub push"
exit 1
fi
- name: Get short commit hash
id: vars
run: echo "tag=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build and tag image
run: |
docker build . --tag ${{ secrets.DOCKER_USERNAME }}/pesu-auth:${{ steps.vars.outputs.tag }}
docker tag ${{ secrets.DOCKER_USERNAME }}/pesu-auth:${{ steps.vars.outputs.tag }} ${{ secrets.DOCKER_USERNAME }}/pesu-auth:latest
- name: Push image to Docker Hub
run: |
docker push ${{ secrets.DOCKER_USERNAME }}/pesu-auth:${{ steps.vars.outputs.tag }}
docker push ${{ secrets.DOCKER_USERNAME }}/pesu-auth:latest
# GHCR build and push (main only)
# Push to GitHub Container Registry
push-to-ghcr:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.head_branch == 'main' && github.event.workflow_run.conclusion == 'success' }}
needs: sync-dev-to-main
if: ${{ contains(fromJson(env.ALLOWED_USERS), github.actor) }}
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v3
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main

- name: Get short commit hash
id: vars
run: echo "tag=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and tag image for GHCR
run: |
docker build . --tag ghcr.io/${{ github.repository_owner }}/pesu-auth:${{ steps.vars.outputs.tag }}
docker tag ghcr.io/${{ github.repository_owner }}/pesu-auth:${{ steps.vars.outputs.tag }} ghcr.io/${{ github.repository_owner }}/pesu-auth:latest
- name: Push image to GitHub Container Registry
run: |
docker push ghcr.io/${{ github.repository_owner }}/pesu-auth:${{ steps.vars.outputs.tag }}
docker push ghcr.io/${{ github.repository_owner }}/pesu-auth:latest
# Deploy both environments on main
# Deploy to both Production and Staging
deploy-prod-and-staging:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.head_branch == 'main' && github.event.workflow_run.conclusion == 'success' }}
needs: [sync-dev-to-main, push-to-dockerhub, push-to-ghcr]
if: ${{ contains(fromJson(env.ALLOWED_USERS), github.actor) }}
env:
RENDER_DEPLOY_HOOK_URL_PROD: ${{ secrets.RENDER_DEPLOY_HOOK_URL_PROD }}
RENDER_DEPLOY_HOOK_URL_DEV: ${{ secrets.RENDER_DEPLOY_HOOK_URL_DEV }}
steps:
- name: Check Deploy Hook URLs
run: |
if [ -z "${{ secrets.RENDER_DEPLOY_HOOK_URL_PROD }}" ]; then
echo "Production deploy hook missing!"
echo "❌ Production deploy hook missing!"
exit 1
fi
if [ -z "${{ secrets.RENDER_DEPLOY_HOOK_URL_DEV }}" ]; then
echo "Staging deploy hook missing!"
echo "❌ Staging deploy hook missing!"
exit 1
fi
- name: Deploy to Production
run: |
echo "πŸš€ Deploying to Production..."
curl -X POST ${{ secrets.RENDER_DEPLOY_HOOK_URL_PROD }} || {
echo "❌ Production deploy failed!"
exit 1
}
- name: Sync Staging with Production
run: |
echo "πŸš€ Deploying to Staging (mirror prod)..."
curl -X POST ${{ secrets.RENDER_DEPLOY_HOOK_URL_DEV }} || {
echo "❌ Staging deploy failed!"
exit 1
}
echo "βœ… Production deployment completed successfully!"
# Deploy only to staging on dev
deploy-staging-only:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.head_branch == 'dev' && github.event.workflow_run.conclusion == 'success' }}
env:
RENDER_DEPLOY_HOOK_URL_DEV: ${{ secrets.RENDER_DEPLOY_HOOK_URL_DEV }}
steps:
- name: Check Staging Deploy Hook URL
run: |
if [ -z "${{ secrets.RENDER_DEPLOY_HOOK_URL_DEV }}" ]; then
echo "Staging deploy hook missing!"
exit 1
fi
- name: Deploy to Staging (Dev branch)
- name: Deploy to Staging
run: |
echo "πŸš€ Deploying to Staging..."
curl -X POST ${{ secrets.RENDER_DEPLOY_HOOK_URL_DEV }} || {
echo "❌ Staging deploy failed!"
exit 1
}
echo "βœ… Staging deployment completed successfully!"
- name: Deployment Summary
run: |
echo "πŸŽ‰ All deployments completed successfully!"
echo "βœ… Branch sync: dev β†’ main"
echo "βœ… Docker images: pushed to Docker Hub and GHCR"
echo "βœ… Production: deployed"
echo "βœ… Staging: deployed"
31 changes: 31 additions & 0 deletions .github/workflows/deploy-staging.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Deploy to Staging

on:
workflow_run:
workflows: [ "Pre-Commit Checks" ]
types:
- completed

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' }}
env:
RENDER_DEPLOY_HOOK_URL_DEV: ${{ secrets.RENDER_DEPLOY_HOOK_URL_DEV }}
steps:
- name: Check Staging Deploy Hook URL
run: |
if [ -z "${{ secrets.RENDER_DEPLOY_HOOK_URL_DEV }}" ]; then
echo "❌ Staging deploy hook missing!"
exit 1
fi

- name: Deploy to Staging Environment
run: |
echo "πŸš€ Deploying to Staging..."
curl -X POST ${{ secrets.RENDER_DEPLOY_HOOK_URL_DEV }} || {
echo "❌ Staging deploy failed!"
exit 1
}
echo "βœ… Staging deployment completed successfully!"
15 changes: 11 additions & 4 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
name: Docker Image Build

on: [ push, pull_request ]
on:
push:
branches-ignore:
- main
- dev
pull_request:
types:
- opened
- synchronize
- reopened

jobs:

build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Get short commit hash
id: vars
Expand Down
18 changes: 12 additions & 6 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
name: Lint

on: [ push, pull_request ]
on:
push:
branches-ignore:
- main
- dev
pull_request:
types:
- opened
- synchronize
- reopened

jobs:
lint:
Expand All @@ -11,14 +20,11 @@ jobs:
python-version: [ "3.11", "3.12", "3.13" ]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install -r requirements.txt

- name: Install Ruff
run: pip install ruff
Expand Down
10 changes: 4 additions & 6 deletions .github/workflows/pre-commit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Pre-Commit Checks
on: [ push, pull_request ]

jobs:
pre-commit:
pre-commit-checks:
runs-on: ubuntu-latest
strategy:
max-parallel: 1
Expand All @@ -16,7 +16,6 @@ jobs:
TEST_SRN: ${{ secrets.TEST_SRN }}
TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
TEST_BRANCH: ${{ secrets.TEST_BRANCH }}
TEST_BRANCH_SHORT_CODE: ${{ secrets.TEST_BRANCH_SHORT_CODE }}
TEST_PROGRAM: ${{ secrets.TEST_PROGRAM }}
TEST_SEMESTER: ${{ secrets.TEST_SEMESTER }}
TEST_SECTION: ${{ secrets.TEST_SECTION }}
Expand All @@ -26,18 +25,17 @@ jobs:
TEST_CAMPUS_CODE: ${{ secrets.TEST_CAMPUS_CODE }}

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

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

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pre-commit pytest pytest-cov httpx python-dotenv pytest-asyncio
pip install .[dev]

- name: Run pre-commit hooks
run: pre-commit run --all-files
14 changes: 5 additions & 9 deletions .github/workflows/source.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,21 @@ jobs:

- name: Validate PR origin and target branch
run: |
# Allow dev β†’ main PRs, but only if it's within the same repo (not a fork)
if [ "$SOURCE_REPO" = "$TARGET_REPO" ] && [ "$SOURCE_BRANCH" = "dev" ] && [ "$TARGET_BRANCH" = "main" ]; then
echo "βœ… Dev to Main PR (release) allowed (same repo)."
exit 0
fi

# Otherwise: PRs must come from a fork, non-main branch, targeting dev
# PRs must come from a fork
if [ "$SOURCE_REPO" = "$TARGET_REPO" ]; then
echo "❌ PR must come from a fork (not the main repo)."
echo "❌ PR must come from a fork."
exit 1
fi

# PRs cannot come from the 'main' branch of a fork
if [ "$SOURCE_BRANCH" = "main" ]; then
echo "❌ PR cannot come from the 'main' branch of a fork."
exit 1
fi

# PRs must target the 'dev' branch only
if [ "$TARGET_BRANCH" != "dev" ]; then
echo "❌ PR must target the 'dev' branch (unless it's a dev β†’ main release)."
echo "❌ PR must target the 'dev' branch only. PRs to 'main' are not allowed."
exit 1
fi

Expand Down