sheerlox
SemanticReleaseHex - Fully automated version management and release processes
Hello, Elixir community!
I’m excited to introduce a new tool that aims to streamline version management and release processes for Elixir projects: semantic-release-hex.
Disclaimers
Before we dive in, I want to clarify that semantic-release-hex is a JavaScript library designed to enhance version management and release processes in Elixir projects. While it’s not an Elixir library per se, its integration with Elixir projects can bring the power and simplicity of semantic-release to your workflow.
I also want to mention that although it’s only been two weeks, I’ve recently been invited to the semantic-release organization. The reason I’m developing this library is unrelated to my membership in the organization and is solely motivated by my complete trust and utter admiration for that project, which I’ve been using for more than 6 years in all of my projects, both personal and professional.*
Why?
In the course of developing a SaaS project with Elixir & Phoenix, I encountered the challenge of automating version management while adhering to best practices. Initially being a JavaScript developer, I turned to the reliable semantic-release tool but found it lacking in Elixir integration. This led me to create semantic-release-hex.
semantic-release features
- Determining the next version number
- Generating release notes & updating the changelog file
- Creating a git tag
- Publishing GitHub/GitLab releases
- Commenting on released Pull Requests/Issues
semantic-release-hex features
- Updating the version in
mix.exs
semantic-release-hex roadmap
- Updating the version in
README - Updating the version in
Mix.install/2scripts - Distributed as a
hexpackage (similar totailwind) - Publishing to Hex
Benefits
- Fully automated release
- Enforce Semantic Versioning specification
- New features and fixes are immediately available to users
- Notify maintainers and users of new releases
- Use formalized commit message convention to document changes in the codebase
- Integrate with your continuous integration workflow
- Avoid potential errors associated with manual releases
- Simple and reusable configuration via shareable configurations
Trying it out
I’ve set up a demo repository to showcase what that would look like in an Elixir project: semantic-release-hex-demo. Feel free to explore its content, commit history, or even fork it to test things out, as it’s what it’s meant for.
You will also find detailed instructions on how to set it up in your own Elixir project on the main repository.
I’m eager to hear your thoughts, answer any questions, and discuss how semantic-release-hex can enhance your Elixir projects!
Also, if you’d like to share your views on features currently being specified/implemented, don’t hesitate to visit the Discussions/Issues for feature requests.
Thank you for reading ![]()
Acknowledgements
Special thanks to @Eiji and @D4no0 for their invaluable feedback!
Most Liked
sheerlox
That all makes total sense, I now understand your point about having the documentation on hexdocs, which would be even further solidified by the creation of an Elixir package abstracting the installation and release mechanisms associated with Node.js. I really like this solution and have already started looking into it.
I’m not aware of any mention of a standalone release of semantic-release-cli, but that will be a great addition to the tool that I’m sure the core team will welcome with enthusiasm! I’ll run the idea by them while working on a prototype.
Regarding the AI-based documentation generator, semantic-release indeed does not ship with that feature, but maybe someone will create a plugin for that in the future ![]()
Thank you for being so patient with me, your input is really valuable and highly appreciated!
thiagomajesk
Eiji
Isn’t it easier to create a mix task which firstly guess based on configurable prefix (let’s say: "fix: ") and then asks for a type of version change giving the guessed one as default (to just press enter)?
config ::semantic_release, :prefix,
major: ["…"],
minor: ["…"],
major: ["fix: ", "other: "],
Some projects would need to add node as extra environment dependency which is not always a good idea. If we are going to simplify one thing we shouldn’t complicate other one. For me it’s simple on my laptop, because I use asdf, but not everyone is in such case. Also obviously the documentation is not on hex with all of it’s side-effects which may be confusing especially for new developers.
$ mix semantic.release --log-level debug
[debug] Found "…" prefix in commit message which is configured for … version change
[debug] Found (…)
(…)
[info] The determined version change is …
Which version change should be applied?
1) Major
2) Minor
3) Bug fix (default)
Choose type of version change [1/2/3] _
[debug] The chosen type is …
[info] The new version is …
Are you ready to push changes [Y/n] _
[debug] Pushes commit(s)
Do you want to create a new git tag "v1.x.y"? [Y/n] _
[debug] Created git tag "v1.x.y"
Do you want to publish a release to hex? [Y/n] _
[debug] The release has been published
[debug] The documentation has been published
The version has been successfully changed from … to …
$ mix semantic.release --yes-all
Which version change should be applied?
1) Major
2) Minor (default)
3) Bug fix
Choose type of version change [1/2/3] _
The version has been successfully changed from … to …
$ mix semantic.release --yes-all --default
The version has been successfully changed from … to …
Does it have any strict format or it’s configurable somehow?
Does it creates a git tags automatically as well (git checkout v1.x.y or so)?
What is the comment content? Is it configurable? How about wiki?
For me the best documentation is:
wikiasuserperspectiveissueasdeveloperperspectivepull requestas implementation details
How about Installation in README.md file? It should be easy to find in markdown as long as you know the project name and previous version.
Those links are relative, so browser searches it on this forum …
sheerlox
Isn’t it easier to create a
mixtask which firstly guess based on configurable prefix (let’s say: "fix: ") and then asks for a type of version change giving the guessed one as default (to just press enter)?
I thought about making an actual Elixir library to solve the issue at hand.
However, semantic-release is the industry standard battle-tested tool (was created almost 10 years ago and is the 128th most depended upon package on NPM, ahead of jquery, underscore, babel and lots of other staples), packs in a lot of useful features (e.g. support for pre-release / maintenance branches) and is highly configurable to suit almost any workflow.
For these reasons, while it would be extremely instructive to try and create an Elixir equivalent, I don’t think reinventing the wheel is a good use of time, especially when there is virtually no downside to using (and extending) the already available tooling.
Some projects would need to add
nodeas extra environment dependency which is not always a good idea.
Technically, because semantic-release is made with a CI-first approach in mind, it doesn’t have to ever be run locally. Because of this, the Node.js environment dependency is only in the release workflow file. Node.js is required locally only when initializing the tool, to install the packages and run the dry-run to check everything is working as expected.
Also obviously the documentation is not on
hexwith all of it’s side-effects which may be confusing especially for new developers.
I’m not sure what you mean by “side-effects”, but I don’t think not having the documentation on hex is an issue, since this isn’t an Elixir library per see, and the only place it will be referenced is in the release configuration. Similar to CI tools, where you wouldn’t expect GitHub Actions documentation to be on Hex, the relevant documentation is readily available where it’s most relevant.
Does it have any strict format or it’s configurable somehow?
This is fully configurable by choosing an existing conventional changelog preset, or creating your own by forking one of the existing presets and making adjustments as I did (to be exact it is a maintained fork) with @insurgent/conventional-changelog-preset (which includes all commit types and adds emojis before categories). You can take a look at the relevant source code in lib/commit-transform.js. But note that with all the available presets, you probably don’t have to create a new one.
Does it creates a
gittags automatically as well (git checkout v1.x.yor so)?
Yes, I forgot to mention that in the post, but semantic-release tags the version to the release commit before creating a GitHub/GitLab release, as it actually relies heavily on tags (e.g. to determine the current version).
What is the comment content? Is it configurable? How about
wiki?
You can take a look at an example comment here: semantic-release/semantic-release#3062 (comment).
It is also fully configurable, please refer to the semantic-release/github options documentation if you’d like to know more.
Regarding the wiki, I’m not sure what you mean by that. Could you please expand on the use case(s) you have in mind?
How about
InstallationinREADME.mdfile? It should be easy to find in markdown as long as you know the project name and previous version.
That’s actually a very good idea, thank you so much! I’ll be adding it to the feature requests and will start working on it as soon as it is specified correctly (btw if you’d like to share your views on features currently being specified/implemented, don’t hesitate to visit the Discussions/Issues for feature requests).
Those links are relative, so browser searches it on this forum …
Sorry about that, thanks for pointing this out I’ll fix them immediately.
Thank you so much for responding to my post to share your views and concerns, and I hope I’ve addressed them as best as possible ![]()
D4no0
I’m also not a big fan of installing node and random JS packages either on dev or CI/CD, I am tired of redoing the CI script every few months because of some forced “deprecations” introduced in the ways to install node or other js packages.
If the implementation of the package is what matters, I think making a CLI and packaging it together with a elixir library, just like tailwind does is a much more sane approach and would make everyone happy by not caring about any implementation details.







