main.yml 20 KB

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