Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions .github/workflows/native-image-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,33 @@ on:
- main

jobs:
setup:
runs-on: ubuntu-latest

outputs:
tests: ${{ steps.set-tests.outputs.tests }}

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup
uses: ./.github/workflows/shared-setup

- id: set-tests
name: Set test var for matrix
# run ci_native_tests.clj directly instead of via bb task to avoid generic task output
run: echo "tests=$(bb script/ci_native_tests.clj matrix-for-ci --format=json)" >> $GITHUB_OUTPUT

build:
needs: setup
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [ windows, ubuntu, macos ]
java-version: [ '25.0.2' ]
test: [ native, native-sci ]
clojure-version: [ '1.12' ]
include: ${{ fromJSON(needs.setup.outputs.tests) }}

name: ${{ matrix.os }},jdk${{ matrix.java-version }},${{ matrix.test }},clj${{ matrix.clojure-version }}
name: ${{ matrix.desc }}

steps:
#
Expand Down Expand Up @@ -49,5 +65,5 @@ jobs:
#
# native image tests
#
- name: Execute test-${{ matrix.test }}
run: bb test-${{ matrix.test }} --clojure-version ${{ matrix.clojure-version }}
- name: Run Tests
run: ${{ matrix.cmd }}
2 changes: 1 addition & 1 deletion .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:

- id: set-tests
name: Set test var for matrix
# run test.clj directly instead of via bb task to avoid generic task output
# run ci-unit_tests.clj directly instead of via bb task to avoid generic task output
run: echo "tests=$(bb script/ci_unit_tests.clj matrix-for-ci --format=json)" >> $GITHUB_OUTPUT

build:
Expand Down
4 changes: 3 additions & 1 deletion bb.edn
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
lread/status-line {:git/url "https://github.com/lread/status-line.git"
:sha "eace48e2e0fcc65a3986d696fb0b910fa5790a1c"}
etaoin/etaoin {:mvn/version "1.1.43"}
wevre/natural-compare {:mvn/version "0.0.10"}
io.github.babashka/neil {:git/tag "v0.3.69", :git/sha "fa79321"}}
:tasks {;; setup
:requires ([clojure.string :as string]
Expand All @@ -23,7 +24,7 @@
lint {:task lint/-main :doc "[--rebuild] lint source code using clj-kondo, eastwood"}
-lint-kondo {:task lint-kondo/-main :doc "[--rebuild]"}
-lint-eastwood {:task lint-eastwood/-main}
test-clj {:task test-clj/-main :doc "[--clojure-version (1.8|1.9|1.10|1.11|1.12)]"}
test-clj {:task test-clj/-main :doc "use --help for args"}
test-cljs {:task test-cljs/-main :doc "use --help for args"}
test-shadow-cljs {:task test-shadow-cljs/-main}
test-native {:task test-native/-main :doc "run rewrite-clj and tests after both compiled with GraalVM native-image"}
Expand All @@ -37,6 +38,7 @@
outdated {:task outdated/-main :doc "report on outdated Clojure and npm dependencies"}
doc-update-readme {:task doc-update-readme/-main :doc "honour our contributors in README"}
cljdoc-preview {:task cljdoc-preview/-main :doc "preview what docs will look like on cljdoc, use --help for args"}
ci-native-tests {:task ci-native-tests/-main :doc "matrix-for-ci - list native integration tests"}
ci-unit-tests {:task ci-unit-tests/-main :doc "run/list continuous integration unit tests, use --help for args"}
pubcheck {:task publish/pubcheck :doc "Run only publish checks (without publishing)"}
publish {:task publish/-main :doc "Publish a release (for maintainers)"}
Expand Down
19 changes: 12 additions & 7 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@
:github-coords clj-commons/rewrite-clj}}

