﻿<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text" xml:lang="en">MfGames Conventional Commit</title>
  <link type="application/atom+xml" href="https://mfgames.com/mfgames-conventional-commit-rs/atom.xml" rel="self" />
  <link type="text/html" href="https://mfgames.com/mfgames-conventional-commit-rs/" rel="alternate" />
  <updated>2026-04-18T17:43:18Z</updated>
  <id>https://mfgames.com/mfgames-conventional-commit-rs/</id>
  <author>
    <name>D. Moonfire</name>
  </author>
  <rights>Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International</rights>
  <entry>
    <title>Making It Useful (MfGames Conventional Commit)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2025/08/12/making-it-useful/" />
    <updated>2025-08-12T05:00:00Z</updated>
    <id>https://mfgames.com/blog/2025/08/12/making-it-useful/</id>
    <category term="mfgames-conventional-commit" scheme="https://mfgames.com/categories/" label="MfGames Conventional Commit" />
    <content type="html">&lt;p&gt;We wrote &lt;code&gt;mfgames-conventional-commits&lt;/code&gt; to solve a small itch of wanting to be able to calculate version numbers based on &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;Conventional Commits&lt;/a&gt; but only for commits that touch specific directories. That way, a change to &lt;code&gt;MfGames.IO&lt;/code&gt; would bump that version up but not touch the versioning for &lt;code&gt;MfGames.Nitride&lt;/code&gt; in the same &lt;a href="//mfgames.com/mfgames-cil/"&gt;monorepo&lt;/a&gt;. For the most part, it was to allow the CIL projects to have different versions as they all had different lineages before they were combined.&lt;/p&gt;
