main.yml 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. ######################################################################################
  2. # JME CI/CD
  3. ######################################################################################
  4. # Quick overview of what is going on in this script:
  5. # - Build natives for android
  6. # - Merge the natives, build the engine, create the zip release, maven artifacts, javadoc and native snapshot
  7. # - (only when native code changes) Deploy the natives snapshot to the MinIO instance
  8. # - (only when building a release) Deploy everything else to github releases and Sonatype
  9. # - (only when building a release) Update javadoc.jmonkeyengine.org
  10. # Note:
  11. # All the actions/upload-artifact and actions/download-artifact steps are used to pass
  12. # stuff between jobs, github actions has some sort of storage that is local to the
  13. # running workflow, we use it to store the result of each job since the filesystem
  14. # is not maintained between jobs.
  15. ################# CONFIGURATIONS #####################################################
  16. # >> Configure MINIO NATIVES SNAPSHOT
  17. # OBJECTS_KEY=XXXXXX
  18. # >> Configure SONATYPE RELEASE
  19. # CENTRAL_PASSWORD=XXXXXX
  20. # CENTRAL_USERNAME=XXXXXX
  21. # >> Configure SIGNING
  22. # SIGNING_KEY=XXXXXX
  23. # SIGNING_PASSWORD=XXXXXX
  24. # >> Configure PACKAGE REGISTRY RELEASE
  25. # Nothing to do here, everything is autoconfigured to work with the account/org that
  26. # is running the build.
  27. # >> Configure JAVADOC
  28. # JAVADOC_GHPAGES_REPO="riccardoblsandbox/javadoc.jmonkeyengine.org.git"
  29. # Generate a deploy key
  30. # ssh-keygen -t rsa -b 4096 -C "[email protected]" -f javadoc_deploy
  31. # Set
  32. # JAVADOC_GHPAGES_DEPLOY_PRIVKEY="......."
  33. # In github repo -> Settings, use javadoc_deploy.pub as Deploy key with write access
  34. ######################################################################################
  35. # Resources:
  36. # - Github actions docs: https://help.github.com/en/articles/about-github-actions
  37. # - Package registry docs: https://help.github.com/en/articles/about-github-package-registry
  38. # - Official actions: https://github.com/actions
  39. # - Community actions: https://github.com/sdras/awesome-actions
  40. ######################################################################################
  41. # - Riccardo Balbo
  42. ######################################################################################
  43. name: Build jMonkeyEngine
  44. on:
  45. push:
  46. branches:
  47. - master
  48. - v3.7
  49. - v3.6
  50. - v3.5
  51. - v3.4
  52. - v3.3
  53. - ios-2024_2
  54. pull_request:
  55. release:
  56. types: [published]
  57. jobs:
  58. ScreenshotTests:
  59. name: Run Screenshot Tests
  60. runs-on: ubuntu-latest
  61. container:
  62. image: ghcr.io/onemillionworlds/opengl-docker-image:v1
  63. permissions:
  64. contents: read
  65. steps:
  66. - uses: actions/checkout@v4
  67. - name: Start xvfb
  68. run: |
  69. Xvfb :99 -ac -screen 0 1024x768x16 &
  70. export DISPLAY=:99
  71. echo "DISPLAY=:99" >> $GITHUB_ENV
  72. - name: Report GL/Vulkan
  73. run: |
  74. set -x
  75. echo "DISPLAY=$DISPLAY"
  76. glxinfo | grep -E "OpenGL version|OpenGL renderer|OpenGL vendor" || true
  77. vulkaninfo --summary || true
  78. echo "VK_ICD_FILENAMES=$VK_ICD_FILENAMES"
  79. echo "MESA_LOADER_DRIVER_OVERRIDE=$MESA_LOADER_DRIVER_OVERRIDE"
  80. echo "GALLIUM_DRIVER=$GALLIUM_DRIVER"
  81. - name: Validate the Gradle wrapper
  82. uses: gradle/actions/wrapper-validation@v3
  83. - name: Test with Gradle Wrapper
  84. run: |
  85. ./gradlew :jme3-screenshot-test:screenshotTest
  86. - name: Upload Test Reports
  87. uses: actions/upload-artifact@master
  88. if: always()
  89. with:
  90. name: screenshot-test-report
  91. retention-days: 30
  92. path: |
  93. **/build/reports/**
  94. **/build/changed-images/**
  95. **/build/test-results/**
  96. # Build iOS natives
  97. BuildIosNatives:
  98. name: Build natives for iOS
  99. runs-on: macOS-14
  100. steps:
  101. - name: Check default JAVAs
  102. run: echo $JAVA_HOME --- $JAVA_HOME_8_X64 --- $JAVA_HOME_11_X64 --- $JAVA_HOME_17_X64 --- $JAVA_HOME_21_X64 ---
  103. - name: Setup the java environment
  104. uses: actions/setup-java@v4
  105. with:
  106. distribution: 'temurin'
  107. java-version: '11.0.26+4'
  108. - name: Setup the XCode version to 15.1.0
  109. uses: maxim-lobanov/setup-xcode@v1
  110. with:
  111. xcode-version: '15.1.0'
  112. - name: Clone the repo
  113. uses: actions/checkout@v4
  114. with:
  115. fetch-depth: 1
  116. - name: Validate the Gradle wrapper
  117. uses: gradle/actions/wrapper-validation@v3
  118. - name: Build
  119. run: |
  120. ./gradlew -PuseCommitHashAsVersionName=true --no-daemon -PbuildNativeProjects=true \
  121. :jme3-ios-native:build
  122. - name: Upload natives
  123. uses: actions/upload-artifact@master
  124. with:
  125. name: ios-natives
  126. path: jme3-ios-native/template/META-INF/robovm/ios/libs/jme3-ios-native.xcframework
  127. # Build the natives on android
  128. BuildAndroidNatives:
  129. name: Build natives for android
  130. runs-on: ubuntu-latest
  131. container:
  132. image: ghcr.io/cirruslabs/android-sdk:36-ndk
  133. steps:
  134. - name: Clone the repo
  135. uses: actions/checkout@v4
  136. with:
  137. fetch-depth: 1
  138. - name: Setup Java 11
  139. uses: actions/setup-java@v4
  140. with:
  141. distribution: temurin
  142. java-version: '11'
  143. - name: Check java version
  144. run: java -version
  145. - name: Install CMake
  146. run: |
  147. apt-get update
  148. apt-get install -y cmake
  149. cmake --version
  150. - name: Validate the Gradle wrapper
  151. uses: gradle/actions/wrapper-validation@v3
  152. - name: Build
  153. run: |
  154. export ANDROID_NDK="$ANDROID_SDK_ROOT/ndk/$ANDROID_NDK_VERSION"
  155. ./gradlew -PuseCommitHashAsVersionName=true --no-daemon -PbuildNativeProjects=true \
  156. :jme3-android-native:assemble
  157. - name: Upload natives
  158. uses: actions/upload-artifact@master
  159. with:
  160. name: android-natives
  161. path: build/native
  162. # Build the engine, we only deploy from ubuntu-latest jdk21
  163. BuildJMonkey:
  164. needs: [BuildAndroidNatives, BuildIosNatives]
  165. name: Build on ${{ matrix.osName }} jdk${{ matrix.jdk }}
  166. runs-on: ${{ matrix.os }}
  167. strategy:
  168. fail-fast: false
  169. matrix:
  170. os: [ubuntu-latest,windows-latest,macOS-latest]
  171. jdk: [11, 17, 21]
  172. include:
  173. - os: ubuntu-latest
  174. osName: linux
  175. deploy: true
  176. - os: windows-latest
  177. osName: windows
  178. deploy: false
  179. - os: macOS-latest
  180. osName: mac
  181. deploy: false
  182. - jdk: 11
  183. deploy: false
  184. - jdk: 17
  185. deploy: false
  186. steps:
  187. - name: Clone the repo
  188. uses: actions/checkout@v4
  189. with:
  190. fetch-depth: 1
  191. - name: Setup the java environment
  192. uses: actions/setup-java@v4
  193. with:
  194. distribution: 'temurin'
  195. java-version: ${{ matrix.jdk }}
  196. - name: Download natives for android
  197. uses: actions/download-artifact@master
  198. with:
  199. name: android-natives
  200. path: build/native
  201. - name: Download natives for iOS
  202. uses: actions/download-artifact@master
  203. with:
  204. name: ios-natives
  205. path: jme3-ios-native/template/META-INF/robovm/ios/libs/jme3-ios-native.xcframework
  206. - name: Validate the Gradle wrapper
  207. uses: gradle/actions/wrapper-validation@v3
  208. - name: Build Engine
  209. shell: bash
  210. run: |
  211. # Normal build plus ZIP distribution and merged javadoc
  212. ./gradlew -PuseCommitHashAsVersionName=true -PskipPrebuildLibraries=true \
  213. build createZipDistribution mergedJavadoc
  214. if [ "${{ matrix.deploy }}" = "true" ];
  215. then
  216. # We are going to need "zip"
  217. sudo apt-get update
  218. sudo apt-get install -y zip
  219. # We prepare the release for deploy
  220. mkdir -p ./dist/release/
  221. mv build/distributions/*.zip dist/release/
  222. # Install maven artifacts to ./dist/maven and sign them if possible
  223. if [ "${{ secrets.SIGNING_PASSWORD }}" = "" ];
  224. then
  225. echo "Configure the following secrets to enable signing:"
  226. echo "SIGNING_KEY, SIGNING_PASSWORD"
  227. ./gradlew publishMavenPublicationToDistRepository \
  228. -PskipPrebuildLibraries=true -PuseCommitHashAsVersionName=true \
  229. --console=plain --stacktrace
  230. else
  231. ./gradlew publishMavenPublicationToDistRepository \
  232. -PsigningKey='${{ secrets.SIGNING_KEY }}' \
  233. -PsigningPassword='${{ secrets.SIGNING_PASSWORD }}' \
  234. -PskipPrebuildLibraries=true -PuseCommitHashAsVersionName=true \
  235. --console=plain --stacktrace
  236. fi
  237. # Zip the natives into a single archive (we are going to use this to deploy native snapshots)
  238. echo "Create native zip"
  239. cdir="$PWD"
  240. cd "build/native"
  241. zip -r "$cdir/dist/jme3-natives.zip" *
  242. cd "$cdir"
  243. echo "Done"
  244. fi
  245. # Used later by DeploySnapshot
  246. - name: Upload merged natives
  247. if: matrix.deploy==true
  248. uses: actions/upload-artifact@master
  249. with:
  250. name: natives
  251. path: dist/jme3-natives.zip
  252. # Upload maven artifacts to be used later by the deploy job
  253. - name: Upload maven artifacts
  254. if: matrix.deploy==true
  255. uses: actions/upload-artifact@master
  256. with:
  257. name: maven
  258. path: dist/maven
  259. - name: Upload javadoc
  260. if: matrix.deploy==true
  261. uses: actions/upload-artifact@master
  262. with:
  263. name: javadoc
  264. path: dist/javadoc
  265. # Upload release archive to be used later by the deploy job
  266. - name: Upload release
  267. if: github.event_name == 'release' && matrix.deploy==true
  268. uses: actions/upload-artifact@master
  269. with:
  270. name: release
  271. path: dist/release
  272. # This job deploys the native snapshot.
  273. # The snapshot is downloaded when people build the engine without setting buildNativeProject
  274. # this is useful for people that want to build only the java part and don't have
  275. # all the stuff needed to compile natives.
  276. DeployNativeSnapshot:
  277. needs: [BuildJMonkey]
  278. name: "Deploy native snapshot"
  279. runs-on: ubuntu-latest
  280. if: github.event_name == 'push'
  281. steps:
  282. # We clone the repo manually, since we are going to push back a reference to the snapshot
  283. - name: Clone the repo
  284. run: |
  285. branch="${GITHUB_REF//refs\/heads\//}"
  286. if [ "$branch" != "" ];
  287. then
  288. git clone --single-branch --branch "$branch" https://github.com/${GITHUB_REPOSITORY}.git .
  289. fi
  290. - name: Download merged natives
  291. uses: actions/download-artifact@master
  292. with:
  293. name: natives
  294. path: dist/
  295. - name: Deploy natives snapshot
  296. run: |
  297. source .github/actions/tools/minio.sh
  298. NATIVE_CHANGES="yes"
  299. branch="${GITHUB_REF//refs\/heads\//}"
  300. if [ "$branch" != "" ];
  301. then
  302. if [ -f "natives-snapshot.properties" ];
  303. then
  304. nativeSnapshot=`cat "natives-snapshot.properties"`
  305. nativeSnapshot="${nativeSnapshot#*=}"
  306. # We deploy ONLY if GITHUB_SHA (the current commit hash) is newer than $nativeSnapshot
  307. if [ "`git rev-list --count $nativeSnapshot..$GITHUB_SHA`" = "0" ];
  308. then
  309. NATIVE_CHANGES=""
  310. else
  311. # We check if the native code changed.
  312. echo "Detect changes"
  313. NATIVE_CHANGES="$(git diff-tree --name-only "$GITHUB_SHA" "$nativeSnapshot" -- jme3-android-native/)"
  314. fi
  315. fi
  316. # We do nothing if there is no change
  317. if [ "$NATIVE_CHANGES" = "" ];
  318. then
  319. echo "No changes, skip."
  320. else
  321. if [ "${{ secrets.OBJECTS_KEY }}" = "" ];
  322. then
  323. echo "Configure the OBJECTS_KEY secret to enable natives snapshot deployment to MinIO"
  324. else
  325. # Deploy natives snapshot to a MinIO instance using function in minio.sh
  326. minio_uploadFile dist/jme3-natives.zip \
  327. native-snapshots/$GITHUB_SHA/jme3-natives.zip \
  328. https://objects.jmonkeyengine.org \
  329. jmonkeyengine \
  330. ${{ secrets.OBJECTS_KEY }}
  331. # We reference the snapshot by writing its commit hash in natives-snapshot.properties
  332. echo "natives.snapshot=$GITHUB_SHA" > natives-snapshot.properties
  333. # We commit the updated natives-snapshot.properties
  334. git config --global user.name "Github Actions"
  335. git config --global user.email "[email protected]"
  336. git add natives-snapshot.properties
  337. git commit -m "[skip ci] update natives snapshot"
  338. # Pull rebase from the remote repo, just in case there was a push in the meantime
  339. git pull -q --rebase
  340. # We need to calculate the header for git authentication
  341. header=$(echo -n "ad-m:${{ secrets.GITHUB_TOKEN }}" | base64)
  342. # Push
  343. (git -c http.extraheader="AUTHORIZATION: basic $header" push origin "$branch" || true)
  344. fi
  345. fi
  346. fi
  347. # This job deploys snapshots on the master branch
  348. DeployJavaSnapshot:
  349. needs: [BuildJMonkey]
  350. name: Deploy Java Snapshot
  351. runs-on: ubuntu-latest
  352. if: github.event_name == 'push' && github.ref_name == 'master'
  353. steps:
  354. # We need to clone everything again for uploadToMaven.sh ...
  355. - name: Clone the repo
  356. uses: actions/checkout@v4
  357. with:
  358. fetch-depth: 1
  359. # Setup jdk 21 used for building Maven-style artifacts
  360. - name: Setup the java environment
  361. uses: actions/setup-java@v4
  362. with:
  363. distribution: 'temurin'
  364. java-version: '21'
  365. - name: Download natives for android
  366. uses: actions/download-artifact@master
  367. with:
  368. name: android-natives
  369. path: build/native
  370. - name: Download natives for iOS
  371. uses: actions/download-artifact@master
  372. with:
  373. name: ios-natives
  374. path: jme3-ios-native/template/META-INF/robovm/ios/libs/jme3-ios-native.xcframework
  375. - name: Rebuild the maven artifacts and upload them to Sonatype's maven-snapshots repo
  376. run: |
  377. if [ "${{ secrets.CENTRAL_PASSWORD }}" = "" ];
  378. then
  379. echo "Configure the following secrets to enable uploading to Sonatype:"
  380. echo "CENTRAL_PASSWORD, CENTRAL_USERNAME, SIGNING_KEY, SIGNING_PASSWORD"
  381. else
  382. ./gradlew publishMavenPublicationToSNAPSHOTRepository \
  383. -PcentralPassword=${{ secrets.CENTRAL_PASSWORD }} \
  384. -PcentralUsername=${{ secrets.CENTRAL_USERNAME }} \
  385. -PsigningKey='${{ secrets.SIGNING_KEY }}' \
  386. -PsigningPassword='${{ secrets.SIGNING_PASSWORD }}' \
  387. -PuseCommitHashAsVersionName=true \
  388. --console=plain --stacktrace
  389. fi
  390. # This job deploys the release
  391. DeployRelease:
  392. needs: [BuildJMonkey]
  393. name: Deploy Release
  394. runs-on: ubuntu-latest
  395. if: github.event_name == 'release'
  396. steps:
  397. # We need to clone everything again for uploadToCentral.sh ...
  398. - name: Clone the repo
  399. uses: actions/checkout@v4
  400. with:
  401. fetch-depth: 1
  402. # Setup jdk 21 used for building Sonatype artifacts
  403. - name: Setup the java environment
  404. uses: actions/setup-java@v4
  405. with:
  406. distribution: 'temurin'
  407. java-version: '21'
  408. # Download all the stuff...
  409. - name: Download maven artifacts
  410. uses: actions/download-artifact@master
  411. with:
  412. name: maven
  413. path: dist/maven
  414. - name: Download release
  415. uses: actions/download-artifact@master
  416. with:
  417. name: release
  418. path: dist/release
  419. - name: Download natives for android
  420. uses: actions/download-artifact@master
  421. with:
  422. name: android-natives
  423. path: build/native
  424. - name: Download natives for iOS
  425. uses: actions/download-artifact@master
  426. with:
  427. name: ios-natives
  428. path: jme3-ios-native/template/META-INF/robovm/ios/libs/jme3-ios-native.xcframework
  429. - name: Rebuild the maven artifacts and upload them to Sonatype's Central Publisher Portal
  430. run: |
  431. if [ "${{ secrets.CENTRAL_PASSWORD }}" = "" ];
  432. then
  433. echo "Configure the following secrets to enable uploading to Sonatype:"
  434. echo "CENTRAL_PASSWORD, CENTRAL_USERNAME, SIGNING_KEY, SIGNING_PASSWORD"
  435. else
  436. ./gradlew publishMavenPublicationToCentralRepository \
  437. -PcentralPassword=${{ secrets.CENTRAL_PASSWORD }} \
  438. -PcentralUsername=${{ secrets.CENTRAL_USERNAME }} \
  439. -PsigningKey='${{ secrets.SIGNING_KEY }}' \
  440. -PsigningPassword='${{ secrets.SIGNING_PASSWORD }}' \
  441. -PuseCommitHashAsVersionName=true \
  442. --console=plain --stacktrace
  443. .github/actions/tools/uploadToCentral.sh \
  444. -p '${{ secrets.CENTRAL_PASSWORD }}' \
  445. -u '${{ secrets.CENTRAL_USERNAME }}'
  446. fi
  447. - name: Deploy to GitHub Releases
  448. run: |
  449. # We need to get the release id (yeah, it's not the same as the tag)
  450. echo "${GITHUB_EVENT_PATH}"
  451. cat ${GITHUB_EVENT_PATH}
  452. releaseId=$(jq --raw-output '.release.id' ${GITHUB_EVENT_PATH})
  453. # Now that we have the id, we just upload the release zip from before
  454. echo "Upload to release $releaseId"
  455. filename="$(ls dist/release/*.zip)"
  456. url="https://uploads.github.com/repos/${GITHUB_REPOSITORY}/releases/$releaseId/assets?name=$(basename $filename)"
  457. echo "Upload to $url"
  458. curl -L \
  459. -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
  460. -H "Content-Type: application/zip" \
  461. --data-binary @"$filename" \
  462. "$url"
  463. - name: Deploy to github package registry
  464. run: |
  465. source .github/actions/tools/uploadToMaven.sh
  466. registry="https://maven.pkg.github.com/$GITHUB_REPOSITORY"
  467. echo "Deploy to github package registry $registry"
  468. uploadAllToMaven dist/maven/ $registry "token" ${{ secrets.GITHUB_TOKEN }}
  469. # Deploy the javadoc
  470. DeployJavaDoc:
  471. needs: [BuildJMonkey]
  472. name: Deploy Javadoc
  473. runs-on: ubuntu-latest
  474. if: github.event_name == 'release'
  475. steps:
  476. # We are going to need a deploy key for this, since we need
  477. # to push to a different repo
  478. - name: Set ssh key
  479. run: |
  480. mkdir -p ~/.ssh/
  481. echo "${{ secrets.JAVADOC_GHPAGES_DEPLOY_PRIVKEY }}" > $HOME/.ssh/deploy.key
  482. chmod 600 $HOME/.ssh/deploy.key
  483. # We clone the javadoc repo
  484. - name: Clone gh-pages
  485. run: |
  486. branch="gh-pages"
  487. export GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $HOME/.ssh/deploy.key"
  488. git clone --single-branch --branch "$branch" [email protected]:${{ secrets.JAVADOC_GHPAGES_REPO }} .
  489. # Download the javadoc in the new directory "newdoc"
  490. - name: Download javadoc
  491. uses: actions/download-artifact@master
  492. with:
  493. name: javadoc
  494. path: newdoc
  495. # The actual deploy
  496. - name: Deploy to github pages
  497. run: |
  498. set -f
  499. IFS=$'\n'
  500. # Get the tag for this release
  501. version="`if [[ $GITHUB_REF == refs\/tags* ]]; then echo ${GITHUB_REF//refs\/tags\//}; fi`"
  502. # If there is no tag, then we do nothing.
  503. if [ "$version" != "" ];
  504. then
  505. echo "Deploy as $version"
  506. # Remove any older version of the javadoc for this tag
  507. if [ -d "$version" ];then rm -Rf "$version"; fi
  508. # Rename newdoc with the version name
  509. mv newdoc "$version"
  510. # if there isn't an index.txt we create one (we need this to list the versions)
  511. if [ ! -f "index.txt" ]; then echo "" > index.txt ; fi
  512. index="`cat index.txt`"
  513. # Check if this version is already in index.txt
  514. addNew=true
  515. for v in $index;
  516. do
  517. if [ "$v" = "$version" ];
  518. then
  519. echo "$v" "$version"
  520. addNew=false
  521. break
  522. fi
  523. done
  524. # If not, we add it to the beginning
  525. if [ "$addNew" = "true" ];
  526. then
  527. echo -e "$version\n$index" > index.txt
  528. index="`cat index.txt`"
  529. fi
  530. # Regenerate the pages
  531. chmod +x make.sh
  532. ./make.sh
  533. # Configure git to use the deploy key
  534. export GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $HOME/.ssh/deploy.key"
  535. # Commit the changes
  536. git config --global user.name "Github Actions"
  537. git config --global user.email "[email protected]"
  538. git add . || true
  539. git commit -m "$version" || true
  540. branch="gh-pages"
  541. git push origin "$branch" --force || true
  542. fi