github.yml 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. name: VCMI
  2. on:
  3. push:
  4. branches:
  5. - beta
  6. - master
  7. - develop
  8. pull_request:
  9. workflow_dispatch:
  10. jobs:
  11. build:
  12. name: Build (${{ matrix.platform }})
  13. strategy:
  14. matrix:
  15. include:
  16. - platform: mac-intel
  17. os: macos-14
  18. pack: 1
  19. upload: 1
  20. pack_type: Release
  21. extension: dmg
  22. before_install: macos.sh
  23. preset: macos-conan-ninja-release
  24. conan_profile: macos-intel
  25. conan_prebuilts: dependencies-mac-intel
  26. conan_options: --profile=dependencies/conan_profiles/base/apple-system
  27. artifact_platform: intel
  28. - platform: mac-arm
  29. os: macos-14
  30. pack: 1
  31. upload: 1
  32. pack_type: Release
  33. extension: dmg
  34. before_install: macos.sh
  35. preset: macos-arm-conan-ninja-release
  36. conan_profile: macos-arm
  37. conan_prebuilts: dependencies-mac-arm
  38. conan_options: --profile=dependencies/conan_profiles/base/apple-system
  39. artifact_platform: arm
  40. - platform: ios
  41. os: macos-14
  42. pack: 1
  43. upload: 1
  44. pack_type: Release
  45. extension: ipa
  46. before_install: macos.sh
  47. preset: ios-release-conan-ccache
  48. conan_profile: ios-arm64
  49. conan_prebuilts: dependencies-ios
  50. conan_options: --profile=dependencies/conan_profiles/base/apple-system
  51. - platform: msvc-x64
  52. arch: x64
  53. toolset: '14.29'
  54. os: windows-2025
  55. pack: 1
  56. upload: 0
  57. pack_type: RelWithDebInfo
  58. extension: zip
  59. preset: windows-msvc-ninja-release
  60. conan_profile: msvc-x64
  61. conan_prebuilts: dependencies-windows-x64
  62. conan_options: -s "&:build_type=RelWithDebInfo" -c tools.env.virtualenv:powershell=pwsh -o "&:target_pre_windows10=True"
  63. artifact_platform: x64
  64. - platform: msvc-x86
  65. arch: amd64_x86
  66. toolset: '14.29'
  67. os: windows-2025
  68. pack: 1
  69. upload: 0
  70. pack_type: RelWithDebInfo
  71. extension: zip
  72. preset: windows-msvc-ninja-release-x86
  73. conan_profile: msvc-x86
  74. conan_prebuilts: dependencies-windows-x86
  75. conan_options: -s "&:build_type=RelWithDebInfo" -c tools.env.virtualenv:powershell=pwsh -o "&:target_pre_windows10=True"
  76. artifact_platform: x86
  77. - platform: msvc-arm64
  78. arch: arm64
  79. os: windows-11-arm
  80. pack: 1
  81. upload: 0
  82. pack_type: RelWithDebInfo
  83. extension: zip
  84. preset: windows-msvc-ninja-release-arm64
  85. conan_profile: msvc-arm64
  86. conan_prebuilts: dependencies-windows-arm64
  87. conan_options: -s "&:build_type=RelWithDebInfo" -c tools.env.virtualenv:powershell=pwsh -o "&:lua_lib=lua"
  88. artifact_platform: arm64
  89. - platform: android-32
  90. os: ubuntu-latest
  91. upload: 1
  92. extension: apk
  93. preset: android-conan-ninja-release
  94. conan_profile: android-32-ndk
  95. conan_prebuilts: dependencies-android-armeabi-v7a
  96. conan_options: --profile=dependencies/conan_profiles/base/android-system
  97. artifact_platform: armeabi-v7a
  98. - platform: android-64
  99. os: ubuntu-latest
  100. upload: 1
  101. extension: apk
  102. preset: android-conan-ninja-release
  103. conan_profile: android-64-ndk
  104. conan_prebuilts: dependencies-android-arm64-v8a
  105. conan_options: --profile=dependencies/conan_profiles/base/android-system
  106. artifact_platform: arm64-v8a
  107. - platform: android-64-intel
  108. os: ubuntu-latest
  109. upload: 1
  110. extension: apk
  111. preset: android-conan-ninja-release
  112. conan_profile: android-x64-ndk
  113. conan_prebuilts: dependencies-android-x64
  114. conan_options: --profile=dependencies/conan_profiles/base/android-system
  115. artifact_platform: x64
  116. runs-on: ${{ matrix.os }}
  117. defaults:
  118. run:
  119. shell: bash
  120. steps:
  121. - name: Checkout repository
  122. uses: actions/checkout@v6
  123. with:
  124. submodules: recursive
  125. - name: Prepare APT staging dir
  126. if: contains(matrix.os, 'ubuntu')
  127. run: mkdir -p "$RUNNER_TEMP/apt-cache"
  128. - name: APT cache restore
  129. if: contains(matrix.os, 'ubuntu')
  130. id: aptcache
  131. uses: actions/cache/restore@v5
  132. with:
  133. path: ${{ runner.temp }}/apt-cache
  134. key: ${{ matrix.platform }}-apt-${{ matrix.os }}
  135. restore-keys: |
  136. ${{ matrix.platform }}-apt-${{ matrix.os }}
  137. - name: Prepare CI
  138. if: "${{ matrix.before_install != '' }}"
  139. run: source '${{github.workspace}}/CI/before_install/${{matrix.before_install}}' '${{matrix.arch}}'
  140. # Save only on cache miss, GitHub caches are immutable per key
  141. - name: APT cache save
  142. if: contains(matrix.os, 'ubuntu') && steps.aptcache.outputs.cache-hit != 'true'
  143. uses: actions/cache/save@v5
  144. with:
  145. path: ${{ runner.temp }}/apt-cache
  146. key: ${{ steps.aptcache.outputs.cache-primary-key }}
  147. - name: Install Conan Dependencies
  148. if: "${{ matrix.conan_prebuilts != '' }}"
  149. run: |
  150. pipx install conan
  151. source '${{github.workspace}}/CI/install_conan_dependencies.sh' '${{matrix.conan_prebuilts}}'
  152. - name: Setup MSVC Developer Command Prompt
  153. if: ${{ startsWith(matrix.platform, 'msvc') }}
  154. uses: ilammy/msvc-dev-cmd@v1
  155. with:
  156. arch: ${{ matrix.arch }}
  157. toolset: ${{ matrix.toolset }}
  158. # ensure the cache for each PR is separate so they don't interfere with each other
  159. # fall back to cache of the vcmi/vcmi repo if no PR-specific cache is found
  160. - name: Setup compiler cache for PRs
  161. uses: hendrikmuhs/[email protected]
  162. if: ${{ github.event.number != '' }}
  163. with:
  164. variant: ${{ startsWith(matrix.platform, 'msvc') && 'sccache' || 'ccache' }}
  165. key: ${{ matrix.platform }}-PR-${{ github.event.number }}
  166. restore-keys: |
  167. ${{ matrix.platform }}-PR-${{ github.event.number }}
  168. ${{ matrix.platform }}-branch-${{ github.base_ref }}
  169. ${{ matrix.platform }}-
  170. create-symlink: ${{ !startsWith(matrix.platform, 'msvc') }}
  171. max-size: '5G'
  172. verbose: 2
  173. job-summary: "" # <-- disable built-in summary to avoid duplicate block
  174. - name: Setup compiler cache for branch builds
  175. uses: hendrikmuhs/[email protected]
  176. if: ${{ github.event.number == '' }}
  177. with:
  178. variant: ${{ startsWith(matrix.platform, 'msvc') && 'sccache' || 'ccache' }}
  179. key: ${{ matrix.platform }}-branch-${{ github.ref_name }}
  180. restore-keys: |
  181. ${{ matrix.platform }}-branch-${{ github.ref_name }}
  182. ${{ matrix.platform }}-
  183. create-symlink: ${{ !startsWith(matrix.platform, 'msvc') }}
  184. max-size: '5G'
  185. verbose: 2
  186. job-summary: "" # <-- disable built-in summary to avoid duplicate block
  187. - name: CCache tuning (Android)
  188. if: ${{ startsWith(matrix.platform, 'android') }}
  189. run: |
  190. echo "/usr/lib/ccache" >> $GITHUB_PATH
  191. ccache --set-config=compiler_check=content
  192. ccache --set-config=base_dir="${GITHUB_WORKSPACE}"
  193. ccache --set-config=hash_dir=true
  194. ccache --set-config=sloppiness=time_macros
  195. - name: Install Conan profile
  196. if: "${{ matrix.conan_profile != '' }}"
  197. run: |
  198. conan profile detect
  199. outFolder=conan-generated
  200. conan install . \
  201. --output-folder="$outFolder" \
  202. --build=never \
  203. --profile=dependencies/conan_profiles/${{ matrix.conan_profile }} \
  204. ${{ matrix.conan_options }}
  205. ${{ startsWith(matrix.platform, 'msvc') && 'echo CONANRUN_PWSH_SCRIPT="$outFolder/conanrun.ps1" >> $GITHUB_ENV' || '' }}
  206. # Can't be set in Gradle project
  207. - name: Configure enableUncompressedNativeLibs
  208. if: ${{ startsWith(matrix.platform, 'android') }}
  209. run: mkdir -p ~/.gradle && echo "android.bundle.enableUncompressedNativeLibs=true" > ~/.gradle/gradle.properties
  210. - name: Install Java
  211. uses: actions/setup-java@v5
  212. if: ${{ startsWith(matrix.platform, 'android') }}
  213. with:
  214. distribution: 'temurin'
  215. java-version: '17'
  216. # Frees 10+GB on linux runners by removing unused tools (.NET, Haskell compiler)
  217. - name: Free up disk space
  218. if: contains(matrix.os, 'ubuntu')
  219. run: |
  220. echo "Disk usage BEFORE cleanup:"
  221. df -h
  222. sudo rm -rf /opt/ghc /usr/local/.ghcup /usr/share/dotnet || :
  223. echo "Disk usage AFTER cleanup:"
  224. df -h
  225. # a hack to build ID for x64 build in order for Google Play to allow upload of both 32 and 64 bit builds
  226. # TODO: x86_64
  227. - name: Bump Android x64 build ID
  228. if: ${{ matrix.platform == 'android-64' }}
  229. run: perl -i -pe 's/versionCode (\d+)/$x=$1+1; "versionCode $x"/e' android/vcmi-app/build.gradle
  230. - name: Build Number
  231. run: |
  232. source '${{github.workspace}}/CI/get_package_name.sh'
  233. if [ '${{ matrix.artifact_platform }}' ]; then
  234. VCMI_PACKAGE_FILE_NAME+="-${{ matrix.artifact_platform }}"
  235. fi
  236. echo VCMI_PACKAGE_FILE_NAME="$VCMI_PACKAGE_FILE_NAME" >> $GITHUB_ENV
  237. echo VCMI_PACKAGE_BUILD="$VCMI_PACKAGE_BUILD" >> $GITHUB_ENV
  238. echo VCMI_PACKAGE_NAME_SUFFIX="$VCMI_PACKAGE_NAME_SUFFIX" >> $GITHUB_ENV
  239. echo VCMI_PACKAGE_GOLDMASTER="$VCMI_PACKAGE_GOLDMASTER" >> $GITHUB_ENV
  240. env:
  241. PULL_REQUEST: ${{ github.event.pull_request.number }}
  242. - name: Configure (non-MSVC)
  243. if: ${{ !startsWith(matrix.platform, 'msvc') }}
  244. run: |
  245. if [[ ("${{ matrix.preset }}" == "android-conan-ninja-release") && ("${{ github.ref }}" != 'refs/heads/master') ]]; then
  246. # key1=value1;key2=value2;...
  247. gradleProperties=$(python3 CI/android/gradle_daily_props.py)
  248. androidOptions=("-DANDROID_GRADLE_PROPERTIES=$gradleProperties")
  249. androidOptions+=("-DCMAKE_C_COMPILER_LAUNCHER=ccache" "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache")
  250. fi
  251. cmake -DENABLE_CCACHE:BOOL=ON "${androidOptions[@]}" --preset ${{ matrix.preset }}
  252. - name: Configure (MSVC)
  253. if: ${{ startsWith(matrix.platform, 'msvc') }}
  254. run: |
  255. & $env:CONANRUN_PWSH_SCRIPT
  256. cmake --preset ${{ matrix.preset }}
  257. shell: pwsh
  258. - name: Build
  259. run: |
  260. ${{ startsWith(matrix.platform, 'msvc') && '& $env:CONANRUN_PWSH_SCRIPT' }}
  261. cmake --build --preset ${{matrix.preset}}
  262. shell: pwsh
  263. env:
  264. ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }}
  265. ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
  266. - name: Kill XProtect to work around CPack issue on macOS
  267. if: ${{ startsWith(matrix.platform, 'mac') }}
  268. run: |
  269. # Cf. https://github.com/actions/runner-images/issues/7522#issuecomment-1556766641
  270. echo Killing...; sudo pkill -9 XProtect >/dev/null || true;
  271. echo "Waiting..."; counter=0; while pgrep XProtect && ((counter < 20)); do sleep 3; ((counter++)); done
  272. pgrep XProtect || true
  273. - name: Pack
  274. id: cpack
  275. if: ${{ matrix.pack == 1 }}
  276. run: |
  277. ${{ startsWith(matrix.platform, 'msvc') && '& $env:CONANRUN_PWSH_SCRIPT' }}
  278. cd "${{github.workspace}}/out/build/${{matrix.preset}}"
  279. cpack -C ${{matrix.pack_type}}
  280. shell: pwsh
  281. - name: Find Android package
  282. if: ${{ startsWith(matrix.platform, 'android') }}
  283. run: |
  284. OUTPUT_DIRECTORY="${{ github.workspace }}/out/build/${{ matrix.preset }}/android-build/vcmi-app/build/outputs"
  285. mv "$OUTPUT_DIRECTORY/apk/release/vcmi-release.apk" "${{github.workspace}}/out/build/${{matrix.preset}}/${{ env.VCMI_PACKAGE_FILE_NAME }}.apk"
  286. mv "$OUTPUT_DIRECTORY/bundle/release/vcmi-release.aab" "${{github.workspace}}/out/build/${{matrix.preset}}/${{ env.VCMI_PACKAGE_FILE_NAME }}.aab"
  287. - name: Upload Artifact
  288. id: upload_artifact
  289. uses: actions/upload-artifact@v6
  290. with:
  291. name: ${{ env.VCMI_PACKAGE_FILE_NAME }} - ${{ matrix.platform }}
  292. compression-level: 9
  293. path: |
  294. ${{github.workspace}}/out/build/${{matrix.preset}}/${{ env.VCMI_PACKAGE_FILE_NAME }}.${{ matrix.extension }}
  295. - name: Upload AAB Artifact
  296. id: upload_aab
  297. if: ${{ startsWith(matrix.platform, 'android') && github.ref == 'refs/heads/master' }}
  298. uses: actions/upload-artifact@v6
  299. with:
  300. name: ${{ env.VCMI_PACKAGE_FILE_NAME }} - ${{ matrix.platform }} - aab
  301. compression-level: 9
  302. path: |
  303. ${{github.workspace}}/out/build/${{matrix.preset}}/${{ env.VCMI_PACKAGE_FILE_NAME }}.aab
  304. - name: Upload debug symbols
  305. id: upload_symbols
  306. if: ${{ startsWith(matrix.platform, 'msvc') }}
  307. uses: actions/upload-artifact@v6
  308. with:
  309. name: ${{ env.VCMI_PACKAGE_FILE_NAME }} - ${{ matrix.platform }} - symbols
  310. compression-level: 9
  311. path: |
  312. ${{github.workspace}}/**/*.pdb
  313. - name: Upload build to download.vcmi.eu
  314. if: ${{ matrix.upload == 1 && github.event.number == '' && env.DEPLOY_RSA != '' }}
  315. run: |
  316. if [ -z '${{ env.ANDROID_APK_PATH }}' ] ; then
  317. cd '${{github.workspace}}/out/build/${{matrix.preset}}'
  318. fi
  319. source '${{github.workspace}}/CI/upload_package.sh'
  320. env:
  321. DEPLOY_RSA: ${{ secrets.DEPLOY_RSA }}
  322. PACKAGE_EXTENSION: ${{ matrix.extension }}
  323. - name: Prepare partial JSON with build informations
  324. id: make_partial_json
  325. env:
  326. PLATFORM: ${{ matrix.platform }}
  327. ARTIFACT_URL: ${{ steps.upload_artifact.outputs.artifact-url }}
  328. DEBUG_SYMBOLS_URL: ${{ steps.upload_symbols.outputs.artifact-url }}
  329. AAB_URL: ${{ steps.upload_aab.outputs.artifact-url }}
  330. run: |
  331. python3 CI/emit_partial.py
  332. - name: Upload partial JSON with build informations
  333. uses: actions/upload-artifact@v6
  334. with:
  335. name: partial-json-${{ matrix.platform }}
  336. path: .summary/${{ matrix.platform }}.json
  337. upload-source-package:
  338. name: Upload Source Code Package
  339. if: always() && github.event.number == ''
  340. runs-on: ubuntu-latest
  341. defaults:
  342. run:
  343. shell: bash
  344. steps:
  345. - uses: actions/checkout@v6
  346. with:
  347. submodules: recursive
  348. - name: Build Number
  349. run: |
  350. source '${{github.workspace}}/CI/get_package_name.sh'
  351. echo VCMI_PACKAGE_FILE_NAME="$VCMI_PACKAGE_FILE_NAME" >> $GITHUB_ENV
  352. - name: Create source code archive (including submodules)
  353. run: |
  354. git archive HEAD -o "release.tar" --worktree-attributes -v
  355. git submodule update --init --recursive
  356. git submodule --quiet foreach 'cd "$toplevel"; tar -rvf "release.tar" "$sm_path"'
  357. gzip release.tar
  358. - name: Upload source code archive
  359. id: upload_source
  360. uses: actions/upload-artifact@v6
  361. with:
  362. name: ${{ env.VCMI_PACKAGE_FILE_NAME }}
  363. compression-level: 9
  364. path: |
  365. ./release.tar.gz
  366. - name: Prepare partial JSON with source informations
  367. shell: bash
  368. run: |
  369. mkdir -p .summary
  370. cat > .summary/source.json <<JSON
  371. {"source_url": "${{ steps.upload_source.outputs.artifact-url }}"}
  372. JSON
  373. - name: Upload partial JSON with source informations
  374. uses: actions/upload-artifact@v6
  375. with:
  376. name: partial-json-source
  377. path: .summary/source.json
  378. test:
  379. continue-on-error: true
  380. name: Test (${{ matrix.platform }})
  381. env:
  382. HEROES_3_DATA_PASSWORD: ${{ secrets.HEROES_3_DATA_PASSWORD }}
  383. strategy:
  384. fail-fast: false
  385. matrix:
  386. include:
  387. - platform: gcc-latest-release
  388. os: ubuntu-24.04
  389. before_install: linux_qt6.sh
  390. compiler_cxx: g++-14
  391. compiler_cc: gcc-14
  392. preset: linux-gcc-test
  393. - platform: clang-latest-debug
  394. os: ubuntu-24.04
  395. before_install: linux_qt6.sh
  396. compiler_cxx: clang++-18
  397. compiler_cc: clang-18
  398. preset: linux-clang-debug
  399. - platform: gcc-oldest-debug
  400. os: ubuntu-22.04
  401. before_install: linux_qt5.sh
  402. compiler_cxx: g++-10
  403. compiler_cc: gcc-10
  404. preset: linux-gcc-debug
  405. - platform: clang-oldest-release
  406. os: ubuntu-22.04
  407. before_install: linux_qt5.sh
  408. compiler_cxx: clang++-13
  409. compiler_cc: clang-13
  410. preset: linux-clang-test
  411. runs-on: ${{ matrix.os }}
  412. defaults:
  413. run:
  414. shell: bash
  415. steps:
  416. - name: Checkout repository
  417. uses: actions/checkout@v6
  418. with:
  419. submodules: recursive
  420. - name: Prepare APT staging dir
  421. if: contains(matrix.os, 'ubuntu')
  422. run: mkdir -p "$RUNNER_TEMP/apt-cache"
  423. - name: APT cache restore
  424. if: contains(matrix.os, 'ubuntu')
  425. id: aptcache
  426. uses: actions/cache/restore@v5
  427. with:
  428. path: ${{ runner.temp }}/apt-cache
  429. key: ${{ matrix.platform }}-apt-${{ matrix.os }}
  430. restore-keys: |
  431. ${{ matrix.platform }}-apt-${{ matrix.os }}
  432. - name: Prepare CI
  433. run: source '${{github.workspace}}/CI/before_install/${{matrix.before_install}}' '${{matrix.arch}}'
  434. - name: APT cache save
  435. if: contains(matrix.os, 'ubuntu') && steps.aptcache.outputs.cache-hit != 'true'
  436. uses: actions/cache/save@v5
  437. with:
  438. path: ${{ runner.temp }}/apt-cache
  439. key: ${{ steps.aptcache.outputs.cache-primary-key }}
  440. - name: Setup compiler cache for PRs
  441. uses: hendrikmuhs/[email protected]
  442. if: ${{ github.event.number != '' }}
  443. with:
  444. key: ${{ matrix.platform }}-PR-${{ github.event.number }}
  445. restore-keys: |
  446. ${{ matrix.platform }}-PR-${{ github.event.number }}
  447. ${{ matrix.platform }}-branch-${{ github.base_ref }}
  448. ${{ matrix.platform }}-
  449. max-size: '5G'
  450. verbose: 2
  451. - name: Setup compiler cache for branch builds
  452. uses: hendrikmuhs/[email protected]
  453. if: ${{ github.event.number == '' }}
  454. with:
  455. key: ${{ matrix.platform }}-branch-${{ github.ref_name }}
  456. restore-keys: |
  457. ${{ matrix.platform }}-branch-${{ github.ref_name }}
  458. ${{ matrix.platform }}-
  459. max-size: '5G'
  460. verbose: 2
  461. - name: Prepare Heroes 3 data
  462. if: ${{ env.HEROES_3_DATA_PASSWORD != '' }}
  463. run: |
  464. if [[ ${{github.repository_owner}} == vcmi ]]
  465. then
  466. data_url="https://github.com/vcmi-mods/vcmi-test-data/releases/download/v1.0/h3_assets.zip"
  467. else
  468. data_url="https://github.com/${{github.repository_owner}}/vcmi-test-data/releases/download/v1.0/h3_assets.zip"
  469. fi
  470. wget --progress=dot:giga "$data_url" -O h3_assets.zip
  471. 7za x h3_assets.zip -p$HEROES_3_DATA_PASSWORD
  472. mkdir -p ~/.local/share/vcmi/
  473. mv h3_assets/* ~/.local/share/vcmi/
  474. - name: Configure
  475. run: |
  476. cmake -DENABLE_CCACHE:BOOL=ON -DCMAKE_C_COMPILER=${{ matrix.compiler_cc }} -DCMAKE_CXX_COMPILER=${{ matrix.compiler_cxx }} --preset ${{ matrix.preset }}
  477. - name: Build
  478. run: |
  479. cmake --build --preset ${{matrix.preset}}
  480. - name: Test
  481. if: ${{ env.HEROES_3_DATA_PASSWORD != '' }}
  482. run: |
  483. ctest --preset ${{matrix.preset}}
  484. windows-installer:
  485. needs: build
  486. if: ${{ needs.build.result == 'success' }}
  487. name: Create Windows Installer (${{ matrix.arch }})
  488. strategy:
  489. matrix:
  490. include:
  491. - platform: msvc-x64
  492. arch: x64
  493. os: windows-2025
  494. - platform: msvc-x86
  495. arch: x86
  496. os: windows-2025
  497. - platform: msvc-arm64
  498. arch: arm64
  499. os: windows-11-arm
  500. runs-on: ${{ matrix.os }}
  501. defaults:
  502. run:
  503. shell: bash
  504. steps:
  505. - name: Checkout repository
  506. uses: actions/checkout@v6
  507. with:
  508. submodules: recursive
  509. - name: Extract version info
  510. id: extract-version
  511. run: |
  512. filePath="${GITHUB_WORKSPACE}/cmake_modules/VersionDefinition.cmake"
  513. major=$(grep -m 1 "VCMI_VERSION_MAJOR" "$filePath" | tr -d -c 0-9)
  514. minor=$(grep -m 1 "VCMI_VERSION_MINOR" "$filePath" | tr -d -c 0-9)
  515. patch=$(grep -m 1 "VCMI_VERSION_PATCH" "$filePath" | tr -d -c 0-9)
  516. short_version="${major}.${minor}.${patch}"
  517. version_timestamp=$(date +"%Y%m%d%H%M%S")
  518. echo "short_version=${short_version}" >> "$GITHUB_OUTPUT"
  519. echo "version_timestamp=${version_timestamp}" >> "$GITHUB_OUTPUT"
  520. - name: Download UCRT
  521. run: source '${{github.workspace}}/CI/wininstaller/download_ucrt.sh' '${{matrix.platform}}'
  522. - name: Build Number
  523. run: |
  524. source '${{github.workspace}}/CI/get_package_name.sh'
  525. VCMI_PACKAGE_FILE_NAME+="-${{ matrix.arch }}"
  526. echo VCMI_PACKAGE_FILE_NAME="$VCMI_PACKAGE_FILE_NAME" >> $GITHUB_ENV
  527. echo VCMI_PACKAGE_BUILD="$VCMI_PACKAGE_BUILD" >> $GITHUB_ENV
  528. echo VCMI_PACKAGE_NAME_SUFFIX="$VCMI_PACKAGE_NAME_SUFFIX" >> $GITHUB_ENV
  529. echo VCMI_PACKAGE_GOLDMASTER="$VCMI_PACKAGE_GOLDMASTER" >> $GITHUB_ENV
  530. env:
  531. PULL_REQUEST: ${{ github.event.pull_request.number }}
  532. - name: Download Artifact
  533. uses: actions/download-artifact@v7
  534. with:
  535. name: ${{ env.VCMI_PACKAGE_FILE_NAME }} - ${{ matrix.platform }}
  536. path: ${{github.workspace}}/artifact
  537. - name: Extract Artifact
  538. run: |
  539. mkdir artifact/extracted
  540. unzip "artifact/${{ env.VCMI_PACKAGE_FILE_NAME }}.zip" -d artifact/extracted
  541. - name: Ensure Inno Setup is installed
  542. run: |
  543. if [ ! -f "/c/Program Files (x86)/Inno Setup 6/ISCC.exe" ] && [ ! -f "/c/ProgramData/Chocolatey/bin/ISCC.exe" ]; then
  544. choco install innosetup --no-progress -y
  545. fi
  546. - name: Build VCMI Installer
  547. run: >
  548. CI\wininstaller\build_installer.cmd
  549. "${{ steps.extract-version.outputs.short_version }}"
  550. "${{ env.VCMI_PACKAGE_BUILD }}"
  551. "${{ matrix.arch }}"
  552. "VCMI ${{ env.VCMI_PACKAGE_NAME_SUFFIX }}"
  553. "${{ env.VCMI_PACKAGE_FILE_NAME }}"
  554. "${{ github.workspace }}\artifact\extracted"
  555. "${{ github.workspace }}\ucrt"
  556. shell: cmd
  557. - name: Upload VCMI Installer Artifacts
  558. id: upload_installer
  559. uses: actions/upload-artifact@v6
  560. with:
  561. name: ${{ env.VCMI_PACKAGE_FILE_NAME }} - ${{ matrix.platform }} - installer
  562. compression-level: 9
  563. path: |
  564. ${{ github.workspace }}/CI/wininstaller/Output/*.exe
  565. - name: Upload Installer
  566. if: ${{ github.event.number == '' && env.DEPLOY_RSA != '' }}
  567. run: |
  568. cd '${{github.workspace}}/CI/wininstaller/Output'
  569. source '${{github.workspace}}/CI/upload_package.sh'
  570. env:
  571. DEPLOY_RSA: ${{ secrets.DEPLOY_RSA }}
  572. PACKAGE_EXTENSION: exe
  573. - name: Prepare partial JSON with installer informations
  574. shell: bash
  575. run: |
  576. mkdir -p .summary
  577. cat > .summary/installer-${{ matrix.platform }}.json <<JSON
  578. {
  579. "platform": "${{ matrix.platform }}",
  580. "installer_url": "${{ steps.upload_installer.outputs.artifact-url }}"
  581. }
  582. JSON
  583. - name: Upload partial JSON with installer informations
  584. uses: actions/upload-artifact@v6
  585. with:
  586. name: partial-json-${{ matrix.platform }}-installer
  587. path: .summary/installer-${{ matrix.platform }}.json
  588. validate-code:
  589. name: Validate Code
  590. if: always()
  591. runs-on: ubuntu-latest
  592. defaults:
  593. run:
  594. shell: bash
  595. steps:
  596. - uses: actions/checkout@v6
  597. - name: Ensure LF line endings
  598. run: |
  599. find . -path ./.git -prune -o -path ./AI/FuzzyLite -prune -o -path ./test/googletest \
  600. -o -path ./osx -prune -o -type f \
  601. -not -name '*.png' -and -not -name '*.ttf' -and -not -name '*.wav' -and -not -name '*.webm' -and -not -name '*.ico' -and -not -name '*.bat' -and -not -name '*.cmd' -and -not -name '*.iss' -and -not -name '*.isl' -print0 | \
  602. { ! xargs -0 grep -l -z -P '\r\n'; }
  603. - name: Validate JSON
  604. run: |
  605. sudo apt install python3-jstyleson
  606. python3 CI/validate_json.py
  607. - name: Validate Markdown
  608. uses: DavidAnson/markdownlint-cli2-action@v22
  609. with:
  610. config: 'CI/example.markdownlint-cli2.jsonc'
  611. globs: '**/*.md'
  612. final-summary:
  613. name: Build report
  614. if: always()
  615. needs: [build, windows-installer, validate-code, test, upload-source-package]
  616. runs-on: ubuntu-latest
  617. permissions:
  618. contents: read
  619. actions: write # Partial JSON artifacts can't be deleted in PRs
  620. steps:
  621. - name: Checkout (for script path)
  622. uses: actions/checkout@v6
  623. - name: Download all partial JSON artifacts
  624. continue-on-error: true
  625. uses: actions/download-artifact@v7
  626. with:
  627. pattern: partial-json-*
  628. merge-multiple: true
  629. path: partials
  630. - name: Run final summary
  631. env:
  632. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  633. run: |
  634. python3 CI/final_summary.py