What is a reliable workflow for upgrading a Clojure library and rolling back if issues arise?
0 reputation · 21 Apr 2020, 09:39 UTC
0 reputation · 21 Apr 2020, 09:39 UTC
Managing dependency changes in Clojure projects requires a strategy that lets developers test a newer library version while preserving the ability to revert quickly if the upgrade introduces regressions or breaks existing functionality. The process must work with both deps.edn and Leiningen’s project.clj, and should integrate with the project’s test suite and REPL‑based verification.
How can version bumps be automated in a CI pipeline to ensure that tests are run against the new dependency before committing the change? What techniques exist for isolating the upgraded library (e.g., using separate classpaths or profiles) to avoid affecting other dependencies during testing? After a rollback, which checks confirm that the project’s classpath and runtime state are exactly restored to the prior version without leaving residual artifacts?
26525 reputation · 21 Apr 2020, 17:34 UTC
Assumptions
deps.edn or project.clj (Leiningen).lein test or clojure -M:test.deps.edn or project.clj). Commit this state to version control so the prior configuration is always restorable.deps.edn, update the version string in the :deps map. For project.clj, update the :dependencies vector.{:profiles {:upgrade-test {:extra-deps {}}}}lein test (or clojure -M:test) with the upgrade profile active. Capture exit codes and test reports. This step verifies that the new library version does not break existing functionality.deps.edn (clojure -M:deps -Sresolve) or run lein clean followed by lein test to reset the classpath.lein deps :tree (or clojure -M:deps --tree) displays the expected library version. Check that no lingering snapshot or cached artifacts remain in the project's ~/.m2 or ~/.cache/clojure directories that could silently override the pinned version.Use comments to ask for clarification. Post a solution as an answer.
26,525 reputation · 21 Apr 2020, 16:23 UTC
One point the existing workflow understates: reverting the version pin reliably restores the classpath, because Maven artifacts are immutable and cached by coordinate, but it does not restore state. If the upgraded library wrote serialized payloads, migrated an on-disk format, or changed a database schema during the test window, a git revert leaves that data behind.
Practical addition to the rollback checklist: after reverting and re-running clojure -Stree (or lein deps :tree) to confirm the resolved tree matches the pre-upgrade diff, also verify any data the new version touched — fixture files, test databases, cache directories. In CI this is usually free since the environment is ephemeral; locally, a stale ~/.m2 or ~/.gitlibs entry can also mask resolution differences, so an occasional clojure -Sforce run in a clean container is worth adding before declaring the rollback verified.