mirror of
https://github.com/nimbusdotstorage/Nimbus
synced 2026-04-22 17:45:03 +02:00
227 lines
8.6 KiB
YAML
227 lines
8.6 KiB
YAML
name: Deploy Server, Migrate Database, and Deploy Web
|
|
run-name: Deploying to ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.environment || github.ref_name == 'main' && 'production' || github.ref_name == 'staging' && 'staging' || 'preview' }} Environment by ${{ github.actor }}
|
|
|
|
on:
|
|
pull_request:
|
|
branches: [main]
|
|
types: [closed]
|
|
workflow_run:
|
|
workflows: ["Ready to Merge"]
|
|
types: [completed]
|
|
branches: [main, staging]
|
|
workflow_dispatch:
|
|
inputs:
|
|
deploy_server:
|
|
description: "Whether to deploy the server"
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
deploy_web:
|
|
description: "Whether to deploy the web application"
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
migrate_database:
|
|
description: "Whether to run database migrations"
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
create_release:
|
|
description: "Create Release"
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
pr_main:
|
|
description: "Create Pull Request to Main"
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
environment:
|
|
description: "Environment to deploy to"
|
|
required: true
|
|
default: "preview"
|
|
type: choice
|
|
options: ["production", "staging", "preview"]
|
|
|
|
env:
|
|
WORKFLOW_DEPLOY_ENV: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.environment || github.ref_name == 'main' && 'production' || github.ref_name == 'staging' && 'staging' || 'preview' }}
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
jobs:
|
|
deploy:
|
|
if: ${{ (github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success') && !startsWith(github.ref_name, 'release/') }}
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 60
|
|
|
|
# Determine environment based on branch or input
|
|
environment:
|
|
name: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.environment || github.ref_name == 'main' && 'production' || github.ref_name == 'staging' && 'staging' || 'preview' }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@master
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- name: Install dependencies
|
|
run: bun install --frozen-lockfile
|
|
|
|
- name: Check migrations
|
|
if: ${{ github.event.inputs.migrate_database != 'false' }}
|
|
env:
|
|
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
run: cd packages/db && bun run check
|
|
|
|
- name: Download deployment info
|
|
if: ${{ github.event_name == 'workflow_run' && github.event.inputs.deploy_server != 'false' }}
|
|
uses: actions/download-artifact@master
|
|
with:
|
|
name: deployment-info
|
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
run-id: ${{ github.event.workflow_run.id }}
|
|
|
|
- name: Set deployment variables
|
|
if: ${{ github.event_name == 'workflow_run' && github.event.inputs.deploy_server != 'false' }}
|
|
run: |
|
|
if [ -f "deployment_name.txt" ]; then
|
|
DEPLOYMENT_NAME=$(cat deployment_name.txt)
|
|
echo "DEPLOY_COMMAND=deploy --env $WORKFLOW_DEPLOY_ENV --name $DEPLOYMENT_NAME" >> $GITHUB_ENV
|
|
else
|
|
echo "DEPLOY_COMMAND=deploy --env $WORKFLOW_DEPLOY_ENV" >> $GITHUB_ENV
|
|
fi
|
|
|
|
- name: Deploy Server Worker
|
|
if: ${{ github.event.inputs.deploy_server != 'false' }}
|
|
id: deploy-server-worker
|
|
|
|
env:
|
|
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
|
|
GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}
|
|
MICROSOFT_CLIENT_ID: ${{ secrets.MICROSOFT_CLIENT_ID }}
|
|
MICROSOFT_CLIENT_SECRET: ${{ secrets.MICROSOFT_CLIENT_SECRET }}
|
|
BETTER_AUTH_SECRET: ${{ secrets.BETTER_AUTH_SECRET }}
|
|
BETTER_AUTH_URL: ${{ secrets.BETTER_AUTH_URL }}
|
|
SERVER_PORT: ${{ secrets.SERVER_PORT }}
|
|
WEB_PORT: ${{ secrets.WEB_PORT }}
|
|
BACKEND_URL: ${{ secrets.BACKEND_URL }}
|
|
TRUSTED_ORIGINS: ${{ secrets.TRUSTED_ORIGINS }}
|
|
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
DATABASE_HOST: ${{ secrets.DATABASE_HOST }}
|
|
POSTGRES_PORT: ${{ secrets.POSTGRES_PORT }}
|
|
POSTGRES_USER: ${{ secrets.POSTGRES_USER }}
|
|
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
|
|
POSTGRES_DB: ${{ secrets.POSTGRES_DB }}
|
|
UPSTASH_REDIS_REST_URL: ${{ secrets.UPSTASH_REDIS_REST_URL }}
|
|
UPSTASH_REDIS_REST_TOKEN: ${{ secrets.UPSTASH_REDIS_REST_TOKEN }}
|
|
EMAIL_FROM: ${{ secrets.EMAIL_FROM }}
|
|
RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }}
|
|
NODE_ENV: ${{ secrets.NODE_ENV }}
|
|
IS_EDGE_RUNTIME: ${{ secrets.IS_EDGE_RUNTIME }}
|
|
|
|
uses: cloudflare/wrangler-action@v3
|
|
with:
|
|
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
|
|
packageManager: bun
|
|
workingDirectory: "apps/server"
|
|
|
|
command: ${{ env.DEPLOY_COMMAND }}
|
|
# This is required for wrangler to know which environment to deploy to even though --env ${{ env.WORKFLOW_DEPLOY_ENV }} is specified in the command
|
|
environment: ${{ env.WORKFLOW_DEPLOY_ENV }}
|
|
|
|
secrets: |
|
|
GOOGLE_CLIENT_ID
|
|
GOOGLE_CLIENT_SECRET
|
|
MICROSOFT_CLIENT_ID
|
|
MICROSOFT_CLIENT_SECRET
|
|
BETTER_AUTH_SECRET
|
|
BETTER_AUTH_URL
|
|
SERVER_PORT
|
|
WEB_PORT
|
|
BACKEND_URL
|
|
TRUSTED_ORIGINS
|
|
DATABASE_URL
|
|
DATABASE_HOST
|
|
POSTGRES_PORT
|
|
POSTGRES_USER
|
|
POSTGRES_PASSWORD
|
|
POSTGRES_DB
|
|
UPSTASH_REDIS_REST_URL
|
|
UPSTASH_REDIS_REST_TOKEN
|
|
EMAIL_FROM
|
|
RESEND_API_KEY
|
|
NODE_ENV
|
|
IS_EDGE_RUNTIME
|
|
|
|
- name: Print Server deployment URL
|
|
if: ${{ github.event.inputs.deploy_server != 'false' }}
|
|
env:
|
|
SERVER_DEPLOYMENT_URL: ${{ steps.deploy-server-worker.outputs.deployment-url }}
|
|
run: echo $SERVER_DEPLOYMENT_URL
|
|
|
|
- name: Run migrations
|
|
if: ${{ github.event.inputs.migrate_database != 'false' }}
|
|
env:
|
|
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
run: cd packages/db && bun run migrate
|
|
|
|
- name: Deploy Web Worker
|
|
if: ${{ github.event.inputs.deploy_web != 'false' }}
|
|
id: deploy-web-worker
|
|
env:
|
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
NODE_ENV: ${{ secrets.NODE_ENV }}
|
|
VITE_PUBLIC_BACKEND_URL: ${{ secrets.VITE_PUBLIC_BACKEND_URL }}
|
|
VITE_PUBLIC_FRONTEND_URL: ${{ secrets.VITE_PUBLIC_FRONTEND_URL }}
|
|
run: |
|
|
cd apps/web
|
|
bun run cf:build
|
|
bun run cf:deploy:${{ env.WORKFLOW_DEPLOY_ENV }} | tee web-build.log
|
|
tail_output=$(tail -n 4 web-build.log)
|
|
rm web-build.log
|
|
echo "$tail_output"
|
|
echo "tail_output<<EOF" >> $GITHUB_OUTPUT
|
|
echo "$tail_output" >> $GITHUB_OUTPUT
|
|
echo "EOF" >> $GITHUB_OUTPUT
|
|
|
|
- name: Print Web deployment output
|
|
if: ${{ github.event.inputs.deploy_web != 'false' }}
|
|
env:
|
|
WEB_DEPLOYMENT_OUTPUT: ${{ steps.deploy-web-worker.outputs.tail_output }}
|
|
run: echo $WEB_DEPLOYMENT_OUTPUT
|
|
|
|
- name: Setup Git
|
|
if: ${{ github.ref_name == 'staging' && github.event.inputs.create_release != 'false' }}
|
|
run: |
|
|
git config --global user.name "${{ github.actor || 'GitHub Actions' }}"
|
|
git config --global user.email "${{ github.actor || 'github-actions' }}@users.noreply.github.com"
|
|
|
|
- name: Create Release
|
|
if: ${{ github.ref_name == 'staging' && github.event.inputs.create_release != 'false' }}
|
|
id: create-release
|
|
run: ./scripts/release.sh
|
|
|
|
- name: Create Pull Request to Main
|
|
if: ${{ github.ref_name == 'staging' && github.event.inputs.pr_main != 'false' }}
|
|
id: create-pr-to-main
|
|
uses: peter-evans/create-pull-request@v4
|
|
with:
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
branch: main
|
|
title: "Release: ${{ github.sha }}"
|
|
body: >-
|
|
Automated release PR from staging branch
|
|
|
|
- Deployment URL:
|
|
${{ steps.deploy-server-worker.outputs.deployment-url }}
|
|
|
|
- Web Deployment Output:
|
|
${{ steps.deploy-web-worker.outputs.tail_output }}
|
|
|
|
This PR is created automatically after successful staging deployment.
|
|
labels: release, automated
|