From 8b9269037308da4f74307af48494b395ce31d481 Mon Sep 17 00:00:00 2001 From: Sam Waggoner Date: Tue, 27 May 2025 16:46:51 -0500 Subject: [PATCH 01/10] Improve release automation. Includes automation for synchronizing the project version and CTIM schema version. --- README.md | 5 +++++ project.clj | 10 ++++++++-- resources/config.edn | 1 + resources/version.edn | 1 + resources/version.txt | 1 + script/release.sh | 3 --- src/ctim/change_schema_version.clj | 5 +++++ src/ctim/schemas/common.cljc | 10 +++++++--- test/ctim/schemas/common_test.cljc | 23 ++++++++++++++++++++--- 9 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 resources/config.edn create mode 100644 resources/version.edn create mode 100644 resources/version.txt delete mode 100755 script/release.sh create mode 100644 src/ctim/change_schema_version.clj diff --git a/README.md b/README.md index 4e2eaa21..566324a8 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,11 @@ lein doc ## Releases ```clojure +# Minor version releases +# Expect this task to modify project files and deploy to Clojars. +# See `release-tasks` in project.clj for details. +lein release + # snapshot release lein deploy diff --git a/project.clj b/project.clj index 90a1734a..d86a678b 100644 --- a/project.clj +++ b/project.clj @@ -20,7 +20,7 @@ [kovacnica/clojure.network.ip "0.1.5"]] :uberjar-name "ctim.jar" - :resource-paths ["doc"] + :resource-paths ["doc" "resources"] :plugins [[lein-cljsbuild "1.1.7"] [com.google.guava/guava "20.0"] ;resolve internal conflict in `lein-doo` @@ -39,11 +39,13 @@ ;; please commit it and try again ["vcs" "assert-committed"] ["change" "version" "leiningen.release/bump-version" "release"] + ["sync-schema-version"] ;; will fail if project.clj doesn't already have -SNAPSHOT version ["vcs" "commit"] ["vcs" "tag" "--no-sign"] ["deploy" "clojars"] ["change" "version" "leiningen.release/bump-version"] + ["sync-shcmea-version"] ["vcs" "commit"] ;; fails if no upstream branch is defined ;; if it fails at this point you can complete the release using: @@ -52,7 +54,11 @@ :aliases {"doc" ^{:doc "Generate documentation"} ["run" "-m" "ctim.document"] "docs" ^{:doc "Generate documentation"} ["doc"] - "gen" ^{:doc "Generate an example"} ["run" "-m" "ctim.generate"]} + "gen" ^{:doc "Generate an example"} ["run" "-m" "ctim.generate"] + "sync-schema-version" ^{:doc "Updates the CTIM schema version to match the project version."} ["run" + "-m" + "ctim.change-schema-version" + :project/version]} :cljsbuild {:builds {:node {:source-paths ["src" "test"] :compiler {:output-to "target/tests.js" diff --git a/resources/config.edn b/resources/config.edn new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/config.edn @@ -0,0 +1 @@ + diff --git a/resources/version.edn b/resources/version.edn new file mode 100644 index 00000000..ca15edb3 --- /dev/null +++ b/resources/version.edn @@ -0,0 +1 @@ +"1.3.25-SNAPSHOT" \ No newline at end of file diff --git a/resources/version.txt b/resources/version.txt new file mode 100644 index 00000000..2bffbc56 --- /dev/null +++ b/resources/version.txt @@ -0,0 +1 @@ +1.3.25-SNAPSHOT diff --git a/script/release.sh b/script/release.sh deleted file mode 100755 index a1c085b5..00000000 --- a/script/release.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -set -xe -lein release :patch diff --git a/src/ctim/change_schema_version.clj b/src/ctim/change_schema_version.clj new file mode 100644 index 00000000..3a69bca3 --- /dev/null +++ b/src/ctim/change_schema_version.clj @@ -0,0 +1,5 @@ +(ns ctim.change-schema-version) + +(defn -main + [version] + (spit "./resources/version.edn" (pr-str version))) diff --git a/src/ctim/schemas/common.cljc b/src/ctim/schemas/common.cljc index 875c4eba..7ff10d16 100644 --- a/src/ctim/schemas/common.cljc +++ b/src/ctim/schemas/common.cljc @@ -1,7 +1,10 @@ (ns ctim.schemas.common (:refer-clojure :exclude [ref uri?]) (:require [clj-momo.lib.clj-time.coerce :refer [to-long]] + [clojure.edn :as edn] + [clojure.java.io :as io] [clojure.set :refer [map-invert]] + [clojure.string :as str] #?(:clj [clojure.spec.alpha :as cs] :cljs [cljs.spec.alpha :as cs]) [clojure.zip :as z] @@ -17,10 +20,11 @@ def-enum-type def-eq]]) [flanders.navigation :as fn] - [flanders.predicates :as fp] - [clojure.string :as str])) + [flanders.predicates :as fp])) -(def ctim-schema-version "1.3.30") +(def ctim-schema-version (-> (io/resource "version.edn") + slurp + edn/read-string)) (def-eq CTIMSchemaVersion ctim-schema-version) diff --git a/test/ctim/schemas/common_test.cljc b/test/ctim/schemas/common_test.cljc index da6be43f..b308da5f 100644 --- a/test/ctim/schemas/common_test.cljc +++ b/test/ctim/schemas/common_test.cljc @@ -1,8 +1,10 @@ (ns ctim.schemas.common-test (:refer-clojure :exclude [ref uri?]) - (:require [ctim.schemas.common :as sut] - [flanders.schema :as fs] - [clojure.test :refer [deftest is]])) + (:require + [clojure.java.io :as io] + [clojure.test :refer [deftest is testing]] + [ctim.schemas.common :as sut] + [flanders.schema :as fs])) (defn- ->swagger [dll] (:json-schema (meta (fs/->schema dll)))) @@ -10,3 +12,18 @@ (is (= {:example {:value "1.2.3.4", :type "ip"} :description "A simple, atomic value which has a consistent identity, and is stable enough to be attributed an intent or nature. This is the classic 'indicator' which might appear in a data feed of bad IPs, or bad Domains. These do not exist as objects within the CTIA storage model, so you never create an observable."} (->swagger sut/Observable)))) + +(defn lein-project-version + [] + (let [properties (with-open [pom-properties-reader (io/reader (io/resource "META-INF/maven/threatgrid/ctim/pom.properties"))] + (doto (java.util.Properties.) + (.load pom-properties-reader)))] + (if-let [ver (get properties "version")] + ver + (throw (ex-info "Unable to resolve ctim version" {}))))) + +(deftest version-test + (testing "The lein project version and ctim schema version are in sync." + (is (re-matches #"[\d]+\.[\d]+\.[\d]+.*?" sut/ctim-schema-version) + "Version follows the expected semantic versioning pattern.") + (is (= (lein-project-version) sut/ctim-schema-version)))) From 27530f893d526c4109c2363454e32f57cb3d3b47 Mon Sep 17 00:00:00 2001 From: Sam Waggoner Date: Wed, 28 May 2025 08:55:15 -0500 Subject: [PATCH 02/10] fixup: PR feedback --- {src => dev}/ctim/change_schema_version.clj | 2 +- project.clj | 5 +++-- resources/ctim/version.txt | 1 + resources/version.edn | 1 - src/ctim/schemas/common.cljc | 6 ++---- 5 files changed, 7 insertions(+), 8 deletions(-) rename {src => dev}/ctim/change_schema_version.clj (51%) create mode 100644 resources/ctim/version.txt delete mode 100644 resources/version.edn diff --git a/src/ctim/change_schema_version.clj b/dev/ctim/change_schema_version.clj similarity index 51% rename from src/ctim/change_schema_version.clj rename to dev/ctim/change_schema_version.clj index 3a69bca3..f03ce41f 100644 --- a/src/ctim/change_schema_version.clj +++ b/dev/ctim/change_schema_version.clj @@ -2,4 +2,4 @@ (defn -main [version] - (spit "./resources/version.edn" (pr-str version))) + (spit "./resources/version.txt" version)) diff --git a/project.clj b/project.clj index d86a678b..54b2cad8 100644 --- a/project.clj +++ b/project.clj @@ -45,7 +45,7 @@ ["vcs" "tag" "--no-sign"] ["deploy" "clojars"] ["change" "version" "leiningen.release/bump-version"] - ["sync-shcmea-version"] + ["sync-schema-version"] ["vcs" "commit"] ;; fails if no upstream branch is defined ;; if it fails at this point you can complete the release using: @@ -82,4 +82,5 @@ [com.google.errorprone/error_prone_annotations "2.1.3"] ;;https://clojure.atlassian.net/browse/CLJS-3047 [com.google.code.findbugs/jsr305 "3.0.2"] - [org.clojure/clojurescript "1.12.42"]]}}) + [org.clojure/clojurescript "1.12.42"]]} + :dev {:source-paths ["dev"]}}) diff --git a/resources/ctim/version.txt b/resources/ctim/version.txt new file mode 100644 index 00000000..3ef6f64f --- /dev/null +++ b/resources/ctim/version.txt @@ -0,0 +1 @@ +1.3.25-SNAPSHOT \ No newline at end of file diff --git a/resources/version.edn b/resources/version.edn deleted file mode 100644 index ca15edb3..00000000 --- a/resources/version.edn +++ /dev/null @@ -1 +0,0 @@ -"1.3.25-SNAPSHOT" \ No newline at end of file diff --git a/src/ctim/schemas/common.cljc b/src/ctim/schemas/common.cljc index 7ff10d16..0c52e6f9 100644 --- a/src/ctim/schemas/common.cljc +++ b/src/ctim/schemas/common.cljc @@ -22,14 +22,12 @@ [flanders.navigation :as fn] [flanders.predicates :as fp])) -(def ctim-schema-version (-> (io/resource "version.edn") - slurp - edn/read-string)) +(def ctim-schema-version (slurp (io/resource "version.txt"))) (def-eq CTIMSchemaVersion ctim-schema-version) (cs/def ::ctim-schema-version - #(re-matches #"\w+.\w+\.\w+" %)) + #(re-matches #"\w+.\w+\.\w+(-SNAPSHOT)?" %)) (def SchemaVersion (f/str From 6bff584304dae82b734fd6d828005dea7dff28e9 Mon Sep 17 00:00:00 2001 From: Sam Waggoner Date: Wed, 28 May 2025 09:10:59 -0500 Subject: [PATCH 03/10] Fixup. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 566324a8..de4c54b4 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ lein doc ## Releases ```clojure -# Minor version releases +# Patch version releases (minor and major increments require a manual edit of version). # Expect this task to modify project files and deploy to Clojars. # See `release-tasks` in project.clj for details. lein release From 3066eaa886db2e436190aec7b50fa0a2348600a8 Mon Sep 17 00:00:00 2001 From: Sam Waggoner Date: Wed, 28 May 2025 09:43:33 -0500 Subject: [PATCH 04/10] fixup --- src/ctim/schemas/common.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctim/schemas/common.cljc b/src/ctim/schemas/common.cljc index 0c52e6f9..7389c4d7 100644 --- a/src/ctim/schemas/common.cljc +++ b/src/ctim/schemas/common.cljc @@ -22,7 +22,7 @@ [flanders.navigation :as fn] [flanders.predicates :as fp])) -(def ctim-schema-version (slurp (io/resource "version.txt"))) +(def ctim-schema-version (slurp (io/resource "ctim/version.txt"))) (def-eq CTIMSchemaVersion ctim-schema-version) From ea1607b8b409fc34ab49ac025703313f11cede2f Mon Sep 17 00:00:00 2001 From: Sam Waggoner Date: Wed, 28 May 2025 11:18:17 -0500 Subject: [PATCH 05/10] fixup --- resources/config.edn | 1 - 1 file changed, 1 deletion(-) delete mode 100644 resources/config.edn diff --git a/resources/config.edn b/resources/config.edn deleted file mode 100644 index 8b137891..00000000 --- a/resources/config.edn +++ /dev/null @@ -1 +0,0 @@ - From 01c9c4c15f709f731088711377f1beb5c9ae238d Mon Sep 17 00:00:00 2001 From: Sam Waggoner Date: Wed, 28 May 2025 13:45:45 -0500 Subject: [PATCH 06/10] Remove gha workflow schedule. --- .github/workflows/build.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9308b7f2..0cd9f4a4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,9 +5,6 @@ on: branches: - master pull_request: - schedule: - # 12:00AM on the first of every month - - cron: "0 0 1 * *" jobs: setup: From 028c11eeba9587782940318b4a374eb54ba9fa5c Mon Sep 17 00:00:00 2001 From: Sam Waggoner Date: Wed, 28 May 2025 14:43:31 -0500 Subject: [PATCH 07/10] Make version from resource work for cljs. --- src/ctim/schemas/common.cljc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ctim/schemas/common.cljc b/src/ctim/schemas/common.cljc index 7389c4d7..c3e3d53b 100644 --- a/src/ctim/schemas/common.cljc +++ b/src/ctim/schemas/common.cljc @@ -1,8 +1,7 @@ (ns ctim.schemas.common (:refer-clojure :exclude [ref uri?]) (:require [clj-momo.lib.clj-time.coerce :refer [to-long]] - [clojure.edn :as edn] - [clojure.java.io :as io] + #?(:clj [clojure.java.io :as io]) [clojure.set :refer [map-invert]] [clojure.string :as str] #?(:clj [clojure.spec.alpha :as cs] @@ -22,7 +21,14 @@ [flanders.navigation :as fn] [flanders.predicates :as fp])) -(def ctim-schema-version (slurp (io/resource "ctim/version.txt"))) +;; Wrapping the JVM resource retrieval in a macro allows cljs forms to access +;; it at cljs compile time. +#?(:clj + (defmacro ctim-version + [] + (slurp (io/resource "ctim/version.txt")))) + +(def ctim-schema-version (ctim-version)) (def-eq CTIMSchemaVersion ctim-schema-version) From 84a901e2b29ecb4308a840b6727f40c7813601ce Mon Sep 17 00:00:00 2001 From: Sam Waggoner Date: Wed, 28 May 2025 21:00:12 -0500 Subject: [PATCH 08/10] Make ctim version retrieval work for cljs - take 2 --- src/ctim/schemas/common.cljc | 9 +++------ src/ctim/version.clj | 8 ++++++++ 2 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 src/ctim/version.clj diff --git a/src/ctim/schemas/common.cljc b/src/ctim/schemas/common.cljc index c3e3d53b..388b55ab 100644 --- a/src/ctim/schemas/common.cljc +++ b/src/ctim/schemas/common.cljc @@ -1,5 +1,7 @@ (ns ctim.schemas.common (:refer-clojure :exclude [ref uri?]) + #?(:cljs + (:require-macros [ctim.version :refer [ctim-version]])) (:require [clj-momo.lib.clj-time.coerce :refer [to-long]] #?(:clj [clojure.java.io :as io]) [clojure.set :refer [map-invert]] @@ -12,6 +14,7 @@ #?(:clj [ctim.lib.generators :as gen]) [ctim.lib.predicates :as pred] [ctim.schemas.vocabularies :as v] + #?(:clj [ctim.version :refer [ctim-version]]) #?(:clj [flanders.core :as f :refer [def-map-type def-enum-type def-eq]] @@ -21,12 +24,6 @@ [flanders.navigation :as fn] [flanders.predicates :as fp])) -;; Wrapping the JVM resource retrieval in a macro allows cljs forms to access -;; it at cljs compile time. -#?(:clj - (defmacro ctim-version - [] - (slurp (io/resource "ctim/version.txt")))) (def ctim-schema-version (ctim-version)) diff --git a/src/ctim/version.clj b/src/ctim/version.clj new file mode 100644 index 00000000..be7ac12d --- /dev/null +++ b/src/ctim/version.clj @@ -0,0 +1,8 @@ +(ns ctim.version + (:require [clojure.java.io :as io])) + +(defmacro ctim-version + "This is a macro to support cljs compile-time inlining of the version string + from the JVM resource." + [] + (slurp (io/resource "ctim/version.txt"))) From 6492bc115b7d2c50f3c794fcf9ea88fc6e518740 Mon Sep 17 00:00:00 2001 From: Sam Waggoner Date: Fri, 13 Mar 2026 14:04:15 -0500 Subject: [PATCH 09/10] Address PR review feedback - Simplify cljs macro require using reader conditional on :require/:require-macros - Remove unused clojure.java.io require - Consolidate "doc" alias to sync schema version and generate docs together - Restructure README release instructions for clarity Co-Authored-By: Claude Opus 4.6 --- README.md | 37 +++++++++++++++++++++++------------- project.clj | 4 ++-- src/ctim/schemas/common.cljc | 7 ++----- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index de4c54b4..88296971 100644 --- a/README.md +++ b/README.md @@ -29,29 +29,40 @@ lein doc ## Releases -```clojure -# Patch version releases (minor and major increments require a manual edit of version). -# Expect this task to modify project files and deploy to Clojars. -# See `release-tasks` in project.clj for details. -lein release +### Patch release -# snapshot release -lein deploy +Set the version in `project.clj` to `x.y.z-SNAPSHOT`, then run: -# for releases, set project.clj version to x.y.z-SNAPSHOT -# this command then releases as x.y.z and bumps to x.y.(z+1)-SNAPSHOT -# aliased as ./script/release.sh +```bash lein release :patch +``` + +This bumps to `x.y.z`, deploys to Clojars, then bumps to `x.y.(z+1)-SNAPSHOT`. +See `:release-tasks` in `project.clj` for the full sequence. + +For minor or major version bumps, manually edit the version in `project.clj` before running `lein release`. + +### Snapshot release + +```bash +lein deploy +``` + +### Recovery -# if release fails partway through, use these commands to recover +If a release fails partway through: + +```bash +# delete the tag if it was created git tag --delete x.y.z -# you might have a redundant commit "Version x.y.z", undo with: + +# reset to the commit before the failed release git reset --hard SHA_BEFORE_FAILED_RELEASE ``` ## License -Copyright © 2016-2024 Cisco Systems +Copyright © 2016-2026 Cisco Systems Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version. diff --git a/project.clj b/project.clj index 54b2cad8..039808a6 100644 --- a/project.clj +++ b/project.clj @@ -52,8 +52,8 @@ ;; git push --tags --set-upstream origin release-x.y.z ["vcs" "push"]] - :aliases {"doc" ^{:doc "Generate documentation"} ["run" "-m" "ctim.document"] - "docs" ^{:doc "Generate documentation"} ["doc"] + :aliases {"doc" ^{:doc "Sync schema version and generate documentation"} ["do" ["sync-schema-version"] ["run" "-m" "ctim.document"]] + "docs" ^{:doc "Sync schema version and generate documentation"} ["doc"] "gen" ^{:doc "Generate an example"} ["run" "-m" "ctim.generate"] "sync-schema-version" ^{:doc "Updates the CTIM schema version to match the project version."} ["run" "-m" diff --git a/src/ctim/schemas/common.cljc b/src/ctim/schemas/common.cljc index 388b55ab..3ce5669d 100644 --- a/src/ctim/schemas/common.cljc +++ b/src/ctim/schemas/common.cljc @@ -1,9 +1,6 @@ (ns ctim.schemas.common (:refer-clojure :exclude [ref uri?]) - #?(:cljs - (:require-macros [ctim.version :refer [ctim-version]])) (:require [clj-momo.lib.clj-time.coerce :refer [to-long]] - #?(:clj [clojure.java.io :as io]) [clojure.set :refer [map-invert]] [clojure.string :as str] #?(:clj [clojure.spec.alpha :as cs] @@ -14,7 +11,6 @@ #?(:clj [ctim.lib.generators :as gen]) [ctim.lib.predicates :as pred] [ctim.schemas.vocabularies :as v] - #?(:clj [ctim.version :refer [ctim-version]]) #?(:clj [flanders.core :as f :refer [def-map-type def-enum-type def-eq]] @@ -22,7 +18,8 @@ def-enum-type def-eq]]) [flanders.navigation :as fn] - [flanders.predicates :as fp])) + [flanders.predicates :as fp]) + (#?(:clj :require :cljs :require-macros) [ctim.version :refer [ctim-version]])) (def ctim-schema-version (ctim-version)) From b505a2b2a26e04840c5b2c8f51ffaf2144a467e6 Mon Sep 17 00:00:00 2001 From: Sam Waggoner Date: Mon, 16 Mar 2026 10:48:46 -0500 Subject: [PATCH 10/10] Fix release automation bugs and improve README - Fix change_schema_version to write to resources/ctim/version.txt - Sync version.txt to current project version (1.3.30-SNAPSHOT) - Remove stale resources/version.txt - Rewrite release docs: add pre-release steps, split recovery scenarios Co-Authored-By: Claude Opus 4.6 --- README.md | 28 ++++++++++++++++++---------- dev/ctim/change_schema_version.clj | 2 +- resources/ctim/version.txt | 2 +- resources/version.txt | 1 - 4 files changed, 20 insertions(+), 13 deletions(-) delete mode 100644 resources/version.txt diff --git a/README.md b/README.md index 88296971..c828a22d 100644 --- a/README.md +++ b/README.md @@ -29,18 +29,22 @@ lein doc ## Releases -### Patch release +The project version in `project.clj` should always be a `-SNAPSHOT` on the main branch. +The release process (defined in `:release-tasks` in `project.clj`) handles bumping, +deploying, and advancing to the next snapshot automatically. + +### Before releasing -Set the version in `project.clj` to `x.y.z-SNAPSHOT`, then run: +Run `lein doc` and commit any generated changes. The release will fail at the +`vcs assert-committed` step if there are uncommitted doc changes. + +### Patch release ```bash lein release :patch ``` -This bumps to `x.y.z`, deploys to Clojars, then bumps to `x.y.(z+1)-SNAPSHOT`. -See `:release-tasks` in `project.clj` for the full sequence. - -For minor or major version bumps, manually edit the version in `project.clj` before running `lein release`. +For minor or major bumps, use `lein release :minor` or `lein release :major`. ### Snapshot release @@ -50,16 +54,20 @@ lein deploy ### Recovery -If a release fails partway through: +If the release fails **before** `deploy clojars`: ```bash -# delete the tag if it was created git tag --delete x.y.z - -# reset to the commit before the failed release git reset --hard SHA_BEFORE_FAILED_RELEASE ``` +If the release fails **after** `deploy clojars` (e.g., at the `vcs push` step), +the artifact is already published. Complete the release manually: + +```bash +git push --tags --set-upstream origin release-x.y.z +``` + ## License Copyright © 2016-2026 Cisco Systems diff --git a/dev/ctim/change_schema_version.clj b/dev/ctim/change_schema_version.clj index f03ce41f..4a6c6d7f 100644 --- a/dev/ctim/change_schema_version.clj +++ b/dev/ctim/change_schema_version.clj @@ -2,4 +2,4 @@ (defn -main [version] - (spit "./resources/version.txt" version)) + (spit "./resources/ctim/version.txt" version)) diff --git a/resources/ctim/version.txt b/resources/ctim/version.txt index 3ef6f64f..2b43cb36 100644 --- a/resources/ctim/version.txt +++ b/resources/ctim/version.txt @@ -1 +1 @@ -1.3.25-SNAPSHOT \ No newline at end of file +1.3.30-SNAPSHOT \ No newline at end of file diff --git a/resources/version.txt b/resources/version.txt deleted file mode 100644 index 2bffbc56..00000000 --- a/resources/version.txt +++ /dev/null @@ -1 +0,0 @@ -1.3.25-SNAPSHOT