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
build-linux-armv7l:
name: Build Linux ARMv7l
needs: validate-tag
if: always() && (needs.validate-tag.result == 'success' || needs.validate-tag.result == 'skipped')
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
- name: Set up QEMU and binfmt
run: |
sudo apt-get update
sudo apt-get install -y qemu-user-static binfmt-support python3-setuptools
sudo apt-get install -y python3-distutils || sudo apt-get install -y python3-dev python-is-python3
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-arm
sudo update-binfmts --import qemu-aarch64
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')
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
- name: Set up QEMU and binfmt
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 }}
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
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