name: Create Release on: push: tags: - "v*" workflow_dispatch: concurrency: group: release-${{ github.ref }} cancel-in-progress: true env: NODE_VERSION: 22.22.2 GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} CSC_LINK: ${{ secrets.MAC_CERT_P12_BASE64 }} CSC_KEY_PASSWORD: ${{ secrets.MAC_CERT_P12_PASSWORD }} WIN_CSC_LINK: ${{ secrets.WIN_CERT_P12_BASE64 }} WIN_CSC_KEY_PASSWORD: ${{ secrets.WIN_CERT_P12_PASSWORD }} APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }} jobs: validate-tag: name: Validate Tag Matches package.json if: github.ref_type == 'tag' runs-on: ubuntu-latest steps: - uses: actions/checkout@v6.0.3 - name: Check tag matches package.json version run: | TAG="${{ github.ref_name }}" ROOT_VERSION="v$(jq -r .version package.json)" APP_VERSION="v$(jq -r .version app/package.json)" FAILED=0 if [ "$TAG" != "$ROOT_VERSION" ]; then echo "Error: tag '$TAG' does not match package.json version '$ROOT_VERSION'" FAILED=1 fi if [ "$TAG" != "$APP_VERSION" ]; then echo "Error: tag '$TAG' does not match app/package.json version '$APP_VERSION'" FAILED=1 fi exit $FAILED build: name: Build ${{ matrix.name }} needs: validate-tag if: always() && (needs.validate-tag.result == 'success' || needs.validate-tag.result == 'skipped') strategy: matrix: include: - os: ubuntu-latest name: Ubuntu matrix-name: ubuntu - os: macos-latest name: macOS matrix-name: macos - os: windows-latest name: Windows matrix-name: win runs-on: ${{ matrix.os }} steps: - name: Checkout code uses: actions/checkout@v6.0.3 - name: Build uses: ./.github/actions/build env: NODE_VERSION: ${{ env.NODE_VERSION }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: node-version: ${{ env.NODE_VERSION }} matrix-os: ${{ matrix.os }} matrix-name: ${{ matrix.matrix-name }} upload-artifact: true # ARM Linux: build-linux-armv7l: name: Build Linux ARMv7l needs: validate-tag if: always() && (needs.validate-tag.result == 'success' || needs.validate-tag.result == 'skipped') # qemu-user-static, used here and by arm-runner-action, is not packaged on Ubuntu 26.04 runs-on: ubuntu-24.04 steps: - name: Checkout code uses: actions/checkout@v6.0.3 - name: Set up QEMU and binfmt run: | # Install qemu-user-static sudo apt-get update sudo apt-get install -y qemu-user-static binfmt-support python3-setuptools # Install distutils for node-gyp sudo apt-get install -y python3-distutils || sudo apt-get install -y python3-dev python-is-python3 # Download and install binfmt configurations wget https://github.com/qemu/qemu/raw/master/scripts/qemu-binfmt-conf.sh chmod +x qemu-binfmt-conf.sh sudo ./qemu-binfmt-conf.sh --qemu-path /usr/bin --qemu-suffix -static --debian # Import the binfmt configurations sudo update-binfmts --import qemu-arm sudo update-binfmts --import qemu-aarch64 # Verify they exist ls -la /proc/sys/fs/binfmt_misc/qemu-arm* || true - name: Build ARMv7l uses: ./.github/actions/build-linux-arm env: NODE_VERSION: ${{ env.NODE_VERSION }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: node-version: ${{ env.NODE_VERSION }} matrix-name: armv7l matrix-cpu: cortex-a8 matrix-image: raspios_lite:latest upload-artifact: true build-linux-arm64: name: Build Linux ARM64 needs: validate-tag if: always() && (needs.validate-tag.result == 'success' || needs.validate-tag.result == 'skipped') # qemu-user-static, used here and by arm-runner-action, is not packaged on Ubuntu 26.04 runs-on: ubuntu-24.04 steps: - name: Checkout code uses: actions/checkout@v6.0.3 - name: Set up QEMU and binfmt # Needed so flatpak-builder's bwrap sandbox can run aarch64 build # commands on this x86_64 runner. run: | sudo apt-get update sudo apt-get install -y qemu-user-static binfmt-support wget https://github.com/qemu/qemu/raw/master/scripts/qemu-binfmt-conf.sh chmod +x qemu-binfmt-conf.sh sudo ./qemu-binfmt-conf.sh --qemu-path /usr/bin --qemu-suffix -static --debian sudo update-binfmts --import qemu-aarch64 ls -la /proc/sys/fs/binfmt_misc/qemu-aarch64* || true - name: Build ARM64 uses: ./.github/actions/build-linux-arm env: NODE_VERSION: ${{ env.NODE_VERSION }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: node-version: ${{ env.NODE_VERSION }} matrix-name: arm64 matrix-cpu: cortex-a53 matrix-image: raspios_lite_arm64:latest upload-artifact: true ### upload-release: name: Upload and Create Release needs: - build - build-linux-armv7l - build-linux-arm64 if: always() && github.ref_type == 'tag' && needs.build.result == 'success' && needs['build-linux-armv7l'].result == 'success' && needs['build-linux-arm64'].result == 'success' runs-on: ubuntu-latest steps: - name: Download all artifacts uses: actions/download-artifact@v8.0.1 with: path: ./artifacts - name: List downloaded artifacts run: ls -R ./artifacts - name: Ensure non-empty artifacts run: | echo "Checking for zero-byte files in artifacts/..." find artifacts/ -type f -empty -print -delete echo "Cleaned up any zero-byte files." echo "Remaining files:" ls -R artifacts/ - name: Dump release assets for debugging if: always() env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GitHub CLI needs this run: | echo "Fetching release assets for tag: ${{ github.ref_name }}" gh release view "${{ github.ref_name }}" --repo "${{ github.repository }}" --json assets --jq '.assets[] | "\(.name) - \(.url)"' || true - name: Create GitHub Release # TODO Pinned to work around https://github.com/softprops/action-gh-release/issues/445 uses: softprops/action-gh-release@v3.0.0 env: NODE_VERSION: ${{ env.NODE_VERSION }} ACTIONS_STEP_DEBUG: true with: preserve_order: true overwrite: true name: Release ${{ github.ref_name }} tag_name: ${{ github.ref }} token: ${{ secrets.GITHUB_TOKEN }} draft: true files: | artifacts/**/*.dmg artifacts/**/*.snap artifacts/**/*.AppImage artifacts/**/*.deb artifacts/**/*.pacman artifacts/**/*.rpm artifacts/**/*.exe artifacts/**/*.flatpak