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
212 changes: 212 additions & 0 deletions .github/workflows/deploy-stage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
name: Stage Deployment

on:
push:
branches: [main]

jobs:
detect-changes:
name: Detect Changes
runs-on: ubuntu-latest
outputs:
web: ${{ steps.filter.outputs.web }}
admin: ${{ steps.filter.outputs.admin }}
shared: ${{ steps.filter.outputs.shared }}
root: ${{ steps.filter.outputs.root }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Check changed files
uses: dorny/paths-filter@v3
id: filter
with:
filters: |
web:
- 'apps/web/**'
admin:
- 'apps/admin/**'
shared:
- 'packages/**'
root:
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- 'turbo.json'
- '.github/workflows/**'

deploy-web-stage:
name: Deploy Web (Stage)
runs-on: ubuntu-latest
needs: detect-changes
if: needs.detect-changes.outputs.web == 'true' || needs.detect-changes.outputs.shared == 'true' || needs.detect-changes.outputs.root == 'true'
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID_WEB_STAGE }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 9

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22.x"
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Install Vercel CLI
run: pnpm add --global vercel@latest

- name: Turbo cached build (web)
run: pnpm turbo run build --filter=@solid-connect/web

- name: Prepare Vercel project metadata (web)
run: |
rm -rf .vercel
mkdir -p .vercel-ci
working-directory: apps/web

- name: Pull Vercel environment (web stage)
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }} 2>&1 | tee .vercel-ci/pull.log
working-directory: apps/web

- name: Build prebuilt artifacts (web stage)
run: vercel build --yes --target=preview --token=${{ secrets.VERCEL_TOKEN }} 2>&1 | tee .vercel-ci/build.log
working-directory: apps/web

- name: Verify prebuilt artifacts (web)
run: |
test -f .vercel/output/config.json
test -d .vercel/output/functions
working-directory: apps/web

- name: Deploy prebuilt artifacts (web stage)
id: deploy_web
run: |
set -euo pipefail
vercel deploy --prebuilt --target=preview --token=${{ secrets.VERCEL_TOKEN }} 2>&1 | tee .vercel-ci/deploy.log
URL=$(grep -Eo 'https://[^ ]+\.vercel\.app' .vercel-ci/deploy.log | head -n 1)
if [ -z "$URL" ]; then
echo "Failed to parse deployment URL from Vercel output" >&2
exit 1
fi
echo "url=$URL" >> "$GITHUB_OUTPUT"
{
echo "## Web Stage Deployment"
echo "- Status: success"
echo "- URL: $URL"
} >> "$GITHUB_STEP_SUMMARY"
working-directory: apps/web

- name: Append failure summary (web stage)
if: failure()
run: |
{
echo "## Web Stage Deployment Failed"
echo "- Inspect artifact: web-stage-vercel-logs"
} >> "$GITHUB_STEP_SUMMARY"

