diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..6c71a884 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,111 @@ +name: Release Build + +on: + release: + types: [published] + +jobs: + build: + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Extract version from tag + id: version + shell: bash + run: | + # Remove 'v' prefix if present (e.g., "v1.2.3" -> "1.2.3") + VERSION="${{ github.event.release.tag_name }}" + VERSION="${VERSION#v}" + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "Extracted version: ${VERSION}" + + - name: Update package.json version + shell: bash + run: | + node apps/ui/scripts/update-version.mjs "${{ steps.version.outputs.version }}" + + - name: Setup project + uses: ./.github/actions/setup-project + with: + check-lockfile: 'true' + + - name: Build Electron app (macOS) + if: matrix.os == 'macos-latest' + shell: bash + run: npm run build:electron:mac --workspace=apps/ui + env: + CSC_IDENTITY_AUTO_DISCOVERY: false + + - name: Build Electron app (Windows) + if: matrix.os == 'windows-latest' + shell: bash + run: npm run build:electron:win --workspace=apps/ui + + - name: Build Electron app (Linux) + if: matrix.os == 'ubuntu-latest' + shell: bash + run: npm run build:electron:linux --workspace=apps/ui + + - name: Upload macOS artifacts + if: matrix.os == 'macos-latest' + uses: actions/upload-artifact@v4 + with: + name: macos-builds + path: apps/ui/release/*.{dmg,zip} + retention-days: 30 + + - name: Upload Windows artifacts + if: matrix.os == 'windows-latest' + uses: actions/upload-artifact@v4 + with: + name: windows-builds + path: apps/ui/release/*.exe + retention-days: 30 + + - name: Upload Linux artifacts + if: matrix.os == 'ubuntu-latest' + uses: actions/upload-artifact@v4 + with: + name: linux-builds + path: apps/ui/release/*.{AppImage,deb} + retention-days: 30 + + upload: + needs: build + runs-on: ubuntu-latest + if: github.event.release.draft == false + + steps: + - name: Download macOS artifacts + uses: actions/download-artifact@v4 + with: + name: macos-builds + path: artifacts/macos-builds + + - name: Download Windows artifacts + uses: actions/download-artifact@v4 + with: + name: windows-builds + path: artifacts/windows-builds + + - name: Download Linux artifacts + uses: actions/download-artifact@v4 + with: + name: linux-builds + path: artifacts/linux-builds + + - name: Upload to GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: | + artifacts/macos-builds/* + artifacts/windows-builds/* + artifacts/linux-builds/* + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/apps/ui/scripts/update-version.mjs b/apps/ui/scripts/update-version.mjs new file mode 100755 index 00000000..d8a958b1 --- /dev/null +++ b/apps/ui/scripts/update-version.mjs @@ -0,0 +1,47 @@ +#!/usr/bin/env node +/** + * Updates the version in apps/ui/package.json + * Usage: node scripts/update-version.mjs + * Example: node scripts/update-version.mjs 1.2.3 + */ + +import { readFileSync, writeFileSync } from 'fs'; +import { fileURLToPath } from 'url'; +import { dirname, join } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const version = process.argv[2]; + +if (!version) { + console.error('Error: Version argument is required'); + console.error('Usage: node scripts/update-version.mjs '); + process.exit(1); +} + +// Remove 'v' prefix if present (e.g., "v1.2.3" -> "1.2.3") +const cleanVersion = version.startsWith('v') ? version.slice(1) : version; + +// Validate version format (basic semver check) +if (!/^\d+\.\d+\.\d+/.test(cleanVersion)) { + console.error(`Error: Invalid version format: ${cleanVersion}`); + console.error('Expected format: X.Y.Z (e.g., 1.2.3)'); + process.exit(1); +} + +const packageJsonPath = join(__dirname, '..', 'package.json'); + +try { + const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); + const oldVersion = packageJson.version; + packageJson.version = cleanVersion; + + writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf8'); + + console.log(`Updated version from ${oldVersion} to ${cleanVersion}`); +} catch (error) { + console.error(`Error updating version: ${error.message}`); + process.exit(1); +} +