Skip to content

ci: set SNAPSHOT_SUFFIX when not on main branch #39

ci: set SNAPSHOT_SUFFIX when not on main branch

ci: set SNAPSHOT_SUFFIX when not on main branch #39

Workflow file for this run

name: 'CI/CD'
on:
pull_request:
push:
branches:
- canary
- main
# GitHub hosted runners are available for Linux x64, Windows x64, and macOS (x64 and arm).
# https://docs.github.com/en/actions/using-github-hosted-runners/using-larger-runners/about-larger-runners#runner-images
# https://github.com/actions/runner-images
# There are other providers that offer ARM runners for Linux (e.g. WarpBuild).
# https://github.com/neysofu/awesome-github-actions-runners#list-of-providers
env:
GRAALVM_VERSION: 23.0.0
HEAP_SIZE_AT_BUILD_TIME: '-R:MaxHeapSize=1024m'
JAVA_VERSION: 21
OPTIMIZATION_LEVEL: '-O2'
POD_ID: pod.jackdbd.jsoup
POD_NAME: pod-jackdbd-jsoup
jobs:
build-uberjar:
name: Build uberjar
runs-on: ubuntu-latest
# strategy:
# matrix:
# os: [ubuntu-latest, macOS-latest, windows-latest]
# runs-on: ${{ matrix.os }}
outputs:
pod_version: ${{ steps.set_pod_version.outputs.pod_version }}
snapshot_suffix: ${{ steps.set_snapshot_suffix.outputs.snapshot_suffix }}
steps:
- name: 🛎️ Checkout
uses: actions/checkout@v4
- name: Set SNAPSHOT_SUFFIX (environment variable) and snapshot_suffix (job output)
id: set_snapshot_suffix
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables
run: |
if [ "${{ github.ref }}" != "refs/heads/main" ]; then
echo "SNAPSHOT_SUFFIX=${GITHUB_SHA}" >> $GITHUB_ENV
else
echo "SNAPSHOT_SUFFIX=" >> $GITHUB_ENV
fi
echo "snapshot_suffix=$SNAPSHOT_SUFFIX" >> $GITHUB_OUTPUT
echo "SNAPSHOT_SUFFIX is ${{ env.SNAPSHOT_SUFFIX }}"
# https://github.com/marketplace/actions/github-action-for-graalvm
- name: 🔧 Setup GraalVM
uses: graalvm/setup-graalvm@v1
with:
check-for-updates: true
distribution: graalvm-community
java-version: ${{ env.JAVA_VERSION }}
version: ${{ env.GRAALVM_VERSION }}
# It's important to install java before installing clojure tools, because
# clojure tools needs java exclusions: babashka, clj-kondo and cljstyle.
# https://github.com/marketplace/actions/setup-clojure
- name: 🔧 Setup Clojure tools
uses: DeLaGuardo/setup-clojure@12.5
with:
cli: 'latest' # Clojure CLI based on tools.deps
bb: 'latest' # Babashka
# https://github.com/actions/cache
- name: Cache clojure dependencies
uses: actions/cache@v4
with:
path: |
~/.m2/repository
~/.gitlibs
~/.deps.clj
# List all files containing dependencies:
# key: cljdeps-${{ hashFiles('deps.edn') }}
key: cljdeps-${{ hashFiles('deps.edn', 'bb.edn') }}
restore-keys: cljdeps-
# Example of an uberjar of a standard release:
# pod.jackdbd.jsoup-0.1.2-standalone.jar
# Example of an uberjar of a snapshot release:
# pod.jackdbd.jsoup-0.1.2-345-SNAPSHOT-standalone.jar
- name: Set POD_VERSION (environment variable) and pod_version (job output)
id: set_pod_version
run: |
PROJECT_VERSION=$(bb -e '(-> (slurp "deps.edn") edn/read-string :aliases :neil :project :version)' | tr -d '"')
if [ -z "${SNAPSHOT_SUFFIX}" ]; then
POD_VERSION=$PROJECT_VERSION
else
POD_VERSION="${PROJECT_VERSION}-${SNAPSHOT_SUFFIX}"
fi
echo "POD_VERSION=$POD_VERSION" >> $GITHUB_ENV
echo "pod_version=$POD_VERSION" >> $GITHUB_OUTPUT
echo "POD_VERSION is ${{ env.POD_VERSION }}"
- name: 📦 Compile pod into an uberjar
run: |
if [ -n "${SNAPSHOT_SUFFIX}" ]; then
clojure -T:build uber :snapshot-suffix ${{ env.SNAPSHOT_SUFFIX }}
else
clojure -T:build uber
fi
- name: ⬆️ Upload uberjar
uses: actions/upload-artifact@v4
with:
name: uberjar
path: target/${{ env.POD_ID }}-${{ env.POD_VERSION }}-standalone.jar
linux:
name: Compile ubuntu-latest-x86_64-binary, Test
runs-on: ubuntu-latest
needs: [build-uberjar]
env:
POD_VERSION: ${{ needs.build-uberjar.outputs.pod_version }}
SNAPSHOT_SUFFIX: ${{ needs.build-uberjar.outputs.snapshot_suffix }}
steps:
- name: 🛎️ Checkout
uses: actions/checkout@v4
# https://github.com/marketplace/actions/github-action-for-graalvm
- name: 🔧 Setup GraalVM
uses: graalvm/setup-graalvm@v1
with:
check-for-updates: true
distribution: graalvm-community
java-version: ${{ env.JAVA_VERSION }}
native-image-job-reports: true
native-image-musl: true # Use musl to build a statically compiled binary (Linux only)
native-image-pr-reports: true
version: ${{ env.GRAALVM_VERSION }}
# It's important to install java before installing clojure tools, because
# clojure tools needs java exclusions: babashka, clj-kondo and cljstyle.
# https://github.com/marketplace/actions/setup-clojure
- name: 🔧 Setup Clojure tools
uses: DeLaGuardo/setup-clojure@12.5
with:
cli: 'latest' # Clojure CLI based on tools.deps
bb: 'latest' # Babashka
- name: Cache clojure dependencies
uses: actions/cache@v4
with:
path: |
~/.m2/repository
~/.gitlibs
~/.deps.clj
# List all files containing dependencies:
# key: cljdeps-${{ hashFiles('deps.edn') }}
key: cljdeps-${{ hashFiles('deps.edn', 'bb.edn') }}
restore-keys: cljdeps-
# This takes ~7 minutes both on my laptop and on GitHub Actions. Maybe look for an alternative.
# - name: 🛡️ Audit deps.edn dependencies
# run: clojure -M:clj-nvd check
- name: ⬇️ Download uberjar
uses: actions/download-artifact@v4
with:
name: uberjar
- name: 📦 Compile uberjar to x86_64-linux binary with GraalVM native-image
run: ./script/compile.sh
env:
BABASHKA_STATIC: true
BABASHKA_MUSL: true
# The tests expect the uberjar and the binary to be in a directory called "target"
- name: Copy the uberjar and the binary to the target directory
run: |
mkdir target
cp ${{ env.POD_ID }}-${{ env.POD_VERSION }}-standalone.jar target/${{ env.POD_ID }}-${{ env.POD_VERSION }}-standalone.jar
cp ${{ env.POD_ID }}-${{ env.POD_VERSION }}-standalone target/${{ env.POD_NAME }}
- name: ⬆️ Upload the x86_64 Linux binary
uses: actions/upload-artifact@v4
with:
name: ubuntu-latest-x86_64-binary
path: target/${{ env.POD_NAME }}
- name: 🔍 Run all tests
run: clojure -X:test
macos:
name: Compile macos-latest-aarch64-binary, Test
runs-on: macOS-latest
needs: [build-uberjar]
env:
POD_VERSION: ${{ needs.build-uberjar.outputs.pod_version }}
steps:
- name: 🛎️ Checkout
uses: actions/checkout@v4
- name: 🔧 Setup GraalVM
uses: graalvm/setup-graalvm@v1
with:
check-for-updates: true
distribution: graalvm-community
java-version: ${{ env.JAVA_VERSION }}
native-image-job-reports: true
native-image-pr-reports: true
version: ${{ env.GRAALVM_VERSION }}
- name: 🔧 Setup Clojure tools
uses: DeLaGuardo/setup-clojure@12.5
with:
cli: 'latest'
- name: Cache clojure dependencies
uses: actions/cache@v4
with:
path: |
~/.m2/repository
~/.gitlibs
~/.deps.clj
key: cljdeps-${{ hashFiles('deps.edn', 'bb.edn') }}
restore-keys: cljdeps-
- name: ⬇️ Download uberjar
uses: actions/download-artifact@v4
with:
name: uberjar
- name: 📦 Compile uberjar to AArch64-macOS binary with GraalVM native-image
# I tried setting -march=x86_64 and the GitHub hosted runner macos-latest
# gave me this error:
# On AArch64, only 'ARMV8_A', 'ARMV8_1_A', 'COMPATIBILITY', 'NATIVE' are available.
run: |
native-image \
-jar ${{ env.POD_ID }}-${{ env.POD_VERSION }}-standalone.jar \
'-H:ReflectionConfigurationFiles=reflection.json' \
'-H:+ReportExceptionStackTraces' \
'-J-Dclojure.compiler.direct-linking=true' \
${{ env.HEAP_SIZE_AT_BUILD_TIME }} \
${{ env.OPTIMIZATION_LEVEL }} \
'-march=armv8-a' \
'--initialize-at-build-time' \
'--native-image-info' \
'--no-fallback' \
'--report-unsupported-elements-at-runtime'
# The tests expect the uberjar and the binary to be in a directory called "target"
- name: Copy the uberjar and the binary to the target directory
run: |
mkdir target
cp ${{ env.POD_ID }}-${{ env.POD_VERSION }}-standalone.jar target/${{ env.POD_ID }}-${{ env.POD_VERSION }}-standalone.jar
cp ${{ env.POD_ID }}-${{ env.POD_VERSION }}-standalone target/${{ env.POD_NAME }}
- name: ⬆️ Upload the aarch64 macOS binary
uses: actions/upload-artifact@v4
with:
name: macos-latest-aarch64-binary
path: target/${{ env.POD_NAME }}
- name: 🔍 Run all tests
run: clojure -X:test
windows:
name: Compile windows-latest-x86_64-binary, Test
runs-on: windows-latest
needs: [build-uberjar]
env:
POD_VERSION: ${{ needs.build-uberjar.outputs.pod_version }}
steps:
- name: 🛎️ Checkout
uses: actions/checkout@v4
- name: 🔧 Setup GraalVM
uses: graalvm/setup-graalvm@v1
with:
check-for-updates: true
distribution: graalvm-community
java-version: ${{ env.JAVA_VERSION }}
native-image-job-reports: true
native-image-pr-reports: true
version: ${{ env.GRAALVM_VERSION }}
- name: 🔧 Setup Clojure tools
uses: DeLaGuardo/setup-clojure@12.5
with:
cli: 'latest'
- name: Cache clojure dependencies
uses: actions/cache@v4
with:
path: |
~/.m2/repository
~/.gitlibs
~/.deps.clj
key: cljdeps-${{ hashFiles('deps.edn', 'bb.edn') }}
restore-keys: cljdeps-
- name: ⬇️ Download uberjar
uses: actions/download-artifact@v4
with:
name: uberjar
# See: https://github.com/babashka/pod-babashka-buddy/blob/main/script/compile.bat
- name: 📦 Compile uberjar to x86_64-windows binary with GraalVM native-image
run: >
native-image
-jar ${{ env.POD_ID }}-${{ env.POD_VERSION }}-standalone.jar
'-H:ReflectionConfigurationFiles=reflection.json'
'-H:+ReportExceptionStackTraces'
'-J-Dclojure.compiler.direct-linking=true'
${{ env.HEAP_SIZE_AT_BUILD_TIME }}
${{ env.OPTIMIZATION_LEVEL }}
'-march=x86-64-v3'
'--initialize-at-build-time'
'--native-image-info'
'--no-fallback'
'--report-unsupported-elements-at-runtime'
- name: Copy the uberjar and the binary to the target directory
run: |
mkdir target
move ${{ env.POD_ID }}-${{ env.POD_VERSION }}-standalone.jar target\\${{ env.POD_ID }}-${{ env.POD_VERSION }}-standalone.jar
move "${{ env.POD_ID }}-${{ env.POD_VERSION }}-standalone.exe" ".\\target\\${{ env.POD_NAME }}.exe"
shell: cmd
- name: ⬆️ Upload the x86_64 Windows binary
uses: actions/upload-artifact@v4
with:
name: windows-latest-x86_64-binary
path: ".\\target\\${{ env.POD_NAME }}.exe"
- name: 🔍 Run all tests
run: clojure -X:test
release:
name: Release
if: ${{ github.event_name != 'pull_request' }}
needs: [build-uberjar, linux, macos, windows]
concurrency: deploy-group # Ensures that only a single instance of this job is running at any given time.
runs-on: ubuntu-latest
env:
POD_VERSION: ${{ needs.build-uberjar.outputs.pod_version }}
permissions:
contents: write
steps:
- name: 🛎️ Checkout
uses: actions/checkout@v4
- name: 🔧 Setup Clojure tools
uses: DeLaGuardo/setup-clojure@12.5
with:
cli: 'latest'
bb: 'latest'
- name: 🌐 Publish to Clojars
env:
CLOJARS_USERNAME: jackdbd
CLOJARS_PASSWORD: ${{ secrets.CLOJARS_PASSWORD }}
run: |
if [ -n "${SNAPSHOT_SUFFIX}" ]; then
clojure -T:build uber :snapshot-suffix ${{ env.SNAPSHOT_SUFFIX }}
clojure -T:build deploy :snapshot-suffix ${{ env.SNAPSHOT_SUFFIX }}
else
clojure -T:build uber
clojure -T:build deploy
fi
- name: ⬇️ Download x86_64 Linux binary
uses: actions/download-artifact@v4
with:
name: ubuntu-latest-x86_64-binary
path: ubuntu-latest-x86_64
- name: ⬇️ Download aarch64 macOS binary
uses: actions/download-artifact@v4
with:
name: macos-latest-aarch64-binary
path: macos-latest-aarch64
- name: ⬇️ Download x86_64 Windows binary
uses: actions/download-artifact@v4
with:
name: windows-latest-x86_64-binary
path: windows-latest-x86_64
# Troubleshooting: let's see if we have actually downloaded everything
# - run: ls -R
- name: 📦 Create zip archives for all binaries compiled with GraalVM native-image
run: |
pushd . && cd ubuntu-latest-x86_64 && zip "${{ env.POD_NAME }}-${{ env.POD_VERSION }}-ubuntu-latest-x86_64.zip" "pod-jackdbd-jsoup" && popd
pushd . && cd macos-latest-aarch64 && zip "${{ env.POD_NAME }}-${{ env.POD_VERSION }}-macos-latest-aarch64.zip" "pod-jackdbd-jsoup" && popd
pushd . && cd windows-latest-x86_64 && zip "${{ env.POD_NAME }}-${{ env.POD_VERSION }}-windows-latest-x86_64.zip" "pod-jackdbd-jsoup.exe" && popd
mv ubuntu-latest-x86_64/${{ env.POD_NAME }}-${{ env.POD_VERSION }}-ubuntu-latest-x86_64.zip .
mv macos-latest-aarch64/${{ env.POD_NAME }}-${{ env.POD_VERSION }}-macos-latest-aarch64.zip .
mv windows-latest-x86_64/${{ env.POD_NAME }}-${{ env.POD_VERSION }}-windows-latest-x86_64.zip .
# Troubleshooting: let's see if we have actually created all zip archives and moved them to the correct place
- run: ls -R
# https://github.com/marketplace/actions/gh-release
# See also this workflow that uses the bruceadams/get-release action:
# https://github.com/juji-io/datalevin/blob/master/.github/workflows/release.binaries.yml
# https://github.com/bruceadams/get-release
- name: 🚀 Create GitHub release
uses: softprops/action-gh-release@v2
id: github_release
with:
body: |
This is a release of **${{ env.POD_NAME }}** version `${{ env.POD_VERSION }}`.
The pod is also [published as an uberjar to Clojars](https://clojars.org/com.github.jackdbd/pod.jackdbd.jsoup).
draft: true
fail_on_unmatched_files: true
files: |
${{ env.POD_NAME }}-${{ env.POD_VERSION }}-macos-latest-aarch64.zip
${{ env.POD_NAME }}-${{ env.POD_VERSION }}-ubuntu-latest-x86_64.zip
${{ env.POD_NAME }}-${{ env.POD_VERSION }}-windows-latest-x86_64.zip
generate_release_notes: false # TODO: decide whether to use this or not
name: v${{ env.POD_VERSION }}
prerelease: true # maybe if SNAPSHOT is true set this to true as well
tag_name: v${{ env.POD_VERSION }}
# ATTENTION: the order of `steps.github_release.outputs.assets` depends on the order of the `files` defined in the `github_release` step.
# https://github.com/marketplace/actions/gh-release#outputs
- name: 📄 Create manifest.edn for Babashka pod registry
run: |
RELEASE_URL=${{ steps.github_release.outputs.url }}
RELEASE_ID=${{ steps.github_release.outputs.id }}
UPLOAD_URL=${{ steps.github_release.outputs.upload_url }}
ASSETS=${{ steps.github_release.outputs.assets }}
MACOS_LATEST_AARCH64_ZIP_URL=${{ fromJSON(steps.github_release.outputs.assets)[0].browser_download_url }}
UBUNTU_LATEST_x86_64_ZIP_URL=${{ fromJSON(steps.github_release.outputs.assets)[1].browser_download_url }}
WINDOWS_LATEST_x86_64_ZIP_URL=${{ fromJSON(steps.github_release.outputs.assets)[2].browser_download_url }}
echo "RELEASE_URL is $RELEASE_URL"
echo "MACOS_LATEST_AARCH64_ZIP_URL is $MACOS_LATEST_AARCH64_ZIP_URL"
echo "UBUNTU_LATEST_x86_64_ZIP_URL is $UBUNTU_LATEST_x86_64_ZIP_URL"
echo "WINDOWS_LATEST_x86_64_ZIP_URL is $WINDOWS_LATEST_x86_64_ZIP_URL"
bb bb/manifest.bb --license MIT --pod-id com.github.jackdbd/pod.jackdbd.jsoup --version ${{ env.POD_VERSION }} --uberjar $UBERJAR_URL --linux-x86_64 $UBUNTU_LATEST_x86_64_ZIP_URL --macos-aarch64 $MACOS_LATEST_AARCH64_ZIP_URL --windows-x86_64 $WINDOWS_LATEST_x86_64_ZIP_URL
echo "Here is the manifest.edn generated"
cat manifest.edn
- name: ⬆️ Upload manifest.edn (TODO Download it and make a PR on Babashka pod registry?)
uses: actions/upload-artifact@v4
with:
name: manifest-edn
path: manifest.edn