- name: Upload Vercel logs (web stage)
if: always()
uses: actions/upload-artifact@v4
with:
name: web-stage-vercel-logs
path: apps/web/.vercel-ci/*.log
if-no-files-found: ignore

deploy-admin-stage:
name: Deploy Admin (Stage)
runs-on: ubuntu-latest
needs: detect-changes
if: needs.detect-changes.outputs.admin == 'true' || needs.detect-changes.outputs.shared == 'true' || needs.detect-changes.outputs.root == 'true'
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID_ADMIN_STAGE }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 9

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22.x"
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Install Vercel CLI
run: pnpm add --global vercel@latest

- name: Turbo cached build (admin)
run: pnpm turbo run build --filter=@solid-connect/admin

- name: Prepare Vercel project metadata (admin)
run: |
rm -rf .vercel
mkdir -p .vercel-ci
working-directory: apps/admin

- name: Pull Vercel environment (admin stage)
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }} 2>&1 | tee .vercel-ci/pull.log
working-directory: apps/admin

- name: Build prebuilt artifacts (admin stage)
run: vercel build --yes --target=preview --token=${{ secrets.VERCEL_TOKEN }} 2>&1 | tee .vercel-ci/build.log
working-directory: apps/admin

- name: Verify prebuilt artifacts (admin)
run: |
test -f .vercel/output/config.json
test -d .vercel/output/functions
working-directory: apps/admin

- name: Deploy prebuilt artifacts (admin stage)
id: deploy_admin
run: |
set -euo pipefail
vercel deploy --prebuilt --target=preview --token=${{ secrets.VERCEL_TOKEN }} 2>&1 | tee .vercel-ci/deploy.log
URL=$(grep -Eo 'https://[^ ]+\.vercel\.app' .vercel-ci/deploy.log | head -n 1)
if [ -z "$URL" ]; then
echo "Failed to parse deployment URL from Vercel output" >&2
exit 1
fi
echo "url=$URL" >> "$GITHUB_OUTPUT"
{
echo "## Admin Stage Deployment"
echo "- Status: success"
echo "- URL: $URL"
} >> "$GITHUB_STEP_SUMMARY"
working-directory: apps/admin

- name: Append failure summary (admin stage)
if: failure()
run: |
{
echo "## Admin Stage Deployment Failed"
echo "- Inspect artifact: admin-stage-vercel-logs"
} >> "$GITHUB_STEP_SUMMARY"

- name: Upload Vercel logs (admin stage)
if: always()
uses: actions/upload-artifact@v4
with:
name: admin-stage-vercel-logs
path: apps/admin/.vercel-ci/*.log
if-no-files-found: ignore
86 changes: 52 additions & 34 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
name: Build and Vercel Production Deployment
name: Promote Main to Release

permissions:
contents: write

env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
VERCEL_ENV: production

on:
workflow_dispatch:

Expand All @@ -25,49 +20,72 @@ jobs:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Create Release
id: create_release
uses: ncipollo/release-action@v1
with:
tag: "v${{ needs.generate_tag.outputs.version }}"
release_name: "Release v${{ needs.generate_tag.outputs.version }}"
body: "Automated release created for build v${{ needs.generate_tag.outputs.version }}"
token: ${{ secrets.GITHUB_TOKEN }}

deploy_production:
promote_release_branch:
name: Promote main -> release
runs-on: ubuntu-latest
needs: create_release
env:
VERSION_TAG: ${{ needs.generate_tag.outputs.version }}
steps:
- uses: actions/checkout@v3

- name: Install pnpm
uses: pnpm/action-setup@v3
- name: Checkout repository
uses: actions/checkout@v4
with:
version: 9
fetch-depth: 0

- name: Install Vercel CLI
run: pnpm add --global vercel@latest
- name: Promote main branch to release branch
run: |
set -euo pipefail

- name: Remove existing .vercel directory
run: rm -rf .vercel
git fetch origin main
git fetch origin release || true

- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=${{ env.VERCEL_ENV }} --token=${{ secrets.VERCEL_TOKEN }}
MAIN_SHA=$(git rev-parse origin/main)

- name: Build Project Artifacts
run: |
vercel build \
--yes \
--target=${{ env.VERCEL_ENV }} \
--build-env NEXT_PUBLIC_WEB_URL=https://www.solid-connection.com \
--build-env NEXT_PUBLIC_API_SERVER_URL=https://api.solid-connection.com \
--build-env NEXT_PUBLIC_KAKAO_JS_KEY=b285223d3e57a6820552018b93805658 \
--token=${{ secrets.VERCEL_TOKEN }}
if git show-ref --verify --quiet refs/remotes/origin/release; then
RELEASE_SHA=$(git rev-parse origin/release)
else
RELEASE_SHA=""
fi

if [ -z "$RELEASE_SHA" ]; then
git push origin origin/main:refs/heads/release
{
echo "## Release Promotion"
echo "- Status: success (release branch created)"
echo "- Promoted main SHA: $MAIN_SHA"
echo "- Target branch: release"
echo "- Note: Vercel production deploy is triggered by release branch update"
} >> "$GITHUB_STEP_SUMMARY"
exit 0
fi

if [ "$MAIN_SHA" = "$RELEASE_SHA" ]; then
{
echo "## Release Promotion"
echo "- Status: skipped (release is already up to date)"
echo "- main: $MAIN_SHA"
} >> "$GITHUB_STEP_SUMMARY"
exit 0
fi

if ! git merge-base --is-ancestor origin/release origin/main; then
echo "release branch is not an ancestor of main. Resolve release history before promotion." >&2
exit 1
fi

- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --target=${{ env.VERCEL_ENV }} --token=${{ secrets.VERCEL_TOKEN }}
git push origin origin/main:refs/heads/release

- name: Output Tag Version
run: echo "Deployment completed for version $VERSION_TAG"
{
echo "## Release Promotion"
echo "- Status: success"
echo "- Promoted main SHA: $MAIN_SHA"
echo "- Target branch: release"
echo "- Note: Vercel production deploy is triggered by release branch update"
} >> "$GITHUB_STEP_SUMMARY"
2 changes: 1 addition & 1 deletion turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".output/**"],
"outputs": ["dist/**", ".output/**", ".vercel/output/**"],
"env": ["NODE_ENV", "NEXT_PUBLIC_*"]
},
"@solid-connect/web#build": {
Expand Down