;;
;; Clojure versions we support
;;
:1.8 {:override-deps {org.clojure/clojure {:mvn/version "1.8.0"}}}
:1.9 {:override-deps {org.clojure/clojure {:mvn/version "1.9.0"}}}
:1.10 {:override-deps {org.clojure/clojure {:mvn/version "1.10.3"}}}
:1.11 {:override-deps {org.clojure/clojure {:mvn/version "1.11.4"}}}
:1.12 {:override-deps {org.clojure/clojure {:mvn/version "1.12.4"}}}
;; Clojure versions we support (discovered by scripts by their clojure- prefix)
;; unit tests target all versions
;; native tests will target current prod (last non-pre by natural sort) and pre (if any)
;; See script/helper/clojure_versions.clj
;;
:clojure-1.8 {:override-deps {org.clojure/clojure {:mvn/version "1.8.0"}}}
:clojure-1.9 {:override-deps {org.clojure/clojure {:mvn/version "1.9.0"}}}
:clojure-1.10 {:override-deps {org.clojure/clojure {:mvn/version "1.10.3"}}}
:clojure-1.11 {:override-deps {org.clojure/clojure {:mvn/version "1.11.4"}}}
:clojure-1.12 {:override-deps {org.clojure/clojure {:mvn/version "1.12.4"}}}
;; Candidate release is :clojure-pre-* (ex. clojure-candidate-1.12.5-alpha1) (if any)
:clojure-pre-1.12.5-alpha1 {:override-deps {org.clojure/clojure {:mvn/version "1.12.5-alpha1"}}}

;;
;; ClojureScript version we test with (and support)
Expand Down
12 changes: 10 additions & 2 deletions doc/02-developer-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@ We made use of planck for cljs bootstrap (aka cljs self-hosted) testing on macOS
But... planck is not currently maintained, it uses an older version of CloureScript and it can be difficult to get a binary for current OSes, so we've disabled these tests for now.
See: https://github.com/clj-commons/rewrite-clj/issues/420

We test that rewrite-clj operates as expected when natively compile via GraalVM.
Automated testing is setup using GraalVM for JDK 25.
Scripts run on GitHub Actions automatically discover what versions of Clojure to test via auto-discovery of `:clojure-*` aliases in `deps.edn`. Unit tests will cover all versions. Native image tests cover the current production release and `:clojure-pre-*` releases (if any).

JVM tests cover supported LTS JDKs and the current latest JDK.
For GraalVM native image tests, we cover and support only the current latest GraalVM version.
At this time we only test against the Community Edition.

GitHub Actions test matrixes are fed from:

* `bb ci-unit-tests matrix-for-ci` - unit tests
* `bb ci-native-tests matrix-for-ci` - native image tests
* `bb test-libs list --format=table` - lib tests

== Prerequisites
* Java JDK 1.8 or above (shadow-cljs tests require min of JDK 11)
* NodeJs v12 or above
Expand Down
42 changes: 42 additions & 0 deletions script/ci_native_tests.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
(ns ci-native-tests
(:require [cheshire.core :as json]
[doric.core :as doric]
[helper.clojure-versions :as clojure-versions]
[helper.main :as main]
[lread.status-line :as status]))

(def java-versions ["25.0.2"])
(def oses ["ubuntu" "macos" "windows"])

(defn- ci-test-matrix []
(for [os oses
java-version java-versions
test-task ["test-native" "test-native-sci"]
clj-version (mapv :version (clojure-versions/for-native))]
{:desc (str os ",jdk" java-version "," test-task ",clj" clj-version)
:cmd (str "bb " test-task " --clojure-version " clj-version)
:os os
:java-version java-version}))

(def args-usage "Valid args:
matrix-for-ci [--format=json]
--help

Commands:
matrix-for-ci Return a matrix for use within GitHub Actions workflow

Options:
--help Show this help")

(defn -main [& args]
(when-let [opts (main/doc-arg-opt args-usage args)]
(let [matrix (ci-test-matrix)]
(if (= "json" (get opts "--format"))
(status/line :detail (json/generate-string matrix))
(do
(status/line :detail (doric/table [:os :java-version :desc :cmd] matrix))
(status/line :detail "Total jobs found: %d" (count matrix))))))
nil)

(main/when-invoked-as-script
(apply -main *command-line-args*))
3 changes: 2 additions & 1 deletion script/dev_repl.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
(:require [babashka.cli :as cli]
[babashka.process :as process]
[clojure.string :as str]
[helper.clojure-versions :as clojure-versions]
[lread.status-line :as status]))

