# Release workflow builds the release executables for all platforms and publishes them to GitHub # Runs on all pushes/pull requests, but only publishes the executables on v*.*.* tags name: Release builds on: push: pull_request: env: CARGO_TERM_COLOR: always permissions: contents: write # Required to upload artifacts to releases (and pushing the version update) jobs: update-cargo-version: name: Update the version in Cargo.toml runs-on: ubuntu-24.04 permissions: contents: write pull-requests: write outputs: BRANCH_NAME: ${{ steps.auto-update.outputs.BRANCH_NAME || github.ref }} steps: - if: ${{ startsWith(github.ref, 'refs/tags/v') }} name: Checkout uses: actions/checkout@v6 - if: ${{ startsWith(github.ref, 'refs/tags/v') }} uses: dtolnay/rust-toolchain@stable - if: ${{ startsWith(github.ref, 'refs/tags/v') }} uses: Swatinem/rust-cache@v2.9.1 - if: ${{ startsWith(github.ref, 'refs/tags/v') }} name: Auto-update Cargo.toml and move the release tag id: auto-update env: GH_TOKEN: ${{ secrets.PAT }} run: | set -ex # This needs to be done in a new branch as master is protected export VERSION="${GITHUB_REF##*/}" export BRANCH_NAME="update-cargo-version-${VERSION:1}" git checkout -b "${BRANCH_NAME}" echo "BRANCH_NAME=${BRANCH_NAME}" >> $GITHUB_ENV # Actually update the Cargo.toml sed -E -i "s/^version = \"[^\"]*\"/version = \"${VERSION:1}\"/g" Cargo.toml # e.g. v0.0.1 -> version = "0.0.1" cargo tree # Check that we did not break the Cargo.toml (also updates Cargo.lock) # Commit the changes git config --global user.email "yeicor@users.noreply.github.com" git config --global user.name "Yeicor" if ! git commit -am "Update Cargo.toml to version ${VERSION:1} (automatic)"; then echo "No change to the Cargo.toml version (did you repeat a release tag??)" exit 1 fi # Move the tag to the commit and push the new branch git tag -d "${VERSION}" git push -d origin "${VERSION}" git tag "${VERSION}" git push origin "${BRANCH_NAME}" "${VERSION}" gh release edit "${VERSION}" --draft=false --verify-tag # Make sure the release corresponds to the new tag # Open a pull request that will automatically merge after the CI passes gh pr create --base master --head "update-cargo-version-${VERSION:1}" --title "Update Cargo.toml to version ${VERSION:1}" --body "This PR updates the version in Cargo.toml to ${VERSION:1} and moves the release tag to the commit." gh pr merge --auto --squash --delete-branch deploy-linux: name: Release runs-on: "${{ matrix.os }}" needs: - update-cargo-version strategy: fail-fast: false matrix: include: # TODO: Release different feature combinations (app-only, server-only and both) # Linux x86_64 - os: ubuntu-latest target: x86_64-unknown-linux-gnu ext: "" pre: sudo apt update && sudo apt install pkg-config libx11-dev libxi-dev libgl1-mesa-dev libasound2-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libspeechd-dev libxkbcommon-dev libssl-dev libatk1.0-dev libgtk-3-dev # TODO: Mac OS x86_64 # - os: macos-latest # target: x86_64-apple-darwin # pre: brew install libx11 libxi # post: TODO: (pack a .dmg?) # Windows x86_64 - os: windows-latest target: x86_64-pc-windows-msvc ext: exe # Web (WebAssembly) - os: ubuntu-latest target: wasm32-unknown-unknown ext: tar.gz # After post-processing build: .github/scripts/web/build.sh --release post: .github/scripts/web/build-demo.sh ./target/pkg/${GITHUB_REPOSITORY#*/}.wasm --release - os: ubuntu-latest target: android # Multiple architectures are supported pre: | sudo apt update sudo apt install google-android-cmdline-tools-13.0-installer openjdk-8-jre-headless # sudo sdkmanager --list sudo sdkmanager --install "platforms;android-35" "ndk;27.2.12479018" "build-tools;35.0.0" export ANDROID_HOME=/opt/android-sdk ANDROID_NDK_ROOT=/opt/android-sdk/ndk/27.* rustup target add aarch64-linux-android # armv7-linux-androideabi i686-linux-android x86_64-linux-android cargo install --git https://github.com/parasyte/cargo-apk.git --rev 282639508eeed7d73f2e1eaeea042da2716436d5 cargo-apk build: cargo apk build --lib --no-default-features --features default-android # --release requires keystore ext: apk # TODO: iOS # - os: macos-latest # target: ??? # pre: ??? # build: ??? # post: ??? steps: - name: Free up disk space if: ${{ matrix.os == 'ubuntu-latest' }} run: | sudo rm -rf /usr/share/dotnet sudo rm -rf /opt/ghc sudo rm -rf /usr/local/share/boost sudo rm -rf $AGENT_TOOLSDIRECTORY docker image prune -a -f - if: ${{ startsWith(github.ref, 'refs/tags/v') }} name: Checkout uses: actions/checkout@v6 with: ref: ${{ needs.update-cargo-version.outputs.BRANCH_NAME }} - if: ${{ !startsWith(github.ref, 'refs/tags/v') }} name: Checkout uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2.9.1 with: key: ${{ matrix.os }}-${{ matrix.target }} - uses: nttld/setup-ndk@v1 if: ${{ matrix.target == 'android' }} with: ndk-version: r21e - name: Preparing for build if: ${{ matrix.pre != '' }} run: ${{ matrix.pre }} - name: Release build if: ${{ matrix.build == '' }} uses: actions-rs/cargo@v1 with: command: build args: --release --target ${{ matrix.target }} - name: Release build if: ${{ matrix.build != '' }} run: ${{ matrix.build }} env: ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} PKG_CONFIG_SYSROOT_DIR: ${{ steps.setup-ndk.outputs.ndk-path }}/sysroot - name: Postprocessing after build if: ${{ matrix.post != '' }} run: ${{ matrix.post }} - name: Prepare release id: prepare-release shell: bash run: | set -ex build_name="${{ matrix.build_name }}" exe_name="${GITHUB_REPOSITORY#*/}-${GITHUB_REF##*/}-${{ matrix.target }}-${GITHUB_SHA:0:7}" if [[ -z "$build_name" ]]; then # Default build name: . if [[ -z "${{ matrix.ext }}" ]]; then build_name="${GITHUB_REPOSITORY#*/}" else build_name="${GITHUB_REPOSITORY#*/}.${{ matrix.ext }}" exe_name="$exe_name.${{ matrix.ext }}" fi fi # Make sure we own all files (for Docker) if [[ "${{ matrix.os }}" == "ubuntu-latest" ]]; then sudo chown -R $(id -u):$(id -g) target; fi # Find and copy the release binary find target -type f -name "$build_name" -printf '%p' -exec mv {} "${exe_name}" \; echo "EXE_NAME=${exe_name}" >> $GITHUB_OUTPUT du -h "${exe_name}" - if: ${{ startsWith(github.ref, 'refs/tags/v') }} name: Publish the release build uses: softprops/action-gh-release@v3 with: files: ${{ steps.prepare-release.outputs.EXE_NAME }} token: ${{ secrets.GITHUB_TOKEN }} - if: ${{ !startsWith(github.ref, 'refs/tags/v') }} name: Publish the release as an artifact uses: actions/upload-artifact@v7 with: name: ${{ steps.prepare-release.outputs.EXE_NAME }} path: ${{ steps.prepare-release.outputs.EXE_NAME }} - name: Prepare static site (only for web builds) if: ${{ matrix.target == 'wasm32-unknown-unknown' }} run: mkdir public && tar -xvzf "${{ steps.prepare-release.outputs.EXE_NAME }}" --directory public - if: ${{ startsWith(github.ref, 'refs/tags/v') && matrix.target == 'wasm32-unknown-unknown' }} name: Deploy static site (only for web builds) uses: JamesIves/github-pages-deploy-action@v4 with: branch: gh-pages folder: public