github.yml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. name: VCMI
  2. on:
  3. push:
  4. branches:
  5. - beta
  6. - master
  7. - develop
  8. pull_request:
  9. workflow_dispatch:
  10. env:
  11. # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
  12. BUILD_TYPE: Release
  13. jobs:
  14. build:
  15. strategy:
  16. matrix:
  17. include:
  18. - platform: linux-qt6
  19. os: ubuntu-24.04
  20. test: 0
  21. before_install: linux_qt6.sh
  22. preset: linux-clang-test
  23. - platform: linux
  24. os: ubuntu-24.04
  25. test: 1
  26. before_install: linux_qt5.sh
  27. preset: linux-gcc-test
  28. - platform: linux
  29. os: ubuntu-22.04
  30. test: 0
  31. before_install: linux_qt5.sh
  32. preset: linux-gcc-debug
  33. - platform: mac-intel
  34. os: macos-13
  35. test: 0
  36. pack: 1
  37. upload: 1
  38. pack_type: Release
  39. extension: dmg
  40. before_install: macos.sh
  41. preset: macos-conan-ninja-release
  42. conan_profile: macos-intel
  43. conan_prebuilts: dependencies-mac-intel
  44. conan_options: --options with_apple_system_libs=True
  45. artifact_platform: intel
  46. - platform: mac-arm
  47. os: macos-13
  48. test: 0
  49. pack: 1
  50. upload: 1
  51. pack_type: Release
  52. extension: dmg
  53. before_install: macos.sh
  54. preset: macos-arm-conan-ninja-release
  55. conan_profile: macos-arm
  56. conan_prebuilts: dependencies-mac-arm
  57. conan_options: --options with_apple_system_libs=True
  58. artifact_platform: arm
  59. - platform: ios
  60. os: macos-13
  61. test: 0
  62. pack: 1
  63. upload: 1
  64. pack_type: Release
  65. extension: ipa
  66. before_install: macos.sh
  67. preset: ios-release-conan-ccache
  68. conan_profile: ios-arm64
  69. conan_prebuilts: dependencies-ios
  70. conan_options: --options with_apple_system_libs=True
  71. - platform: msvc-x64
  72. os: windows-latest
  73. test: 0
  74. pack: 1
  75. upload: 1
  76. pack_type: RelWithDebInfo
  77. extension: exe
  78. before_install: msvc.sh
  79. preset: windows-msvc-release
  80. - platform: msvc-x86
  81. os: windows-latest
  82. test: 0
  83. pack: 1
  84. pack_type: RelWithDebInfo
  85. extension: exe
  86. before_install: msvc.sh
  87. preset: windows-msvc-release-x86
  88. - platform: mingw_x86_64
  89. os: ubuntu-24.04
  90. test: 0
  91. pack: 1
  92. pack_type: Release
  93. extension: exe
  94. cmake_args: -G Ninja
  95. before_install: mingw.sh
  96. preset: windows-mingw-conan-linux
  97. conan_profile: mingw64-linux.jinja
  98. conan_prebuilts: dependencies-mingw-x86-64
  99. - platform: mingw_x86
  100. os: ubuntu-24.04
  101. test: 0
  102. pack: 1
  103. pack_type: Release
  104. extension: exe
  105. cmake_args: -G Ninja
  106. before_install: mingw.sh
  107. preset: windows-mingw-conan-linux
  108. conan_profile: mingw32-linux.jinja
  109. conan_prebuilts: dependencies-mingw-x86
  110. - platform: android-32
  111. os: ubuntu-24.04
  112. upload: 1
  113. extension: apk
  114. preset: android-conan-ninja-release
  115. before_install: android.sh
  116. conan_profile: android-32-ndk
  117. conan_prebuilts: dependencies-android-armeabi-v7a
  118. artifact_platform: armeabi-v7a
  119. - platform: android-64
  120. os: ubuntu-24.04
  121. upload: 1
  122. extension: apk
  123. preset: android-conan-ninja-release
  124. before_install: android.sh
  125. conan_profile: android-64-ndk
  126. conan_prebuilts: dependencies-android-arm64-v8a
  127. artifact_platform: arm64-v8a
  128. runs-on: ${{ matrix.os }}
  129. defaults:
  130. run:
  131. shell: bash
  132. steps:
  133. - name: Checkout repository
  134. uses: actions/checkout@v4
  135. with:
  136. submodules: recursive
  137. - name: Prepare CI
  138. if: "${{ matrix.before_install != '' }}"
  139. run: source '${{github.workspace}}/CI/before_install/${{matrix.before_install}}'
  140. env:
  141. VCMI_BUILD_PLATFORM: x64
  142. - name: Install Conan Dependencies
  143. if: "${{ matrix.conan_prebuilts != '' }}"
  144. run: source '${{github.workspace}}/CI/install_conan_dependencies.sh' '${{matrix.conan_prebuilts}}'
  145. - name: Install vcpkg Dependencies
  146. if: ${{ startsWith(matrix.platform, 'msvc') }}
  147. run: source '${{github.workspace}}/CI/install_vcpkg_dependencies.sh' '${{matrix.platform}}'
  148. # ensure the ccache for each PR is separate so they don't interfere with each other
  149. # fall back to ccache of the vcmi/vcmi repo if no PR-specific ccache is found
  150. - name: ccache for PRs
  151. uses: hendrikmuhs/[email protected]
  152. if: ${{ github.event.number != '' }}
  153. with:
  154. key: ${{ matrix.preset }}-PR-${{ github.event.number }}
  155. restore-keys: |
  156. ${{ matrix.preset }}-PR-${{ github.event.number }}
  157. ${{ matrix.preset }}-no-PR
  158. # actual cache takes up less space, at most ~1 GB
  159. max-size: "5G"
  160. verbose: 2
  161. - name: ccache for everything but PRs
  162. uses: hendrikmuhs/[email protected]
  163. if: ${{ (github.repository == 'vcmi/vcmi' && github.event.number == '' && (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta' || github.ref == 'refs/heads/master')) || github.repository != 'vcmi/vcmi' }}
  164. with:
  165. key: ${{ matrix.preset }}-no-PR
  166. restore-keys: |
  167. ${{ matrix.preset }}-no-PR
  168. # actual cache takes up less space, at most ~1 GB
  169. max-size: "5G"
  170. verbose: 2
  171. - name: Prepare Heroes 3 data
  172. env:
  173. HEROES_3_DATA_PASSWORD: ${{ secrets.HEROES_3_DATA_PASSWORD }}
  174. if: ${{ env.HEROES_3_DATA_PASSWORD != '' && matrix.test == 1 }}
  175. run: |
  176. if [[ ${{github.repository_owner}} == vcmi ]]
  177. then
  178. data_url="https://github.com/vcmi-mods/vcmi-test-data/releases/download/v1.0/h3_assets.zip"
  179. else
  180. data_url="https://github.com/${{github.repository_owner}}/vcmi-test-data/releases/download/v1.0/h3_assets.zip"
  181. fi
  182. wget --progress=dot:giga "$data_url" -O h3_assets.zip
  183. 7za x h3_assets.zip -p$HEROES_3_DATA_PASSWORD
  184. mkdir -p ~/.local/share/vcmi/
  185. mv h3_assets/* ~/.local/share/vcmi/
  186. - name: Install Conan
  187. if: "${{ matrix.conan_profile != '' }}"
  188. run: pipx install 'conan<2.0'
  189. - name: Install Conan profile
  190. if: "${{ matrix.conan_profile != '' }}"
  191. run: |
  192. conan profile new default --detect
  193. conan install . \
  194. --install-folder=conan-generated \
  195. --no-imports \
  196. --build=never \
  197. --profile:build=default \
  198. --profile:host=CI/conan/${{ matrix.conan_profile }} \
  199. ${{ matrix.conan_options }}
  200. env:
  201. GENERATE_ONLY_BUILT_CONFIG: 1
  202. # Workaround for gradle not discovering SDK that was installed via conan
  203. - name: Find Android NDK
  204. if: ${{ startsWith(matrix.platform, 'android') }}
  205. run: sudo ln -s -T /home/runner/.conan/data/android-ndk/r25c/_/_/package/4db1be536558d833e52e862fd84d64d75c2b3656/bin /usr/local/lib/android/sdk/ndk/25.2.9519653
  206. - name: Install Java
  207. uses: actions/setup-java@v4
  208. if: ${{ startsWith(matrix.platform, 'android') }}
  209. with:
  210. distribution: 'temurin'
  211. java-version: '11'
  212. # a hack to build ID for x64 build in order for Google Play to allow upload of both 32 and 64 bit builds
  213. - name: Bump Android x64 build ID
  214. if: ${{ matrix.platform == 'android-64' }}
  215. run: perl -i -pe 's/versionCode (\d+)/$x=$1+1; "versionCode $x"/e' android/vcmi-app/build.gradle
  216. - name: Build Number
  217. run: |
  218. source '${{github.workspace}}/CI/get_package_name.sh'
  219. if [ '${{ matrix.artifact_platform }}' ]; then
  220. VCMI_PACKAGE_FILE_NAME+="-${{ matrix.artifact_platform }}"
  221. fi
  222. echo VCMI_PACKAGE_FILE_NAME="$VCMI_PACKAGE_FILE_NAME" >> $GITHUB_ENV
  223. echo VCMI_PACKAGE_NAME_SUFFIX="$VCMI_PACKAGE_NAME_SUFFIX" >> $GITHUB_ENV
  224. echo VCMI_PACKAGE_GOLDMASTER="$VCMI_PACKAGE_GOLDMASTER" >> $GITHUB_ENV
  225. env:
  226. PULL_REQUEST: ${{ github.event.pull_request.number }}
  227. - name: Configure
  228. run: |
  229. if [[ ${{matrix.preset}} == linux-gcc-test ]]
  230. then
  231. cmake -DENABLE_CCACHE:BOOL=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 --preset ${{ matrix.preset }}
  232. elif [[ ${{matrix.preset}} == linux-gcc-debug ]]
  233. then
  234. cmake -DENABLE_CCACHE:BOOL=ON -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 --preset ${{ matrix.preset }}
  235. elif [[ (${{matrix.preset}} == android-conan-ninja-release) && (${{github.ref}} != 'refs/heads/master') ]]
  236. then
  237. cmake -DENABLE_CCACHE:BOOL=ON -DANDROID_GRADLE_PROPERTIES="applicationIdSuffix=.daily;signingConfig=dailySigning;applicationLabel=VCMI daily;applicationVariant=daily" --preset ${{ matrix.preset }}
  238. elif [[ ${{startsWith(matrix.platform, 'msvc') }} ]]
  239. then
  240. cmake --preset ${{ matrix.preset }}
  241. else
  242. cmake -DENABLE_CCACHE:BOOL=ON --preset ${{ matrix.preset }}
  243. fi
  244. - name: Build
  245. run: |
  246. cmake --build --preset ${{matrix.preset}}
  247. env:
  248. ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }}
  249. ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
  250. - name: Test
  251. env:
  252. HEROES_3_DATA_PASSWORD: ${{ secrets.HEROES_3_DATA_PASSWORD }}
  253. if: ${{ env.HEROES_3_DATA_PASSWORD != '' && matrix.test == 1 }}
  254. continue-on-error: true
  255. run: |
  256. ctest --preset ${{matrix.preset}}
  257. - name: Kill XProtect to work around CPack issue on macOS
  258. if: ${{ startsWith(matrix.platform, 'mac') }}
  259. run: |
  260. # Cf. https://github.com/actions/runner-images/issues/7522#issuecomment-1556766641
  261. echo Killing...; sudo pkill -9 XProtect >/dev/null || true;
  262. echo "Waiting..."; counter=0; while pgrep XProtect && ((counter < 20)); do sleep 3; ((counter++)); done
  263. pgrep XProtect || true
  264. - name: Pack
  265. id: cpack
  266. if: ${{ matrix.pack == 1 }}
  267. run: |
  268. cd '${{github.workspace}}/out/build/${{matrix.preset}}'
  269. # Workaround for CPack bug on macOS 13
  270. counter=0
  271. until cpack -C ${{matrix.pack_type}} || ((counter > 20)); do
  272. sleep 3
  273. ((counter++))
  274. done
  275. rm -rf _CPack_Packages
  276. - name: Artifacts
  277. if: ${{ matrix.pack == 1 }}
  278. uses: actions/upload-artifact@v4
  279. with:
  280. name: ${{ env.VCMI_PACKAGE_FILE_NAME }} - ${{ matrix.platform }}
  281. compression-level: 0
  282. path: |
  283. ${{github.workspace}}/out/build/${{matrix.preset}}/${{ env.VCMI_PACKAGE_FILE_NAME }}.${{ matrix.extension }}
  284. - name: Find Android package
  285. if: ${{ startsWith(matrix.platform, 'android') }}
  286. run: |
  287. builtApkPath="$(ls ${{ github.workspace }}/out/build/${{ matrix.preset }}/android-build/vcmi-app/build/outputs/apk/release/*.${{ matrix.extension }})"
  288. builtAabPath="$(ls ${{ github.workspace }}/out/build/${{ matrix.preset }}/android-build/vcmi-app/build/outputs/bundle/release/*.aab)"
  289. ANDROID_APK_PATH="${{ github.workspace }}/$VCMI_PACKAGE_FILE_NAME.${{ matrix.extension }}"
  290. ANDROID_AAB_PATH="${{ github.workspace }}/$VCMI_PACKAGE_FILE_NAME.aab"
  291. mv "$builtApkPath" "$ANDROID_APK_PATH"
  292. mv "$builtAabPath" "$ANDROID_AAB_PATH"
  293. echo "ANDROID_APK_PATH=$ANDROID_APK_PATH" >> $GITHUB_ENV
  294. echo "ANDROID_AAB_PATH=$ANDROID_AAB_PATH" >> $GITHUB_ENV
  295. - name: Upload android apk artifacts
  296. if: ${{ startsWith(matrix.platform, 'android') }}
  297. uses: actions/upload-artifact@v4
  298. with:
  299. name: ${{ env.VCMI_PACKAGE_FILE_NAME }} - ${{ matrix.platform }}
  300. compression-level: 0
  301. path: |
  302. ${{ env.ANDROID_APK_PATH }}
  303. - name: Upload Android aab artifacts
  304. if: ${{ startsWith(matrix.platform, 'android') && github.ref == 'refs/heads/master' }}
  305. uses: actions/upload-artifact@v4
  306. with:
  307. name: ${{ env.VCMI_PACKAGE_FILE_NAME }} - ${{ matrix.platform }} - aab
  308. compression-level: 0
  309. path: |
  310. ${{ env.ANDROID_AAB_PATH }}
  311. - name: Upload debug symbols
  312. if: ${{ startsWith(matrix.platform, 'msvc') }}
  313. uses: actions/upload-artifact@v4
  314. with:
  315. name: ${{ env.VCMI_PACKAGE_FILE_NAME }} - ${{ matrix.platform }} - symbols
  316. compression-level: 9
  317. path: |
  318. ${{github.workspace}}/**/*.pdb
  319. - name: Upload build
  320. if: ${{ (matrix.upload == 1) && (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta' || github.ref == 'refs/heads/master') }}
  321. continue-on-error: true
  322. run: |
  323. if [ -z '${{ env.ANDROID_APK_PATH }}' ] ; then
  324. cd '${{github.workspace}}/out/build/${{matrix.preset}}'
  325. fi
  326. source '${{github.workspace}}/CI/upload_package.sh'
  327. env:
  328. DEPLOY_RSA: ${{ secrets.DEPLOY_RSA }}
  329. PACKAGE_EXTENSION: ${{ matrix.extension }}
  330. deploy-src:
  331. if: always() && github.ref == 'refs/heads/master'
  332. runs-on: ubuntu-24.04
  333. defaults:
  334. run:
  335. shell: bash
  336. steps:
  337. - uses: actions/checkout@v4
  338. with:
  339. submodules: recursive
  340. - name: Build Number
  341. run: |
  342. source '${{github.workspace}}/CI/get_package_name.sh'
  343. echo VCMI_PACKAGE_FILE_NAME="$VCMI_PACKAGE_FILE_NAME" >> $GITHUB_ENV
  344. - name: Create source code archive (including submodules)
  345. run: |
  346. git archive HEAD -o "release.tar" --worktree-attributes -v
  347. git submodule update --init --recursive
  348. git submodule --quiet foreach 'cd "$toplevel"; tar -rvf "release.tar" "$sm_path"'
  349. gzip release.tar
  350. - name: Upload source code archive
  351. uses: actions/upload-artifact@v4
  352. with:
  353. name: ${{ env.VCMI_PACKAGE_FILE_NAME }}
  354. path: |
  355. ./release.tar.gz
  356. validate-code:
  357. if: always()
  358. runs-on: ubuntu-24.04
  359. defaults:
  360. run:
  361. shell: bash
  362. steps:
  363. - uses: actions/checkout@v4
  364. - name: Ensure LF line endings
  365. run: |
  366. find . -path ./.git -prune -o -path ./AI/FuzzyLite -prune -o -path ./test/googletest \
  367. -o -path ./osx -prune -o -type f \
  368. -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 | \
  369. { ! xargs -0 grep -l -z -P '\r\n'; }
  370. - name: Validate JSON
  371. run: |
  372. sudo apt install python3-jstyleson
  373. python3 CI/validate_json.py
  374. - name: Validate Markdown
  375. uses: DavidAnson/markdownlint-cli2-action@v20
  376. with:
  377. config: 'CI/example.markdownlint-cli2.jsonc'
  378. globs: '**/*.md'