Skip to content

Production

Production #716

Workflow file for this run

name: Production
on:
pull_request:
merge_group:
types: [checks_requested]
jobs:
# 👾 GIT METADATA 👾 #
git-meta:
runs-on: ubuntu-latest
if: always() && github.event_name == 'merge_group'
outputs:
git_pr_branch_name: ${{ steps.git-meta.outputs.github_commit_ref }}
github_commit_sha: ${{ steps.git-meta.outputs.github_commit_sha }}
github_commit_author_name: ${{ steps.git-meta.outputs.github_commit_author_name }}
github_commit_author_login: ${{ steps.git-meta.outputs.github_commit_author_login }}
github_deployment: ${{ steps.git-meta.outputs.github_deployment }}
github_org: ${{ steps.git-meta.outputs.github_org }}
github_repo: ${{ steps.git-meta.outputs.github_repo }}
github_commit_org: ${{ steps.git-meta.outputs.github_commit_org }}
github_commit_repo: ${{ steps.git-meta.outputs.github_commit_repo }}
github_commit_message: ${{ steps.git-meta.outputs.github_commit_message }}
github_commit_ref: ${{ steps.git-meta.outputs.github_commit_ref }}
vercel_git_metadata: ${{ steps.git-meta.outputs.vercel_git_metadata }}
steps:
- name: checkout
uses: actions/checkout@v4
with:
fetch-depth: 2
- id: git-meta
run: |
github_commit_author_login=${{ github.actor }}
github_deployment=1
github_org=${{ github.repository_owner }}
github_repo=${{ github.repository }}
github_commit_org=${{ github.repository_owner }}
github_commit_repo=${{ github.repository }}
github_commit_message=$(git show -s --format=%)
commit_ref=${{ github.ref }}
echo "commit_ref: $commit_ref"
pr_number=$(echo $commit_ref | awk -F'/' '{print $5}' | awk -F'-' '{print $2}')
pr_info=$(curl -s H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/${{ github.repository }}/pulls/$pr_number)
github_commit_ref=$(echo $pr_info | jq -r '.head.ref')
echo "github_commit_ref: $github_commit_ref"
github_commit_sha=$(echo $pr_info | jq -r '.head.sha')
echo "github_commit_sha: $github_commit_sha"
if [ "$github_commit_ref" = "main" ]; then
echo "Error: Cannot proceed with 'main' branch."
exit 1
fi
vercel_git_metadata="-m githubCommitSha=$github_commit_sha -m githubCommitAuthorName=$github_commit_author_login -m githubCommitAuthorLogin=$github_commit_author_login -m githubDeployment=$github_deployment -m githubOrg=$github_org -m githubRepo=$github_repo -m githubCommitOrg=$github_commit_org -m githubCommitRepo=$github_commit_repo -m githubCommitMessage=\"$github_commit_message\" -m githubCommitRef=$github_commit_ref"
echo "github_commit_sha=$github_commit_sha" >> $GITHUB_OUTPUT
echo "github_commit_author_name=$github_commit_author_name" >> $GITHUB_OUTPUT
echo "github_commit_author_login=$github_commit_author_login" >> $GITHUB_OUTPUT
echo "github_deployment=$github_deployment" >> $GITHUB_OUTPUT
echo "github_org=$github_org" >> $GITHUB_OUTPUT
echo "github_repo=$github_repo" >> $GITHUB_OUTPUT
echo "github_commit_org=$github_commit_org" >> $GITHUB_OUTPUT
echo "github_commit_repo=$github_commit_repo" >> $GITHUB_OUTPUT
echo "github_commit_message=$github_commit_message" >> $GITHUB_OUTPUT
echo "github_commit_ref=$github_commit_ref" >> $GITHUB_OUTPUT
echo "vercel_git_metadata=$vercel_git_metadata" >> $GITHUB_OUTPUT
# 🐘 NEON DB:PUSH 🐘 #
db-push:
name: db:push
needs: [git-meta]
if: always() && github.event_name == 'merge_group' && needs.git-meta.result == 'success'
permissions: write-all
runs-on: ubuntu-latest
outputs:
neon_branch_id: ${{ steps.get-neon-branch.outputs.branch_id }}
steps:
- name: checkout
uses: actions/checkout@v4
- name: setup node/pnpm/turbo/vercel
uses: ./tooling/github/setup
- name: install neon cli
run: pnpm install -g neonctl
- name: copy env
shell: bash
run: cp .env.example .env
- id: get-neon-branch
run: |
echo branch_id=$(neonctl branches get main --project-id ${{ secrets.NEON_PROJECT_ID }} --api-key ${{ secrets.NEON_API_KEY }} --output json | jq -r '.id') >> $GITHUB_OUTPUT
- name: db:push
run: |
rm -f .env
touch .env
echo DATABASE_URL=$(neonctl cs ${{ secrets.NEON_MAIN_BRANCH_NAME }} --project-id ${{ secrets.NEON_PROJECT_ID }} --role-name ${{ secrets.PG_USERNAME }} --database-name ${{ secrets.PG_DATABASE }} --api-key ${{ secrets.NEON_API_KEY }}) >> .env
echo DIRECT_DATABASE_URL=$(neonctl cs ${{ secrets.NEON_MAIN_BRANCH_NAME }} --project-id ${{ secrets.NEON_PROJECT_ID }} --role-name ${{ secrets.PG_USERNAME }} --database-name ${{ secrets.PG_DATABASE }} --api-key ${{ secrets.NEON_API_KEY }}) >> .env
output=$(pnpm db:push)
echo "output: $output"
if [[ $output == *"error:"* || $output == *"severity: 'ERROR'"* ]]; then
echo "Unhandled error: $output" && exit 1
fi
# 📱 DEPLOY APPS -- PROD (Not Aliasing to Production Yet) #
deploy-app:
uses: ./.github/workflows/deploy-to-vercel.yml
needs: [git-meta, db-push]
with:
app_name: app
working_directory: apps/app
scope: barely
environment: production
git_branch: ${{ needs.git-meta.outputs.github_commit_ref }}
vercel_git_metadata: ${{ needs.git-meta.outputs.vercel_git_metadata }}
secrets:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_TEAM_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_APP_PROJECT_ID }}
deploy-cart:
uses: ./.github/workflows/deploy-to-vercel.yml
needs: [git-meta, db-push]
with:
app_name: cart
working_directory: apps/cart
scope: barely
environment: production
git_branch: ${{ needs.git-meta.outputs.github_commit_ref }}
vercel_git_metadata: ${{ needs.git-meta.outputs.vercel_git_metadata }}
secrets:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_TEAM_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_CART_PROJECT_ID }}
deploy-fm:
uses: ./.github/workflows/deploy-to-vercel.yml
needs: [git-meta, db-push]
with:
app_name: fm
working_directory: apps/fm
scope: barely
environment: production
git_branch: ${{ needs.git-meta.outputs.github_commit_ref }}
vercel_git_metadata: ${{ needs.git-meta.outputs.vercel_git_metadata }}
secrets:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_TEAM_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_FM_PROJECT_ID }}
deploy-link:
uses: ./.github/workflows/deploy-to-vercel.yml
needs: [git-meta, db-push]
with:
app_name: link
working_directory: apps/link
scope: barely
environment: production
git_branch: ${{ needs.git-meta.outputs.github_commit_ref }}
vercel_git_metadata: ${{ needs.git-meta.outputs.vercel_git_metadata }}
secrets:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_TEAM_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_LINK_PROJECT_ID }}
deploy-manage-email:
uses: ./.github/workflows/deploy-to-vercel.yml
needs: [git-meta, db-push]
with:
app_name: manage-email
working_directory: apps/manage-email
scope: barely
environment: production
git_branch: ${{ needs.git-meta.outputs.github_commit_ref }}
vercel_git_metadata: ${{ needs.git-meta.outputs.vercel_git_metadata }}
secrets:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_TEAM_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_MANAGE_EMAIL_PROJECT_ID }}
deploy-page:
uses: ./.github/workflows/deploy-to-vercel.yml
needs: [git-meta, db-push]
with:
app_name: page
working_directory: apps/page
scope: barely
environment: production
git_branch: ${{ needs.git-meta.outputs.github_commit_ref }}
vercel_git_metadata: ${{ needs.git-meta.outputs.vercel_git_metadata }}
secrets:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_TEAM_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PAGE_PROJECT_ID }}
deploy-press:
uses: ./.github/workflows/deploy-to-vercel.yml
needs: [git-meta, db-push]
with:
app_name: press
working_directory: apps/press
scope: barely
environment: production
git_branch: ${{ needs.git-meta.outputs.github_commit_ref }}
vercel_git_metadata: ${{ needs.git-meta.outputs.vercel_git_metadata }}
secrets:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_TEAM_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PRESS_PROJECT_ID }}
deploy-sparrow:
uses: ./.github/workflows/deploy-to-vercel.yml
needs: [git-meta, db-push]
with:
app_name: sparrow
working_directory: apps/sparrow
scope: barely
environment: production
git_branch: ${{ needs.git-meta.outputs.github_commit_ref }}
vercel_git_metadata: ${{ needs.git-meta.outputs.vercel_git_metadata }}
secrets:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_TEAM_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_SPARROW_PROJECT_ID }}
deploy-www:
uses: ./.github/workflows/deploy-to-vercel.yml
needs: [git-meta, db-push]
with:
app_name: www
working_directory: apps/www
scope: barely
environment: production
git_branch: ${{ needs.git-meta.outputs.github_commit_ref }}
vercel_git_metadata: ${{ needs.git-meta.outputs.vercel_git_metadata }}
secrets:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_TEAM_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_WWW_PROJECT_ID }}
# trigger.dev
trigger-production:
name: trigger production
needs:
[
git-meta,
db-push,
deploy-app,
deploy-cart,
deploy-link,
deploy-manage-email,
deploy-page,
deploy-press,
deploy-sparrow,
deploy-www,
]
if: always() && github.event_name == 'merge_group' # skip if pull request, which allows entry into merge queue
permissions:
actions: read
runs-on: ubuntu-latest
steps:
- name: Transform outcomes to JSON
env:
NEEDS_JSON: '${{ toJson(needs) }}'
run: |
echo "ALL_SUCCESS=$(echo "$NEEDS_JSON" | jq '. | to_entries | map([.value.result == "success", .value.result == "skipped"] | any) | all')" >> $GITHUB_ENV
- name: Check outcomes
run: '[ $ALL_SUCCESS = true ]'
- uses: actions/checkout@v4
- name: setup node/pnpm/turbo/vercel
uses: ./tooling/github/setup
- name: deploy trigger.dev
env:
TRIGGER_ACCESS_TOKEN: ${{ secrets.TRIGGER_ACCESS_TOKEN }}
run: pnpm deploy-trigger:production
# 🔀 MERGE PR BRANCH TO MAIN 🔀
production--can-merge:
needs:
[
git-meta,
db-push,
deploy-app,
deploy-cart,
deploy-fm,
deploy-link,
deploy-manage-email,
deploy-page,
deploy-press,
deploy-sparrow,
deploy-www,
trigger-production,
]
if: always() && github.event_name == 'merge_group' # skip if pull request, which allows entry into merge queue
permissions:
actions: read
runs-on: ubuntu-latest
steps:
- name: Transform outcomes to JSON
env:
NEEDS_JSON: '${{ toJson(needs) }}'
run: |
echo "ALL_SUCCESS=$(echo "$NEEDS_JSON" | jq '. | to_entries | map([.value.result == "success", .value.result == "skipped"] | any) | all')" >> $GITHUB_ENV
- name: Check outcomes
run: '[ $ALL_SUCCESS = true ]'
# 🚀 PROMOTE APPS TO PRODUCTION DOMAINS 🚀 #
# -- at a later date, we could decouple this promotion step from deploying & merging to main
promote-app:
name: promote app to production
needs: [production--can-merge, deploy-app]
if: always() && github.event_name == 'merge_group' && ${{ needs.production--can-merge.result }} == 'success'
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_APP_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Promote app to production
run: vercel promote dpl_${{ needs.deploy-app.outputs.deployment_id }} --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
promote-cart:
name: promote cart to production
needs: [production--can-merge, deploy-cart]
if: always() && github.event_name == 'merge_group' && ${{ needs.production--can-merge.result }} == 'success'
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_CART_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Promote cart to production
run: vercel promote dpl_${{ needs.deploy-cart.outputs.deployment_id }} --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
promote-fm:
name: promote fm to production
needs: [production--can-merge, deploy-fm]
if: always() && github.event_name == 'merge_group' && ${{ needs.production--can-merge.result }} == 'success'
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_FM_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Promote fm to production
run: vercel promote dpl_${{ needs.deploy-fm.outputs.deployment_id }} --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
promote-link:
name: promote link to production
needs: [production--can-merge, deploy-link]
if: always() && github.event_name == 'merge_group' && ${{ needs.production--can-merge.result }} == 'success'
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_LINK_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Promote link to production
run: vercel promote dpl_${{ needs.deploy-link.outputs.deployment_id }} --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
promote-manage-email:
name: promote manage-email to production
needs: [production--can-merge, deploy-manage-email]
if: always() && github.event_name == 'merge_group' && ${{ needs.production--can-merge.result }} == 'success'
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_MANAGE_EMAIL_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Promote manage-email to production
run: vercel promote dpl_${{ needs.deploy-manage-email.outputs.deployment_id }} --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
promote-page:
name: promote page to production
needs: [production--can-merge, deploy-page]
if: always() && github.event_name == 'merge_group' && ${{ needs.production--can-merge.result }} == 'success'
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PAGE_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Promote page to production
run: vercel promote dpl_${{ needs.deploy-page.outputs.deployment_id }} --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
promote-press:
name: promote press to production
needs: [production--can-merge, deploy-press]
if: always() && github.event_name == 'merge_group' && ${{ needs.production--can-merge.result }} == 'success'
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PRESS_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Promote press to production
run: vercel promote dpl_${{ needs.deploy-press.outputs.deployment_id }} --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
promote-sparrow:
name: promote sparrow to production
needs: [production--can-merge, deploy-sparrow]
if: always() && github.event_name == 'merge_group' && ${{ needs.production--can-merge.result }} == 'success'
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_SPARROW_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Promote sparrow to production
run: vercel promote dpl_${{ needs.deploy-sparrow.outputs.deployment_id }} --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
promote-www:
name: promote www to production
needs: [production--can-merge, deploy-www]
if: always() && github.event_name == 'merge_group' && ${{ needs.production--can-merge.result }} == 'success'
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_WWW_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Promote www to production
run: vercel promote dpl_${{ needs.deploy-www.outputs.deployment_id }} --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
# 🚨 ROLLBACK APPS (IF ANY PROMOTION FAILS) 🚨 #
# ref: https://dev.to/philw_/using-vercels-instant-rollback-feature-in-your-own-cicd-pipeline-57oi
rollback-app:
name: rollback app if any deployments fail
needs:
[
promote-app,
promote-cart,
promote-link,
promote-manage-email,
promote-page,
promote-press,
promote-sparrow,
promote-www,
]
if: ${{ failure() && needs.promote-app.result == 'success' }}
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_APP_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Rollback app
run: |
ROLLBACK_DEPLOYMENT_ID=$(curl -s "https://api.vercel.com/v6/deployments?teamId=${{ secrets.VERCEL_TEAM_ID }}&projectId=${{ secrets.VERCEL_APP_PROJECT_ID}}&limit=2&rollbackCandidate=true&state=READY&target=production" -H "Authorization: Bearer ${{ secrets.VERCEL_TOKEN }}" | jq -r '.deployments[1].uid')
echo "Rolling back to the previous deployment ID: $ROLLBACK_DEPLOYMENT_ID"
vercel rollback $ROLLBACK_DEPLOYMENT_ID --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
rollback-cart:
name: rollback cart if any deployments fail
needs:
[
promote-app,
promote-cart,
promote-link,
promote-manage-email,
promote-page,
promote-press,
promote-sparrow,
promote-www,
]
if: ${{ failure() && needs.promote-cart.result == 'success' }}
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_CART_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Rollback cart
run: |
ROLLBACK_DEPLOYMENT_ID=$(curl -s "https://api.vercel.com/v6/deployments?teamId=${{ secrets.VERCEL_TEAM_ID }}&projectId=${{ secrets.VERCEL_CART_PROJECT_ID}}&limit=2&rollbackCandidate=true&state=READY&target=production" -H "Authorization: Bearer ${{ secrets.VERCEL_TOKEN }}" | jq -r '.deployments[1].uid')
echo "Rolling back to the previous deployment ID: $ROLLBACK_DEPLOYMENT_ID"
vercel rollback $ROLLBACK_DEPLOYMENT_ID --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
rollback-fm:
name: rollback fm if any deployments fail
needs:
[
promote-app,
promote-cart,
promote-fm,
promote-link,
promote-manage-email,
promote-page,
promote-press,
promote-sparrow,
promote-www,
]
if: ${{ failure() && needs.promote-fm.result == 'success' }}
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_FM_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Rollback fm
run: |
ROLLBACK_DEPLOYMENT_ID=$(curl -s "https://api.vercel.com/v6/deployments?teamId=${{ secrets.VERCEL_TEAM_ID }}&projectId=${{ secrets.VERCEL_FM_PROJECT_ID}}&limit=2&rollbackCandidate=true&state=READY&target=production" -H "Authorization: Bearer ${{ secrets.VERCEL_TOKEN }}" | jq -r '.deployments[1].uid')
echo "Rolling back to the previous deployment ID: $ROLLBACK_DEPLOYMENT_ID"
vercel rollback $ROLLBACK_DEPLOYMENT_ID --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
rollback-link:
name: rollback link if any deployments fail
needs:
[
promote-app,
promote-cart,
promote-link,
promote-manage-email,
promote-page,
promote-press,
promote-sparrow,
promote-www,
]
if: ${{ failure() && needs.promote-link.result == 'success' }}
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_LINK_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Rollback link
run: |
ROLLBACK_DEPLOYMENT_ID=$(curl -s "https://api.vercel.com/v6/deployments?teamId=${{ secrets.VERCEL_TEAM_ID }}&projectId=${{ secrets.VERCEL_LINK_PROJECT_ID}}&limit=2&rollbackCandidate=true&state=READY&target=production" -H "Authorization: Bearer ${{ secrets.VERCEL_TOKEN }}" | jq -r '.deployments[1].uid')
echo "Rolling back to the previous deployment ID: $ROLLBACK_DEPLOYMENT_ID"
vercel rollback $ROLLBACK_DEPLOYMENT_ID --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
rollback-manage-email:
name: rollback manage-email if any deployments fail
needs:
[
promote-app,
promote-cart,
promote-link,
promote-manage-email,
promote-page,
promote-press,
promote-sparrow,
promote-www,
]
if: ${{ failure() && needs.promote-manage-email.result == 'success' }}
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_MANAGE_EMAIL_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Rollback manage-email
run: |
ROLLBACK_DEPLOYMENT_ID=$(curl -s "https://api.vercel.com/v6/deployments?teamId=${{ secrets.VERCEL_TEAM_ID }}&projectId=${{ secrets.VERCEL_MANAGE_EMAIL_PROJECT_ID}}&limit=2&rollbackCandidate=true&state=READY&target=production" -H "Authorization: Bearer ${{ secrets.VERCEL_TOKEN }}" | jq -r '.deployments[1].uid')
echo "Rolling back to the previous deployment ID: $ROLLBACK_DEPLOYMENT_ID"
vercel rollback $ROLLBACK_DEPLOYMENT_ID --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
rollback-page:
name: rollback page if any deployments fail
needs:
[
promote-app,
promote-cart,
promote-link,
promote-manage-email,
promote-page,
promote-press,
promote-sparrow,
promote-www,
]
if: ${{ failure() && needs.promote-page.result == 'success' }}
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PAGE_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Rollback page
run: |
ROLLBACK_DEPLOYMENT_ID=$(curl -s "https://api.vercel.com/v6/deployments?teamId=${{ secrets.VERCEL_TEAM_ID }}&projectId=${{ secrets.VERCEL_PAGE_PROJECT_ID}}&limit=2&rollbackCandidate=true&state=READY&target=production" -H "Authorization: Bearer ${{ secrets.VERCEL_TOKEN }}" | jq -r '.deployments[1].uid')
echo "Rolling back to the previous deployment ID: $ROLLBACK_DEPLOYMENT_ID"
vercel rollback $ROLLBACK_DEPLOYMENT_ID --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
rollback-press:
name: rollback press if any deployments fail
needs:
[
promote-app,
promote-cart,
promote-link,
promote-manage-email,
promote-page,
promote-press,
promote-sparrow,
promote-www,
]
if: ${{ failure() && needs.promote-press.result == 'success' }}
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PRESS_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Rollback press
run: |
ROLLBACK_DEPLOYMENT_ID=$(curl -s "https://api.vercel.com/v6/deployments?teamId=${{ secrets.VERCEL_TEAM_ID }}&projectId=${{ secrets.VERCEL_PRESS_PROJECT_ID}}&limit=2&rollbackCandidate=true&state=READY&target=production" -H "Authorization: Bearer ${{ secrets.VERCEL_TOKEN }}" | jq -r '.deployments[1].uid')
echo "Rolling back to the previous deployment ID: $ROLLBACK_DEPLOYMENT_ID"
vercel rollback $ROLLBACK_DEPLOYMENT_ID --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
rollback-sparrow:
name: rollback sparrow if any deployments fail
needs:
[
promote-app,
promote-cart,
promote-link,
promote-manage-email,
promote-page,
promote-press,
promote-sparrow,
promote-www,
]
if: ${{ failure() && needs.promote-sparrow.result == 'success' }}
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_SPARROW_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Rollback sparrow
run: |
ROLLBACK_DEPLOYMENT_ID=$(curl -s "https://api.vercel.com/v6/deployments?teamId=${{ secrets.VERCEL_TEAM_ID }}&projectId=${{ secrets.VERCEL_SPARROW_PROJECT_ID}}&limit=2&rollbackCandidate=true&state=READY&target=production" -H "Authorization: Bearer ${{ secrets.VERCEL_TOKEN }}" | jq -r '.deployments[1].uid')
echo "Rolling back to the previous deployment ID: $ROLLBACK_DEPLOYMENT_ID"
vercel rollback $ROLLBACK_DEPLOYMENT_ID --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
rollback-www:
name: rollback www if any deployments fail
needs:
[
promote-app,
promote-cart,
promote-link,
promote-manage-email,
promote-page,
promote-press,
promote-sparrow,
promote-www,
]
if: ${{ failure() && needs.promote-www.result == 'success' }}
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_WWW_PROJECT_ID }}
steps:
- name: Install Vercel CLI
run: npm i -g vercel@latest
- name: Rollback www
run: |
ROLLBACK_DEPLOYMENT_ID=$(curl -s "https://api.vercel.com/v6/deployments?teamId=${{ secrets.VERCEL_TEAM_ID }}&projectId=${{ secrets.VERCEL_WWW_PROJECT_ID}}&limit=2&rollbackCandidate=true&state=READY&target=production" -H "Authorization: Bearer ${{ secrets.VERCEL_TOKEN }}" | jq -r '.deployments[1].uid')
echo "Rolling back to the previous deployment ID: $ROLLBACK_DEPLOYMENT_ID"
vercel rollback $ROLLBACK_DEPLOYMENT_ID --scope=barely --token=${{ secrets.VERCEL_TOKEN }}
# 🧹 CLEAN UP 🧹 #
delete-neon-branch:
needs:
[
git-meta,
db-push,
production--can-merge,
promote-app,
promote-cart,
promote-fm,
promote-link,
promote-manage-email,
promote-page,
promote-press,
promote-sparrow,
promote-www,
]
if:
always() && github.event_name == 'merge_group' && needs.git-meta.outputs.git_pr_branch_name != 'main' &&
needs.production--can-merge.result == 'success' &&
needs.promote-app.result == 'success' &&
needs.promote-cart.result == 'success' &&
needs.promote-fm.result == 'success' &&
needs.promote-link.result == 'success' &&
needs.promote-manage-email.result == 'success' &&
needs.promote-page.result == 'success' &&
needs.promote-press.result == 'success' &&
needs.promote-sparrow.result == 'success' &&
needs.promote-www.result == 'success'
runs-on: ubuntu-latest
steps:
- name: install neon cli
run: npm i -g neonctl
- name: delete neon preview branch
run: neonctl branches delete ${{ needs.git-meta.outputs.git_pr_branch_name }} --project-id ${{ secrets.NEON_PROJECT_ID }} --api-key ${{ secrets.NEON_API_KEY }}
- name: delete neon dev branches
run: |
# Fetch the current PR branch name
PR_BRANCH_NAME=${{ needs.git-meta.outputs.git_pr_branch_name }}
# List all branches using neonctl and filter those matching the pattern
MATCHING_BRANCHES=$(neonctl branches list --project-id ${{ secrets.NEON_PROJECT_ID }} --api-key ${{ secrets.NEON_API_KEY }} | grep "$PR_BRANCH_NAME"__dev_ | awk '{print $2}')
# Loop through the filtered list and delete each matching branch
for BRANCH in $MATCHING_BRANCHES; do
echo "Deleting branch: $BRANCH"
neonctl branches delete $BRANCH --project-id ${{ secrets.NEON_PROJECT_ID }} --api-key ${{ secrets.NEON_API_KEY }}
done