name: CI on: push: paths-ignore: - '.editorconfig' - '.gitattributes' - '.github/*_TEMPLATE/**' - '.github/workflows/localisation.yml' - '.gitignore' - '.vscode/**' pull_request: paths-ignore: - '.editorconfig' - '.gitattributes' - '.github/*_TEMPLATE/**' - '.github/workflows/localisation.yml' - '.gitignore' - '.vscode/**' workflow_dispatch: inputs: sign: description: Sign binaries type: choice options: - 'no' - test-signing - release-signing default: test-signing defaults: run: shell: bash env: OPENRCT2_BUILD_SERVER: GitHub OPENRCT2_ORG_TOKEN: ${{ secrets.OPENRCT2_ORG_TOKEN }} BACKTRACE_IO_TOKEN: ${{ secrets.BACKTRACE_IO_TOKEN }} OPENRCT2_VERSION: 0.5.0 # https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value concurrency: group: ${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: build_variables: name: Get version info runs-on: ubuntu-latest # This job is too heavy for ubuntu-slim. It takes almost a minute to checkout the code on slim vs 23s on ubuntu-latest. # We want to sign tagged releases with release certificates, but it is only allowed to be ran manually. # Disable automatic runs for tags and force release signing for tags. if: | (startsWith(github.ref, 'refs/tags/v') && github.event_name == 'workflow_dispatch' && github.event.inputs.sign == 'release-signing') || (!startsWith(github.ref, 'refs/tags/v') && github.event.inputs.sign != 'release-signing') outputs: name: ${{ steps.artifact-name.outputs.name }} describe: ${{ steps.ghd.outputs.describe }} short-sha: ${{ steps.ghd.outputs.short-sha }} distance: ${{ steps.ghd.outputs.distance }} tag: ${{ steps.ghd.outputs.tag }} push: ${{ steps.setenv.outputs.push }} sign: ${{ steps.sign.outputs.sign }} certificate: ${{ steps.sign.outputs.certificate }} steps: # We need to fetch entire repo to get the tags and correctly run `describe` - name: Check out code uses: actions/checkout@v6 with: fetch-depth: 0 # We cannot use proudust/gh-describe, as it reports incorrect (too short) short-sha - name: Git describe id: ghd run: | TAG=$(git describe --tags --abbrev=0) DESCRIBE=$(git describe --tags) SHORT_SHA=$(git rev-parse --short HEAD) DISTANCE=$(git rev-list --count $TAG..HEAD) echo "tag=$TAG" echo "describe=$DESCRIBE" echo "short-sha=$SHORT_SHA" echo "distance=$DISTANCE" echo "tag=$TAG" >> $GITHUB_OUTPUT echo "describe=$DESCRIBE" >> $GITHUB_OUTPUT echo "short-sha=$SHORT_SHA" >> $GITHUB_OUTPUT echo "distance=$DISTANCE" >> $GITHUB_OUTPUT - name: Set env id: setenv run: | . scripts/setenv echo "push=$OPENRCT2_PUSH" echo "push=$OPENRCT2_PUSH" >> $GITHUB_OUTPUT # Name now uses the same format as "describe" - name: Get artifact name id: artifact-name run: | echo "name=${{ steps.ghd.outputs.describe }}" echo "name=${{ steps.ghd.outputs.describe }}" >> $GITHUB_OUTPUT - name: Sign id: sign env: SIGNPATH_API_TOKEN: ${{ secrets.SIGNPATH_API_TOKEN }} run: | sign=${{ env.SIGNPATH_API_TOKEN != '' && github.event.inputs.sign != 'no' && (needs.build_variables.outputs.push || startsWith(github.ref, 'refs/tags/v')) }} # if using workflow_dispatch, use the provided certificate if [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then certificate=${{ github.event.inputs.sign }} else # Default to no signing certificate=no sign=false fi echo "sign=$sign" echo "certificate=$certificate" echo "sign=$sign" >> $GITHUB_OUTPUT echo "certificate=$certificate" >> $GITHUB_OUTPUT # lint-commit: # name: Lint Commit Message # if: github.event_name == 'pull_request' # runs-on: ubuntu-latest # env: # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # steps: # - name: Checkout # uses: actions/checkout@v6 # with: # fetch-depth: 0 # - name: Lint Commit Messages # uses: wagoid/commitlint-github-action@v5 # with: # configFile: .commitlint.json check-code-formatting: name: Check code formatting runs-on: ubuntu-latest container: ghcr.io/openrct2/openrct2-build:26-format permissions: pull-requests: write contents: read defaults: run: shell: sh steps: - name: Checkout uses: actions/checkout@v6 - run: git config --global --add safe.directory $PWD - name: Run clang-format id: clang_format run: scripts/check-code-formatting - uses: parkerbxyz/suggest-changes@v3 if: github.event_name == 'pull_request' && failure() with: comment: 'Please commit the suggested changes from clang-format.' event: 'REQUEST_CHANGES' check-changelog-formatting: name: Check changelog formatting runs-on: ubuntu-slim defaults: run: shell: bash steps: - name: Checkout uses: actions/checkout@v6 - name: Run check-changelog-formatting run: scripts/check-changelog-formatting g2dat: name: Graphics .dat files runs-on: ubuntu-slim needs: build_variables steps: - name: Checkout OpenRCT2 uses: actions/checkout@v6 with: path: OpenRCT2 - name: Download gxc run: | curl -Lo tools.tar.gz https://github.com/OpenRCT2/libsawyer/releases/download/v1.4.0/libsawyer-tools-linux-x64.tar.gz mkdir -p "$GITHUB_WORKSPACE/bin" tar -C "$GITHUB_WORKSPACE/bin" -xf tools.tar.gz echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH - name: Build graphics .dat files run: | OpenRCT2/scripts/build-graphics-dat "$PWD" - name: Upload graphics .dat files uses: actions/upload-artifact@v6 with: name: graphics-${{ needs.build_variables.outputs.name }} path: | g2.dat palettes.dat fonts.dat tracks.dat windows: name: Windows runs-on: ${{ matrix.runs_on }} needs: [check-code-formatting, build_variables, g2dat] strategy: fail-fast: false matrix: include: - platform: win32 runs_on: windows-2025-vs2026 - platform: x64 runs_on: windows-2025-vs2026 # keep arm64 on vs2022 for now. VS2026 is a bit slower and we can maintain # compatibility with vs2022 - platform: arm64 runs_on: windows-latest env: PLATFORM: ${{ matrix.platform }} DISTANCE_FROM_TAG: ${{ needs.build_variables.outputs.distance }} steps: - name: Setup environment run: | BRANCH=$(echo $GITHUB_REF | cut -d'/' -f 3) if [[ $BRANCH == 'develop' || $GITHUB_REF_TYPE == 'tag' ]]; then echo "CONFIGURATION=ReleaseLTCG" >> "$GITHUB_ENV" else echo "CONFIGURATION=Release" >> "$GITHUB_ENV" fi - name: Checkout uses: actions/checkout@v6 - name: Install MSVC problem matcher uses: ammaraskar/msvc-problem-matcher@master - name: Build OpenRCT2 run: . scripts/setenv && build - name: Upload unsigned binaries id: upload-windows-binaries-unsigned uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-unsigned-${{ matrix.platform }} path: | bin/openrct2.exe bin/openrct2.com # Sign the binaries first, so that all other artifacts (portable, installer, symbols) use signed binaries - name: Sign binaries id: sign-binaries env: SIGNPATH_API_TOKEN: ${{ secrets.SIGNPATH_API_TOKEN }} if: ${{ needs.build_variables.outputs.sign == 'true' }} uses: signpath/github-action-submit-signing-request@v2 with: api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' organization-id: 645b821f-6283-45e1-8198-264997072801 project-slug: OpenRCT2 signing-policy-slug: ${{ needs.build_variables.outputs.certificate }} artifact-configuration-slug: 'binaries' github-artifact-id: ${{ steps.upload-windows-binaries-unsigned.outputs.artifact-id }} wait-for-completion: true output-artifact-directory: files-signed parameters: | version: "${{ env.OPENRCT2_VERSION }}.${{ needs.build_variables.outputs.distance }}-${{ needs.build_variables.outputs.short-sha }}" - name: Use signed binaries if: ${{ needs.build_variables.outputs.sign == 'true' }} run: | mv files-signed/openrct2.com bin/openrct2.com mv files-signed/openrct2.exe bin/openrct2.exe - name: Download graphics .dat files on ARM64 if: matrix.platform == 'arm64' uses: actions/download-artifact@v7 with: name: graphics-${{ needs.build_variables.outputs.name }} path: bin/data - name: Build artifacts run: | . scripts/setenv -q build-portable build-symbols build-installer -i echo "OPENRCT2_VERSION_EXTRA=$OPENRCT2_VERSION_EXTRA" >> "$GITHUB_ENV" - name: Rename artifacts run: | mv artifacts/openrct2-portable-*.zip artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-portable-$PLATFORM.zip mv artifacts/openrct2-installer-*.exe artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-installer-$PLATFORM.exe mv artifacts/openrct2-symbols-*.zip artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-symbols-$PLATFORM.zip - name: Upload portable artifact (CI) uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-${{ runner.os }}-portable-${{ matrix.platform }} path: artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-portable-${{ matrix.platform }}.zip if-no-files-found: error - name: Upload unsigned installer artifact (CI) id: upload-windows-installer-unsigned uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-${{ runner.os }}-installer-${{ matrix.platform }}-unsigned path: artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-installer-${{ matrix.platform }}.exe if-no-files-found: error - name: Sign installer id: sign-installer if: ${{ needs.build_variables.outputs.sign == 'true' }} uses: signpath/github-action-submit-signing-request@v2 with: api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' organization-id: 645b821f-6283-45e1-8198-264997072801 project-slug: OpenRCT2 signing-policy-slug: ${{ needs.build_variables.outputs.certificate }} artifact-configuration-slug: 'installer' github-artifact-id: ${{ steps.upload-windows-installer-unsigned.outputs.artifact-id }} wait-for-completion: true output-artifact-directory: files-signed parameters: | version: "${{ env.OPENRCT2_VERSION }}${{ env.OPENRCT2_VERSION_EXTRA }}" product: "OpenRCT2 ${{ matrix.platform }} Installer for Windows 7 and later" - name: Upload signed installer artifact (CI) id: upload-windows-installer-signed if: ${{ needs.build_variables.outputs.sign == 'true' }} uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-${{ runner.os }}-installer-${{ matrix.platform }} path: files-signed/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-installer-${{ matrix.platform }}.exe if-no-files-found: error - name: Upload symbols artifact (CI) uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-${{ runner.os }}-symbols-${{ matrix.platform }} path: artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-symbols-${{ matrix.platform }}.zip if-no-files-found: error - name: Run Tests if: matrix.platform != 'arm64' run: . scripts/setenv -q && run-tests - name: Test Summary uses: test-summary/action@v2 with: paths: "artifacts/test-**.xml" if: matrix.platform != 'arm64' - name: Upload symbols (backtrace.io) run: | . scripts/setenv if [[ "$OPENRCT2_PUSH" == "true" ]]; then upload-backtrace-symbols artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-symbols-*.zip else echo 'Not going to push build' fi windows-mingw: name: Windows (${{ matrix.platform_name }}) using mingw runs-on: ubuntu-latest needs: [check-code-formatting, build_variables] container: ghcr.io/openrct2/openrct2-build:26-mingw strategy: fail-fast: false matrix: platform: [win32] include: - platform: win32 platform_name: win32 cache_key: windows-mingw build_flags: -DBUILD_SHARED_LIBS=ON -DENABLE_SCRIPTING=ON steps: - name: Checkout uses: actions/checkout@v6 - name: ccache uses: hendrikmuhs/ccache-action@v1.2.21 with: key: ${{ matrix.cache_key }} - name: Install GCC problem matcher uses: ammaraskar/gcc-problem-matcher@master - name: Build OpenRCT2 run: | sudo su cmake -B bin -G Ninja -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt -DCMAKE_BUILD_TYPE=Release -DDISABLE_IPO=on -DFORCE32=on ${{ matrix.build_flags }} cd bin ninja -k0 - name: Upload artifacts (CI) if: matrix.platform == 'NT5.1' uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-Windows-mingw-${{ matrix.platform }} path: bin/openrct2.exe if-no-files-found: error macos-cmake: name: macOS (${{ matrix.arch }}) using CMake runs-on: macos-15 needs: [check-code-formatting, build_variables] strategy: fail-fast: false matrix: arch: [x64, arm64] include: - arch: arm64 cache_key: macos-arm64 # Note: only build/run tests on the native architecture of the CI agent # GitHub macos-12 agents are all Intel, but as of 2024-04-25 new images, e.g. macos-14 (current macos-latest) are arm64 # See https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories build_flags: -DARCH="arm64" -DWITH_TESTS=on run_tests: true - arch: x64 cache_key: macos-x64 build_flags: -DARCH="x86_64" -DWITH_TESTS=on run_tests: true steps: - name: Checkout uses: actions/checkout@v6 - name: ccache uses: hendrikmuhs/ccache-action@v1.2.21 with: key: ${{ matrix.cache_key }} - name: Install GCC problem matcher uses: ammaraskar/gcc-problem-matcher@master - name: Build OpenRCT2 run: | # NB: GitHub comes with `pkg-config` and `ninja` preinstalled on macOS images . scripts/setenv -q && build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=on ${{ matrix.build_flags }} - name: Build artifacts run: | . scripts/setenv mkdir -p artifacts mv bin/OpenRCT2.app artifacts echo -e "\033[0;36mCompressing OpenRCT2.app...\033[0m" cd artifacts zip -rqy openrct2-macos.zip OpenRCT2.app - name: Upload artifacts (CI) uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ runner.os }}-${{ matrix.arch }}-cmake path: artifacts/openrct2-macos.zip if-no-files-found: error - name: Run Tests if: ${{matrix.run_tests}} run: . scripts/setenv -q && run-tests - name: Test Summary uses: test-summary/action@v2 with: paths: "artifacts/test-**.xml" if: ${{matrix.run_tests}} macos-universal: name: macOS universal app bundle runs-on: macos-15 needs: [macos-cmake, build_variables] steps: - name: Checkout uses: actions/checkout@v6 - name: download x64 app bundle uses: actions/download-artifact@v7 with: name: OpenRCT2-${{ runner.os }}-x64-cmake path: macos_universal/x64 - name: download arm64 app bundle uses: actions/download-artifact@v7 with: name: OpenRCT2-${{ runner.os }}-arm64-cmake path: macos_universal/arm64 - name: Make Universal app bundle run: | . scripts/setenv cd macos_universal unzip x64/openrct2-macos.zip -d x64 unzip arm64/openrct2-macos.zip -d arm64 create-macos-universal - name: Create artifact run: | . scripts/setenv mkdir -p artifacts mv macos_universal/OpenRCT2-universal.app artifacts/OpenRCT2.app echo -e "\033[0;36mCompressing OpenRCT2.app...\033[0m" cd artifacts zip -rqy OpenRCT2-${{ needs.build_variables.outputs.name }}-macos-universal.zip OpenRCT2.app - name: Upload artifacts (CI) uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-${{ runner.os }}-universal path: artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-macos-universal.zip if-no-files-found: error linux-portable: name: ${{ matrix.distro }} Linux (${{ matrix.release }}, ${{ matrix.platform }}, portable) runs-on: ubuntu-latest needs: [check-code-formatting, build_variables] container: ${{ matrix.image }} strategy: fail-fast: false matrix: include: # Use `-fno-var-tracking-assignments` to reduce amount of produced debug information. This is necessary due to 100MiB limit of GitHub / openrct2.org API. - platform: x86_64 distro: Ubuntu release: noble image: ghcr.io/openrct2/openrct2-build:26-noble build_flags: -DCMAKE_POSITION_INDEPENDENT_CODE=on -DCMAKE_CXX_FLAGS="-g1 -gz -fno-var-tracking-assignments" - platform: x86_64 distro: Ubuntu release: resolute image: ghcr.io/openrct2/openrct2-build:26-resolute build_flags: -DCMAKE_POSITION_INDEPENDENT_CODE=on -DCMAKE_CXX_FLAGS="-g1 -gz" - platform: x86_64 distro: Debian release: bookworm image: ghcr.io/openrct2/openrct2-build:26-bookworm build_flags: -DCMAKE_POSITION_INDEPENDENT_CODE=on -DCMAKE_CXX_FLAGS="-g1 -gz -fno-var-tracking-assignments" -DWITH_TESTS=off - platform: x86_64 distro: Debian release: trixie image: ghcr.io/openrct2/openrct2-build:26-trixie build_flags: -DCMAKE_POSITION_INDEPENDENT_CODE=on -DCMAKE_CXX_FLAGS="-g1 -gz -fno-var-tracking-assignments" -DWITH_TESTS=off steps: - name: Checkout uses: actions/checkout@v6 - name: ccache uses: hendrikmuhs/ccache-action@v1.2.21 with: key: linux-${{ matrix.platform }}-${{ matrix.distro }}-${{ matrix.release }} - name: Get pre-reqs run: . scripts/setenv && get-discord-rpc - name: Install GCC problem matcher uses: ammaraskar/gcc-problem-matcher@master - name: Build OpenRCT2 run: | . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-g1 -gz -fno-var-tracking-assignments" -DBUILD_SHARED_LIBS=ON -DPORTABLE=ON ${{ matrix.build_flags }} - name: Build artifacts run: . scripts/setenv -q && build-portable artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-${{ runner.os }}-${{ matrix.release }}-${{ matrix.platform }}.tar.gz bin/install/usr - name: Upload artifacts (CI) uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-${{ runner.os }}-${{ matrix.release }}-${{ matrix.platform }} path: artifacts if-no-files-found: error - name: Run Tests run: . scripts/setenv -q && run-tests linux-appimage: name: Ubuntu Linux (AppImage, x86_64) runs-on: ubuntu-latest needs: [check-code-formatting, build_variables] container: openrct2/openrct2-build:24-jammy steps: - name: Checkout uses: actions/checkout@v6 - name: ccache uses: hendrikmuhs/ccache-action@v1.2.21 with: key: linux-appimage - name: Get pre-reqs run: . scripts/setenv -q && get-discord-rpc - name: Build OpenRCT2 run: | . scripts/setenv -q && build -DCMAKE_CXX_COMPILER=clang++-20 -DCMAKE_BUILD_TYPE=Release -DAPPIMAGE=ON -DOPENRCT2_USE_CCACHE=on - name: Build AppImage env: APPIMAGE_FILE_NAME: OpenRCT2-${{ needs.build_variables.outputs.name }}-linux-x86_64.AppImage NO_STRIP: true # https://github.com/linuxdeploy/linuxdeploy/blob/d2557d616749c325a61058049e41a2d35ffce924/src/core/appdir.cpp#L248 run: . scripts/setenv -q && build-appimage - name: Upload artifacts (CI) uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-AppImage path: artifacts if-no-files-found: error linux-docker: name: Ubuntu Linux (Docker) needs: [check-code-formatting, build_variables] runs-on: ubuntu-latest steps: - name: Checkout image if: github.repository == 'OpenRCT2/OpenRCT2' && github.ref == 'refs/heads/develop' uses: actions/checkout@v6 with: repository: OpenRCT2/openrct2-docker - name: Build image if: github.repository == 'OpenRCT2/OpenRCT2' && github.ref == 'refs/heads/develop' run: docker build -t openrct2/openrct2-cli:develop develop/cli - name: Push image if: github.repository == 'OpenRCT2/OpenRCT2' && github.ref == 'refs/heads/develop' env: OPENRCT2_DOCKER_USER: ${{ secrets.OPENRCT2_DOCKER_USER }} OPENRCT2_DOCKER_PASS: ${{ secrets.OPENRCT2_DOCKER_PASS }} run: | OPENRCT2_BRANCH=$(echo "$GITHUB_REF" | sed 's/refs\/heads\///') echo "Current branch is $OPENRCT2_BRANCH" if [ "$OPENRCT2_BRANCH" = 'develop' ]; then docker login -u "$OPENRCT2_DOCKER_USER" -p "$OPENRCT2_DOCKER_PASS" docker push openrct2/openrct2-cli:develop else echo 'Image not pushed' fi linux-clang: name: Ubuntu Linux (noble, debug, [http, network, flac, vorbis OpenGL] disabled) using clang runs-on: ubuntu-latest needs: [check-code-formatting, build_variables] container: ghcr.io/openrct2/openrct2-build:26-noble steps: - name: Checkout uses: actions/checkout@v6 - name: ccache uses: hendrikmuhs/ccache-action@v1.2.21 with: key: linux-clang - name: Install GCC problem matcher uses: ammaraskar/gcc-problem-matcher@master - name: Build OpenRCT2 run: . scripts/setenv && build -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Debug -DDISABLE_NETWORK=ON -DDISABLE_HTTP=ON -DDISABLE_FLAC=ON -DDISABLE_VORBIS=ON -DDISABLE_OPENGL=ON linux-clang-tests: name: Ubuntu Linux (debug) using clang, coverage enabled runs-on: ubuntu-latest needs: [check-code-formatting, build_variables] container: ghcr.io/openrct2/openrct2-build:26-noble steps: - name: Checkout uses: actions/checkout@v6 - name: ccache uses: hendrikmuhs/ccache-action@v1.2.21 with: key: linux-clang-tests - name: Install GCC problem matcher uses: ammaraskar/gcc-problem-matcher@master - name: Build OpenRCT2 run: . scripts/setenv && build -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Debug -DENABLE_HEADERS_CHECK=on -DCMAKE_CXX_FLAGS="-fprofile-instr-generate -fcoverage-mapping" -DWITH_TESTS=on - name: Run Tests run: . scripts/setenv -q && LLVM_PROFILE_FILE="openrct2-coverage-%p.profraw" run-tests - name: Test Summary uses: test-summary/action@v2 with: paths: "artifacts/test-**.xml" if: always() - name: Process coverage information run: | cd bin llvm-profdata merge -sparse openrct2-coverage*profraw -o openrct2.profdata llvm-cov export -instr-profile=openrct2.profdata ./OpenRCT2Tests > coverage.json llvm-cov report ./OpenRCT2Tests -instr-profile=openrct2.profdata xz -1v openrct2.profdata xz -1v coverage.json xz -1v OpenRCT2Tests - name: Upload artifacts (CI) uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-${{ runner.os }}-coverage path: | bin/*profdata* bin/coverage.json* bin/OpenRCT2Tests.xz if-no-files-found: error android-libs: name: Android (${{ matrix.arch }}) runs-on: ubuntu-latest needs: [check-code-formatting, build_variables] container: ghcr.io/openrct2/openrct2-build:26-android strategy: fail-fast: false matrix: arch: [armeabi-v7a, arm64-v8a, x86_64] steps: - name: Checkout uses: actions/checkout@v6 - name: ccache uses: hendrikmuhs/ccache-action@v1.2.21 with: key: android-${{ matrix.arch }} - name: Cache Gradle uses: actions/cache@v5 with: # The gradle cache is by default ~/.gradle/caches, but ~ gets resolved by GitHub Actions to the runner's # home directory (/home/github), not the user inside the container (/root). Name the path explicitly. path: /root/.gradle/caches # The cache key needs to occasionally be updated as the cache itself is immutable, otherwise it can grow stale. The easiest way to force this is to include the tag, which changes every month. # Keep in sync with the cache key used in the `android` job. key: gradle-${{ runner.os }}-${{ needs.build_variables.outputs.tag }}-android-${{ hashFiles('src/openrct2-android/build.gradle', 'src/openrct2-android/settings.gradle', 'src/openrct2-android/app/build.gradle', 'src/openrct2-android/gradle.properties', 'src/openrct2-android/gradle/wrapper/gradle-wrapper.properties') }} restore-keys: | gradle-${{ runner.os }}-${{ needs.build_variables.outputs.tag }}-android- - name: Install GCC problem matcher uses: ammaraskar/gcc-problem-matcher@master - name: Build Native Libs run: | . scripts/setenv pushd src/openrct2-android ./gradlew app:externalNativeBuildRelease -PabiFilter=${{ matrix.arch }} -PskipAssets -PskipJava popd - name: Upload Native Libs uses: actions/upload-artifact@v6 with: name: android-libs-${{ matrix.arch }} path: src/openrct2-android/app/build/intermediates/cmake/release/obj/${{ matrix.arch }} if-no-files-found: error android: name: Android runs-on: ubuntu-latest needs: [android-libs, build_variables, g2dat] container: ghcr.io/openrct2/openrct2-build:26-android steps: - name: Checkout uses: actions/checkout@v6 - name: Cache Gradle uses: actions/cache@v5 with: # The gradle cache is by default ~/.gradle/caches, but ~ gets resolved by GitHub Actions to the runner's # home directory (/home/github), not the user inside the container (/root). Name the path explicitly. path: /root/.gradle/caches # Keep in sync with the cache key used in the `android-libs` job. key: gradle-${{ runner.os }}-${{ needs.build_variables.outputs.tag }}-android-${{ hashFiles('src/openrct2-android/build.gradle', 'src/openrct2-android/settings.gradle', 'src/openrct2-android/app/build.gradle', 'src/openrct2-android/gradle.properties', 'src/openrct2-android/gradle/wrapper/gradle-wrapper.properties') }} restore-keys: | gradle-${{ runner.os }}-${{ needs.build_variables.outputs.tag }}-android- - name: Setup keystore run: | echo "${{ secrets.OPENRCT2_KEYSTORE_CONTENTS }}" | base64 -d > keystore.jks echo "OPENRCT2_KEYSTORE_FILE=${{ github.workspace }}/keystore.jks" >> $GITHUB_ENV echo "OPENRCT2_KEYSTORE_PASSWORD=${{ secrets.OPENRCT2_KEYSTORE_PASSWORD }}" >> $GITHUB_ENV - name: Download all libs uses: actions/download-artifact@v7 with: pattern: android-libs-* path: artifacts/android-libs - name: Move libs to project run: | mkdir -p src/openrct2-android/app/libs for arch in armeabi-v7a arm64-v8a x86_64; do if [ -d "artifacts/android-libs/android-libs-$arch" ]; then mkdir -p src/openrct2-android/app/libs/$arch mv artifacts/android-libs/android-libs-$arch/* src/openrct2-android/app/libs/$arch/ else echo "::warning title=Missing libraries::Warning: No libs found for $arch" fi done - name: Download graphics .dat files uses: actions/download-artifact@v7 with: name: graphics-${{ needs.build_variables.outputs.name }} path: bin/data - name: Build OpenRCT2 run: | . scripts/setenv export OPENRCT2_DAT_DIR="$GITHUB_WORKSPACE/bin/data" pushd src/openrct2-android ./gradlew app:assembleRelease -PskipNativeBuild popd mkdir -p artifacts mv src/openrct2-android/app/build/outputs/apk/release/app-release.apk artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-android.apk - name: Upload artifacts (CI) uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-Android path: artifacts if-no-files-found: error - name: Upload gradle issues uses: actions/upload-artifact@v6 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-gradle-issues path: src/openrct2-android/build/reports/problems/problems-report.html if-no-files-found: ignore emscripten: name: Emscripten runs-on: ubuntu-latest needs: [check-code-formatting, build_variables] container: ghcr.io/openrct2/openrct2-build:26-emscripten steps: - name: Checkout uses: actions/checkout@v6 - name: ccache uses: hendrikmuhs/ccache-action@v1.2.21 with: key: emscripten - name: Install GCC problem matcher uses: ammaraskar/gcc-problem-matcher@master - name: Build OpenRCT2 run: | . scripts/setenv build-emscripten - name: Upload artifacts (CI) uses: actions/upload-artifact@v6 with: path: build/www name: OpenRCT2-${{ needs.build_variables.outputs.name }}-emscripten release: name: Release runs-on: ubuntu-slim needs: [build_variables, linux-portable, android, linux-appimage, macos-universal, windows] steps: - name: Checkout uses: actions/checkout@v6 with: sparse-checkout: | distribution/changelog.txt - name: Download artifacts uses: actions/download-artifact@v7 with: merge-multiple: false # Only remove unsigned artifacts if signing is enabled, otherwise we might end up with no artifacts at all - name: Remove unsigned artifacts and flatten run: | ls -lR if [[ "${{ needs.build_variables.outputs.sign }}" == "true" ]]; then echo "Signing enabled, removing unsigned artifacts" find . -maxdepth 1 -name '*unsigned*' -type d -exec rm -rf {} + 2>/dev/null || true echo "Unsigned artifacts removed" else echo "Signing not enabled, keeping unsigned artifacts" fi # Flatten remaining artifact directories find . -maxdepth 2 -type f \( -path './OpenRCT2-*/*' -o -path './graphics-*/*' \) -exec mv {} . \; # Clean up empty directories find . -maxdepth 1 -type d \( -name 'OpenRCT2-*' -o -name 'graphics-*' \) -empty -delete 2>/dev/null || true ls -lR - name: Concatenate sha256 files run: | ls -lR pushd ${{ github.workspace }} find . -maxdepth 1 -type f -name 'OpenRCT2-*' -print0 | xargs -0 sha256sum > OpenRCT2-${{ needs.build_variables.outputs.name }}-sha256sums.txt popd - name: Create release notes run: | # Print all the lines until an empty line sed -n '1,/^$/p' distribution/changelog.txt >> release_notes.txt echo "" >> release_notes.txt echo "Release created in ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> release_notes.txt echo "" >> release_notes.txt echo "SHA256 checksums:" >> release_notes.txt echo "\`\`\`" >> release_notes.txt cat OpenRCT2-${{ needs.build_variables.outputs.name }}-sha256sums.txt >> release_notes.txt echo "\`\`\`" >> release_notes.txt echo "" >> release_notes.txt cat release_notes.txt # Only upload tagged releases, mark them as draft for manual verification - name: Create tagged release uses: softprops/action-gh-release@v2 if: startsWith(github.ref, 'refs/tags/v') with: draft: true files: | OpenRCT2-${{ needs.build_variables.outputs.name }}-* body_path: release_notes.txt tag_name: ${{ needs.build_variables.outputs.tag }} # The upload to binaries repository is done from develop only - name: Create tag for binaries repository uses: actions/github-script@v8 if: ${{ needs.build_variables.outputs.push }} with: github-token: ${{ secrets.OPENRCT2_BINARIES_CI_UPLOAD }} script: | github.rest.git.createRef({ owner: 'OpenRCT2', repo: 'OpenRCT2-binaries', ref: 'refs/tags/${{ needs.build_variables.outputs.name }}', sha: '2032e1601f3b35d07f088758d34bedbb84868616' }) - name: Create release in binaries repo uses: softprops/action-gh-release@v2 if: ${{ needs.build_variables.outputs.push }} with: repository: OpenRCT2/OpenRCT2-binaries token: ${{ secrets.OPENRCT2_BINARIES_CI_UPLOAD }} files: | OpenRCT2-${{ needs.build_variables.outputs.name }}-* body_path: release_notes.txt tag_name: ${{ needs.build_variables.outputs.name }}