Skip to content

chore: promote main (i.e. staging) to production #279

chore: promote main (i.e. staging) to production

chore: promote main (i.e. staging) to production #279

Workflow file for this run

# Manual Release Workflow (Orchestrator)
#
# This workflow orchestrates both web and desktop releases when triggered.
# It runs semantic-release once and then calls both release workflows.
#
# Role in release workflow:
# - Triggered by push to release branch or manual dispatch
# - Creates GitHub releases with semantic versioning once
# - Calls release-web.yaml for web deployment on ref==release
# - Syncs release version to main branch if ref==release
# - Calls release-desktop.yaml for desktop app builds on ref==release
# - Coordinates both releases to use same version
name: Release
on:
push:
branches:
- release
- main
paths-ignore:
- 'docs/**'
- '**.md'
- '.vscode/**'
workflow_dispatch:
env:
# Define whether this is a production release (release branch)
IS_PRODUCTION_RELEASE: ${{ github.ref_name == 'release' }}
concurrency: orchestrate-release
jobs:
ci:
name: CI
uses: makerxstudio/shared-config/.github/workflows/node-ci.yml@main
with:
working-directory: .
node-version: 20.x
audit-script: npm run audit
compile-script: npm run check-types
test-script: npm run test
pre-test-script: |
pipx install algokit
algokit localnet start
npx --yes wait-on tcp:4001 -t 30000
build-and-release:
name: Build and Create Release
needs: [ci]
runs-on: ubuntu-latest
outputs:
release-version: ${{ steps.generate-release-version.outputs.release-version }}
release-tag: ${{ steps.generate-release-version.outputs.release-tag }}
release-id: ${{ steps.generate-release-version.outputs.release-id }}
crabnebula-release-id: ${{ steps.get-crabnebula-release-id.outputs.release-id }}
steps:
- name: Generate bot token
uses: actions/create-github-app-token@v1
id: app_token
with:
app-id: ${{ secrets.BOT_ID }}
private-key: ${{ secrets.BOT_SK }}
- uses: actions/checkout@v4
with:
token: ${{ steps.app_token.outputs.token }}
fetch-depth: 0
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20
registry-url: 'https://npm.pkg.github.com'
scope: '@algorandfoundation'
cache: 'npm'
- name: Install npm dependencies
run: npm ci --ignore-scripts
env:
NODE_AUTH_TOKEN: ${{ steps.app_token.outputs.token }}
# Let scripts run without the token
- run: npm rebuild
- name: Validate CrabNebula API key
id: validate-cn-api
uses: crabnebula-dev/[email protected]
with:
command: release list ${{ secrets.CN_ORG_NAME }}/${{ secrets.CN_APP_NAME }} --limit 1
api-key: ${{ secrets.CN_API_KEY }}
continue-on-error: false
- name: Generate release version
uses: ./.github/actions/generate-release-version
id: generate-release-version
with:
# Use bot token for semantic-release operations
github-token: ${{ steps.app_token.outputs.token }}
node-version: 20
- name: Create .env file with production values
if: env.IS_PRODUCTION_RELEASE == 'true'
run: |
cat > .env << EOF
VITE_DISPENSER_AUTH0_DOMAIN=dispenser-prod.eu.auth0.com
VITE_DISPENSER_AUTH0_CLIENT_ID=Cg13HjvSV45pMme4dnK9yVJde8tVeDaM
VITE_DISPENSER_AUTH0_AUDIENCE=api-prod-dispenser-user
VITE_TESTNET_DISPENSER_API_URL=https://api.dispenser.algorandfoundation.tools
VITE_TESTNET_DISPENSER_ADDRESS=Z5GPJQCHVU54C2I4FLYNE2XHRQRL5OV2GPJQKXJFMW34CRIN2KRQFXF7DI
EOF
- name: Create .env file with dev values
if: env.IS_PRODUCTION_RELEASE != 'true'
run: cp .env.sample .env
- name: Build application
run: npm run build
- name: Upload app build artifacts
uses: actions/upload-artifact@v4
with:
name: app-build
path: dist/
retention-days: 1
- name: Validate release outputs
run: |
echo "generate-release-version outputs:"
echo "release-version: ${{ steps.generate-release-version.outputs.release-version }}"
echo "release-tag: ${{ steps.generate-release-version.outputs.release-tag }}"
echo "release-notes: ${{ steps.generate-release-version.outputs.release-notes }}"
echo "release-channel: ${{ steps.generate-release-version.outputs.release-channel }}"
# Validate required outputs
if [ -z "${{ steps.generate-release-version.outputs.release-version }}" ]; then
echo "❌ Error: release-version is empty"
exit 1
fi
if [ -z "${{ steps.generate-release-version.outputs.release-tag }}" ]; then
echo "❌ Error: release-tag is empty"
exit 1
fi
echo "✅ All required release outputs are present"
- name: Create draft CrabNebula release
uses: crabnebula-dev/[email protected]
id: create-crabnebula-release
if: env.IS_PRODUCTION_RELEASE == 'true'
with:
command: release draft ${{ secrets.CN_ORG_NAME }}/${{ secrets.CN_APP_NAME }} ${{ steps.generate-release-version.outputs.release-version }} ${{ env.IS_PRODUCTION_RELEASE != 'true' && '--channel beta' || '' }}
api-key: ${{ secrets.CN_API_KEY }}
- name: Get CrabNebula release ID
id: get-crabnebula-release-id
if: env.IS_PRODUCTION_RELEASE == 'true'
run: echo "release-id=${{ fromJson(steps.create-crabnebula-release.outputs.stdout).id }}" >> $GITHUB_OUTPUT
sync-release-to-main:
name: Sync Release Version to Main
runs-on: ubuntu-latest
needs: [build-and-release]
if: github.ref_name == 'release'
steps:
- name: Generate bot token
uses: actions/create-github-app-token@v1
id: app_token
with:
app-id: ${{ secrets.BOT_ID }}
private-key: ${{ secrets.BOT_SK }}
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ steps.app_token.outputs.token }}
- name: Set Git user as GitHub actions
run: git config --global user.email "179917785+engineering-ci[bot]@users.noreply.github.com" && git config --global user.name "engineering-ci[bot]"
- name: Sync stable release back to main
run: |
VERSION="${{ needs.build-and-release.outputs.release-version }}"
TAG="${{ needs.build-and-release.outputs.release-tag }}"
echo "Syncing release version $VERSION (tag: $TAG) back to main..."
# Get the latest state of both branches
git fetch origin
git checkout release
git pull origin release
# Switch to main and merge the release commit
git checkout main
git pull origin main
# Find the commit that has the version tag
RELEASE_COMMIT=$(git rev-list -n 1 $TAG)
echo "Release commit: $RELEASE_COMMIT"
# Cherry-pick the release commit into main (without merge history)
# Use -X theirs to automatically resolve conflicts in favor of the release branch
git cherry-pick $RELEASE_COMMIT --no-commit -X theirs
git commit -m "chore: sync stable release $VERSION to main [skip ci]
This commit syncs the stable release version back to main branch
to ensure the next beta cycle starts from the correct version base.
Release: $VERSION
Tag: $TAG"
# Create the same tag on main branch (force move if it exists)
git tag -f $TAG
# Push the updated main branch and tags
git push origin main
git push origin $TAG -f
echo "✅ Successfully synced $VERSION to main branch"
release-web:
name: Release Web
needs: [build-and-release]
if: github.ref_name == 'release'
uses: ./.github/workflows/release-web.yaml
with:
version: ${{ needs.build-and-release.outputs.release-version }}
secrets: inherit
release-desktop:
name: Release Desktop
needs: [build-and-release]
if: github.ref_name == 'release'
uses: ./.github/workflows/release-desktop.yaml
with:
version: ${{ needs.build-and-release.outputs.release-version }}
production-release: ${{ github.ref_name == 'release' }}
release-tag: ${{ needs.build-and-release.outputs.release-tag }}
crabnebula-release-id: ${{ needs.build-and-release.outputs.crabnebula-release-id }}
secrets: inherit