name: Desktop Release on: push: tags: - 'v*' - 'desktop-v*' - 'desktop-macos-v*' - 'desktop-linux-v*' - 'desktop-windows-v*' workflow_dispatch: inputs: tag: description: 'Existing tag to build (e.g. v0.1.0)' required: true type: string platform: description: 'Optional desktop platform to build.' required: false default: 'all' type: choice options: - all - macos - linux - windows concurrency: group: desktop-release-${{ github.ref }} cancel-in-progress: false env: SOURCE_TAG: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref_name }} DESKTOP_WORKSPACE: '@getpaseo/desktop' DESKTOP_PACKAGE_PATH: 'packages/desktop' jobs: publish-macos: if: ${{ (github.event_name == 'workflow_dispatch' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'macos')) || (github.event_name == 'push' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'desktop-v') || startsWith(github.ref_name, 'desktop-macos-v'))) }} strategy: fail-fast: false matrix: include: - runner: macos-14 electron_arch: arm64 - runner: macos-15-intel electron_arch: x64 permissions: contents: write packages: read runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref }} - name: Resolve release metadata shell: bash run: | set -euo pipefail source_tag="${SOURCE_TAG}" if [[ "$source_tag" =~ ^(desktop-(windows|linux|macos)-|desktop-)?v([0-9]+\.[0-9]+\.[0-9]+) ]]; then release_tag="v${BASH_REMATCH[3]}" else release_tag="$source_tag" fi echo "RELEASE_TAG=$release_tag" >> "$GITHUB_ENV" version="${release_tag#v}" echo "DESKTOP_VERSION=$version" >> "$GITHUB_ENV" if [[ "$source_tag" == *gha-smoke* ]]; then echo "IS_SMOKE_TAG=true" >> "$GITHUB_ENV" else echo "IS_SMOKE_TAG=false" >> "$GITHUB_ENV" fi - name: Setup Node uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' cache-dependency-path: package-lock.json registry-url: 'https://npm.pkg.github.com' scope: '@boudra' - name: Install JS dependencies run: npm ci env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Set desktop package version from tag shell: bash run: | node <<'NODE' const fs = require('node:fs'); const path = require('node:path'); const version = process.env.DESKTOP_VERSION; if (!version) throw new Error('DESKTOP_VERSION env var is missing'); const packageJsonPath = path.join(process.env.DESKTOP_PACKAGE_PATH, 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); packageJson.version = version; fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`); NODE - name: Build web app for desktop run: npm run build:web --workspace=@getpaseo/app - name: Detect existing GitHub release state if: env.IS_SMOKE_TAG != 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash run: | set -euo pipefail if release_draft="$(gh release view "$RELEASE_TAG" --repo "${{ github.repository }}" --json isDraft --jq '.isDraft' 2>/dev/null)"; then if [[ "$release_draft" == "true" ]]; then release_type="draft" else release_type="release" fi else release_type="release" fi echo "RELEASE_TYPE=$release_type" >> "$GITHUB_ENV" - name: Build desktop release shell: bash env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} EP_GH_IGNORE_TIME: true CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }} CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }} APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} run: | set -euo pipefail publish_mode="never" publish_args=() if [[ "$IS_SMOKE_TAG" != "true" ]]; then publish_mode="always" publish_args+=("-c.publish.releaseType=$RELEASE_TYPE") fi npm run build --workspace="$DESKTOP_WORKSPACE" -- --publish "$publish_mode" --mac --${{ matrix.electron_arch }} "${publish_args[@]}" publish-linux: if: ${{ (github.event_name == 'workflow_dispatch' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'linux')) || (github.event_name == 'push' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'desktop-v') || startsWith(github.ref_name, 'desktop-linux-v'))) }} permissions: contents: write packages: read runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 with: fetch-depth: 0 ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref }} - name: Resolve release metadata shell: bash run: | set -euo pipefail source_tag="${SOURCE_TAG}" if [[ "$source_tag" =~ ^(desktop-(windows|linux|macos)-|desktop-)?v([0-9]+\.[0-9]+\.[0-9]+) ]]; then release_tag="v${BASH_REMATCH[3]}" else release_tag="$source_tag" fi echo "RELEASE_TAG=$release_tag" >> "$GITHUB_ENV" version="${release_tag#v}" echo "DESKTOP_VERSION=$version" >> "$GITHUB_ENV" if [[ "$source_tag" == *gha-smoke* ]]; then echo "IS_SMOKE_TAG=true" >> "$GITHUB_ENV" else echo "IS_SMOKE_TAG=false" >> "$GITHUB_ENV" fi - name: Setup Node uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' cache-dependency-path: package-lock.json registry-url: 'https://npm.pkg.github.com' scope: '@boudra' - name: Install JS dependencies run: npm ci env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Set desktop package version from tag shell: bash run: | node <<'NODE' const fs = require('node:fs'); const path = require('node:path'); const version = process.env.DESKTOP_VERSION; if (!version) throw new Error('DESKTOP_VERSION env var is missing'); const packageJsonPath = path.join(process.env.DESKTOP_PACKAGE_PATH, 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); packageJson.version = version; fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`); NODE - name: Build web app for desktop run: npm run build:web --workspace=@getpaseo/app - name: Detect existing GitHub release state if: env.IS_SMOKE_TAG != 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash run: | set -euo pipefail if release_draft="$(gh release view "$RELEASE_TAG" --repo "${{ github.repository }}" --json isDraft --jq '.isDraft' 2>/dev/null)"; then if [[ "$release_draft" == "true" ]]; then release_type="draft" else release_type="release" fi else release_type="release" fi echo "RELEASE_TYPE=$release_type" >> "$GITHUB_ENV" - name: Build desktop release shell: bash env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} EP_GH_IGNORE_TIME: true run: | set -euo pipefail publish_mode="never" publish_args=() if [[ "$IS_SMOKE_TAG" != "true" ]]; then publish_mode="always" publish_args+=("-c.publish.releaseType=$RELEASE_TYPE") fi npm run build --workspace="$DESKTOP_WORKSPACE" -- --publish "$publish_mode" --linux --x64 "${publish_args[@]}" publish-windows: if: ${{ (github.event_name == 'workflow_dispatch' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'windows')) || (github.event_name == 'push' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'desktop-v') || startsWith(github.ref_name, 'desktop-windows-v'))) }} permissions: contents: write packages: read runs-on: windows-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref }} - name: Resolve release metadata shell: bash run: | set -euo pipefail source_tag="${SOURCE_TAG}" if [[ "$source_tag" =~ ^(desktop-(windows|linux|macos)-|desktop-)?v([0-9]+\.[0-9]+\.[0-9]+) ]]; then release_tag="v${BASH_REMATCH[3]}" else release_tag="$source_tag" fi echo "RELEASE_TAG=$release_tag" >> "$GITHUB_ENV" version="${release_tag#v}" echo "DESKTOP_VERSION=$version" >> "$GITHUB_ENV" if [[ "$source_tag" == *gha-smoke* ]]; then echo "IS_SMOKE_TAG=true" >> "$GITHUB_ENV" else echo "IS_SMOKE_TAG=false" >> "$GITHUB_ENV" fi - name: Setup Node uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' cache-dependency-path: package-lock.json registry-url: 'https://npm.pkg.github.com' scope: '@boudra' - name: Install JS dependencies run: npm ci env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Set desktop package version from tag shell: bash run: | node <<'NODE' const fs = require('node:fs'); const path = require('node:path'); const version = process.env.DESKTOP_VERSION; if (!version) throw new Error('DESKTOP_VERSION env var is missing'); const packageJsonPath = path.join(process.env.DESKTOP_PACKAGE_PATH, 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); packageJson.version = version; fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`); NODE - name: Build workspace dependencies run: npm run build:workspace-deps --workspace=@getpaseo/app - name: Build web app for desktop shell: pwsh run: | $patchPath = (Get-Item "$env:GITHUB_WORKSPACE/scripts/metro-config-windows-loader-patch.cjs").FullName $env:NODE_OPTIONS = "--require=$patchPath" npx expo export --platform web working-directory: packages/app - name: Detect existing GitHub release state if: env.IS_SMOKE_TAG != 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash run: | set -euo pipefail if release_draft="$(gh release view "$RELEASE_TAG" --repo "${{ github.repository }}" --json isDraft --jq '.isDraft' 2>/dev/null)"; then if [[ "$release_draft" == "true" ]]; then release_type="draft" else release_type="release" fi else release_type="release" fi echo "RELEASE_TYPE=$release_type" >> "$GITHUB_ENV" - name: Build desktop release shell: bash env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} EP_GH_IGNORE_TIME: true run: | set -euo pipefail publish_mode="never" publish_args=() if [[ "$IS_SMOKE_TAG" != "true" ]]; then publish_mode="always" publish_args+=("-c.publish.releaseType=$RELEASE_TYPE") fi npm run build --workspace="$DESKTOP_WORKSPACE" -- --publish "$publish_mode" --win --x64 "${publish_args[@]}"