main.yml 19 KB

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