(def cli-spec {:help {:desc "This usage help"}
Expand Down Expand Up @@ -55,7 +56,7 @@
(status/line :head "Launching Clojure %s nREPL" (name flavor))
(when flowstorm
(status/line :detail "Flowstorm support is enabled"))
(process/exec "clj" (str "-M:1.12:test-common:nrepl:" (str/join ":" aliases))
(process/exec "clj" (str "-M:" (:alias (clojure-versions/current-prod)) ":test-common:nrepl:" (str/join ":" aliases))
"-h" host
"-b" bind
"-p" port)))))
Expand Down
36 changes: 36 additions & 0 deletions script/helper/clojure_versions.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
(ns helper.clojure-versions
(:require [clojure.edn :as edn]
[wevre.natural-compare :as natural-compare]))

(defn all
"Returns vector of maps with :version :alias :pre-release?"
[]
(->> (slurp "deps.edn")
edn/read-string
:aliases
keys
(keep (fn [k]
(when-let [[_ prefix version] (re-find #"(clojure-pre-|clojure-)(.*)" (name k))]
{:version version
:alias k
:pre-release? (= "clojure-pre-" prefix)})))
(sort-by :version natural-compare/natural-compare)
(into [])))

(defn current-prod
"Returns current production release"
[]
(->> (all)
(remove :pre-release?)
last))

(defn for-native
"Returns clojure versions for native image testing"
[]
(into [(current-prod)] (filter :pre-release? (all))))

(defn lookup
"Retunrs :version :alias :pre-release? map for `version`"
[version]
(or (some #(when (= version (:version %)) %) (all))
(throw (ex-info (str "Clojure version not found: " version) {}))))
43 changes: 23 additions & 20 deletions script/test_clj.clj
Original file line number Diff line number Diff line change
@@ -1,45 +1,48 @@
#!/usr/bin/env bb

(ns test-clj
(:require [helper.main :as main]
(:require [clojure.string :as str]
[helper.clojure-versions :as clojure-versions]
[helper.main :as main]
[helper.shell :as shell]
[lread.status-line :as status]))

(def allowed-clojure-versions '("1.8" "1.9" "1.10" "1.11" "1.12"))

(defn run-unit-tests [clojure-version]
(status/line :head (str "testing clojure source against clojure v" clojure-version))
(if (= "1.8" clojure-version)
(defn run-unit-tests [{:keys [version alias] :as _clojure-version}]
(status/line :head (str "testing clojure source against clojure v" version))
(if (= "1.8" version)
(shell/command "clojure"
(str "-M:test-common:clj-test-runner:" clojure-version))
(str "-M:test-common:clj-test-runner:" alias))
(shell/command "clojure"
(str "-M:test-common:kaocha:" clojure-version)
(str "-M:test-common:kaocha:" alias)
"--reporter" "documentation")))

(defn run-isolated-tests[clojure-version]
(status/line :head (str "running isolated tests against clojure v" clojure-version))
(if (= "1.8" clojure-version)
(shell/command "clojure" (str "-M:clj-test-runner:test-isolated:" clojure-version)
(defn run-isolated-tests[{:keys [version alias] :as _clojure-version}]
(status/line :head (str "running isolated tests against clojure v" version))
(if (= "1.8" version)
(shell/command "clojure" (str "-M:clj-test-runner:test-isolated:" alias)
"--dir" "test-isolated")
(shell/command "clojure" (str "-M:kaocha:" clojure-version)
(shell/command "clojure" (str "-M:kaocha:" alias)
"--profile" "test-isolated"
"--reporter" "documentation")))

(def args-usage "Valid args: [options]
(def cli-clojure-versions (conj (mapv :version (clojure-versions/all)) "all"))

(def args-usage (format "Valid args: [options]

Options:
-v, --clojure-version VERSION Test with Clojure [1.8, 1.9, 1.10, 1.11, 1.12 all] [default: 1.8]
--help Show this help")
-v, --clojure-version VERSION Test with Clojure [%s] [default: %s]
--help Show this help"
(str/join ", " cli-clojure-versions)
(first cli-clojure-versions)))

(defn -main [& args]
(when-let [opts (main/doc-arg-opt args-usage args)]
(let [clojure-version (get opts "--clojure-version")]

(if (not (some #{clojure-version} (conj allowed-clojure-versions "all")))
(if (not (some #{clojure-version} cli-clojure-versions))
(status/die 1 args-usage)
(let [clojure-versions (if (= "all" clojure-version)
allowed-clojure-versions
[clojure-version])]
(clojure-versions/all)
[(clojure-versions/lookup clojure-version)])]
(doseq [v clojure-versions]
(run-unit-tests v)
(run-isolated-tests v))))))
Expand Down
25 changes: 13 additions & 12 deletions script/test_jvm_sci.clj
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
#!/usr/bin/env bb

(ns test-jvm-sci
(:require [helper.main :as main]
(:require [clojure.string :as str]
[helper.clojure-versions :as clojure-versions]
[helper.main :as main]
[helper.shell :as shell]
[lread.status-line :as status]))

(def allowed-clojure-versions '("1.11" "1.12"))
(def cli-clojure-versions (mapv :version (clojure-versions/for-native)))

(def args-usage "Valid args: [options]
(def args-usage (format "Valid args: [options]

Options:
-v, --clojure-version VERSION Test with Clojure [1.11, 1.12] [default: 1.12]
--help Show this help")

-v, --clojure-version VERSION Test with Clojure [%s] [default: %s]
--help Show this help"
(str/join ", " cli-clojure-versions)
(first cli-clojure-versions)))

(defn validate-opts [opts]
(when (not (some #{(get opts "--clojure-version")} allowed-clojure-versions))
(when (not (some #{(get opts "--clojure-version")} cli-clojure-versions))
(status/die 1 args-usage)))


(defn -main [& args]
(when-let [opts (main/doc-arg-opt args-usage args)]
(validate-opts opts)
(let [clojure-version (get opts "--clojure-version")]

(let [clojure-version (clojure-versions/lookup (get opts "--clojure-version"))]
(status/line :head "Exposing rewrite-clj API to sci")
(shell/command "clojure -M:script -m sci-test-gen-publics")

(status/line :head "Interpreting tests with sci from using JVM using Clojure %s" clojure-version)
(status/line :head "Interpreting tests with sci from using JVM using Clojure %s" (:version clojure-version))
(shell/command (format "clojure -M:sci-test:%s -m sci-test.main --file script/sci_test_runner.clj --classpath test"
clojure-version))))
(:alias clojure-version)))))
nil)

(main/when-invoked-as-script
Expand Down
19 changes: 11 additions & 8 deletions script/test_native.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
(ns test-native
(:require [babashka.fs :as fs]
[clojure.java.io :as io]
[clojure.string :as str]
[helper.clojure-versions :as clojure-versions]
[helper.graal :as graal]
[helper.main :as main]
[helper.os :as os]
Expand All @@ -17,24 +19,25 @@
"-m" "clj-graal.gen-test-runner"
"--dest-dir" dir "test-by-namespace"))

(def allowed-clojure-versions '("1.10" "1.11" "1.12"))
(def cli-clojure-versions (mapv :version (clojure-versions/for-native)))

(def args-usage "Valid args: [options]
(def args-usage (format "Valid args: [options]

Options:
-v, --clojure-version VERSION Test with Clojure [1.10, 1.11, 1.12] [default: 1.12]
--help Show this help")

-v, --clojure-version VERSION Test with Clojure [%s] [default: %s]
--help Show this help"
(str/join ", " cli-clojure-versions)
(first cli-clojure-versions)))

(defn validate-opts [opts]
(when (not (some #{(get opts "--clojure-version")} allowed-clojure-versions))
(when (not (some #{(get opts "--clojure-version")} cli-clojure-versions))
(status/die 1 args-usage)))

(defn -main [& args]
(when-let [opts (main/doc-arg-opt args-usage args)]
(validate-opts opts)
(graal/assert-min-version)
(let [clojure-version (get opts "--clojure-version")
(let [clojure-version (clojure-versions/lookup (get opts "--clojure-version"))
native-image-xmx "6g"
target-path "target"
target-exe "rewrite-clj-test"
Expand All @@ -47,7 +50,7 @@ Options:
test-runner-dir "target/generated/graal"]
(graal/clean)
(generate-test-runner test-runner-dir)
(let [classpath (graal/compute-classpath (str "test-common:graal:native-test:" clojure-version))]
(let [classpath (graal/compute-classpath (str "test-common:graal:native-test:" (:alias clojure-version)))]
(graal/aot-compile-sources classpath "clj-graal.test-runner")
(graal/run-native-image {:graal-native-image graal-native-image
:target-path target-path
Expand Down
Loading