From 1153342f5ee24248d02b3eb413644ce18f5db361 Mon Sep 17 00:00:00 2001 From: Amatsugu Date: Sat, 5 Jul 2025 16:25:26 -0400 Subject: [PATCH] Profiles and workflow --- .github/workflows/ci.yaml | 140 ++++++++++ .github/workflows/release.yaml | 335 +++++++++++++++++++++++ .github/workflows/release.yaml.template | 347 ++++++++++++++++++++++++ 3 files changed, 822 insertions(+) create mode 100644 .github/workflows/ci.yaml create mode 100644 .github/workflows/release.yaml create mode 100644 .github/workflows/release.yaml.template diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..7623e3b --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,140 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +env: + # Reduce compile time and cache size. + RUSTFLAGS: -Zshare-generics=y -Zthreads=0 + RUSTDOCFLAGS: -Zshare-generics=y -Zthreads=0 + # Use the same Rust toolchain across jobs so they can share a cache. + toolchain: nightly-2025-04-03 + +jobs: + # Run Clippy lints. + clippy-lints: + name: Clippy lints + runs-on: ubuntu-latest + env: + RUSTFLAGS: "-Dwarnings" + timeout-minutes: 20 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.toolchain }} + components: clippy + + - name: Restore Rust cache + id: cache + uses: Swatinem/rust-cache@v2 + with: + shared-key: ci + save-if: ${{ github.ref == 'refs/heads/main' }} + + - name: Install build dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev + + - name: Run Clippy lints + run: cargo clippy --locked --workspace --all-targets --profile ci --all-features + + # Run Bevy lints. + bevy-lints: + name: Bevy lints + runs-on: ubuntu-latest + env: + RUSTFLAGS: "-Dwarnings" + timeout-minutes: 20 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust toolchain (plus bevy_lint) + uses: TheBevyFlock/bevy_cli/bevy_lint@lint-v0.3.0 + + - name: Restore Rust cache + id: cache + uses: Swatinem/rust-cache@v2 + with: + shared-key: ci + save-if: false + + - name: Install build dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev + + - name: Run Bevy lints + run: bevy_lint --locked --workspace --all-targets --profile ci --all-features + + # Run tests. + tests: + name: Tests + runs-on: ubuntu-latest + timeout-minutes: 40 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up environment + run: echo "RUSTFLAGS=${RUSTFLAGS:+$RUSTFLAGS }-Zcodegen-backend=cranelift" >> "${GITHUB_ENV}" + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.toolchain }} + components: rustc-codegen-cranelift-preview + + - name: Restore Rust cache + uses: Swatinem/rust-cache@v2 + with: + shared-key: test + cache-directories: ${{ env.LD_LIBRARY_PATH }} + save-if: ${{ github.ref == 'refs/heads/main' }} + + - name: Install build dependencies + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev + + - name: Run tests + run: cargo test --locked --workspace --all-targets --profile ci --no-fail-fast + + # Check that the web build compiles. + check-web: + name: Check web + runs-on: ubuntu-latest + env: + RUSTFLAGS: -Zshare-generics=y -Zthreads=0 --cfg getrandom_backend="wasm_js" + timeout-minutes: 20 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.toolchain }} + targets: wasm32-unknown-unknown + + - name: Restore Rust cache + id: cache + uses: Swatinem/rust-cache@v2 + with: + shared-key: web-ci + save-if: ${{ github.ref == 'refs/heads/main' }} + + - name: Install build dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev + + - name: Check web + run: cargo check --config 'profile.web.inherits="dev"' --profile ci --no-default-features --features "dev web" --target wasm32-unknown-unknown diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..eb3fa16 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,335 @@ +name: Release + +on: + # Trigger this workflow when a tag is pushed in the format `v1.2.3`. + push: + tags: + # Pattern syntax: . + - "v[0-9]+.[0-9]+.[0-9]+*" + # Trigger this workflow manually via workflow dispatch. + workflow_dispatch: + inputs: + version: + description: "Version number in the format `v1.2.3`" + required: true + type: string + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +# Configure the release workflow by editing the following values. +env: + # The base filename of the binary produced by `cargo build`. + cargo_build_binary_name: space-game + + # The path to the assets directory. + assets_path: assets + + # Whether to build and package a release for a given target platform. + build_for_web: false + build_for_linux: false + build_for_windows: true + build_for_macos: false + + # Whether to upload the packages produced by this workflow to a GitHub release. + upload_to_github: true + + # The itch.io project to upload to in the format `user-name/project-name`. + # There will be no upload to itch.io if this is commented out. + # upload_to_itch: amatsugu/space-game + + ############ + # ADVANCED # + ############ + + # The ID of the app produced by this workflow. + # Applies to macOS releases. + # Must contain only A-Z, a-z, 0-9, hyphen, and period: . + app_id: amatsugu.space-game + + # The base filename of the binary in the package produced by this workflow. + # Applies to Windows, macOS, and Linux releases. + # Defaults to `cargo_build_binary_name` if commented out. + #app_binary_name: bevy_jam_6 + + # The name of the `.zip` or `.dmg` file produced by this workflow. + # Defaults to `app_binary_name` if commented out. + #app_package_name: bevy-new-2d + + # The display name of the app produced by this workflow. + # Applies to macOS releases. + # Defaults to `app_package_name` if commented out. + app_display_name: space-game + + # The short display name of the app produced by this workflow. + # Applies to macOS releases. + # Must be 15 or fewer characters: . + # Defaults to `app_display_name` if commented out. + #app_short_name: Bevy New 2D + + # Before enabling LFS, please take a look at GitHub's documentation for costs and quota limits: + # + git_lfs: false + + # Enabling this only helps with consecutive releases to the same tag (and takes up cache storage space). + # See: . + use_github_cache: false + + # Reduce compile time. + RUSTFLAGS: -Zshare-generics=y -Zthreads=0 + +jobs: + # Forward some environment variables as outputs of this job. + # This is needed because the `env` context can't be used in the `if:` condition of a job: + # + forward-env: + runs-on: ubuntu-latest + steps: + - name: Do nothing + run: "true" + outputs: + upload_to_itch: ${{ env.upload_to_itch }} + + # Determine the version number for this workflow. + get-version: + runs-on: ubuntu-latest + steps: + - name: Determine version number + id: tag + run: echo "tag=${GITHUB_REF#refs/tags/}" >> "${GITHUB_OUTPUT}" + outputs: + # Use the input from workflow dispatch, or fall back to the git tag. + version: ${{ inputs.version || steps.tag.outputs.tag }} + + # Build and package a release for each platform. + build: + needs: + - get-version + env: + version: ${{ needs.get-version.outputs.version }} + # Avoid rate-limiting. See: . + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + strategy: + matrix: + include: + - platform: web + targets: wasm32-unknown-unknown + package_ext: .zip + runner: ubuntu-latest + + - platform: linux + targets: x86_64-unknown-linux-gnu + package_ext: .zip + runner: ubuntu-latest + + - platform: windows + targets: x86_64-pc-windows-msvc + binary_ext: .exe + package_ext: .zip + runner: windows-latest + + - platform: macos + targets: x86_64-apple-darwin aarch64-apple-darwin + app_suffix: .app/Contents/MacOS + package_ext: .dmg + runner: macos-latest + runs-on: ${{ matrix.runner }} + permissions: + # Required to create a GitHub release: . + contents: write + defaults: + run: + shell: bash + + steps: + - name: Set up environment + run: | + # Default values: + echo "app_binary_name=${app_binary_name:=${{ env.cargo_build_binary_name }}}" >> "${GITHUB_ENV}" + echo "app_package_name=${app_package_name:=${app_binary_name}}" >> "${GITHUB_ENV}" + echo "app_display_name=${app_display_name:=${app_package_name}}" >> "${GITHUB_ENV}" + echo "app_short_name=${app_short_name:=${app_display_name}}" >> "${GITHUB_ENV}" + + # File paths: + echo "app=tmp/app/${app_package_name}"'${{ matrix.app_suffix }}' >> "${GITHUB_ENV}" + echo "package=${app_package_name}-"'${{ matrix.platform }}${{ matrix.package_ext }}' >> "${GITHUB_ENV}" + + # macOS environment: + if [ '${{ matrix.platform }}' = 'macos' ]; then + echo 'MACOSX_DEPLOYMENT_TARGET=11.0' >> "${GITHUB_ENV}" # macOS 11.0 Big Sur is the first version to support universal binaries. + echo "SDKROOT=$(xcrun --sdk macosx --show-sdk-path)" >> "${GITHUB_ENV}" + fi + + # Check if building for this platform is enabled. + echo 'is_platform_enabled=${{ + (matrix.platform == 'web' && env.build_for_web == 'true') || + (matrix.platform == 'linux' && env.build_for_linux == 'true') || + (matrix.platform == 'windows' && env.build_for_windows == 'true') || + (matrix.platform == 'macos' && env.build_for_macos == 'true') + }}' >> "${GITHUB_ENV}" + + - name: Checkout repository + if: ${{ env.is_platform_enabled == 'true' }} + uses: actions/checkout@v4 + with: + lfs: ${{ env.git_lfs }} + + - name: Install Rust toolchain + if: ${{ env.is_platform_enabled == 'true' }} + uses: dtolnay/rust-toolchain@nightly + with: + targets: ${{ matrix.targets }} + + - name: Restore Rust cache + if: ${{ env.is_platform_enabled == 'true' && env.use_github_cache == 'true' }} + uses: Swatinem/rust-cache@v2 + with: + shared-key: release + save-if: ${{ github.ref == 'refs/heads/main' }} + + - name: Install build dependencies (Linux) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'linux' }} + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev + + - name: Prepare output directories + if: ${{ env.is_platform_enabled == 'true' }} + run: rm -rf tmp; mkdir -p tmp/binary '${{ env.app }}' + + - name: Install cargo-binstall + if: ${{ env.is_platform_enabled == 'true' }} + uses: cargo-bins/cargo-binstall@main + + - name: Install Bevy CLI + if: ${{ env.is_platform_enabled == 'true' }} + run: cargo binstall --locked --no-confirm --force --git='https://github.com/TheBevyFlock/bevy_cli' bevy_cli + + - name: Build and add web bundle to app (Web) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'web' }} + run: | + cargo binstall --locked --no-confirm --force wasm-bindgen-cli + cargo binstall --locked --no-confirm --force wasm-opt + RUSTFLAGS='-Zshare-generics=y -Zthreads=0 --cfg getrandom_backend="wasm_js"' bevy build --locked --release --features='${{ matrix.features }} web' --yes web --bundle + mv 'target/bevy_web/web-release/${{ env.cargo_build_binary_name }}' '${{ env.app }}' + + - name: Build and add binaries to app (non-Web) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'web' }} + run: | + for target in ${{ matrix.targets }}; do + bevy build --locked --release --target="${target}" --features='${{ matrix.features }}' + mv target/"${target}"/release/'${{ env.cargo_build_binary_name }}${{ matrix.binary_ext }}' tmp/binary/"${target}"'${{ matrix.binary_ext }}' + done + if [ '${{ matrix.platform }}' = 'macos' ]; then + lipo tmp/binary/*'${{ matrix.binary_ext }}' -create -output '${{ env.app }}/${{ env.app_binary_name }}${{ matrix.binary_ext }}' + else + mv tmp/binary/*'${{ matrix.binary_ext }}' '${{ env.app }}/${{ env.app_binary_name }}${{ matrix.binary_ext }}' + fi + + - name: Add assets to app (non-Web) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'web' }} + run: cp -R ./'${{ env.assets_path }}' '${{ env.app }}' || true # Ignore error if assets folder does not exist. + + - name: Add metadata to app (macOS) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'macos' }} + run: | + cat >'${{ env.app }}/../Info.plist' < + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${{ env.app_display_name }} + CFBundleExecutable + ${{ env.app_binary_name }} + CFBundleIdentifier + ${{ env.app_id }} + CFBundleName + ${{ env.app_short_name }} + CFBundleShortVersionString + ${{ env.version }} + CFBundleVersion + ${{ env.version }} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSupportedPlatforms + + MacOSX + + + + EOF + + - name: Package app (non-Windows) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'windows' }} + working-directory: tmp/app + run: | + if [ '${{ matrix.platform }}' = 'macos' ]; then + ln -s /Applications . + hdiutil create -fs HFS+ -volname '${{ env.app_package_name }}' -srcfolder . '${{ env.package }}' + else + zip --recurse-paths '${{ env.package }}' '${{ env.app_package_name }}' + fi + + - name: Package app (Windows) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'windows' }} + working-directory: tmp/app + shell: pwsh + run: Compress-Archive -Path '${{ env.app_package_name }}' -DestinationPath '${{ env.package }}' + + - name: Upload package to workflow artifacts + if: ${{ env.is_platform_enabled == 'true' }} + uses: actions/upload-artifact@v4 + with: + path: tmp/app/${{ env.package }} + name: package-${{ matrix.platform }} + retention-days: 1 + + - name: Upload package to GitHub release + if: ${{ env.is_platform_enabled == 'true' && env.upload_to_github == 'true' }} + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: tmp/app/${{ env.package }} + asset_name: ${{ env.package }} + release_name: ${{ env.version }} + tag: ${{ env.version }} + overwrite: true + + # Upload all packages to itch.io. + upload-to-itch: + runs-on: ubuntu-latest + needs: + - forward-env + - get-version + - build + if: ${{ needs.forward-env.outputs.upload_to_itch != '' }} + + steps: + - name: Download all packages + uses: actions/download-artifact@v4 + with: + pattern: package-* + path: tmp + + - name: Install butler + run: | + curl -L -o butler.zip 'https://broth.itch.zone/butler/linux-amd64/LATEST/archive/default' + unzip butler.zip + chmod +x butler + ./butler -V + + - name: Upload all packages to itch.io + env: + BUTLER_API_KEY: ${{ secrets.BUTLER_CREDENTIALS }} + run: | + for channel in $(ls tmp); do + ./butler push \ + --fix-permissions \ + --userversion='${{ needs.get-version.outputs.version }}' \ + tmp/"${channel}"/* \ + '${{ env.upload_to_itch }}':"${channel#package-}" + done diff --git a/.github/workflows/release.yaml.template b/.github/workflows/release.yaml.template new file mode 100644 index 0000000..5ebf863 --- /dev/null +++ b/.github/workflows/release.yaml.template @@ -0,0 +1,347 @@ +name: Release + +on: + # Trigger this workflow when a tag is pushed in the format `v1.2.3`. + push: + tags: + # Pattern syntax: . + - "v[0-9]+.[0-9]+.[0-9]+*" + # Trigger this workflow manually via workflow dispatch. + workflow_dispatch: + inputs: + version: + description: "Version number in the format `v1.2.3`" + required: true + type: string + +{% raw -%} +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true +{%- endraw %} + +# Configure the release workflow by editing the following values. +env: + # The base filename of the binary produced by `cargo build`. + cargo_build_binary_name: {{project-name}} + + # The path to the assets directory. + assets_path: assets + + # Whether to build and package a release for a given target platform. + build_for_web: true + build_for_linux: true + build_for_windows: true + build_for_macos: true + + # Whether to upload the packages produced by this workflow to a GitHub release. + upload_to_github: true + + # The itch.io project to upload to in the format `user-name/project-name`. + # There will be no upload to itch.io if this is commented out. + {%- if itch_username != "" %} + {%- if itch_project != "" %} + upload_to_itch: {{itch_username}}/{{itch_project}} + {%- else %} + upload_to_itch: {{itch_username}}/{{project-name}} + {%- endif %} + {%- else %} + #upload_to_itch: your-itch-username/{{project-name}} + {%- endif %} + + ############ + # ADVANCED # + ############ + + # The ID of the app produced by this workflow. + # Applies to macOS releases. + # Must contain only A-Z, a-z, 0-9, hyphen, and period: . + app_id: {{itch_username | kebab_case}}.{{project-name | kebab_case}} + + # The base filename of the binary in the package produced by this workflow. + # Applies to Windows, macOS, and Linux releases. + # Defaults to `cargo_build_binary_name` if commented out. + #app_binary_name: {{project-name}} + + # The name of the `.zip` or `.dmg` file produced by this workflow. + # Defaults to `app_binary_name` if commented out. + #app_package_name: {{project-name | kebab_case}} + + # The display name of the app produced by this workflow. + # Applies to macOS releases. + # Defaults to `app_package_name` if commented out. + #app_display_name: {{project-name | title_case}} + + # The short display name of the app produced by this workflow. + # Applies to macOS releases. + # Must be 15 or fewer characters: . + # Defaults to `app_display_name` if commented out. + #app_short_name: {{project-name | title_case | truncate: 15, "…"}} + + # Before enabling LFS, please take a look at GitHub's documentation for costs and quota limits: + # + git_lfs: false + + # Enabling this only helps with consecutive releases to the same tag (and takes up cache storage space). + # See: . + use_github_cache: false + + # Reduce compile time. + RUSTFLAGS: -Dwarnings -Zshare-generics=y -Zthreads=0 + +{% raw -%} +jobs: + # Forward some environment variables as outputs of this job. + # This is needed because the `env` context can't be used in the `if:` condition of a job: + # + forward-env: + runs-on: ubuntu-latest + steps: + - name: Do nothing + run: "true" + outputs: + upload_to_itch: ${{ env.upload_to_itch }} + + # Determine the version number for this workflow. + get-version: + runs-on: ubuntu-latest + steps: + - name: Determine version number + id: tag + run: echo "tag=${GITHUB_REF#refs/tags/}" >> "${GITHUB_OUTPUT}" + outputs: + # Use the input from workflow dispatch, or fall back to the git tag. + version: ${{ inputs.version || steps.tag.outputs.tag }} + + # Build and package a release for each platform. + build: + needs: + - get-version + env: + version: ${{ needs.get-version.outputs.version }} + # Avoid rate-limiting. See: . + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + strategy: + matrix: + include: + - platform: web + targets: wasm32-unknown-unknown + package_ext: .zip + runner: ubuntu-latest + + - platform: linux + targets: x86_64-unknown-linux-gnu + package_ext: .zip + runner: ubuntu-latest + + - platform: windows + targets: x86_64-pc-windows-msvc + binary_ext: .exe + package_ext: .zip + runner: windows-latest + + - platform: macos + targets: x86_64-apple-darwin aarch64-apple-darwin + app_suffix: .app/Contents/MacOS + package_ext: .dmg + runner: macos-latest + runs-on: ${{ matrix.runner }} + permissions: + # Required to create a GitHub release: . + contents: write + defaults: + run: + shell: bash + + steps: + - name: Set up environment + run: | + # Default values: + echo "app_binary_name=${app_binary_name:=${{ env.cargo_build_binary_name }}}" >> "${GITHUB_ENV}" + echo "app_package_name=${app_package_name:=${app_binary_name}}" >> "${GITHUB_ENV}" + echo "app_display_name=${app_display_name:=${app_package_name}}" >> "${GITHUB_ENV}" + echo "app_short_name=${app_short_name:=${app_display_name}}" >> "${GITHUB_ENV}" + + # File paths: + echo "app=tmp/app/${app_package_name}"'${{ matrix.app_suffix }}' >> "${GITHUB_ENV}" + echo "package=${app_package_name}-"'${{ matrix.platform }}${{ matrix.package_ext }}' >> "${GITHUB_ENV}" + + # macOS environment: + if [ '${{ matrix.platform }}' = 'macos' ]; then + echo 'MACOSX_DEPLOYMENT_TARGET=11.0' >> "${GITHUB_ENV}" # macOS 11.0 Big Sur is the first version to support universal binaries. + echo "SDKROOT=$(xcrun --sdk macosx --show-sdk-path)" >> "${GITHUB_ENV}" + fi + + # Check if building for this platform is enabled. + echo 'is_platform_enabled=${{ + (matrix.platform == 'web' && env.build_for_web == 'true') || + (matrix.platform == 'linux' && env.build_for_linux == 'true') || + (matrix.platform == 'windows' && env.build_for_windows == 'true') || + (matrix.platform == 'macos' && env.build_for_macos == 'true') + }}' >> "${GITHUB_ENV}" + + - name: Checkout repository + if: ${{ env.is_platform_enabled == 'true' }} + uses: actions/checkout@v4 + with: + lfs: ${{ env.git_lfs }} + + - name: Install Rust toolchain + if: ${{ env.is_platform_enabled == 'true' }} + uses: dtolnay/rust-toolchain@nightly + with: + targets: ${{ matrix.targets }} + + - name: Restore Rust cache + if: ${{ env.is_platform_enabled == 'true' && env.use_github_cache == 'true' }} + uses: Swatinem/rust-cache@v2 + with: + shared-key: release + save-if: ${{ github.ref == 'refs/heads/main' }} + + - name: Install build dependencies (Linux) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'linux' }} + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev + + - name: Prepare output directories + if: ${{ env.is_platform_enabled == 'true' }} + run: rm -rf tmp; mkdir -p tmp/binary '${{ env.app }}' + + - name: Install cargo-binstall + if: ${{ env.is_platform_enabled == 'true' }} + uses: cargo-bins/cargo-binstall@main + + - name: Install Bevy CLI + if: ${{ env.is_platform_enabled == 'true' }} + run: cargo binstall --locked --no-confirm --force --git='https://github.com/TheBevyFlock/bevy_cli' bevy_cli + + - name: Build and add web bundle to app (Web) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'web' }} + run: | + cargo binstall --locked --no-confirm --force wasm-bindgen-cli + cargo binstall --locked --no-confirm --force wasm-opt + bevy build --locked --release --features='${{ matrix.features }}' --yes web --bundle + mv 'target/bevy_web/web-release/${{ env.cargo_build_binary_name }}' '${{ env.app }}' + + - name: Build and add binaries to app (non-Web) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'web' }} + run: | + for target in ${{ matrix.targets }}; do + bevy build --locked --release --target="${target}" --features='${{ matrix.features }}' + mv target/"${target}"/release/'${{ env.cargo_build_binary_name }}${{ matrix.binary_ext }}' tmp/binary/"${target}"'${{ matrix.binary_ext }}' + done + if [ '${{ matrix.platform }}' = 'macos' ]; then + lipo tmp/binary/*'${{ matrix.binary_ext }}' -create -output '${{ env.app }}/${{ env.app_binary_name }}${{ matrix.binary_ext }}' + else + mv tmp/binary/*'${{ matrix.binary_ext }}' '${{ env.app }}/${{ env.app_binary_name }}${{ matrix.binary_ext }}' + fi + + - name: Add assets to app (non-Web) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'web' }} + run: cp -R ./'${{ env.assets_path }}' '${{ env.app }}' || true # Ignore error if assets folder does not exist. + + - name: Add metadata to app (macOS) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'macos' }} + run: | + cat >'${{ env.app }}/../Info.plist' < + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${{ env.app_display_name }} + CFBundleExecutable + ${{ env.app_binary_name }} + CFBundleIdentifier + ${{ env.app_id }} + CFBundleName + ${{ env.app_short_name }} + CFBundleShortVersionString + ${{ env.version }} + CFBundleVersion + ${{ env.version }} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSupportedPlatforms + + MacOSX + + + + EOF + + - name: Package app (non-Windows) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'windows' }} + working-directory: tmp/app + run: | + if [ '${{ matrix.platform }}' = 'macos' ]; then + ln -s /Applications . + hdiutil create -fs HFS+ -volname '${{ env.app_package_name }}' -srcfolder . '${{ env.package }}' + else + zip --recurse-paths '${{ env.package }}' '${{ env.app_package_name }}' + fi + + - name: Package app (Windows) + if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'windows' }} + working-directory: tmp/app + shell: pwsh + run: Compress-Archive -Path '${{ env.app_package_name }}' -DestinationPath '${{ env.package }}' + + - name: Upload package to workflow artifacts + if: ${{ env.is_platform_enabled == 'true' }} + uses: actions/upload-artifact@v4 + with: + path: tmp/app/${{ env.package }} + name: package-${{ matrix.platform }} + retention-days: 1 + + - name: Upload package to GitHub release + if: ${{ env.is_platform_enabled == 'true' && env.upload_to_github == 'true' }} + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: tmp/app/${{ env.package }} + asset_name: ${{ env.package }} + release_name: ${{ env.version }} + tag: ${{ env.version }} + overwrite: true + + # Upload all packages to itch.io. + upload-to-itch: + runs-on: ubuntu-latest + needs: + - forward-env + - get-version + - build + if: ${{ needs.forward-env.outputs.upload_to_itch != '' }} + + steps: + - name: Download all packages + uses: actions/download-artifact@v4 + with: + pattern: package-* + path: tmp + + - name: Install butler + run: | + curl -L -o butler.zip 'https://broth.itch.zone/butler/linux-amd64/LATEST/archive/default' + unzip butler.zip + chmod +x butler + ./butler -V + + - name: Upload all packages to itch.io + env: + BUTLER_API_KEY: ${{ secrets.BUTLER_CREDENTIALS }} + run: | + for channel in $(ls tmp); do + ./butler push \ + --fix-permissions \ + --userversion='${{ needs.get-version.outputs.version }}' \ + tmp/"${channel}"/* \ + '${{ env.upload_to_itch }}':"${channel#package-}" + done +{%- endraw %}