diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml new file mode 100644 index 0000000..e9d8ca8 --- /dev/null +++ b/.github/workflows/build-test.yml @@ -0,0 +1,42 @@ +name: "Build Test" + +on: + workflow_dispatch: + push: + branches: + - main + - develop + pull_request: + branches: + - main + +jobs: + build-test: + permissions: + contents: read + strategy: + fail-fast: false + matrix: + include: + - platform: "macos-latest" # for Arm based macs (M1 and above). + args: "--target aarch64-apple-darwin" + target: "aarch64-apple-darwin" + - platform: "macos-latest" # for Intel based macs. + args: "--target x86_64-apple-darwin" + target: "x86_64-apple-darwin" + - platform: "ubuntu-24.04" + args: "" + target: "x86_64-unknown-linux-gnu" + - platform: "windows-latest" + args: "" + target: "x86_64-pc-windows-msvc" + + uses: ./.github/workflows/build.yml + with: + platform: ${{ matrix.platform }} + target: ${{ matrix.target }} + build-args: ${{ matrix.args }} + sign-binaries: false + asset-prefix: "handy-test" + upload-artifacts: true + secrets: inherit diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..8c83ed2 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,204 @@ +name: "Build" + +on: + workflow_call: + inputs: + platform: + required: true + type: string + target: + required: true + type: string + build-args: + required: false + type: string + default: "" + release-id: + required: false + type: string + asset-prefix: + required: false + type: string + default: "handy" + upload-artifacts: + required: false + type: boolean + default: false + sign-binaries: + required: false + type: boolean + default: false + repository: + required: false + type: string + ref: + required: false + type: string + default: ${{ github.ref }} + +jobs: + build: + permissions: + contents: write + runs-on: ${{ inputs.platform }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + repository: ${{ inputs.repository }} + ref: ${{ inputs.ref }} + fetch-depth: 0 + + - name: Determine Version + id: determine-version + shell: bash + run: | + APP_VERSION="" + REF="${{ inputs.ref }}" + + if [[ "$REF" == refs/tags/v* ]]; then + APP_VERSION="${REF#refs/tags/v}" + echo "Release version determined from tag: $APP_VERSION" + else + DESCRIBE=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") + APP_VERSION="${DESCRIBE#v}" + echo "CI version determined from latest tag or fallback: $APP_VERSION" + fi + + echo "version=${APP_VERSION}" >> "$GITHUB_OUTPUT" + + - uses: oven-sh/setup-bun@v2 + + - name: install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + # Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds. + targets: ${{ contains(inputs.platform, 'macos') && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} + + - name: Rust cache + uses: swatinem/rust-cache@v2 + with: + workspaces: "./src-tauri -> target" + key: ${{ inputs.platform }}-${{ inputs.target }} + + - name: install dependencies (ubuntu only) + if: contains(inputs.platform, 'ubuntu') + run: | + sudo apt-get update + sudo apt-get install -y libappindicator3-dev librsvg2-dev patchelf libasound2-dev libopenblas-dev libx11-dev libxtst-dev libxrandr-dev \ + libwebkit2gtk-4.1-0=2.44.0-2 \ + libwebkit2gtk-4.1-dev=2.44.0-2 \ + libjavascriptcoregtk-4.1-0=2.44.0-2 \ + libjavascriptcoregtk-4.1-dev=2.44.0-2 \ + gir1.2-javascriptcoregtk-4.1=2.44.0-2 \ + gir1.2-webkit2-4.1=2.44.0-2 + + - name: Install Vulkan SDK (Windows) + if: contains(inputs.platform, 'windows') + uses: humbletim/install-vulkan-sdk@v1.2 + with: + version: 1.4.309.0 + cache: true + + - name: Install trusted-signing-cli + if: contains(inputs.platform, 'windows') && inputs.sign-binaries + run: cargo install trusted-signing-cli + + - name: Prepare Vulkan SDK for Ubuntu + if: contains(inputs.platform, 'ubuntu') + run: | + wget -qO- https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo tee /etc/apt/trusted.gpg.d/lunarg.asc + sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.3.290-noble.list https://packages.lunarg.com/vulkan/1.3.290/lunarg-vulkan-1.3.290-noble.list + sudo apt update + sudo apt install vulkan-sdk -y + sudo apt-get install -y mesa-vulkan-drivers + + - name: install frontend dependencies + run: bun install + + - name: rustup install target + if: ${{ inputs.target != '' && !contains(inputs.target, 'unknown-linux-gnu') && !contains(inputs.target, 'pc-windows-msvc') }} + run: rustup target add ${{ inputs.target }} + + - name: import Apple Developer Certificate + if: contains(inputs.platform, 'macos') && inputs.sign-binaries + env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + run: | + echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12 + security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain + security set-keychain-settings -t 3600 -u build.keychain + security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain + security find-identity -v -p codesigning build.keychain + + - name: verify certificate + if: contains(inputs.platform, 'macos') && inputs.sign-binaries + run: | + CERT_INFO=$(security find-identity -v -p codesigning build.keychain | grep "Developer ID Application") + CERT_ID=$(echo "$CERT_INFO" | awk -F'"' '{print $2}') + echo "CERT_ID=$CERT_ID" >> $GITHUB_ENV + echo "Certificate imported." + + - name: Set application version + shell: bash + run: | + echo "Setting version to: ${{ steps.determine-version.outputs.version }}" + # Update version in tauri.conf.json + sed -i.bak 's/"version": "[^"]*"/"version": "${{ steps.determine-version.outputs.version }}"/' src-tauri/tauri.conf.json + + - name: Build with Tauri + uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + APPLE_ID: ${{ inputs.sign-binaries && secrets.APPLE_ID || '' }} + APPLE_ID_PASSWORD: ${{ inputs.sign-binaries && secrets.APPLE_ID_PASSWORD || '' }} + APPLE_PASSWORD: ${{ inputs.sign-binaries && secrets.APPLE_PASSWORD || '' }} + APPLE_TEAM_ID: ${{ inputs.sign-binaries && secrets.APPLE_TEAM_ID || '' }} + APPLE_CERTIFICATE: ${{ inputs.sign-binaries && secrets.APPLE_CERTIFICATE || '' }} + APPLE_CERTIFICATE_PASSWORD: ${{ inputs.sign-binaries && secrets.APPLE_CERTIFICATE_PASSWORD || '' }} + APPLE_SIGNING_IDENTITY: ${{ inputs.sign-binaries && env.CERT_ID || '' }} + AZURE_CLIENT_ID: ${{ inputs.sign-binaries && secrets.AZURE_CLIENT_ID || '' }} + AZURE_CLIENT_SECRET: ${{ inputs.sign-binaries && secrets.AZURE_CLIENT_SECRET || '' }} + AZURE_TENANT_ID: ${{ inputs.sign-binaries && secrets.AZURE_TENANT_ID || '' }} + TAURI_SIGNING_PRIVATE_KEY: ${{ inputs.sign-binaries && secrets.TAURI_SIGNING_PRIVATE_KEY || '' }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ inputs.sign-binaries && secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD || '' }} + with: + tagName: ${{ inputs.release-id && format('v{0}', steps.determine-version.outputs.version) || '' }} + releaseName: ${{ inputs.release-id && format('v{0}', steps.determine-version.outputs.version) || '' }} + releaseId: ${{ inputs.release-id }} + args: ${{ inputs.build-args }} + + - name: Upload artifacts (macOS) + if: inputs.upload-artifacts && contains(inputs.platform, 'macos') + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.asset-prefix }}-${{ inputs.target }} + path: | + src-tauri/target/${{ inputs.target }}/release/bundle/dmg/*.dmg + src-tauri/target/${{ inputs.target }}/release/bundle/macos/*.app + retention-days: 30 + + - name: Upload artifacts (Linux) + if: inputs.upload-artifacts && contains(inputs.platform, 'ubuntu') + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.asset-prefix }}-${{ inputs.target }} + path: | + src-tauri/target/release/bundle/deb/*.deb + src-tauri/target/release/bundle/appimage/*.AppImage + retention-days: 30 + + - name: Upload artifacts (Windows) + if: inputs.upload-artifacts && contains(inputs.platform, 'windows') + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.asset-prefix }}-${{ inputs.target }} + path: | + src-tauri/target/release/bundle/msi/*.msi + src-tauri/target/release/bundle/nsis/*.exe + retention-days: 30 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 38a6ed7..010d5e8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,109 +16,23 @@ jobs: include: - platform: "macos-latest" # for Arm based macs (M1 and above). args: "--target aarch64-apple-darwin" + target: "aarch64-apple-darwin" - platform: "macos-latest" # for Intel based macs. args: "--target x86_64-apple-darwin" + target: "x86_64-apple-darwin" - platform: "ubuntu-24.04" args: "" + target: "x86_64-unknown-linux-gnu" - platform: "windows-latest" args: "" + target: "x86_64-pc-windows-msvc" - runs-on: ${{ matrix.platform }} - steps: - - uses: actions/checkout@v4 - - - uses: oven-sh/setup-bun@v2 - - - name: install Rust stable - uses: dtolnay/rust-toolchain@stable - with: - # Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds. - targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} - - - name: Rust cache - uses: swatinem/rust-cache@v2 - with: - workspaces: "./src-tauri -> target" - - - name: install dependencies (ubuntu only) - if: matrix.platform == 'ubuntu-24.04' # This must match the platform value defined above. - run: | - sudo apt-get update - sudo apt-get install -y libappindicator3-dev librsvg2-dev patchelf libasound2-dev libopenblas-dev libx11-dev libxtst-dev libxrandr-dev \ - libwebkit2gtk-4.1-0=2.44.0-2 \ - libwebkit2gtk-4.1-dev=2.44.0-2 \ - libjavascriptcoregtk-4.1-0=2.44.0-2 \ - libjavascriptcoregtk-4.1-dev=2.44.0-2 \ - gir1.2-javascriptcoregtk-4.1=2.44.0-2 \ - gir1.2-webkit2-4.1=2.44.0-2 - - - name: Install Vulkan SDK - if: matrix.platform == 'windows-latest' # This must match the platform value defined above. - uses: humbletim/install-vulkan-sdk@v1.2 - with: - version: 1.4.309.0 - cache: true - - - name: Install trusted-signing-cli - if: matrix.platform == 'windows-latest' # This must match the platform value defined above. - run: cargo install trusted-signing-cli - - - name: Prepare Vulkan SDK for Ubuntu - run: | - wget -qO- https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo tee /etc/apt/trusted.gpg.d/lunarg.asc - sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.3.290-noble.list https://packages.lunarg.com/vulkan/1.3.290/lunarg-vulkan-1.3.290-noble.list - sudo apt update - sudo apt install vulkan-sdk -y - sudo apt-get install -y mesa-vulkan-drivers - if: matrix.platform == 'ubuntu-24.04' - - - name: install frontend dependencies - run: bun install # change this to npm, pnpm or bun depending on which one you use. - - - name: import Apple Developer Certificate - if: matrix.platform == 'macos-latest' - # Prevents keychain from locking automatically for 3600 seconds. - env: - APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} - APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - run: | - echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12 - security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain - security default-keychain -s build.keychain - security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain - security set-keychain-settings -t 3600 -u build.keychain - security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign - security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain - security find-identity -v -p codesigning build.keychain - - - name: verify certificate - if: matrix.platform == 'macos-latest' - run: | - CERT_INFO=$(security find-identity -v -p codesigning build.keychain | grep "Developer ID Application") - CERT_ID=$(echo "$CERT_INFO" | awk -F'"' '{print $2}') - echo "CERT_ID=$CERT_ID" >> $GITHUB_ENV - echo "Certificate imported." - - # If tagName and releaseId are omitted tauri-action will only build the app and won't try to upload any assets. - - name: Build - uses: tauri-apps/tauri-action@v0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - APPLE_ID: ${{ secrets.APPLE_ID }} - APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} - APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} - APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} - APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} - APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - APPLE_SIGNING_IDENTITY: ${{ env.CERT_ID }} - AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} - AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} - AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} - TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} - TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} - with: - tagName: v__VERSION__ - releaseName: "v__VERSION__" - args: ${{ matrix.args }} - releaseDraft: true + uses: ./.github/workflows/build.yml + with: + platform: ${{ matrix.platform }} + target: ${{ matrix.target }} + build-args: ${{ matrix.args }} + sign-binaries: true + asset-prefix: "handy" + upload-artifacts: false + secrets: inherit