name: Build for release on: workflow_dispatch: inputs: publish_enabled: description: 'Publish artifacts after build?' required: true type: choice options: - 'true' - 'false' default: 'false' build_os: description: "Build OS" required: true default: "All" type: choice options: - Windows x64 - Windows ARM64 - macOS x64 - macOS ARM64 - Linux x64 - Linux ARM64 - All permissions: contents: read env: ELECTRON_OUTPUT_PATH: ./dist_electron CSC_LINK: ${{ secrets.BUILD_CERTIFICATE_BASE64 }} CSC_KEY_PASSWORD: ${{ secrets.P12_PASSWORD }} USE_HARD_LINKS: false jobs: release: name: Build on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - os: ubuntu-latest platform: 'Linux x64' os_type: linux - os: ubuntu-24.04-arm platform: 'Linux ARM64' os_type: linux - os: macos-15-intel platform: 'macOS x64' os_type: macos - os: macos-latest platform: 'macOS ARM64' os_type: macos - os: windows-latest platform: 'Windows x64' os_type: windows - os: windows-11-arm platform: 'Windows ARM64' os_type: windows steps: - name: Set up git config run: | git config --global core.autocrlf false - name: Check out git repository uses: actions/checkout@v6 # step2: sign - name: Install the Apple certificates if: contains(matrix.os_type, 'macos') && (github.event.inputs.build_os == matrix.platform || github.event.inputs.build_os == 'All') run: | CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH # step3: install node env - name: Install Node.js uses: actions/setup-node@v6 with: node-version: "22.x" - name: Install system deps if: contains(matrix.os_type, 'linux') && (github.event.inputs.build_os == matrix.platform || github.event.inputs.build_os == 'All') run: | sudo apt-get install --no-install-recommends -y icnsutils graphicsmagick xz-utils libfuse2 sudo snap install snapcraft --classic - name: Install FPM if: matrix.os == 'ubuntu-24.04-arm' && (github.event.inputs.build_os == matrix.platform || github.event.inputs.build_os == 'All') run: | sudo apt-get update sudo apt-get install -y ruby ruby-dev build-essential sudo gem install --no-document fpm # step3: yarn - name: Install dependencies if: github.event.inputs.build_os == matrix.platform || github.event.inputs.build_os == 'All' shell: bash run: | yarn config set ignore-engines true rm -rf node_modules dist_electron && yarn install --frozen-lockfile yarn global add xvfb-maybe - name: Generate release notes if: github.event.inputs.build_os == matrix.platform || github.event.inputs.build_os == 'All' shell: bash run: | chmod +x ./scripts/generate-release-notes.sh ./scripts/generate-release-notes.sh - name: Configure electron-builder.json if: github.event.inputs.build_os == matrix.platform || github.event.inputs.build_os == 'All' shell: bash run: | # Remove publish config if not publishing if [ "${{ github.event.inputs.publish_enabled }}" == "false" ]; then jq 'del(.publish)' electron-builder.json > tmp.json && mv tmp.json electron-builder.json fi # Configure architecture based on platform case "${{ matrix.platform }}" in "Windows x64") jq '.win.target[0].arch = ["x64", "ia32"]' electron-builder.json > tmp.json && mv tmp.json electron-builder.json ;; "Windows ARM64") jq '.win.target[0].arch = ["arm64"]' electron-builder.json > tmp.json && mv tmp.json electron-builder.json ;; "macOS x64") jq '.mac.target[0].arch = ["x64"]' electron-builder.json > tmp.json && mv tmp.json electron-builder.json ;; "macOS ARM64") jq '.mac.target[0].arch = ["arm64"]' electron-builder.json > tmp.json && mv tmp.json electron-builder.json ;; "Linux x64") jq '.linux.target[0].arch = ["x64"]' electron-builder.json > tmp.json && mv tmp.json electron-builder.json jq '.linux.target[1].arch = ["x64"]' electron-builder.json > tmp.json && mv tmp.json electron-builder.json # Remove snap if publish is true if [ "${{ github.event.inputs.publish_enabled }}" == "true" ]; then jq 'del(.linux.target[] | select(.target == "snap"))' electron-builder.json > tmp.json && mv tmp.json electron-builder.json fi ;; "Linux ARM64") jq '.linux.target[0].arch = ["arm64"]' electron-builder.json > tmp.json && mv tmp.json electron-builder.json jq '.linux.target[1].arch = ["arm64"]' electron-builder.json > tmp.json && mv tmp.json electron-builder.json jq 'del(.linux.target[] | select(.target == "snap"))' electron-builder.json > tmp.json && mv tmp.json electron-builder.json ;; esac - name: Build & release app if: github.event.inputs.build_os == matrix.platform || github.event.inputs.build_os == 'All' shell: bash run: | if [ "${{ matrix.os }}" == "windows-11-arm" ]; then export CSC_IDENTITY_AUTO_DISCOVERY=false unset CSC_LINK WIN_CSC_LINK CSC_KEY_PASSWORD fi PUBLISH_ARG="never" if [ "${{ github.event.inputs.publish_enabled }}" == "true" ]; then PUBLISH_ARG="always" fi echo "Publishing argument: $PUBLISH_ARG" yarn release --publish $PUBLISH_ARG env: USE_SYSTEM_FPM: ${{ matrix.os == 'ubuntu-24.04-arm' && 'true' || 'false' }} GH_TOKEN: ${{ secrets.GH_TOKEN }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} R2_SECRET_ID: ${{ secrets.R2_SECRET_ID }} R2_SECRET_KEY: ${{ secrets.R2_SECRET_KEY }} R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }} ELECTRON_SKIP_NOTARIZATION: ${{ secrets.ELECTRON_SKIP_NOTARIZATION }} XCODE_APP_LOADER_EMAIL: ${{ secrets.XCODE_APP_LOADER_EMAIL }} XCODE_APP_LOADER_PASSWORD: ${{ secrets.XCODE_APP_LOADER_PASSWORD }} XCODE_TEAM_ID: ${{ secrets.XCODE_TEAM_ID }} BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }} P12_PASSWORD: ${{ secrets.P12_PASSWORD }} BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} USE_HARD_LINKS: false - name: Upload build artifacts if: github.event.inputs.build_os == matrix.platform || github.event.inputs.build_os == 'All' uses: actions/upload-artifact@v4 with: name: ${{ matrix.os_type }}-${{ matrix.platform == 'Windows x64' && 'x64' || matrix.platform == 'Windows ARM64' && 'arm64' || matrix.platform == 'macOS x64' && 'x64' || matrix.platform == 'macOS ARM64' && 'arm64' || matrix.platform == 'Linux x64' && 'x64' || 'arm64' }}-${{ contains(matrix.os, 'windows') && 'executables' || 'packages' }} path: | dist_electron/*.exe dist_electron/*.dmg dist_electron/*.zip dist_electron/*.AppImage dist_electron/*.deb dist_electron/*.rpm dist_electron/*.snap retention-days: 30 if-no-files-found: 'ignore' - name: Upload yml artifacts if: github.event.inputs.build_os == matrix.platform || github.event.inputs.build_os == 'All' uses: actions/upload-artifact@v4 with: name: ${{ matrix.os_type }}-${{ matrix.platform == 'Windows x64' && 'x64' || matrix.platform == 'Windows ARM64' && 'arm64' || matrix.platform == 'macOS x64' && 'x64' || matrix.platform == 'macOS ARM64' && 'arm64' || matrix.platform == 'Linux x64' && 'x64' || 'arm64' }}-yml path: dist_electron/**/*.yml retention-days: 30 if-no-files-found: 'ignore' - name: Get version if: (github.event.inputs.build_os == matrix.platform || github.event.inputs.build_os == 'All') && matrix.platform == 'Windows x64' && github.event.inputs.publish_enabled == true id: get_version shell: bash run: | VERSION=$(node -p "require('./package.json').version") echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Update release draft if: (github.event.inputs.build_os == matrix.platform || github.event.inputs.build_os == 'All') && matrix.platform == 'Windows x64' && github.event.inputs.publish_enabled == true uses: softprops/action-gh-release@v2 with: draft: true prerelease: false body_path: release-notes.md append_body: true tag_name: v${{ steps.get_version.outputs.version }} name: Release v${{ steps.get_version.outputs.version }} token: ${{ secrets.GH_TOKEN }} combine-and-upload-yml: name: Combine YML files needs: release runs-on: ubuntu-latest steps: - name: Check out git repository uses: actions/checkout@v6 - name: Install Node.js uses: actions/setup-node@v6 with: node-version: "22.x" - name: Install dependencies shell: bash run: | yarn config set ignore-engines true rm -rf node_modules && yarn install - name: Download all yml artifacts uses: actions/download-artifact@v4 with: pattern: '*-yml' path: ./yml-artifacts merge-multiple: false - name: List downloaded artifacts run: | echo "Downloaded artifacts structure:" find ./yml-artifacts -type f -name "*.yml" tree ./yml-artifacts - name: Combine and deduplicate yml files run: | node scripts/combine-yml.cjs ./yml-artifacts ./dist_electron/combined echo "Combined YML files:" ls -la ./dist_electron/combined/ echo "Latest combined YML content:" cat ./dist_electron/combined/latest.yml echo "Latest macOS combined YML content:" cat ./dist_electron/combined/latest-mac.yml echo "Latest linux combined YML content:" cat ./dist_electron/combined/latest-linux.yml echo "Latest linux ARM64 combined YML content:" cat ./dist_electron/combined/latest-linux-arm64.yml - name: Get version for release id: get_version run: | VERSION=$(node -p "require('./package.json').version") echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Upload combined yml files to GitHub Release if: github.event.inputs.publish_enabled == 'true' uses: softprops/action-gh-release@v2 with: draft: true tag_name: v${{ steps.get_version.outputs.version }} token: ${{ secrets.GH_TOKEN }}