&lt;p&gt;As things go, we always intended to &lt;a href="https://src.mfgames.com/mfgames-git/mfgames-conventional-commit-rs/issues"&gt;polish&lt;/a&gt; and expand on the tool but other things got in the way. But then &lt;a href="//d.moonfire.us/"&gt;D. Moonfire&lt;/a&gt; was working on &lt;a href="//https://d.moonfire.us/garden/git-for-authors/"&gt;Git For Authors&lt;/a&gt; and realized they didn't have a good solution for calculating version numbers of novels. Since we already had this tool, we spent a few days making it more useful and capable for single package projects and require less overhead to configure it.&lt;/p&gt;
&lt;h2&gt;Simplified Setup&lt;/h2&gt;
&lt;p&gt;The configuration file goes into &lt;code&gt;//.config/mfgames-conventional-commit.json&lt;/code&gt; as usual, but setup has gotten significant easier. we added a &lt;code&gt;defaults&lt;/code&gt; section that applies to every project along with substitutions for packages with &lt;code&gt;{package}&lt;/code&gt; that allow each pack to have their own directories.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-json"&gt;{
  &amp;quot;$schema&amp;quot;: &amp;quot;https://mfgames.com/mfgames-conventional-commit-rs/schemas/v0.json&amp;quot;,
  &amp;quot;defaults&amp;quot;: {
    &amp;quot;tag_prefix&amp;quot;: &amp;quot;{package}-&amp;quot;,
    &amp;quot;directories&amp;quot;: { &amp;quot;include&amp;quot;: [&amp;quot;src/{package}&amp;quot;] },
    &amp;quot;files&amp;quot;: { &amp;quot;include&amp;quot;: [&amp;quot;src/{package}/**/*&amp;quot;] }
  },
  &amp;quot;packages&amp;quot;: {
    &amp;quot;MfGames.Cryptography&amp;quot;: {},
    &amp;quot;MfGames.DI.AutofacExtensions&amp;quot;: {},
    &amp;quot;MfGames.Gallium&amp;quot;: {},
    &amp;quot;MfGames.IO&amp;quot;: {},
    // There is more here
    &amp;quot;MfGames.ToolBuilder.Tables&amp;quot;: {}
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It used to be we had to have the &lt;code&gt;tag_prefix&lt;/code&gt; and &lt;code&gt;files&lt;/code&gt; elements in each one with a customization per project to include the path. Now, &lt;code&gt;{package}&lt;/code&gt; can be used to substitute the package name and defaults to apply to any package that doesn't have settings underneath itself. In the future, we'll have some configuration that will scan the &lt;code&gt;//src&lt;/code&gt; directory for the package names, but not this round.&lt;/p&gt;
&lt;h2&gt;Version Numbers&lt;/h2&gt;
&lt;p&gt;We also have two variants of version numbers based on usage. The first is the &amp;ldquo;flatten&amp;rdquo; version which calculates the most relevant major, minor, or patch version and applies it to the latest found tag. So if you have a &amp;ldquo;feat&amp;rdquo;, &amp;ldquo;fix&amp;rdquo;, &amp;ldquo;fix&amp;rdquo; on 1.0.0, it would be &amp;ldquo;1.1.0&amp;rdquo;. In contrast is the &amp;ldquo;detail&amp;rdquo; version which applies the version one at a time. So if you had the same &amp;ldquo;feat&amp;rdquo;, &amp;ldquo;fix&amp;rdquo;, &amp;ldquo;fix&amp;rdquo; on 1.0.0, the result would be &amp;ldquo;1.1.2&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Most software projects seem to make a conscious decision to bump up the version. With semantic releases, the versioning is done on the pipeline. For a long time, we used &amp;ldquo;flattened&amp;rdquo; as the basic approach since that is what &lt;a href="https://github.com/semantic-release/semantic-release#readme"&gt;Semantic Release&lt;/a&gt; did. However, with novels and the like, sometimes they go out without the pipeline running and it is useful to make sure new versions show up; hence the use of &amp;ldquo;detail&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;This also resulted in a slightly different output for the &lt;code&gt;mfgames-conventional-commit version&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;$ cd src/MfGames.IO
$ mfgames-conventional-commit version
 package_name  last_version  flatten_version  flatten_changed  detail_version  detail_changed
 MfGames.IO    2.7.0         2.7.0            false            2.7.0           false
$ mfgames-conventional-commit version --all | head -n 5
 package_name                        last_version  flatten_version  flatten_changed  detail_version  detail_changed
 MfGames.Cryptography                14.7.0        14.7.0           false            14.7.0          false
 MfGames.DI.AutofacExtensions                      0.0.1            true             0.0.1           true
 MfGames.Gallium                     3.6.0         3.6.0            false            3.6.0           false
 MfGames.IO                          2.7.0         2.7.0            false            2.7.0           false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because we're fond of changing format as needed, so it can also dump a JSON or Markdown version. And all logging is sent to stderr, so piping can work properly.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;$ mfgames-conventional-commit version --json | jq
[
  {
    &amp;quot;package_name&amp;quot;: &amp;quot;MfGames.IO&amp;quot;,
    &amp;quot;last_version&amp;quot;: &amp;quot;2.7.0&amp;quot;,
    &amp;quot;flatten_version&amp;quot;: &amp;quot;2.7.0&amp;quot;,
    &amp;quot;flatten_changed&amp;quot;: false,
    &amp;quot;detail_version&amp;quot;: &amp;quot;2.7.0&amp;quot;,
    &amp;quot;detail_changed&amp;quot;: false
  }
]
$ mfgames-conventional-commit version --all --format markdown | head -n 5
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;package_name&lt;/th&gt;
&lt;th&gt;last_version&lt;/th&gt;
&lt;th&gt;flatten_version&lt;/th&gt;
&lt;th&gt;flatten_changed&lt;/th&gt;
&lt;th&gt;detail_version&lt;/th&gt;
&lt;th&gt;detail_changed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MfGames.Cryptography&lt;/td&gt;
&lt;td&gt;14.7.0&lt;/td&gt;
&lt;td&gt;14.7.0&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;14.7.0&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MfGames.DI.AutofacExtensions&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;0.0.1&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;0.0.1&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MfGames.Gallium&lt;/td&gt;
&lt;td&gt;3.6.0&lt;/td&gt;
&lt;td&gt;3.6.0&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;3.6.0&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MfGames.IO&lt;/td&gt;
&lt;td&gt;2.7.0&lt;/td&gt;
&lt;td&gt;2.7.0&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;2.7.0&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MfGames.Locking&lt;/td&gt;
&lt;td&gt;2.5.1&lt;/td&gt;
&lt;td&gt;2.5.1&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;2.5.1&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Updates&lt;/h2&gt;
&lt;p&gt;Another useful feature is the ability to perform updates if the version number changed. This is used to define an &lt;code&gt;updates&lt;/code&gt; element in the configuration file:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-json"&gt;{
  &amp;quot;$schema&amp;quot;: &amp;quot;https://mfgames.com/mfgames-conventional-commit-rs/schemas/v0.json&amp;quot;,
  &amp;quot;defaults&amp;quot;: {
    &amp;quot;updates&amp;quot;: [
      { &amp;quot;script&amp;quot;: &amp;quot;npm version {detail_version} --no-git-tag-version&amp;quot; },
      { &amp;quot;script&amp;quot;: &amp;quot;git tag v{detail_version}&amp;quot; }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see from above, the command will change the NPM version and create a Git tag. If &lt;code&gt;always_run&lt;/code&gt; is set to true, then it will run every time it is called, otherwise it will only run if the Git tag doesn't match the calculated tag.&lt;/p&gt;
&lt;p&gt;The main reason for this is because then we don't have to write a hundred plugins for different systems. You can just write the script to do it, call another program, or just write some output. Anything a shell can do, this can do.&lt;/p&gt;
&lt;h2&gt;Inferred Package&lt;/h2&gt;
&lt;p&gt;One of the more annoying things is that we couldn't figure out the package name from the current context. For the most part, that didn't mean much since we could always provide &lt;code&gt;--package package-name&lt;/code&gt;, but we found it useful enough that we made the tool figure out the patch from the &lt;code&gt;directories&lt;/code&gt; attribute above. This also handles &lt;code&gt;{package}&lt;/code&gt; substitutions, so it is generally useful.&lt;/p&gt;
&lt;p&gt;Both the &lt;code&gt;version&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; commands also take an &lt;code&gt;--all&lt;/code&gt; which means all packages in the project instead of &lt;code&gt;--package package-name&lt;/code&gt; for an arbitrary package, or either of these to guess it from the directory.&lt;/p&gt;
&lt;h2&gt;Sane Defaults&lt;/h2&gt;
&lt;p&gt;Finally, we added a sane default if the &lt;code&gt;//.config/mfgames-conventional-commit.json&lt;/code&gt; file is missing, or it doesn't have many settings. This assumes the entire directory is a single package called &amp;ldquo;default&amp;rdquo; and it uses a &amp;ldquo;vX.X.X&amp;rdquo; tag to represent versions.&lt;/p&gt;
&lt;h2&gt;Future Steps&lt;/h2&gt;
&lt;p&gt;This is a secondary project for us. Obvious, if we have an itch and it doesn't do something we want, we'll add it. If there are any &lt;a href="https://src.mfgames.com/mfgames-git/mfgames-conventional-commit-rs/issues"&gt;issues&lt;/a&gt; that would be really useful or if you come up with something useful for the project (that is in scope), report or comment on it and we'll see about implementing it.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Updating Dependencies (MfGames Conventional Commit)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2025/12/05/updating-dependencies/" />
    <updated>2025-12-05T06:00:00Z</updated>
    <id>https://mfgames.com/blog/2025/12/05/updating-dependencies/</id>
    <category term="mfgames-conventional-commit" scheme="https://mfgames.com/categories/" label="MfGames Conventional Commit" />
    <content type="html">&lt;p&gt;Just a little maintenance update.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Updated the Nix flake from 25.05 to 25.11&lt;/li&gt;
&lt;li&gt;Updated Rust to the 2025-12-05 nightly&lt;/li&gt;
&lt;li&gt;Updated various dependency packages&lt;/li&gt;
&lt;li&gt;Bumped the version to 0.3.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nothing really fancy, just housekeeping.&lt;/p&gt;
</content>
  </entry>
</feed>
