|
| 1 | +name: Release |
| 2 | + |
| 3 | +on: |
| 4 | + # Trigger this workflow on a manual workflow dispatch. |
| 5 | + workflow_dispatch: |
| 6 | + inputs: |
| 7 | + version: |
| 8 | + description: "Version number in the format `v1.2.3`" |
| 9 | + required: true |
| 10 | + type: string |
| 11 | + build_for_windows: |
| 12 | + description: "Build for Windows (WARNING: slow!)" |
| 13 | + default: true |
| 14 | + type: boolean |
| 15 | + build_for_macos: |
| 16 | + description: "Build for macOS" |
| 17 | + default: true |
| 18 | + type: boolean |
| 19 | + build_for_linux: |
| 20 | + description: "Build for Linux" |
| 21 | + default: true |
| 22 | + type: boolean |
| 23 | + build_for_web: |
| 24 | + description: "Build for web" |
| 25 | + default: true |
| 26 | + type: boolean |
| 27 | + upload_to_github: |
| 28 | + description: "Upload to GitHub releases" |
| 29 | + default: true |
| 30 | + type: boolean |
| 31 | + upload_to_itch: |
| 32 | + description: "Upload to itch.io (if configured)" |
| 33 | + default: true |
| 34 | + type: boolean |
| 35 | + deny_warnings: |
| 36 | + description: "Deny warnings" |
| 37 | + default: false |
| 38 | + type: boolean |
| 39 | + |
| 40 | +# Cancel the release workflow when a more recent workflow begins. |
| 41 | +concurrency: |
| 42 | + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} |
| 43 | + cancel-in-progress: true |
| 44 | + |
| 45 | +# Configure the release workflow by editing the following values. |
| 46 | +env: |
| 47 | + # The base filename of the binary produced by `cargo build`. |
| 48 | + cargo_build_binary_name: bevy_factory |
| 49 | + |
| 50 | + # The path to the assets directory. |
| 51 | + assets_path: assets |
| 52 | + |
| 53 | + # The itch.io project to upload to in the format `user-name/project-name`. |
| 54 | + # There will be no upload to itch.io if this is commented out. |
| 55 | + # itch_page: the-bevy-flock/bevy-new-2d |
| 56 | + |
| 57 | + # The ID of the app produced by this workflow. |
| 58 | + # Applies to macOS releases. |
| 59 | + # Must contain only A-Z, a-z, 0-9, hyphen, and period: <https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleidentifier>. |
| 60 | + # app_id: the-bevy-flock.bevy-new-2d |
| 61 | + |
| 62 | + # The base filename of the binary in the package produced by this workflow. |
| 63 | + # Applies to Windows, macOS, and Linux releases. |
| 64 | + # Defaults to `cargo_build_binary_name` if commented out. |
| 65 | + #app_binary_name: bevy_new_2d |
| 66 | + |
| 67 | + # The name of the `.zip` or `.dmg` file produced by this workflow. |
| 68 | + # Defaults to `app_binary_name` if commented out. |
| 69 | + # app_package_name: bevy-new-2d |
| 70 | + |
| 71 | + # The display name of the app produced by this workflow. |
| 72 | + # Applies to macOS releases. |
| 73 | + # Defaults to `app_package_name` if commented out. |
| 74 | + # app_display_name: Bevy New 2D |
| 75 | + |
| 76 | + # The short display name of the app produced by this workflow. |
| 77 | + # Applies to macOS releases. |
| 78 | + # Must be 15 or fewer characters: <https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundlename>. |
| 79 | + # Defaults to `app_display_name` if commented out. |
| 80 | + #app_short_name: Bevy New 2D |
| 81 | + |
| 82 | + # Before enabling LFS, please take a look at GitHub's documentation for costs and quota limits: |
| 83 | + # <https://docs.github.com/en/repositories/working-with-files/managing-large-files/about-storage-and-bandwidth-usage> |
| 84 | + git_lfs: false |
| 85 | + |
| 86 | + # Enabling this only helps with consecutive releases to the same version (and takes up cache storage space). |
| 87 | + # See: <https://github.com/orgs/community/discussions/27059>. |
| 88 | + use_github_cache: false |
| 89 | + |
| 90 | +jobs: |
| 91 | + # Forward some environment variables as outputs of this job. |
| 92 | + # This is needed because the `env` context can't be used in the `if:` condition of a job: |
| 93 | + # <https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability> |
| 94 | + forward-env: |
| 95 | + runs-on: ubuntu-latest |
| 96 | + steps: |
| 97 | + - name: Do nothing |
| 98 | + run: "true" |
| 99 | + outputs: |
| 100 | + itch_page: ${{ env.itch_page }} |
| 101 | + |
| 102 | + # Determine the version number for this workflow. |
| 103 | + get-version: |
| 104 | + runs-on: ubuntu-latest |
| 105 | + steps: |
| 106 | + - name: Determine version number |
| 107 | + id: tag |
| 108 | + run: echo "ref=${GITHUB_REF#refs/*/}" >> "${GITHUB_OUTPUT}" |
| 109 | + outputs: |
| 110 | + # Use the input from workflow dispatch, or fall back to the git ref. |
| 111 | + version: ${{ inputs.version || steps.ref.outputs.ref }} |
| 112 | + |
| 113 | + # Build and package a release for each platform. |
| 114 | + build: |
| 115 | + needs: |
| 116 | + - get-version |
| 117 | + env: |
| 118 | + version: ${{ needs.get-version.outputs.version }} |
| 119 | + # Avoid rate-limiting. See: <https://github.com/cargo-bins/cargo-binstall/issues/2045>. |
| 120 | + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 121 | + strategy: |
| 122 | + matrix: |
| 123 | + include: |
| 124 | + - platform: web |
| 125 | + targets: wasm32-unknown-unknown |
| 126 | + package_ext: .zip |
| 127 | + runner: ubuntu-latest |
| 128 | + |
| 129 | + - platform: linux |
| 130 | + targets: x86_64-unknown-linux-gnu |
| 131 | + package_ext: .zip |
| 132 | + runner: ubuntu-latest |
| 133 | + |
| 134 | + - platform: windows |
| 135 | + targets: x86_64-pc-windows-msvc |
| 136 | + binary_ext: .exe |
| 137 | + package_ext: .zip |
| 138 | + runner: windows-latest |
| 139 | + |
| 140 | + - platform: macos |
| 141 | + targets: x86_64-apple-darwin aarch64-apple-darwin |
| 142 | + app_suffix: .app/Contents/MacOS |
| 143 | + package_ext: .dmg |
| 144 | + runner: macos-latest |
| 145 | + runs-on: ${{ matrix.runner }} |
| 146 | + permissions: |
| 147 | + # Required to create a GitHub release: <https://docs.github.com/en/rest/releases/releases#create-a-release>. |
| 148 | + contents: write |
| 149 | + defaults: |
| 150 | + run: |
| 151 | + shell: bash |
| 152 | + |
| 153 | + steps: |
| 154 | + - name: Set up environment |
| 155 | + run: | |
| 156 | + # Default values: |
| 157 | + echo "app_binary_name=${app_binary_name:=${{ env.cargo_build_binary_name }}}" >> "${GITHUB_ENV}" |
| 158 | + echo "app_package_name=${app_package_name:=${app_binary_name}}" >> "${GITHUB_ENV}" |
| 159 | + echo "app_display_name=${app_display_name:=${app_package_name}}" >> "${GITHUB_ENV}" |
| 160 | + echo "app_short_name=${app_short_name:=${app_display_name}}" >> "${GITHUB_ENV}" |
| 161 | +
|
| 162 | + # File paths: |
| 163 | + echo "app=tmp/app/${app_package_name}"'${{ matrix.app_suffix }}' >> "${GITHUB_ENV}" |
| 164 | + echo "package=${app_package_name}-"'${{ matrix.platform }}${{ matrix.package_ext }}' >> "${GITHUB_ENV}" |
| 165 | +
|
| 166 | + # Rustflags: |
| 167 | + RUSTFLAGS='-Zthreads=0' |
| 168 | + if [ '${{ matrix.platform }}' != 'windows' ]; then |
| 169 | + RUSTFLAGS="${RUSTFLAGS:+$RUSTFLAGS }"'-Zshare-generics=y' |
| 170 | + fi |
| 171 | + if [ '${{ inputs.deny_warnings }}' = 'true' ]; then |
| 172 | + RUSTFLAGS="${RUSTFLAGS:+$RUSTFLAGS }"'-Dwarnings' |
| 173 | + fi |
| 174 | + echo "RUSTFLAGS=${RUSTFLAGS}" >> "${GITHUB_ENV}" |
| 175 | +
|
| 176 | + # macOS environment: |
| 177 | + if [ '${{ matrix.platform }}' = 'macos' ]; then |
| 178 | + echo 'MACOSX_DEPLOYMENT_TARGET=11.0' >> "${GITHUB_ENV}" # macOS 11.0 Big Sur is the first version to support universal binaries. |
| 179 | + echo "SDKROOT=$(xcrun --sdk macosx --show-sdk-path)" >> "${GITHUB_ENV}" |
| 180 | + fi |
| 181 | +
|
| 182 | + # Check if building for this platform is enabled. |
| 183 | + echo 'is_platform_enabled=${{ |
| 184 | + (matrix.platform == 'web' && inputs.build_for_web) || |
| 185 | + (matrix.platform == 'linux' && inputs.build_for_linux) || |
| 186 | + (matrix.platform == 'windows' && inputs.build_for_windows) || |
| 187 | + (matrix.platform == 'macos' && inputs.build_for_macos) |
| 188 | + }}' >> "${GITHUB_ENV}" |
| 189 | +
|
| 190 | + - name: Checkout repository |
| 191 | + if: ${{ env.is_platform_enabled == 'true' }} |
| 192 | + uses: actions/checkout@v4 |
| 193 | + with: |
| 194 | + lfs: ${{ env.git_lfs }} |
| 195 | + |
| 196 | + - name: Install Rust toolchain |
| 197 | + if: ${{ env.is_platform_enabled == 'true' }} |
| 198 | + uses: dtolnay/rust-toolchain@nightly |
| 199 | + with: |
| 200 | + targets: ${{ matrix.targets }} |
| 201 | + |
| 202 | + - name: Restore Rust cache |
| 203 | + if: ${{ env.is_platform_enabled == 'true' && env.use_github_cache == 'true' }} |
| 204 | + uses: Swatinem/rust-cache@v2 |
| 205 | + with: |
| 206 | + shared-key: release |
| 207 | + save-if: ${{ github.ref == 'refs/heads/main' }} |
| 208 | + |
| 209 | + - name: Install build dependencies (Linux) |
| 210 | + if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'linux' }} |
| 211 | + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev |
| 212 | + |
| 213 | + - name: Prepare output directories |
| 214 | + if: ${{ env.is_platform_enabled == 'true' }} |
| 215 | + run: rm -rf tmp; mkdir -p tmp/binary '${{ env.app }}' |
| 216 | + |
| 217 | + - name: Install cargo-binstall |
| 218 | + if: ${{ env.is_platform_enabled == 'true' }} |
| 219 | + uses: cargo-bins/cargo-binstall@main |
| 220 | + |
| 221 | + - name: Install Bevy CLI |
| 222 | + if: ${{ env.is_platform_enabled == 'true' }} |
| 223 | + run: cargo binstall --locked --no-confirm --force --git='https://github.com/TheBevyFlock/bevy_cli' bevy_cli |
| 224 | + |
| 225 | + - name: Build and add web bundle to app (Web) |
| 226 | + if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'web' }} |
| 227 | + run: | |
| 228 | + cargo binstall --locked --no-confirm --force wasm-bindgen-cli |
| 229 | + cargo binstall --locked --no-confirm --force wasm-opt |
| 230 | + bevy build --locked --release --features='${{ matrix.features }}' --yes web --bundle |
| 231 | + mv 'target/bevy_web/web-release/${{ env.cargo_build_binary_name }}' '${{ env.app }}' |
| 232 | +
|
| 233 | + - name: Build and add binaries to app (non-Web) |
| 234 | + if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'web' }} |
| 235 | + run: | |
| 236 | + for target in ${{ matrix.targets }}; do |
| 237 | + bevy build --locked --release --target="${target}" --features='${{ matrix.features }}' |
| 238 | + mv target/"${target}"/release/'${{ env.cargo_build_binary_name }}${{ matrix.binary_ext }}' tmp/binary/"${target}"'${{ matrix.binary_ext }}' |
| 239 | + done |
| 240 | + if [ '${{ matrix.platform }}' = 'macos' ]; then |
| 241 | + lipo tmp/binary/*'${{ matrix.binary_ext }}' -create -output '${{ env.app }}/${{ env.app_binary_name }}${{ matrix.binary_ext }}' |
| 242 | + else |
| 243 | + mv tmp/binary/*'${{ matrix.binary_ext }}' '${{ env.app }}/${{ env.app_binary_name }}${{ matrix.binary_ext }}' |
| 244 | + fi |
| 245 | +
|
| 246 | + - name: Add assets to app (non-Web) |
| 247 | + if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'web' }} |
| 248 | + run: cp -R ./'${{ env.assets_path }}' '${{ env.app }}' || true # Ignore error if assets folder does not exist. |
| 249 | + |
| 250 | + - name: Add metadata to app (macOS) |
| 251 | + if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'macos' }} |
| 252 | + run: | |
| 253 | + cat >'${{ env.app }}/../Info.plist' <<EOF |
| 254 | + <?xml version="1.0" encoding="UTF-8"?> |
| 255 | + <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
| 256 | + <plist version="1.0"> |
| 257 | + <dict> |
| 258 | + <key>CFBundleDevelopmentRegion</key> |
| 259 | + <string>en</string> |
| 260 | + <key>CFBundleDisplayName</key> |
| 261 | + <string>${{ env.app_display_name }}</string> |
| 262 | + <key>CFBundleExecutable</key> |
| 263 | + <string>${{ env.app_binary_name }}</string> |
| 264 | + <key>CFBundleIdentifier</key> |
| 265 | + <string>${{ env.app_id }}</string> |
| 266 | + <key>CFBundleName</key> |
| 267 | + <string>${{ env.app_short_name }}</string> |
| 268 | + <key>CFBundleShortVersionString</key> |
| 269 | + <string>${{ env.version }}</string> |
| 270 | + <key>CFBundleVersion</key> |
| 271 | + <string>${{ env.version }}</string> |
| 272 | + <key>CFBundleInfoDictionaryVersion</key> |
| 273 | + <string>6.0</string> |
| 274 | + <key>CFBundlePackageType</key> |
| 275 | + <string>APPL</string> |
| 276 | + <key>CFBundleSupportedPlatforms</key> |
| 277 | + <array> |
| 278 | + <string>MacOSX</string> |
| 279 | + </array> |
| 280 | + </dict> |
| 281 | + </plist> |
| 282 | + EOF |
| 283 | +
|
| 284 | + - name: Package app (non-Windows) |
| 285 | + if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'windows' }} |
| 286 | + working-directory: tmp/app |
| 287 | + run: | |
| 288 | + if [ '${{ matrix.platform }}' = 'macos' ]; then |
| 289 | + ln -s /Applications . |
| 290 | + hdiutil create -fs HFS+ -volname '${{ env.app_package_name }}' -srcfolder . '${{ env.package }}' |
| 291 | + else |
| 292 | + zip --recurse-paths '${{ env.package }}' '${{ env.app_package_name }}' |
| 293 | + fi |
| 294 | +
|
| 295 | + - name: Package app (Windows) |
| 296 | + if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'windows' }} |
| 297 | + working-directory: tmp/app |
| 298 | + shell: pwsh |
| 299 | + run: Compress-Archive -Path '${{ env.app_package_name }}' -DestinationPath '${{ env.package }}' |
| 300 | + |
| 301 | + - name: Upload package to workflow artifacts |
| 302 | + if: ${{ env.is_platform_enabled == 'true' }} |
| 303 | + uses: actions/upload-artifact@v4 |
| 304 | + with: |
| 305 | + path: tmp/app/${{ env.package }} |
| 306 | + name: package-${{ matrix.platform }} |
| 307 | + retention-days: 1 |
| 308 | + |
| 309 | + - name: Upload package to GitHub release |
| 310 | + if: ${{ env.is_platform_enabled == 'true' && env.upload_to_github == 'true' }} |
| 311 | + uses: svenstaro/upload-release-action@v2 |
| 312 | + with: |
| 313 | + repo_token: ${{ secrets.GITHUB_TOKEN }} |
| 314 | + file: tmp/app/${{ env.package }} |
| 315 | + asset_name: ${{ env.package }} |
| 316 | + release_name: ${{ env.version }} |
| 317 | + tag: ${{ env.version }} |
| 318 | + overwrite: true |
| 319 | + |
| 320 | + # Upload all packages to itch.io. |
| 321 | + upload-to-itch: |
| 322 | + runs-on: ubuntu-latest |
| 323 | + needs: |
| 324 | + - forward-env |
| 325 | + - get-version |
| 326 | + - build |
| 327 | + if: ${{ inputs.upload_to_itch && needs.forward-env.outputs.itch_page != '' }} |
| 328 | + |
| 329 | + steps: |
| 330 | + - name: Download all packages |
| 331 | + uses: actions/download-artifact@v4 |
| 332 | + with: |
| 333 | + pattern: package-* |
| 334 | + path: tmp |
| 335 | + |
| 336 | + - name: Install butler |
| 337 | + run: | |
| 338 | + curl -L -o butler.zip 'https://broth.itch.zone/butler/linux-amd64/LATEST/archive/default' |
| 339 | + unzip butler.zip |
| 340 | + chmod +x butler |
| 341 | + ./butler -V |
| 342 | +
|
| 343 | + - name: Upload all packages to itch.io |
| 344 | + env: |
| 345 | + BUTLER_API_KEY: ${{ secrets.BUTLER_CREDENTIALS }} |
| 346 | + run: | |
| 347 | + for channel in $(ls tmp); do |
| 348 | + ./butler push \ |
| 349 | + --fix-permissions \ |
| 350 | + --userversion='${{ needs.get-version.outputs.version }}' \ |
| 351 | + tmp/"${channel}"/* \ |
| 352 | + '${{ env.itch_page }}':"${channel#package-}" |
| 353 | + done |
0 commit comments