A Wall Brew Leiningen plugin for automating CHANGELOG management for projects using Semantic Versioning 2.0
The Wall Brew Open Source Standard requires libraries to publish change documentation in a human-readable format. CHANGELOG files tend to be well-structured with embedded convenience links; however, they are almost always manually generated. Sealog is a tool intended help automate:
Sealog is available as a leiningen plugin and can be downloaded from clojars.
To install Sealog, add the following in your :plugins
list in your project.clj
file:
[com.wallbrew/lein-sealog "1.7.0"]
The first time you invoke this plugin, Leiningen will automatically fetch the dependency for you.
From the root of your project directory, you may invoke the following commands:
init
- To initialize sealog with an initial entry and a config file (if not present)bump
- To create a new changelog entry filerender
- To compile all changelog entry files into a markdown Changeloginsert
- To update the most recent changelog entry file with new notesversion
- To print the current project versions from Leiningen and sealogcheck
- To validate Sealog's configuration, changelog entry files, the changelog, and the project versionhelp
- To view the help text of sealog or any commandMost commands will accept several options, which can be configured by the command line arguments passed in or in project configuration. In all cases, the options will follow this order of precedence:
Sealog stores changelog entries in the .sealog/changes
directory in your project.
Since new projects will not have this directory by default, Sealog may create it for you.
Additionally, Sealog will create an initial EDN change file and a configuration file for you.
$ lein sealog init
$ ls .sealog/changes -l
total 7
-rw-r--r-- 1 user user 348 Feb 19 15:36 1-0-0.edn
$ ls .sealog -l
total 8
drwxr-xr-x 2 user user 4096 Feb 19 15:37 changes
-rw-r--r-- 1 user user 128 Feb 19 15:38 config.edn
If the .sealog
directory already exists, Sealog will perform no actions.
$ lein sealog init
Sealog is already initialized!
Bump creates a new changelog entry in the .sealog/changes
directory in your project.
Based on the type of version bump, Sealog will automatically apply the correct SemVer numbering changes.
Valid bump types are: major
, minor
, and patch
.
Assuming the project is currently at version 1.0.0
, major
will create 2.0.0
$ lein sealog bump major
Created new changelog entry: .sealog/2-0-0.edn
Assuming the project is currently at version 1.0.0
, minor
will create 1.1.0
$ lein sealog bump minor
Created new changelog entry: .sealog/1-1-0.edn
Assuming the project is currently at version 1.0.0
, patch
will create 1.0.1
$ lein sealog bump patch
Created new changelog entry: .sealog/1-0-1.edn
If no type is provided, Sealog will automatically apply a patch
change.
Assuming the project is currently at version 1.0.0
:
$ lein sealog bump
Created new changelog entry: .sealog/1-0-1.edn
Insert adds a new change note for the most recent version. The insert command requires you to pass a valid Keep a Changelog key as the second argument followed by one or more double-quoted strings representing your changes.
Assume we're starting with the following changelog entry:
{:version {:major 1
:minor 0
:patch 0}
:version-type :semver3
:changes {:added []
:changed []
:deprecated []
:removed []
:fixed []
:security []}
:timestamp "2024-03-13T02:24:28.296154300Z"}
To denote the changes for this version of sealog, we'd submit the following command:
$ lein sealog insert added "Created the application!"
Reading from .sealog/config.edn
Reading from .sealog/changes/1-0-0.edn
Writing to .sealog/changes/1-0-0.edn
Updated changelog entries: .sealog/changes/1-0-0.edn
From there, we can check the file and see our update:
{:version {:major 1
:minor 0
:patch 0}
:version-type :semver3
:changes {:added ["Created the application!"]
:changed []
:deprecated []
:removed []
:fixed []
:security []}
:timestamp "2024-03-13T02:24:28.296154300Z"}
We can also add several notes at once, and they'll be concatenated into any existing records.
$ lein sealog insert added "Release feature 1!" "Introduce feature 2-alpha"
Reading from .sealog/config.edn
Reading from .sealog/changes/1-0-0.edn
Writing to .sealog/changes/1-0-0.edn
Updated changelog entries: .sealog/changes/1-0-0.edn
Which produces the following updates:
{:version {:major 1
:minor 0
:patch 0}
:version-type :semver3
:changes {:added ["Created the application!"
"Release feature 1!"
"Introduce feature 2-alpha"]
:changed []
:deprecated []
:removed []
:fixed []
:security []}
:timestamp "2024-03-13T02:24:28.296154300Z"}
Sealog can parse your change entries and project.clj
to view the current project information.
By default, sealog will read and compare both sources:
$ lein sealog version
Reading from .sealog/config.edn
Reading from .sealog/changes/1-0-1.edn
Reading from .sealog/changes/1-2-0.edn
Reading from .sealog/changes/1-0-0.edn
Reading from .sealog/changes/1-1-0.edn
Reading from .sealog/changes/1-2-1.edn
Reading from .sealog/changes/1-0-2.edn
Reading from .sealog/changes/1-3-0.edn
project.clj: 1.3.0-SNAPSHOT
sealog: 1.3.0
If you only want to consider project.clj
:
lein sealog version project.clj
Reading from .sealog/config.edn
Reading from .sealog/changes/1-0-1.edn
Reading from .sealog/changes/1-2-0.edn
Reading from .sealog/changes/1-0-0.edn
Reading from .sealog/changes/1-1-0.edn
Reading from .sealog/changes/1-2-1.edn
Reading from .sealog/changes/1-0-2.edn
Reading from .sealog/changes/1-3-0.edn
1.3.0-SNAPSHOT
If you only want to consider sealog sourced data:
lein sealog version sealog
Reading from .sealog/config.edn
Reading from .sealog/changes/1-0-1.edn
Reading from .sealog/changes/1-2-0.edn
Reading from .sealog/changes/1-0-0.edn
Reading from .sealog/changes/1-1-0.edn
Reading from .sealog/changes/1-2-1.edn
Reading from .sealog/changes/1-0-2.edn
Reading from .sealog/changes/1-3-0.edn
1.3.0
Sealog relies on convention to produce sane changelogs. To validate that Sealog is configured appropriately, you may run a series of introspective checks.
$ lein sealog check
Reading from .sealog/config.edn
Sealog configuration is valid.
Reading from .sealog/config.edn
Changelog entry directory contains at least one file.
Reading from .sealog/changes/1-0-1.edn
Reading from .sealog/changes/1-2-0.edn
Reading from .sealog/changes/1-3-0.edn
All changelog entries are valid.
Reading from .sealog/changes/1-0-1.edn
Reading from .sealog/changes/1-2-0.edn
Reading from .sealog/changes/1-3-0.edn
All changelog entries use the same version type.
Reading from .sealog/changes/1-0-1.edn
Reading from .sealog/changes/1-2-0.edn
Reading from .sealog/changes/1-3-0.edn
All changelog entries have distinct versions.
Reading from .sealog/changes/1-0-1.edn
Reading from .sealog/changes/1-2-0.edn
Reading from .sealog/changes/1-3-0.edn
Project version matches latest changelog entry.
Reading from .sealog/changes/1-0-1.edn
Reading from .sealog/changes/1-2-0.edn
Reading from .sealog/changes/1-3-0.edn
Rendered changelog contains all changelog entries.
All checks passed
Checks:
clojure.spec/explain-str
Finally, Sealog can aggregate and render your change entries into a clean, Markdown format.
By default, Sealog will render this file as CHANGELOG.md
in the project's root.
$ lein sealog render
Wrote changelog to: CHANGELOG.md
Additionally, you may pass a filename for Sealog to write to instead of CHANGELOG.md
$ lein sealog render CHANGES.md
Wrote changelog to: CHANGES.md
If you wish to consistently default the filename to write, you may set the value of the :changelog-filename
key in .sealog/config.edn
{:changelog-filename "CHANGES.md"
:changelog-entry-directory ".sealog/changes/"
:version-scheme :semver3}
Sealog stores changelog entries within a repository's .sealog/changes
directory.
A changelog entry is an EDN file storing a map with the following keys:
:version
- A map containing a structured representation of a semantic version:version-type
- A keyword denoting the type of versioning system used. For example, :semver3
:changes
- A map of Keep a Changelog keys, to a sequence of strings containing the changes of that type.:timestamp
- A string containing an RFC 3339 timestamp.Included is an example file for version "1.2.0" of a library.
This file would be located at .sealog/changes/1-2-0.edn
:
{:version {:major 1
:minor 2
:patch 0}
:version-type :semver3
:changes {:added ["A new function `foo` for baz-ing"
"Automation to deploy the project to Clojars"]
:changed []
:deprecated ["`quux` was based on an old API no longer supported by source. Consumers should migrate to `foo`"]
:removed []
:fixed []
:security []}
:timestamp "2022-10-08T22:45:40.974189700Z"}
Empty change lists may be kept for consistency or removed.
Many of Sealog's commands may be modified at execution time with additional arguments.
Long-term decisions, such as where the Changelog should be written to, can also be configured in a static file.
As of version 1.7.0
, Sealog will inspect the following locations for configuration.
The first location found will be used, and the others will be ignored:
:sealog
key in the project's project.clj
file.sealog/config.edn
file, relative to the project's root.wallbrew/sealog/config.edn
file, relative to the project's rootlein sealog init
Sealog will create this file while executing lein sealog init
if no prior Sealog configuration file is detected.
The file will be created with the defaults outlined in this README.
The following keys and values are supported:
:changelog-filename
:changelog-entry-directory
.edn
change files will be stored.:version-scheme
:semver3
- 3 Position Semantic Versioning 2.0:pretty-print-edn?
Copyright © Wall Brew Co
This software is provided for free, public use as outlined in the MIT License
Can you improve this documentation? These fine people already did:
Nick A Nichols & Nick NicholsEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close