Skip to content

cicd tag

cicd tag #131

Workflow file for this run

name: CI/CD
on:
push:
tags:
- 'v*'
permissions:
contents: write
jobs:
# ============================================
# CI Jobs - Run on tag push
# ============================================
lint-and-typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Extract version from STATE.md
run: node scripts/extract-version.cjs
env:
GIT_TAG: ${{ github.ref_name }}
- name: Build packages
run: pnpm build:packages
- name: Typecheck
run: pnpm typecheck
build-apk:
runs-on: ubuntu-latest
needs: [lint-and-typecheck]
if: needs.lint-and-typecheck.result == 'success'
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'
- name: Cache Gradle
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ hashFiles('apps/android/android/gradle/wrapper/gradle-wrapper.properties') }}
restore-keys: gradle-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Extract version from STATE.md
id: version
run: |
VERSION=$(node scripts/extract-version.cjs)
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "build_number=${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "git_sha=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
env:
BUILD_NUMBER: ${{ github.run_number }}
GIT_SHA: ${{ github.sha }}
GIT_TAG: ${{ github.ref_name }}
- name: Build packages
run: pnpm build:packages
- name: Expo prebuild
working-directory: apps/android
run: npx expo prebuild --platform android --clean
env:
EXPO_PUBLIC_SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
EXPO_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID: ${{ secrets.GOOGLE_WEB_CLIENT_ID }}
- name: Decode keystore
run: echo "${{ secrets.ANDROID_KEYSTORE_BASE64 }}" | base64 --decode > apps/android/android/app/release.keystore
- name: Build release APK
working-directory: apps/android/android
run: ./gradlew app:assembleRelease -PversionCode=${{ github.run_number }} -PversionName=${{ steps.version.outputs.version }}
env:
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
EXPO_PUBLIC_SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
EXPO_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID: ${{ secrets.GOOGLE_WEB_CLIENT_ID }}
- name: Rename APK
run: cp apps/android/android/app/build/outputs/apk/release/app-release.apk lumio.apk
- name: Rename APK with version
run: mv lumio.apk "lumio-v${{ steps.version.outputs.version }}+${{ github.run_number }}.${GITHUB_SHA::7}.apk"
- name: Upload APK artifact
uses: actions/upload-artifact@v4
with:
name: lumio-apk-v${{ steps.version.outputs.version }}-build${{ github.run_number }}
path: lumio-v*.apk
retention-days: 30
create-release:
runs-on: ubuntu-latest
needs: [build-apk]
if: needs.build-apk.result == 'success'
steps:
- name: Download APK artifact
uses: actions/download-artifact@v4
with:
name: lumio-apk-v${{ needs.build-apk.outputs.version }}-build${{ github.run_number }}
- name: Prepare short SHA
id: sha
run: echo "short=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
- name: Rename APK to lumio.apk
run: mv lumio-v*.apk lumio.apk
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.build-apk.outputs.version }}
name: v${{ needs.build-apk.outputs.version }}
body: "Lumio v${{ needs.build-apk.outputs.version }} - Build #${{ github.run_number }} (${{ steps.sha.outputs.short }})"
files: lumio.apk
make_latest: true
draft: false
prerelease: false
# ============================================
# Deploy Jobs - Run on tag push
# ============================================
deploy-landing:
runs-on: ubuntu-latest
needs: [lint-and-typecheck]
if: needs.lint-and-typecheck.result == 'success'
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- name: Extract version from STATE.md
id: version
run: |
VERSION=$(node scripts/extract-version.cjs)
echo "version=$VERSION" >> $GITHUB_OUTPUT
env:
GIT_TAG: ${{ github.ref_name }}
- name: Inject version into landing page
run: |
SHORT_SHA=${GITHUB_SHA::7}
DISPLAY_VERSION="${{ steps.version.outputs.version }}+${{ github.run_number }}.${SHORT_SHA}"
sed -i "s/__LUMIO_VERSION__/${DISPLAY_VERSION}/g" apps/landing/index.html
- name: Deploy to DigitalOcean
uses: appleboy/[email protected]
with:
host: ${{ secrets.DO_HOST }}
username: ${{ secrets.DO_USERNAME }}
key: ${{ secrets.DO_SSH_KEY }}
source: 'apps/landing/*'
target: '/var/www/lumio'
strip_components: 2
- name: Reload Nginx
uses: appleboy/[email protected]
with:
host: ${{ secrets.DO_HOST }}
username: ${{ secrets.DO_USERNAME }}
key: ${{ secrets.DO_SSH_KEY }}
script: sudo systemctl reload nginx
deploy-deck-builder:
runs-on: ubuntu-latest
needs: [lint-and-typecheck]
if: needs.lint-and-typecheck.result == 'success'
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Extract version from STATE.md
id: version
run: |
VERSION=$(node scripts/extract-version.cjs)
echo "version=$VERSION" >> $GITHUB_OUTPUT
env:
GIT_TAG: ${{ github.ref_name }}
- name: Build packages
run: pnpm build:packages
- name: Run deck-builder tests
run: pnpm --filter @lumio/deck-builder test
- name: Build deck-builder
run: pnpm --filter @lumio/deck-builder build
env:
VITE_SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
VITE_SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
- name: Inject version into index.html
run: |
SHORT_SHA=${GITHUB_SHA::7}
DISPLAY_VERSION="${{ steps.version.outputs.version }}+${{ github.run_number }}.${SHORT_SHA}"
sed -i "s/__LUMIO_VERSION__/${DISPLAY_VERSION}/g" apps/deck-builder/dist/index.html
- name: Deploy to DigitalOcean
uses: appleboy/[email protected]
with:
host: ${{ secrets.DO_HOST }}
username: ${{ secrets.DO_USERNAME }}
key: ${{ secrets.DO_SSH_KEY }}
source: 'apps/deck-builder/dist/*'
target: '/var/www/deck-lumio'
strip_components: 3
- name: Reload Nginx
uses: appleboy/[email protected]
with:
host: ${{ secrets.DO_HOST }}
username: ${{ secrets.DO_USERNAME }}
key: ${{ secrets.DO_SSH_KEY }}
script: sudo systemctl reload nginx
deploy-migrations:
runs-on: ubuntu-latest
needs: [lint-and-typecheck]
if: needs.lint-and-typecheck.result == 'success'
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- uses: supabase/setup-cli@v1
with:
version: latest
- name: Link Supabase project
run: supabase link --project-ref ${{ secrets.SUPABASE_PROJECT_REF }}
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
- name: Backup database
if: ${{ vars.ENABLE_DB_BACKUP == 'true' }}
run: |
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
supabase db dump --data-only -f "db_backup_${TIMESTAMP}.sql"
echo "Backup created: db_backup_${TIMESTAMP}.sql"
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
SUPABASE_DB_PASSWORD: ${{ secrets.SUPABASE_DB_PASSWORD }}
- name: Upload backup artifact
if: ${{ vars.ENABLE_DB_BACKUP == 'true' }}
uses: actions/upload-artifact@v4
with:
name: db-backup-${{ github.run_number }}
path: db_backup_*.sql
retention-days: 30
- name: Run database migrations
run: supabase db push
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
deploy-functions:
runs-on: ubuntu-latest
needs: [lint-and-typecheck]
if: needs.lint-and-typecheck.result == 'success'
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- name: Extract version from STATE.md
id: version
run: |
VERSION=$(node scripts/extract-version.cjs)
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "build_number=${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "git_sha=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
echo "build_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_OUTPUT
echo "Deploying Edge Functions - Version: $VERSION, Build: ${{ github.run_number }}, SHA: ${GITHUB_SHA::7}"
env:
GIT_TAG: ${{ github.ref_name }}
- uses: supabase/setup-cli@v1
with:
version: latest
- name: Deploy Edge Functions
run: |
supabase functions deploy git-sync --no-verify-jwt --project-ref ${{ secrets.SUPABASE_PROJECT_REF }}
supabase functions deploy docora-webhook --no-verify-jwt --project-ref ${{ secrets.SUPABASE_PROJECT_REF }}
supabase functions deploy llm-proxy --no-verify-jwt --project-ref ${{ secrets.SUPABASE_PROJECT_REF }}
supabase functions deploy question-generator --no-verify-jwt --project-ref ${{ secrets.SUPABASE_PROJECT_REF }}
supabase functions deploy study-planner --project-ref ${{ secrets.SUPABASE_PROJECT_REF }}
supabase functions deploy version --project-ref ${{ secrets.SUPABASE_PROJECT_REF }}
supabase functions deploy deck-commit --no-verify-jwt --project-ref ${{ secrets.SUPABASE_PROJECT_REF }}
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
LUMIO_VERSION: ${{ steps.version.outputs.version }}
BUILD_NUMBER: ${{ steps.version.outputs.build_number }}
GIT_SHA: ${{ steps.version.outputs.git_sha }}
BUILD_DATE: ${{ steps.version.outputs.build_date }}