github.yml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. name: VCMI
  2. on:
  3. push:
  4. branches:
  5. - features/*
  6. - beta
  7. - master
  8. pull_request:
  9. schedule:
  10. - cron: '0 2 * * *'
  11. workflow_dispatch:
  12. env:
  13. # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
  14. BUILD_TYPE: Release
  15. jobs:
  16. check_last_build:
  17. if: github.event.schedule != ''
  18. runs-on: ubuntu-latest
  19. outputs:
  20. skip_build: ${{ steps.check_if_built.outputs.skip_build }}
  21. defaults:
  22. run:
  23. shell: bash
  24. steps:
  25. - name: Get repo name
  26. id: get_repo_name
  27. run: echo "::set-output name=value::${GITHUB_REPOSITORY#*/}"
  28. - name: Get last successful build for ${{ github.sha }}
  29. uses: octokit/[email protected]
  30. id: get_last_scheduled_run
  31. with:
  32. route: GET /repos/{owner}/{repo}/actions/runs
  33. owner: ${{ github.repository_owner }}
  34. repo: ${{ steps.get_repo_name.outputs.value }}
  35. status: success
  36. per_page: 1
  37. head_sha: ${{ github.sha }}
  38. env:
  39. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  40. - name: Check if successful build of the current commit exists
  41. id: check_if_built
  42. run: |
  43. if [ ${{ fromJson(steps.get_last_scheduled_run.outputs.data).total_count }} -gt 0 ]; then
  44. echo '::set-output name=skip_build::1'
  45. else
  46. echo '::set-output name=skip_build::0'
  47. fi
  48. - name: Cancel current run
  49. if: steps.check_if_built.outputs.skip_build == 1
  50. uses: octokit/[email protected]
  51. with:
  52. route: POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel
  53. owner: ${{ github.repository_owner }}
  54. repo: ${{ steps.get_repo_name.outputs.value }}
  55. run_id: ${{ github.run_id }}
  56. env:
  57. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  58. - name: Wait for the run to be cancelled
  59. if: steps.check_if_built.outputs.skip_build == 1
  60. run: sleep 60
  61. build:
  62. needs: check_last_build
  63. if: always() && needs.check_last_build.skip_build != 1
  64. strategy:
  65. matrix:
  66. include:
  67. - platform: linux-qt6
  68. os: ubuntu-22.04
  69. test: 1
  70. preset: linux-clang-test
  71. - platform: linux
  72. os: ubuntu-22.04
  73. test: 1
  74. preset: linux-gcc-test
  75. - platform: linux
  76. os: ubuntu-20.04
  77. test: 0
  78. preset: linux-gcc-debug
  79. - platform: mac-intel
  80. os: macos-12
  81. test: 0
  82. pack: 1
  83. pack_type: Release
  84. extension: dmg
  85. preset: macos-conan-ninja-release
  86. conan_profile: macos-intel
  87. conan_options: --options with_apple_system_libs=True
  88. artifact_platform: intel
  89. - platform: mac-arm
  90. os: macos-12
  91. test: 0
  92. pack: 1
  93. pack_type: Release
  94. extension: dmg
  95. preset: macos-arm-conan-ninja-release
  96. conan_profile: macos-arm
  97. conan_options: --options with_apple_system_libs=True
  98. artifact_platform: arm
  99. - platform: ios
  100. os: macos-12
  101. test: 0
  102. pack: 1
  103. pack_type: Release
  104. extension: ipa
  105. preset: ios-release-conan-ccache
  106. conan_profile: ios-arm64
  107. conan_options: --options with_apple_system_libs=True
  108. - platform: msvc
  109. os: windows-latest
  110. test: 0
  111. pack: 1
  112. pack_type: RelWithDebInfo
  113. extension: exe
  114. preset: windows-msvc-release-ccache
  115. - platform: mingw
  116. os: ubuntu-22.04
  117. test: 0
  118. pack: 1
  119. pack_type: Release
  120. extension: exe
  121. cpack_args: -D CPACK_NSIS_EXECUTABLE=`which makensis`
  122. cmake_args: -G Ninja
  123. preset: windows-mingw-conan-linux
  124. conan_profile: mingw64-linux.jinja
  125. - platform: mingw-32
  126. os: ubuntu-22.04
  127. test: 0
  128. pack: 1
  129. pack_type: Release
  130. extension: exe
  131. cpack_args: -D CPACK_NSIS_EXECUTABLE=`which makensis`
  132. cmake_args: -G Ninja
  133. preset: windows-mingw-conan-linux
  134. conan_profile: mingw32-linux.jinja
  135. - platform: android-32
  136. os: ubuntu-22.04
  137. extension: apk
  138. preset: android-conan-ninja-release
  139. conan_profile: android-32
  140. conan_options: --conf tools.android:ndk_path=$ANDROID_NDK_ROOT
  141. artifact_platform: armeabi-v7a
  142. - platform: android-64
  143. os: ubuntu-22.04
  144. extension: apk
  145. preset: android-conan-ninja-release
  146. conan_profile: android-64
  147. conan_options: --conf tools.android:ndk_path=$ANDROID_NDK_ROOT
  148. artifact_platform: arm64-v8a
  149. runs-on: ${{ matrix.os }}
  150. defaults:
  151. run:
  152. shell: bash
  153. steps:
  154. - uses: actions/checkout@v3
  155. with:
  156. submodules: recursive
  157. - name: Ensure LF line endings
  158. if: ${{ startsWith(matrix.preset, 'linux-clang-test') }}
  159. run: |
  160. find . -path ./.git -prune -o -path ./AI/FuzzyLite -prune -o -path ./test/googletest \
  161. -o -path ./osx -prune -o -type f \
  162. -not -name '*.png' -and -not -name '*.vcxproj*' -and -not -name '*.props' -and -not -name '*.wav' -and -not -name '*.webm' -and -not -name '*.ico' -and -not -name '*.bat' -print0 | \
  163. { ! xargs -0 grep -l -z -P '\r\n'; }
  164. - name: Validate JSON
  165. # the Python yaml module doesn't seem to work on mac-arm
  166. # also, running it on multiple presets is redundant and slightly increases already long CI built times
  167. if: ${{ startsWith(matrix.preset, 'linux-clang-test') }}
  168. run: |
  169. pip3 install json5 jstyleson
  170. python3 CI/linux-qt6/validate_json.py
  171. - name: Dependencies
  172. run: source '${{github.workspace}}/CI/${{matrix.platform}}/before_install.sh'
  173. env:
  174. VCMI_BUILD_PLATFORM: x64
  175. # ensure the ccache for each PR is separate so they don't interfere with each other
  176. # fall back to ccache of the vcmi/vcmi repo if no PR-specific ccache is found
  177. - name: Ccache for PRs
  178. uses: hendrikmuhs/[email protected]
  179. if: ${{ github.event.number != '' }}
  180. with:
  181. key: ${{ matrix.preset }}-PR-${{ github.event.number }}
  182. restore-keys: |
  183. ${{ matrix.preset }}-PR-${{ github.event.number }}
  184. ${{ matrix.preset }}-no-PR
  185. # actual cache takes up less space, at most ~1 GB
  186. max-size: "5G"
  187. verbose: 2
  188. - name: Ccache for everything but PRs
  189. uses: hendrikmuhs/[email protected]
  190. if: ${{ github.event.number == '' }}
  191. with:
  192. key: ${{ matrix.preset }}-no-PR
  193. restore-keys: |
  194. ${{ matrix.preset }}-no-PR
  195. # actual cache takes up less space, at most ~1 GB
  196. max-size: "5G"
  197. verbose: 2
  198. - name: Clone Heroes 3 data
  199. if: ${{ startsWith(matrix.preset, 'linux') && endsWith(matrix.preset, 'test') }}
  200. env:
  201. HEROES_3_DATA_PASSWORD: ${{ secrets.HEROES_3_DATA_PASSWORD }}
  202. run: |
  203. wget --progress=dot:giga https://github.com/vcmi-mods/vcmi-test-data/releases/download/v1.0/h3_assets.zip
  204. 7za x h3_assets.zip -p$HEROES_3_DATA_PASSWORD
  205. mkdir -p ~/.local/share/vcmi/
  206. mv h3_assets/* ~/.local/share/vcmi/
  207. - uses: actions/setup-python@v4
  208. if: "${{ matrix.conan_profile != '' }}"
  209. with:
  210. python-version: '3.10'
  211. - name: Conan setup
  212. if: "${{ matrix.conan_profile != '' }}"
  213. run: |
  214. pip3 install 'conan<2.0'
  215. conan profile new default --detect
  216. conan install . \
  217. --install-folder=conan-generated \
  218. --no-imports \
  219. --build=never \
  220. --profile:build=default \
  221. --profile:host=CI/conan/${{ matrix.conan_profile }} \
  222. ${{ matrix.conan_options }}
  223. env:
  224. GENERATE_ONLY_BUILT_CONFIG: 1
  225. - name: Git branch name
  226. id: git-branch-name
  227. uses: EthanSK/git-branch-name-action@v1
  228. - name: Build Number
  229. run: |
  230. source '${{github.workspace}}/CI/get_package_name.sh'
  231. if [ '${{ matrix.artifact_platform }}' ]; then
  232. VCMI_PACKAGE_FILE_NAME+="-${{ matrix.artifact_platform }}"
  233. fi
  234. echo VCMI_PACKAGE_FILE_NAME="$VCMI_PACKAGE_FILE_NAME" >> $GITHUB_ENV
  235. echo VCMI_PACKAGE_NAME_SUFFIX="$VCMI_PACKAGE_NAME_SUFFIX" >> $GITHUB_ENV
  236. echo VCMI_PACKAGE_GITVERSION="$VCMI_PACKAGE_GITVERSION" >> $GITHUB_ENV
  237. env:
  238. PULL_REQUEST: ${{ github.event.pull_request.number }}
  239. - name: Configure
  240. run: |
  241. if [[ ${{matrix.preset}} == linux-gcc-test ]]; then GCC13=1; fi
  242. cmake -DENABLE_CCACHE:BOOL=ON --preset ${{ matrix.preset }} ${GCC13:+-DCMAKE_C_COMPILER=gcc-13 -DCMAKE_CXX_COMPILER=g++-13}
  243. - name: Build
  244. run: |
  245. cmake --build --preset ${{matrix.preset}}
  246. - name: Test
  247. if: ${{ matrix.test == 1 }}
  248. run: |
  249. ctest --preset ${{matrix.preset}}
  250. - name: Pack
  251. id: cpack
  252. if: ${{ matrix.pack == 1 }}
  253. run: |
  254. cd '${{github.workspace}}/out/build/${{matrix.preset}}'
  255. CPACK_PATH=`which -a cpack | grep -m1 -v -i chocolatey`
  256. "$CPACK_PATH" -C ${{matrix.pack_type}} ${{ matrix.cpack_args }}
  257. test -f '${{github.workspace}}/CI/${{matrix.platform}}/post_pack.sh' \
  258. && '${{github.workspace}}/CI/${{matrix.platform}}/post_pack.sh' '${{github.workspace}}' "$(ls '${{ env.VCMI_PACKAGE_FILE_NAME }}'.*)"
  259. rm -rf _CPack_Packages
  260. - name: Create android package
  261. if: ${{ startsWith(matrix.platform, 'android') }}
  262. run: |
  263. cd android
  264. ./gradlew assembleDaily --info
  265. echo ANDROID_APK_PATH="$(ls ${{ github.workspace }}/android/vcmi-app/build/outputs/apk/daily/*.${{ matrix.extension }})" >> $GITHUB_ENV
  266. - name: Additional logs
  267. if: ${{ failure() && steps.cpack.outcome == 'failure' && matrix.platform == 'msvc' }}
  268. run: |
  269. cat '${{github.workspace}}/out/build/${{matrix.preset}}/_CPack_Packages/win32/NSIS/project.nsi'
  270. cat '${{github.workspace}}/out/build/${{matrix.preset}}/_CPack_Packages/win32/NSIS/NSISOutput.log'
  271. - name: Artifacts
  272. if: ${{ matrix.pack == 1 }}
  273. uses: actions/upload-artifact@v3
  274. with:
  275. name: ${{ env.VCMI_PACKAGE_FILE_NAME }} - ${{ matrix.platform }}
  276. path: |
  277. ${{github.workspace}}/out/build/${{matrix.preset}}/${{ env.VCMI_PACKAGE_FILE_NAME }}.${{ matrix.extension }}
  278. - name: Android artifacts
  279. if: ${{ startsWith(matrix.platform, 'android') }}
  280. uses: actions/upload-artifact@v3
  281. with:
  282. name: ${{ env.VCMI_PACKAGE_FILE_NAME }} - ${{ matrix.platform }}
  283. path: |
  284. ${{ env.ANDROID_APK_PATH }}
  285. - name: Symbols
  286. if: ${{ matrix.platform == 'msvc' }}
  287. uses: actions/upload-artifact@v3
  288. with:
  289. name: ${{ env.VCMI_PACKAGE_FILE_NAME }} - ${{ matrix.platform }} - symbols
  290. path: |
  291. ${{github.workspace}}/**/*.pdb
  292. - name: Android JNI ${{matrix.platform}}
  293. if: ${{ startsWith(matrix.platform, 'android') && github.ref == 'refs/heads/master' }}
  294. uses: actions/upload-artifact@v3
  295. with:
  296. name: Android JNI ${{matrix.platform}}
  297. path: |
  298. ${{ github.workspace }}/android/vcmi-app/src/main/jniLibs
  299. - name: Upload build
  300. if: ${{ (matrix.pack == 1 || startsWith(matrix.platform, 'android')) && (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta' || github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/features/')) && matrix.platform != 'msvc' }}
  301. continue-on-error: true
  302. run: |
  303. if cd '${{github.workspace}}/android/vcmi-app/build/outputs/apk/daily' ; then
  304. mv '${{ env.ANDROID_APK_PATH }}' "$VCMI_PACKAGE_FILE_NAME.${{ matrix.extension }}"
  305. else
  306. cd '${{github.workspace}}/out/build/${{matrix.preset}}'
  307. fi
  308. source '${{github.workspace}}/CI/upload_package.sh'
  309. env:
  310. DEPLOY_RSA: ${{ secrets.DEPLOY_RSA }}
  311. PACKAGE_EXTENSION: ${{ matrix.extension }}
  312. - uses: act10ns/slack@v1
  313. with:
  314. status: ${{ job.status }}
  315. channel: '#notifications'
  316. env:
  317. SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
  318. if: always()
  319. # copy-pasted mostly
  320. bundle_release:
  321. needs: build
  322. if: always() && github.ref == 'refs/heads/master'
  323. strategy:
  324. matrix:
  325. include:
  326. - platform: android-32
  327. os: ubuntu-22.04
  328. extension: aab
  329. preset: android-conan-ninja-release
  330. conan_profile: android-32
  331. conan_options: --conf tools.android:ndk_path=$ANDROID_NDK_ROOT
  332. artifact_platform: aab
  333. runs-on: ${{ matrix.os }}
  334. defaults:
  335. run:
  336. shell: bash
  337. steps:
  338. - uses: actions/checkout@v3
  339. with:
  340. submodules: recursive
  341. - name: Dependencies
  342. run: source '${{github.workspace}}/CI/${{matrix.platform}}/before_install.sh'
  343. env:
  344. VCMI_BUILD_PLATFORM: x64
  345. - uses: actions/setup-python@v4
  346. if: "${{ matrix.conan_profile != '' }}"
  347. with:
  348. python-version: '3.10'
  349. - name: Conan setup
  350. if: "${{ matrix.conan_profile != '' }}"
  351. run: |
  352. pip3 install 'conan<2.0'
  353. conan profile new default --detect
  354. conan install . \
  355. --install-folder=conan-generated \
  356. --no-imports \
  357. --build=never \
  358. --profile:build=default \
  359. --profile:host=CI/conan/${{ matrix.conan_profile }} \
  360. ${{ matrix.conan_options }}
  361. env:
  362. GENERATE_ONLY_BUILT_CONFIG: 1
  363. - name: Git branch name
  364. id: git-branch-name
  365. uses: EthanSK/git-branch-name-action@v1
  366. - name: Build Number
  367. run: |
  368. source '${{github.workspace}}/CI/get_package_name.sh'
  369. if [ '${{ matrix.artifact_platform }}' ]; then
  370. VCMI_PACKAGE_FILE_NAME+="-${{ matrix.artifact_platform }}"
  371. fi
  372. echo VCMI_PACKAGE_FILE_NAME="$VCMI_PACKAGE_FILE_NAME" >> $GITHUB_ENV
  373. echo VCMI_PACKAGE_NAME_SUFFIX="$VCMI_PACKAGE_NAME_SUFFIX" >> $GITHUB_ENV
  374. echo VCMI_PACKAGE_GITVERSION="$VCMI_PACKAGE_GITVERSION" >> $GITHUB_ENV
  375. env:
  376. PULL_REQUEST: ${{ github.event.pull_request.number }}
  377. - name: CMake Preset
  378. run: |
  379. cmake --preset ${{ matrix.preset }}
  380. - name: Build Preset
  381. run: |
  382. cmake --build --preset ${{matrix.preset}}
  383. - name: Download libs x64
  384. uses: actions/download-artifact@v3
  385. with:
  386. name: Android JNI android-64
  387. path: ${{ github.workspace }}/android/vcmi-app/src/main/jniLibs/
  388. - name: Create android package
  389. run: |
  390. cd android
  391. ./gradlew bundleRelease --info
  392. echo ANDROID_APK_PATH="$(ls ${{ github.workspace }}/android/vcmi-app/build/outputs/bundle/release/*.aab)" >> $GITHUB_ENV
  393. env:
  394. ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }}
  395. ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
  396. - name: Android artifacts
  397. uses: actions/upload-artifact@v3
  398. with:
  399. name: ${{ env.VCMI_PACKAGE_FILE_NAME }}
  400. path: |
  401. ${{ env.ANDROID_APK_PATH }}
  402. - uses: act10ns/slack@v1
  403. with:
  404. status: ${{ job.status }}
  405. channel: '#notifications'
  406. env:
  407. SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
  408. if: always()