main.yml 19 KB

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