<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: miniscruff</title>
    <description>The latest articles on DEV Community by miniscruff (@miniscruff).</description>
    <link>https://dev.to/miniscruff</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F162928%2F6e8b1437-d3cb-475e-8697-ed6358dbd6d9.png</url>
      <title>DEV Community: miniscruff</title>
      <link>https://dev.to/miniscruff</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/miniscruff"/>
    <language>en</language>
    <item>
      <title>Changie - Auto mode and GitHub action</title>
      <dc:creator>miniscruff</dc:creator>
      <pubDate>Sun, 05 Feb 2023 06:53:30 +0000</pubDate>
      <link>https://dev.to/miniscruff/changie-auto-mode-and-github-action-1279</link>
      <guid>https://dev.to/miniscruff/changie-auto-mode-and-github-action-1279</guid>
      <description>&lt;h2&gt;
  
  
  Auto Mode
&lt;/h2&gt;

&lt;p&gt;Using Changie for changelog management has a lot of advantages, but one thing that has been missing is a feature that is used a lot by commit message based standards such as &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;conventional commits&lt;/a&gt; which is. Automatic version bumping based on changes. That is, if I add a new feature specified by the &lt;code&gt;feat&lt;/code&gt; prefix, conventional commit knows to bump the minor version. If I instead used the &lt;code&gt;fix&lt;/code&gt; prefix, it knows to bump the patch version.&lt;/p&gt;

&lt;p&gt;Changie now supports this as an optional feature by using &lt;code&gt;changie batch auto&lt;/code&gt; or &lt;code&gt;changie next auto&lt;/code&gt; and it works by looking at the &lt;a href="https://changie.dev/config/#kindconfig-auto"&gt;kind configs&lt;/a&gt; for the unreleased changes.&lt;/p&gt;

&lt;p&gt;When creating a new project, the &lt;code&gt;changie init&lt;/code&gt; command will include the defaults below for auto values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;kinds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Added&lt;/span&gt;
    &lt;span class="na"&gt;auto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;minor&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Changed&lt;/span&gt;
    &lt;span class="na"&gt;auto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;major&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deprecated&lt;/span&gt;
    &lt;span class="na"&gt;auto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;minor&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Removed&lt;/span&gt;
    &lt;span class="na"&gt;auto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;major&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Fixed&lt;/span&gt;
    &lt;span class="na"&gt;auto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;patch&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Security&lt;/span&gt;
    &lt;span class="na"&gt;auto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;patch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This feature allows you to pretty safely execute &lt;code&gt;changie batch auto &amp;amp;&amp;amp; changie merge&lt;/code&gt; whenever you want to release instead of checking what changes are included and what the next version should be. And because this is an automatic change, any CI/CD processes you have can now go from 1 input to 0.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Action
&lt;/h2&gt;

&lt;p&gt;Another thing that can help with using Changie in your project is the new &lt;a href="https://github.com/miniscruff/changie-action"&gt;changie GitHub action&lt;/a&gt; which can be used to run changie commands directly from your GitHub action pipelines.&lt;/p&gt;

&lt;p&gt;A good example of using the Changie action is in the action itself, which uses Changie for changelogs and itself to batch and merge new versions. Quite the recursive project.&lt;/p&gt;

&lt;p&gt;Here is a snippet of the &lt;a href="https://github.com/miniscruff/changie-action/blob/main/.github/workflows/gen-release-pr.yml"&gt;full workflow&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Batch changes&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latest&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;batch auto&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Merge changes&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latest&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;merge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The full workflow for this is to generate a pull request with an updated changelog by running batch and merge, we also use the latest version as part of the commit message and pull request summary. This is also very similar to a workflow changie uses for itself, however, changie just runs the equivalent &lt;code&gt;go run main.go *&lt;/code&gt; commands rather then the changie action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate release pull request&lt;/span&gt;

&lt;span class="c1"&gt;# empty workflow dispatch as we want it to be a manually run &lt;/span&gt;
&lt;span class="c1"&gt;# action, but we have no arguments for it&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;generate-pr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-20.04&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

    &lt;span class="c1"&gt;# any custom build commands you want to include goes here&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Batch changes&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;miniscruff/changie-action@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latest&lt;/span&gt; &lt;span class="c1"&gt;# latest is the default and can be left out&lt;/span&gt;
        &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;batch auto&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Merge changes&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;miniscruff/changie-action@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;merge&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get the latest version&lt;/span&gt;
      &lt;span class="c1"&gt;# id is used to reference our latest version&lt;/span&gt;
      &lt;span class="c1"&gt;# in the next step&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latest&lt;/span&gt; 
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;miniscruff/changie-action@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latest&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create Pull Request&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;peter-evans/create-pull-request@v4&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release ${{ steps.latest.outputs.output }}&lt;/span&gt;
        &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release/${{ steps.latest.outputs.output }}&lt;/span&gt;
        &lt;span class="na"&gt;commit-message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release ${{ steps.latest.outputs.output }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is all for now. Reach me on twitter &lt;a href="https://twitter.com/miniScruffDev"&gt;@miniScruffDev&lt;/a&gt; or by starting a &lt;a href="https://github.com/miniscruff/changie/discussions"&gt;discussion on GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>news</category>
      <category>go</category>
    </item>
    <item>
      <title>Changie - Replacments and Choices</title>
      <dc:creator>miniscruff</dc:creator>
      <pubDate>Mon, 28 Mar 2022 02:08:10 +0000</pubDate>
      <link>https://dev.to/miniscruff/changie-choices-and-replacements-40p5</link>
      <guid>https://dev.to/miniscruff/changie-choices-and-replacements-40p5</guid>
      <description>&lt;h2&gt;
  
  
  Replacements
&lt;/h2&gt;

&lt;p&gt;Odds are, if you are working on a large project or you are part of a team you are going to use more than one language. You might run python for machine learning, react on the frontend, ruby on rails for the backend and some java spring services sprinkled in. This on its own is not a problem, as engineers we have many solutions for this such as docker or kubernetes.&lt;/p&gt;

&lt;p&gt;These tools will all have slight variations on how you might need to prepare and deploy a release. One thing in common is supplying release notes for a shared changelog. For this reason it was important that &lt;a href="https://changie.dev"&gt;Changie&lt;/a&gt; work across as many languages as possible. One way this is achieved is with the &lt;a href="https://changie.dev/config/replacements/"&gt;replacement configurations&lt;/a&gt;. This configuration allows changie to update files with the newly prepared version as part of the build process. It works very similarly to &lt;code&gt;sed&lt;/code&gt; with go templates for the version values.&lt;/p&gt;

&lt;h3&gt;
  
  
  NodeJS
&lt;/h3&gt;

&lt;p&gt;Lets run through some examples, for NodeJS projects you will include the project version in the package json file. To have Changie update this value when you batch your release notes you can use the config below ( also seen on the &lt;a href="https://changie.dev/integrations/nodejs/"&gt;docs here&lt;/a&gt; )&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;replacements&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;package.json&lt;/span&gt;
    &lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"version":&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;".*",'&lt;/span&gt;
    &lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"version":&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"{{.VersionNoPrefix}}",'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;

&lt;p&gt;There are many ways projects define the versions in python projects so I can't go over all of them. But one common method used by &lt;a href="https://github.com/tiangolo/fastapi"&gt;fastAPI&lt;/a&gt; is to create a version attribute in either a &lt;code&gt;__init__.py&lt;/code&gt; or &lt;code&gt;__main__.py&lt;/code&gt; file at the root of your project. For example &lt;a href="https://github.com/tiangolo/fastapi/blob/eddbae948f04e13fe412dc45a569d10e34b698a4/fastapi/__init__.py#L3"&gt;here&lt;/a&gt; is where the version is defined for FastAPI. This can be updated with a configuration similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;replacements&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fastapi/fastapi/__init__.py"&lt;/span&gt;
    &lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__version__&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;".*"'&lt;/span&gt;
    &lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__version__&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"{{.VersionNoPrefix}}"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Rust
&lt;/h3&gt;

&lt;p&gt;The cargo toml file includes a &lt;a href="https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field"&gt;version field&lt;/a&gt; so the replacement for that would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;replacements&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cargo.toml"&lt;/span&gt;
    &lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;".*"'&lt;/span&gt;
    &lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"{{.VersionNoPrefix}}"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are just a few examples, you can of course include multiple replacements and it should work for any language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choices
&lt;/h2&gt;

&lt;p&gt;Changie will prompt the user for answers to two questions, if enabled anyway, when creating a new change fragment. These are kind and body. Kind is associated with the type of change such as added, fixed, removed, or deprecated. &lt;a href="https://changie.dev/config/kind-formatting/"&gt;Kind configuration&lt;/a&gt; allows setting labels, headers and formats.&lt;/p&gt;

&lt;p&gt;The second question is the body of the change. This to can be disabled globally or per kind. You may want to disable this for certain kinds of changes that require more specific prompts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://changie.dev/config/choices/"&gt;Custom choices&lt;/a&gt; can be configured to add additional prompts to provide additional information for each change fragment. These choices are added to a custom map that can be used in the change format.&lt;/p&gt;

&lt;p&gt;A short example is the one from Changie itself that asks for an issue number and adds a link when formatting. Changie's &lt;a href="https://github.com/miniscruff/changie/blob/main/.changie.yaml"&gt;.changie.yaml&lt;/a&gt; is basically the default configuration with the issue choice added.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;changeFormat&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;[#{{.Custom.Issue}}](https://github.com/miniscruff/changie/issues/{{.Custom.Issue}})&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{.Body}}'&lt;/span&gt;
&lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Issue&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;int&lt;/span&gt;
  &lt;span class="na"&gt;minInt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another idea is to include a link to the author at the end.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# config yaml&lt;/span&gt;
&lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Author&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;minLength&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="na"&gt;changeFormat&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{.Body}}&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;fixed&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;by&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;[@{{.Custom.Author}}](https://github.com/{{.Custom.Author}})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Custom choices can also be used in the header and footer formats. Such as including authors in the footer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Author&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;minLength&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="na"&gt;footerFormat&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
  &lt;span class="s"&gt;### Contributors&lt;/span&gt;
  &lt;span class="s"&gt;{{- range (customs .Changes "Author" | uniq) }}&lt;/span&gt;
  &lt;span class="s"&gt;* [{{.}}](https://github.com/{{.}})&lt;/span&gt;
  &lt;span class="s"&gt;{{- end}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is all for now. Reach me on twitter &lt;a href="https://twitter.com/miniScruffDev"&gt;@miniScruffDev&lt;/a&gt; or by starting a &lt;a href="https://github.com/miniscruff/changie/discussions"&gt;discussion on GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>news</category>
      <category>go</category>
      <category>node</category>
    </item>
    <item>
      <title>Changie - Automated Changelog Generation for Large Projects</title>
      <dc:creator>miniscruff</dc:creator>
      <pubDate>Sat, 26 Mar 2022 21:05:51 +0000</pubDate>
      <link>https://dev.to/miniscruff/changie-automated-changelog-generation-for-large-projects-41hm</link>
      <guid>https://dev.to/miniscruff/changie-automated-changelog-generation-for-large-projects-41hm</guid>
      <description>&lt;h2&gt;
  
  
  Preleases
&lt;/h2&gt;

&lt;p&gt;When working on large projects or projects that require a few extra checks before being considered stable it is common to have prerelease builds. They go by many names but most importantly they use &lt;a href="https://semver.org/#spec-item-9"&gt;semver's prerelease field to define them&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It is still important to share notes on the differences in each prerelease build to communicate what has changed but what do you do when the time comes for the final release?&lt;/p&gt;

&lt;p&gt;A common method for this is to create prerelease notes for each build as they are made. Then, when the final version is ready, package all the prerelease changes into one final release. This is because the prerelease builds were really only for testing and once the final version is ready we just want to document what is in the new version.&lt;/p&gt;

&lt;p&gt;Changie supports this workflow by moving change fragments to a separate directory when batching new versions. And then when the final version is ready, including that separate directory or directories.&lt;/p&gt;

&lt;p&gt;Here is an example workflow. Lets say your project is preparing for a big upgrade in v1.5.0. This release brings a lot of nice features while maintaining backwards compatibility so you want to release a series of release candidates before the final one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# add features for next release&lt;/span&gt;
changie new
&lt;span class="c"&gt;# batch our features for this release candidate&lt;/span&gt;
changie batch minor &lt;span class="nt"&gt;--prerelease&lt;/span&gt; rc1 &lt;span class="nt"&gt;--move-dir&lt;/span&gt; v1.5
&lt;span class="c"&gt;# optionally merge to your CHANGELOG.md if desired&lt;/span&gt;
changie merge
&lt;span class="c"&gt;# repeat the above for as many candidates as your project needs&lt;/span&gt;
&lt;span class="c"&gt;# then when the final is ready&lt;/span&gt;
changie batch minor &lt;span class="nt"&gt;--include&lt;/span&gt; v1.5 &lt;span class="nt"&gt;--remove-prereleases&lt;/span&gt;
&lt;span class="c"&gt;# include remove-prereleases to remove the v1.5.0-rcX versions already released&lt;/span&gt;
changie merge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Options are available if you choose to keep prereleases around, move each prerelease into a new directory each or if you prefer to just chain releases you can use &lt;code&gt;--keep&lt;/code&gt; with each build.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://changie.dev/cli/changie_batch/"&gt;Changie batch docs&lt;/a&gt; will have all the information you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Metadata
&lt;/h2&gt;

&lt;p&gt;In addition to prereleases semver supports &lt;a href="https://semver.org/#spec-item-10"&gt;build metadata&lt;/a&gt; to be included with your versions. This can be used for pretty much anything but a few examples are; operating system, date, time, git hash or any combination.&lt;/p&gt;

&lt;p&gt;You can easily include build metadata by adding &lt;code&gt;-m or --metadata&lt;/code&gt; to batch.&lt;/p&gt;

&lt;p&gt;A small example would be to include the current date and time as well as the first 12 characters of the git hash with each release.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;changie next minor &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;git rev-parse &lt;span class="nt"&gt;--short&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;12 HEAD&lt;span class="si"&gt;)&lt;/span&gt;
v1.7.0+20220326.4f48261c620e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://changie.dev/cli/changie_next/"&gt;Changie next&lt;/a&gt; will just output what the next version would be, it takes similar parameters as batch.&lt;/p&gt;

&lt;p&gt;That is all for now. Reach me on twitter &lt;a href="https://twitter.com/miniScruffDev"&gt;@miniScruffDev&lt;/a&gt; or by starting a &lt;a href="https://github.com/miniscruff/changie/discussions"&gt;discussion on GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>news</category>
      <category>go</category>
      <category>devops</category>
    </item>
    <item>
      <title>Changie - Automated Changelog Generation for Any Project</title>
      <dc:creator>miniscruff</dc:creator>
      <pubDate>Sun, 13 Mar 2022 20:40:19 +0000</pubDate>
      <link>https://dev.to/miniscruff/changie-automated-changelog-generation-for-any-project-1b52</link>
      <guid>https://dev.to/miniscruff/changie-automated-changelog-generation-for-any-project-1b52</guid>
      <description>&lt;p&gt;Getting started experience with Changie.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_asciinema"&gt;
  
&lt;/div&gt;


&lt;p&gt;It was over a year ago that I posted &lt;a href="https://dev.to/miniscruff/changie-automated-changelog-tool-11ed"&gt;an article&lt;/a&gt; about my side project &lt;a href="https://changie.dev"&gt;changie&lt;/a&gt;. That post was mostly a comparison of the file based approach compared to commit messages, this post is more about the Changie specific features.&lt;/p&gt;

&lt;p&gt;The full changelog for Changie, generated by Changie can be viewed on the &lt;a href="https://changie.dev/guide/changelog/"&gt;website&lt;/a&gt; or on &lt;a href="https://github.com/miniscruff/changie/blob/main/CHANGELOG.md"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Headers and Footers
&lt;/h2&gt;

&lt;p&gt;A big improvement to Changie has been allowing users to add custom headers and footers in a few formats. With full support for templating you can do some cool stuff.&lt;/p&gt;

&lt;p&gt;For all the details see the docs on &lt;a href="https://changie.dev/config/header-footer/"&gt;headers and footers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A small example could be to show many updates happened for each kind.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;headerFormat&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
  &lt;span class="s"&gt;Updates:&lt;/span&gt;
  &lt;span class="s"&gt;{{- range $kind := (kinds .Changes | uniq)}}&lt;/span&gt;
    &lt;span class="s"&gt;{{- $changeCount := (kinds $.Changes | count $kind)}}&lt;/span&gt;
    &lt;span class="s"&gt;{{- if gt $changeCount 0 }}&lt;/span&gt;
    &lt;span class="s"&gt;* {{$kind}}: {{$changeCount}}&lt;/span&gt;
    &lt;span class="s"&gt;{{- end}}&lt;/span&gt;
  &lt;span class="s"&gt;{{- end}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The end result would look something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## v0.1.0 - 2022-03-13
Update Counts:
  * Added: 2
  * Changed: 1
  * Deprecated: 1
  * Fixed: 3

### Added
* A
* B
### Changed
* C
### Deprecated
* D
### Fixed
* E
* F
* G
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One team is using the custom footers to show any public contributors per pull request, check out the &lt;a href="https://github.com/miniscruff/changie/discussions/262"&gt;discussion&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A simpler version of showing all unique contributors from GitHub would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# config yaml&lt;/span&gt;
&lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Author&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;minLength&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="na"&gt;footerFormat&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
  &lt;span class="s"&gt;### Contributors&lt;/span&gt;
  &lt;span class="s"&gt;{{- range (customs .Changes "Author" | uniq) }}&lt;/span&gt;
  &lt;span class="s"&gt;* [{{.}}](https://github.com/{{.}})&lt;/span&gt;
  &lt;span class="s"&gt;{{- end}}  &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Currently you can see headers and footers using either a format option in the &lt;a href="https://changie.dev/config/header-footer/#configuration"&gt;config&lt;/a&gt;, a file path option in the &lt;a href="https://changie.dev/config/header-footer/#configuration"&gt;config&lt;/a&gt; or by passing an &lt;a href="https://changie.dev/cli/changie_batch/"&gt;argument to batch&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Latest
&lt;/h2&gt;

&lt;p&gt;When creating tooling for automation or release notes it can be quite useful at times to know what our current version is.&lt;br&gt;
A good example of this is combining Changie with release automation such as GoReleaser as seen by this &lt;a href="https://github.com/miniscruff/changie/blob/a80f9b346faab7a5b48c822956fdc8fe068b2dac/.github/workflows/release.yml#L30-L31"&gt;GitHub Workflow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://changie.dev/cli/changie_latest/"&gt;Latest command docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Bumping
&lt;/h2&gt;

&lt;p&gt;Bumping can be used to increase the current version to the next version by semantic name instead of a new version. See the &lt;a href="https://changie.dev/cli/changie_batch/"&gt;batch command docs&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# instead of&lt;/span&gt;
changie batch v1.4.1
&lt;span class="c"&gt;# you can use&lt;/span&gt;
changie batch major
changie batch minor
changie batch patch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you just want the output for the next version you can use &lt;code&gt;next&lt;/code&gt;. See the &lt;a href="https://changie.dev/cli/changie_next/"&gt;next command docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dry runs
&lt;/h2&gt;

&lt;p&gt;When editing Changie configs, running a demo or maybe as part of CI logging, it can be useful to see what the output or changes would be without actually making those changes.&lt;br&gt;
This is especially true for Changie as, by default, it will create and delete many files that could be tedious to get back.&lt;/p&gt;

&lt;p&gt;To that end, any command that would write out to a file, edit a file or delete a file, you can add &lt;code&gt;--dry-run&lt;/code&gt; to instead print to standard out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;changie new &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
changie batch patch &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
changie merge &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is all for now. Reach me on twitter &lt;a href="https://twitter.com/miniScruffDev"&gt;@miniScruffDev&lt;/a&gt; or by starting a &lt;a href="https://github.com/miniscruff/changie/discussions"&gt;discussion on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>news</category>
      <category>go</category>
      <category>devops</category>
    </item>
    <item>
      <title>Get help automating your releases</title>
      <dc:creator>miniscruff</dc:creator>
      <pubDate>Tue, 23 Feb 2021 08:17:30 +0000</pubDate>
      <link>https://dev.to/miniscruff/get-help-automating-your-releases-21ig</link>
      <guid>https://dev.to/miniscruff/get-help-automating-your-releases-21ig</guid>
      <description>&lt;p&gt;Recently I posted an &lt;a href="https://dev.to/miniscruff/changie-automated-changelog-tool-11ed"&gt;article&lt;/a&gt; about my side project &lt;a href="https://changie.dev"&gt;Changie&lt;/a&gt; which automates changelog management. Currently, the only project using Changie is itself, which is kinda funny.&lt;/p&gt;

&lt;p&gt;Changie is only one piece of release automation that, I think, every project should have. But, if you are new or just a little inexperienced with release processes this can be a little overwhelming. So, I plan on offering some of my spare time to help other projects automate releases, including Changelogs. Ideally of course using Changie, but if your project doesn't fit within Changie's scope then I understand.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that the release automation is separate from automated tests, linting, and build checks but those are still very important.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So if you have a project that has the following criteria you can reach me below, on Twitter &lt;a href="https://twitter.com/miniScruffDev"&gt;@miniScruffDev&lt;/a&gt;, or as a discussion post on &lt;a href="https://github.com/miniscruff/changie/discussions"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project is open source&lt;/li&gt;
&lt;li&gt;Project has been updated sort of recently, at least in the last few months&lt;/li&gt;
&lt;li&gt;You would like to create or automate your changelog&lt;/li&gt;
&lt;li&gt;You would like to automate your releases&lt;/li&gt;
&lt;li&gt;The project is written in Go, Python, or Javascript/Typescript ( As I only currently have experience publishing on PyPI/NPM, and Go has no package repository )&lt;/li&gt;
&lt;li&gt;You of course would need to use Changie&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not sure exactly how well this will go, maybe only a few people may be a lot so will see how it goes. Of course, if you want help but maybe don't fit all the requirements you can still ask.&lt;/p&gt;

&lt;p&gt;How exactly I help could range from a simple pull request to private help, or a Zoom call, whatever fits best.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>python</category>
      <category>go</category>
    </item>
    <item>
      <title>Changie - Automated Changelog Tool</title>
      <dc:creator>miniscruff</dc:creator>
      <pubDate>Sat, 20 Feb 2021 22:57:02 +0000</pubDate>
      <link>https://dev.to/miniscruff/changie-automated-changelog-tool-11ed</link>
      <guid>https://dev.to/miniscruff/changie-automated-changelog-tool-11ed</guid>
      <description>&lt;p&gt;If you are developing a library, tool, package, or virtually any software you probably make a lot of changes. With all these changes you will want to inform your users, how might you do that?&lt;/p&gt;

&lt;p&gt;I will be going over as much information as I have about changelog methods and structures to compare my tool &lt;a href="https://changie.dev"&gt;Changie&lt;/a&gt; with. That way you can come up with the best approach for your team, project, or organization.&lt;/p&gt;

&lt;p&gt;Well, if you are building 'dev.to' you can publish &lt;a href="https://dev.to/link2twenty/changelog-paste-images-into-editor-25aj"&gt;Changelog posts&lt;/a&gt; describing all the new features directly. How else might you do it?&lt;/p&gt;

&lt;p&gt;There are two things to consider here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What format and method do we use for versions and changes&lt;/li&gt;
&lt;li&gt;How we track and publish our changes&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  SemVer and Keep A Changelog
&lt;/h2&gt;

&lt;p&gt;By far the most common method of versioning is &lt;a href="https://semver.org/"&gt;semantic versioning&lt;/a&gt;. This is the preferred method if your project needs to keep some form of compatibility with previous versions. Alternatives are &lt;a href="https://calver.org/"&gt;calver&lt;/a&gt; or my own &lt;a href="https://dev.to/miniscruff/introducing-hashver-41oh"&gt;hashver&lt;/a&gt; but for this article, I will be assuming semantic versioning.&lt;/p&gt;

&lt;p&gt;The next question is how we format the changelog in a clear way. For that, the most common structure is &lt;a href="https://keepachangelog.com/en/1.0.0/"&gt;Keep a Changelog&lt;/a&gt;. It is simple, clean, and well organized. There are other structures and creating your own is not too difficult so feel free to customize it a bit. The important part is that you have a cohesive structure and an easy-to-find place.&lt;/p&gt;

&lt;h1&gt;
  
  
  Tracking changes
&lt;/h1&gt;

&lt;p&gt;When developing your features you will need to eventually include these in your changelog, how do you go about tracking all these before your release is ready?&lt;/p&gt;

&lt;p&gt;Well, I have seen 3 different methods:&lt;/p&gt;

&lt;h2&gt;
  
  
  No tracking
&lt;/h2&gt;

&lt;p&gt;Don't do any tracking and write your release notes when you release. The idea here is that... well ok not much of an idea really you just wait until you want to release then try and figure out all your changes from memory, maybe your completed issues or closed pull requests?&lt;/p&gt;

&lt;p&gt;This tends to be the default as it is the "Do Nothing" approach. Of course, this often times translates to not having any changelog.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commit Messages
&lt;/h2&gt;

&lt;p&gt;Probably the most common option, or at least most readily available, is to pull your commit messages since the last release and package it all up. You have tools and formats such as &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;conventional commits&lt;/a&gt; combined with &lt;a href="https://github.com/conventional-changelog/standard-version"&gt;standard version&lt;/a&gt; can auto-generate changelogs for you. NodeJS's &lt;a href="https://github.com/nodejs/changelog-maker"&gt;changelog maker&lt;/a&gt; does the same thing in one package. &lt;a href="https://github.com/goreleaser/goreleaser"&gt;GoReleaser&lt;/a&gt; has a built-in release notes tool that acts very similarly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Files
&lt;/h2&gt;

&lt;p&gt;The last method, and the method used by Changie, is to store "change files" in your repository while you are working on new features, bug fixes, or improvements. Then through some templating tool combining all these files into your CHANGELOG.md for users. Or at least something similar to that.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pythons &lt;a href="https://devguide.python.org/committing/#what-s-new-and-news-entries"&gt;Blurb It&lt;/a&gt; generating the &lt;a href="https://docs.python.org/3/whatsnew/3.9.html"&gt;What's New&lt;/a&gt; pages&lt;/li&gt;
&lt;li&gt;Gitlab's &lt;a href="https://docs.gitlab.com/ee/development/changelog.html"&gt;Changelog Entries&lt;/a&gt; which they explain why in the &lt;a href="https://docs.gitlab.com/ee/development/changelog.html#history-and-reasoning"&gt;History&lt;/a&gt; section&lt;/li&gt;
&lt;li&gt;Twisted's &lt;a href="https://github.com/twisted/towncrier"&gt;Town Crier&lt;/a&gt; is a generic tool&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Changie
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://changie.dev"&gt;Changie&lt;/a&gt; is a new tool very similar to Town Crier and the other file-based solutions with the intent of being customizable enough to fit any project's needs. It is also released as a single binary using Go so it should be easy to install on any machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes Changie unique
&lt;/h2&gt;

&lt;p&gt;In keeping with the agnostic approach Changie aims to remove any language, tool, or framework requirements for changelog management. Creating binary releases for all platforms makes it easy to install no matter what language or tool your project is in (might need to add more but this is the goal). Changie is not a project requirement and will not be included in any dependency file. It is also not required for CI/CD like GitHub actions or Gitlab CI. Although, it can be integrated with them quite well. The &lt;a href="https://changie.dev/cli/changie_latest/"&gt;latest&lt;/a&gt; command can be used to output your latest version for release generation.&lt;/p&gt;

&lt;p&gt;Ability to customize a lot of the &lt;a href="https://changie.dev/config/formatting/"&gt;formatting outputs&lt;/a&gt;, with more options to come if needed.&lt;/p&gt;

&lt;p&gt;Changie uses a prompt-based CLI that can be extended with &lt;a href="https://changie.dev/config/choices/"&gt;additional choices&lt;/a&gt;. This system also includes validation options to check things are proper. More validation options will be added later but this already reduces typos and bad inputs. &lt;/p&gt;

&lt;p&gt;Do you reference your version in multiple places? Update them all during your release process using &lt;a href="https://changie.dev/config/replacements/"&gt;replacements&lt;/a&gt; which is basically just a find and replace option. &lt;/p&gt;

&lt;p&gt;Git is unused and not a requirement, you could use any source control on any platform and Changie would act the same way.&lt;/p&gt;

&lt;p&gt;All these options and features allow you to run two commands (batch+merge), then create a pull or merge request. The result of this commit is a release-ready point with a new changelog and versioned release notes. You could use GitHub releases, GitLab releases, or publish them on a blog.&lt;/p&gt;

&lt;p&gt;Note: Two commands are used here instead of one to allow you to include extra information with each release such as upgrade notes, more in-depth descriptions, or other release information not tied to a specific change.&lt;/p&gt;

&lt;p&gt;For example, Changie uses itself for its own Changelog management. You can view the resulting &lt;a href="https://github.com/miniscruff/changie/blob/main/CHANGELOG.md"&gt;CHANGELOG&lt;/a&gt;, &lt;a href="https://github.com/miniscruff/changie/tree/main/changes"&gt;changes directory&lt;/a&gt; and the GitHub &lt;a href="https://github.com/miniscruff/changie/blob/main/.github/workflows/release.yml"&gt;release&lt;/a&gt; action publishing GitHub &lt;a href="https://github.com/miniscruff/changie/releases"&gt;releases&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Benefits of Files over Commits
&lt;/h1&gt;

&lt;p&gt;Using files may seem a little strange to those who have used commit messages or just written up changelogs before so I would like to include a few advantages of using them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Separate information for developers and users&lt;/strong&gt;: Developers care about technical details but users don't. If you have to pull both from commit messages it will be hard to make it clear. This will not matter if your tool is for developers but even then, some details are only impactful for internal developers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typos&lt;/strong&gt;: If you have a typo in a commit message it will be pulled in for your changelog. If you fix it in the generated changelog it will still be wrong in the commit message. Using a file allows you to update it if you need to. You could also just remove it entirely if the feature was later removed before the release.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reviews&lt;/strong&gt;: Using a file allows you to include changelog updates as a part of your pull requests. This allows you to get reviews on the final output, especially helpful to get managers or tech writers to comment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customization&lt;/strong&gt;: Using commit messages rely on a rather strict input and output system. Customizing these can be difficult if possible at all. Conventional changelog spec can be found &lt;a href="https://github.com/conventional-changelog/conventional-changelog-config-spec/blob/master/versions/2.1.0/README.md"&gt;here&lt;/a&gt; but if you wanted to add a new field it is not possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Any Commit Style&lt;/strong&gt;: Using Changie does not restrict you from defining some commit style like standard commit or anything your team likes. But these are for developers only and should not be generated for your end-users. It also allows you to write smaller more concrete commits knowing each of them won't be part of the changelog.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thanks for reading, if you are interested in trying Changie the &lt;a href="https://changie.dev/guide/"&gt;guide&lt;/a&gt; is a good place to start.&lt;/p&gt;

&lt;p&gt;Changie is of course open-sourced on &lt;a href="https://github.com/miniscruff/changie"&gt;GitHub&lt;/a&gt;. Feel free to comment or reach out on GitHub.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>opensource</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Hidden TDD Benefit: Bookmarks</title>
      <dc:creator>miniscruff</dc:creator>
      <pubDate>Mon, 17 Feb 2020 09:33:02 +0000</pubDate>
      <link>https://dev.to/miniscruff/hidden-tdd-benefit-bookmarks-hl5</link>
      <guid>https://dev.to/miniscruff/hidden-tdd-benefit-bookmarks-hl5</guid>
      <description>&lt;p&gt;TDD is often mentioned for its benefits in code quality such as following DRY, YAGNI or other clean code standards. Today I want to talk about one overlooked benefit that has helped me countless times.&lt;/p&gt;

&lt;p&gt;Working in an open office has a few benefits but many downsides as engineers. Tips such as pair programming or listening to music help a little but even then there are always distractions. In addition to distractions, there are always times in your workday when you need to stop working for some amount of time. We all have to eat at some point.&lt;/p&gt;

&lt;p&gt;With the constant problem of starting and stopping at least a handful of times a day, how does TDD help?&lt;/p&gt;

&lt;h2&gt;
  
  
  Bookmarks
&lt;/h2&gt;

&lt;p&gt;TDD offers one very powerful advantage, a bookmark. You see, TDD is split between 3 phases usually referred to as red, green, refactor. Each of these three states can be easily discovered by running your test suite. By making our feedback loop as small as possible it also reduces the amount of information we have to keep in our heads at once.&lt;/p&gt;

&lt;p&gt;Now generally, TDD expects you to write your test just before it fails. This is so that you do not preemptively write code for a later feature. However, we can take notes on what tests we will &lt;em&gt;probably&lt;/em&gt; want to write later. That is, a comment or a test case that has no code but a failing assertion. We can use the name of the method to know what we need to write when we get there. This acts sort of like chapter titles.&lt;/p&gt;

&lt;p&gt;Before we begin we do have to do some setup work. Depending on your preferences and test runners you can choose between;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing empty test methods that fail

&lt;ul&gt;
&lt;li&gt;Only recommended if you can stop your test runner on the first fail ( for python and pytest you can add the &lt;code&gt;-x&lt;/code&gt; flag )&lt;/li&gt;
&lt;li&gt;If you can not stop on the first failure you will have to keep scrolling up to get the error logs and it's not fun&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Writing notes in code or on paper for your next tests

&lt;ul&gt;
&lt;li&gt;If using this method I like to write the method how it would look but just comment it out so I can pull it in later.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that I recommend configuring your test runner to re-run your suite on file change. For python I use pytest-watch, karma has a configuration for it, I believe jest does as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Take a break at any time
&lt;/h2&gt;

&lt;p&gt;Now that I have a set of test cases written down I have a few benefits. The first is, until all these test cases are done I know exactly what I am doing. And at any point, I can take a break and come back and know exactly what I need to work on next.&lt;/p&gt;

&lt;p&gt;This plays out in two ways depending on your choice of commented test case notes or failing empty test cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Failing empty test cases
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;This is my preferred approach.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We start by writing test methods with descriptive names and just a single failing assertion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_missing_user_auth_raises_401&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An example that has a clear description but no code. We can write as many of these that we come up with ahead of time. Noting that we may change our mind later but that is fine.&lt;/p&gt;

&lt;p&gt;Now, if we come back from a break and our tests fail because 0 is not true ( or the equivalent for your language ) then we know we are in the green or refactor phase and we can choose to refactor or write our test.&lt;/p&gt;

&lt;p&gt;If we come back and our test is failing for any other reason. We know we are in the red phase and we need to add code to get our test to pass.&lt;/p&gt;

&lt;p&gt;Finally, if all our tests pass it means we have finished all our existing test cases. At this point, we can probably make a pull request. ( or add docs and that good stuff )&lt;/p&gt;

&lt;h3&gt;
  
  
  Test comments
&lt;/h3&gt;

&lt;p&gt;If you go the route of just writing comments the flow is similar but has a few differences.&lt;/p&gt;

&lt;p&gt;If we come back from a break and our tests all pass then we are in the green or refactor phase and can pull the next comment out and write a test case.&lt;/p&gt;

&lt;p&gt;If we come back and our test is failing, then we are in the red phase.&lt;/p&gt;

&lt;p&gt;Finally, if our tests pass and we have no more comments we make that pull request.&lt;/p&gt;

&lt;p&gt;With this, I have been able to work quite efficiently despite the many distractions of an open office.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>tdd</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Introducing HashVer</title>
      <dc:creator>miniscruff</dc:creator>
      <pubDate>Mon, 03 Feb 2020 22:06:30 +0000</pubDate>
      <link>https://dev.to/miniscruff/introducing-hashver-41oh</link>
      <guid>https://dev.to/miniscruff/introducing-hashver-41oh</guid>
      <description>&lt;p&gt;I have been using a microservice like architecture at work for quite some time now ( about 2 years ). During this time I have mostly used &lt;a href="http://semver.org"&gt;semantic versioning&lt;/a&gt; for my builds. Using docker and a staging environment my workflow was as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a feature branch and pull request&lt;/li&gt;
&lt;li&gt;After reviews, it is merged into master&lt;/li&gt;
&lt;li&gt;Jenkins then builds a new &lt;code&gt;:stage&lt;/code&gt; docker image and deploys into staging&lt;/li&gt;
&lt;li&gt;After some time passes and we are satisfied with the stage build, we then prepare the next release&lt;/li&gt;
&lt;li&gt;This involves updating the CHANGELOG.md, at first it was manual but then I built a tool&lt;/li&gt;
&lt;li&gt;Then bumping the internal version field&lt;/li&gt;
&lt;li&gt;Creating a new PR for these changes and letting Jenkins redeploy stage.&lt;/li&gt;
&lt;li&gt;Then manually running a second job, which retags the latest stage image as the semantic version number and updates production&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This works out pretty well and is quite an improvement over what others on my team are doing ( do not get me started on that ). However, a few things have bugged me about all this.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A lot of steps for a new release&lt;/li&gt;
&lt;li&gt;Each release usually only had one maybe two small changes and really didn't need that much overhead&lt;/li&gt;
&lt;li&gt;When going from stage to prod, we rebuilt the image after we did our testing&lt;/li&gt;
&lt;li&gt;Our staging environment wasn't being used much and thus our testing wasn't significant&lt;/li&gt;
&lt;li&gt;Finally, the semantic version wasn't helpful in this case ( read more below )&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why not SemVer for services
&lt;/h2&gt;

&lt;p&gt;Semantic versioning is by far the most popular and common versioning scheme out. It is very well documented over at &lt;a href="https://semver.org"&gt;https://semver.org&lt;/a&gt; and is used by countless systems such as NPM, PyPI, NuGet, etc. I recommend and use SemVer for most work, but for services, I do not.&lt;/p&gt;

&lt;p&gt;The reason for this is SemVer aims to provide a means of safety, that is with each update you know if something will break or if its just bug fixes and is a safe upgrade. It aims to communicate a level of compatibility with other versions.&lt;/p&gt;

&lt;p&gt;So if you are using version 1.2.0 and version 1.3.2 is the latest, you know the versions are compatible and are generally safe to upgrade. If you are using 1.2.1 and the latest is 2.1.0 you know there is at least something that may be incompatible and you will need to make changes on your end to resolve it.&lt;/p&gt;

&lt;p&gt;But when you are working on a service presented straight to users this compatibility is largely unhelpful. A version change does not help most, if not all, users. If a new feature is added or major change is happening, you would want a large announcement to go along with it anyway. Additionally, if you merge and deploy often this extra effort of coming up with a version and updating the changelog is tedious.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does versioning do for you?
&lt;/h2&gt;

&lt;p&gt;It is very common for sites and services to just not use any versioning at all. For example, I do not think dev.to has an explicit version number (at least, I couldn't find it anywhere). This is not really a problem, I mean, if your favorite sites did have a version would that help you as a user? No, probably not.&lt;/p&gt;

&lt;p&gt;However, a version change achieves one big thing. It marks a new release. Think about a site you use frequently ( well, one that is also updated frequently ) how are you informed as a user of new changes? Do you get an email, notification, blog post, nothing?&lt;/p&gt;

&lt;p&gt;See versions tie our application at a certain time with the capabilities it had. When a new version is released, there are more, less or better capabilities with it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Hash Versioning
&lt;/h2&gt;

&lt;p&gt;Version numbers for constantly updating services or sites are largely irrelevant but having some version number or string for every release allows us to reference old builds, see changes or diagnose new problems. ( A nice sanity check to make sure that production bug is actually a bug or if the service was never deployed ). So, I created &lt;a href="https://miniscruff.github.io/hashver/"&gt;hashver&lt;/a&gt; which aims to build a generic version based on the date and git hash. &lt;/p&gt;

&lt;p&gt;These two pieces of information allow you to know approximately when the build was made which helps find stale builds and can signal the frequency of updates. The hash can be used to find the source. No need to git tag every release.&lt;/p&gt;

&lt;p&gt;Note that HashVer is not anything too new, I have heard or seen instances where similar versions are used especially for nightly builds. But by writing up a formal definition it can be standardized and shared.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cool now what
&lt;/h2&gt;

&lt;p&gt;Okay, so you have a version number attached to each deployment, now what?&lt;/p&gt;

&lt;p&gt;Well, good point, this version number doesn't by itself provide any benefit to our users but we have now automated it. You no longer need to choose or guess your version numbers, what else can we automate.&lt;/p&gt;

&lt;p&gt;Your changelog.&lt;/p&gt;

&lt;p&gt;What about building our changelog during our build/deploy process. Include this in your final build or referenced somewhere for your users to see when and what was added or changed. You can use many tools but I created &lt;a href="https://github.com/miniscruff/hashversion-python"&gt;hash version&lt;/a&gt; for python, &lt;a href="https://github.com/hawkowl/towncrier"&gt;town crier&lt;/a&gt; is also popular. GitLab has built &lt;a href="https://docs.gitlab.com/charts/development/changelog-manager.html"&gt;changelog manager&lt;/a&gt;. Python uses &lt;a href="https://pypi.org/project/blurb/"&gt;blurb&lt;/a&gt; for its official whats new page.&lt;/p&gt;

&lt;p&gt;What else?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Automated announcements for big updates&lt;/li&gt;
&lt;li&gt;Blog posts integrated into the changelog&lt;/li&gt;
&lt;li&gt;In-app notification on updates&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you have a place for automating release artifacts you can add many more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why go through all this effort?
&lt;/h2&gt;

&lt;p&gt;By including news and updates directly in your application, it allows users to take advantage of new features. How many times have you been using an application and discovered a cool feature and asked yourself "wow, this is cool when did they add this?". What about spending 3 months on a new awesome feature only to have no one use it cause it was hidden? Ever get asked about a new feature request and responded with "Oh, that is already available, and been there for 6 months?".&lt;/p&gt;

&lt;p&gt;Version changes mark a new release. This point is your time to add as much metadata as you can in order to communicate this new release to your users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Okay you convinced me, how can I do this?
&lt;/h2&gt;

&lt;p&gt;First, start tracking all your updates that affect the end-user. They generally do not care if you fixed linting issues or switched from PostgreSQL to MySQL. But they do want to know if markdown tables were added.&lt;/p&gt;

&lt;p&gt;Second, automate everything. Version changes, news generation, everything. If it's not automated, it will fall behind. And we plan on making lots of changes so this has to be lean.&lt;/p&gt;

&lt;p&gt;Finally, provide all this to your users somehow. I like to provide a link to my changelog down in the footer, it fits for my circumstances, but you do you.&lt;/p&gt;

&lt;p&gt;Changelog updates are just one part of what goes into each release, hash version aims to provide a foundation of what steps you should, could or may take in each microrelease. ( Microservices need microreleases just saying )&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>python</category>
      <category>devops</category>
      <category>rails</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How I Split Work: Recap</title>
      <dc:creator>miniscruff</dc:creator>
      <pubDate>Fri, 17 Jan 2020 03:25:31 +0000</pubDate>
      <link>https://dev.to/miniscruff/how-i-split-work-recap-kpn</link>
      <guid>https://dev.to/miniscruff/how-i-split-work-recap-kpn</guid>
      <description>&lt;p&gt;First off, thank you to everyone who has read my posts this will be the last one of the series. Today I will be recapping the series into a much smaller set of notes so you can bookmark this page for later.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pitch

&lt;ol&gt;
&lt;li&gt;Elevator pitch or more of user features and experiences.&lt;/li&gt;
&lt;li&gt;Enough to sell you on the idea&lt;/li&gt;
&lt;li&gt;Could come from anyone&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Cut

&lt;ol&gt;
&lt;li&gt;Take the pitch and cut out fluff, emotion, examples or unnecessary details&lt;/li&gt;
&lt;li&gt;Technical details are also cut and can be saved for the very end&lt;/li&gt;
&lt;li&gt;We end with a bullet point list of requirements&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Merge

&lt;ol&gt;
&lt;li&gt;Combine any bullet points that are very similar and can be handled together&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Abstract

&lt;ol&gt;
&lt;li&gt;Anything too specific can be abstracted up a level&lt;/li&gt;
&lt;li&gt;We end with a clean set of requirements&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Detail your end results

&lt;ol&gt;
&lt;li&gt;Blurb every idea you have&lt;/li&gt;
&lt;li&gt;You may need to trim down some ideas to fit your timeline, but I like to keep them all somewhere for later&lt;/li&gt;
&lt;li&gt;Check each idea to make sure it is viable and even possible&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Detail how users start the experience

&lt;ol&gt;
&lt;li&gt;Match your end results and requirements to what you will need&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Draw it out

&lt;ol&gt;
&lt;li&gt;Take the start and end to draw out a graph leaving a gap in the middle&lt;/li&gt;
&lt;li&gt;Fill in the middle, lining up the start and end parts with the requirements&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Break down

&lt;ol&gt;
&lt;li&gt;Take any abstract, high-level node and add details&lt;/li&gt;
&lt;li&gt;Split any merged requirements into separate nodes&lt;/li&gt;
&lt;li&gt;Make note of any edge cases and abort conditions&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Review

&lt;ol&gt;
&lt;li&gt;Get someone else to review your chart, preferably someone who wasn't part of the process&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Cleanup the chart

&lt;ol&gt;
&lt;li&gt;Optional: If you want to clean up your graph and maybe upload it somewhere&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Order

&lt;ol&gt;
&lt;li&gt;Start with closing the start &amp;gt; finish loop&lt;/li&gt;
&lt;li&gt;Then get the program to work correctly ( sometimes this is done already )&lt;/li&gt;
&lt;li&gt;Then handle any skipped edge cases, usually saving exceptions for last&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If at any point you feel things are not lining up or feels a little off, maybe even too big. Stop and go back a step or two and try again. More art than science here, quickly doing one or two iterations until you are happy is better than being far off later.&lt;/p&gt;

&lt;p&gt;Now you can start working, follow the style you prefer. I recommend TDD ( test-driven development ) or XP ( extreme programming ).&lt;/p&gt;

&lt;p&gt;That is it, thank you for reading this series.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>workflow</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How I Split Work: Review, Cleanup, and Order</title>
      <dc:creator>miniscruff</dc:creator>
      <pubDate>Thu, 16 Jan 2020 05:43:55 +0000</pubDate>
      <link>https://dev.to/miniscruff/how-i-split-work-review-cleanup-and-order-1ipj</link>
      <guid>https://dev.to/miniscruff/how-i-split-work-review-cleanup-and-order-1ipj</guid>
      <description>&lt;p&gt;As with any design you should always get your ideas reviewed by at least one other person. They will help catch things you missed or have incorrect. For this example, I will illustrate this point by mentioning we need to check if there are any available seats before selling a ticket.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleanup
&lt;/h2&gt;

&lt;p&gt;Now that we have our review complete, lets clean up this flow chart. This may or may not be necessary depending on how clean it was the first time.&lt;/p&gt;

&lt;p&gt;I did not do such a great job the first time so I redid the flow chart, a quick sketch by hand is more than enough so do not think you need to spend an hour or anything on this.&lt;/p&gt;

&lt;p&gt;Also, I just pick random shapes for things while trying to be consistent. If you know UML and like it, feel free to use that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffyvj1hxljbgugfsv11ac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffyvj1hxljbgugfsv11ac.png" alt="Cleaned up flow chart for movie theater problem"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Order
&lt;/h2&gt;

&lt;p&gt;Great we have a full flow chart from start to finish of what our product should do. Now what? Finding a reasonable order to work on the items in. The goal here is to do as little work, measured in time not count so big complicated stuff last, as possible in order to get our program to run with a result. The trick here is that we are ok with that result being incorrect as long as it completes.&lt;/p&gt;

&lt;p&gt;An example is skipping out on the sales tax, sure our program won't yield the correct expected results, but it ran and completed with something. We can manually calculate what it should be for now. Or we can just have a failing test, personal preference here.&lt;/p&gt;

&lt;p&gt;After we have our program running, we then want to fix any accuracy errors it may have.&lt;/p&gt;

&lt;p&gt;Then to round it off, handle all the possible edge cases we know of.&lt;/p&gt;

&lt;p&gt;Also, there will be many good answers to how you order things. So if what you came up with is different, that is probably fine. I will explain why I put things in the order I did as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fw3znnbawn4equu10xl5c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fw3znnbawn4equu10xl5c.png" alt="Clean flow with numbers representing the order"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We start with finding the price of a ticket, however, it does not need to be accurate yet. We can simply return any number here as long as it's done in some sort of function or class. We will want to modify this later on without affecting other pieces.&lt;/li&gt;
&lt;li&gt;Once we have a price, we can calculate the total.&lt;/li&gt;
&lt;li&gt;The first step of that is summing up all our tickets. We can make an array of our thing from before to sum it all up.&lt;/li&gt;
&lt;li&gt;We can then calculate the change based on this total and our input cash amount. It will be incorrect with missing sales tax but that's fine for now.&lt;/li&gt;
&lt;li&gt;After all that, we can now complete the flow and run our program from start to finish.&lt;/li&gt;
&lt;li&gt;Now that we have it running we can fix the issue with our accuracy which comes from missing our sales tax. So let's do that next.&lt;/li&gt;
&lt;li&gt;We have this working for a single ticket, lets now run this over a list of tickets.&lt;/li&gt;
&lt;li&gt;Next, let's fix up our price math to return the real value of our tickets in all cases.&lt;/li&gt;
&lt;li&gt;Finally, we end our feature set with calculating our discounts.&lt;/li&gt;
&lt;li&gt;End our work by checking for all our edge cases making sure if anything goes wrong we abort with no tickets created.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is it, you can now start programming. With step by step tasks like this TDD is a great candidate to follow.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>workflow</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How I Split Work: Add all the cases</title>
      <dc:creator>miniscruff</dc:creator>
      <pubDate>Wed, 15 Jan 2020 04:23:25 +0000</pubDate>
      <link>https://dev.to/miniscruff/how-i-split-work-add-all-the-cases-1nli</link>
      <guid>https://dev.to/miniscruff/how-i-split-work-add-all-the-cases-1nli</guid>
      <description>&lt;p&gt;Now that we have a rough outline of what sort of flow we have we want to fill in some of the gaps. At this point, we have to go back through all of our notes to make sure we do not forget anything. It is basically now or never, although not really but we can pretend.&lt;/p&gt;

&lt;p&gt;So anything in our flow chart that is vague or is many smaller pieces we will now break down. Once we break it down we will then handle any bad edge cases and take note of them. We have not decided what will happen for these but we can mark them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Break it down
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Check to see if the ticket is available&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is nothing related to this block that we need to break down, we will be going over this in the next part.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find the cost of the ticket&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This was mentioned during the pitch that we have ignored since. Now we can add those details back.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cheapest tickets during the week before 6 pm&lt;/li&gt;
&lt;li&gt;Middle tickets during the week after 6 or weekends before 4&lt;/li&gt;
&lt;li&gt;Expensive tickets weekends after 4&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note: There are 6 ( 3 ticket prices for child and adult tickets ) values here we do not have, but that is fine. In fact, we could probably pull out the times as parameters in case they end up changing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Apply all discounts&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This one we got back during the pitch as well, just a few different types of discounts. We do not yet know how much or how they combine, we will have to get that answered later ( hint hint ).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Military discounts&lt;/li&gt;
&lt;li&gt;Senior discounts&lt;/li&gt;
&lt;li&gt;Special promotions&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Sum all tickets for a total&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While going through this process you remember that we need to apply a sales tax, so we can add that now.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add X% sales tax to subtotal for a total&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Throw your hands up
&lt;/h2&gt;

&lt;p&gt;Now that we have some more details on our blocks, lets now focus on cases that might cause the order to be aborted. We do not know what to do about it yet, but we can mark it down.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Check to see if the ticket is available&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Is there a movie playing at the requested time?&lt;/li&gt;
&lt;li&gt;Are we trying to buy a child ticket during adult Monday?&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Sum all tickets for a total&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;What if the customer did not give us enough money?&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Print out tickets / receipt&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are going to assume that the printer works just fine, so no edge cases here. In practice, we would want to catch failures here as well but to keep this a little smaller we will ignore it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;That is it, we should have enough details here to present a pretty well thought out plan to our lead or clients.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f6c9Eh7E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/hz0k8in59eoed8qr9bl4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f6c9Eh7E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/hz0k8in59eoed8qr9bl4.png" alt="Flow chart of the movie program up to this point" width="547" height="773"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The flow chart is a bit squirrely at this point which is half cause I do not use draw.io much and half cause we just added a bunch more to our rough draft. This is expected, we will redo it a little later to be cleaner.&lt;/p&gt;

&lt;p&gt;You should see some of my flow charts, 3 or 4 iterations of a rough draft on one page, it gets really bad. For this reason, I like to use a small binder instead of a traditional notebook. It lets me rearrange my pages at will and I can swap between grid and lined pages.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>workflow</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How I Split Work: Draw it out</title>
      <dc:creator>miniscruff</dc:creator>
      <pubDate>Sun, 12 Jan 2020 19:13:41 +0000</pubDate>
      <link>https://dev.to/miniscruff/how-i-split-work-draw-it-out-2jlo</link>
      <guid>https://dev.to/miniscruff/how-i-split-work-draw-it-out-2jlo</guid>
      <description>&lt;p&gt;Through the first four articles, we have achieved some really great results.&lt;br&gt;
We were able to take an elevator pitch, filter just the important parts, analyze the end results and also the beginning. &lt;/p&gt;

&lt;p&gt;At this point, we can take our notes and pitch it to our project lead, product owner or a similar role at our company. Or, we can take this back to our users and get their thoughts. For demo purposes, I will be skipping this review step but this would be the first time you could do one. Even if you do not review it with another group, it is still good to take your notes and just say them out loud. &lt;a href="https://en.wikipedia.org/wiki/Rubber_duck_debugging"&gt;Rubber duckies work great here&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I prefer to do all drawing with pen and paper, but I will be using &lt;a href="https://draw.io"&gt;draw.io&lt;/a&gt; to share.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our goal for this stage is to take what we have written down so far in bullet points and map it to a flow chart. We will be doing this twice, first for the user experience side and second what our internals need to be for that to work.&lt;/p&gt;

&lt;p&gt;For reference our existing notes consist of the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Beginning

&lt;ol&gt;
&lt;li&gt;Requested tickets for the customer&lt;/li&gt;
&lt;li&gt;Amount of cash they are paying with&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Middle

&lt;ol&gt;
&lt;li&gt;Accept multiple tickets for any number of movies at once&lt;/li&gt;
&lt;li&gt;Allow discounts and promotions&lt;/li&gt;
&lt;li&gt;Only accept cash&lt;/li&gt;
&lt;li&gt;Tickets will have varying costs&lt;/li&gt;
&lt;li&gt;No child tickets sold on the first Monday&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;End

&lt;ol&gt;
&lt;li&gt;I should receive one ticket for each person&lt;/li&gt;
&lt;li&gt;My ticket should ...&lt;/li&gt;
&lt;li&gt;I should be given a printed receipt of the transaction&lt;/li&gt;
&lt;li&gt;My receipt should ...&lt;/li&gt;
&lt;li&gt;I should get the change back with my ticket&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As with all our previous steps I do this in two stages. First, I write out the beginning and the end. Then, I fill in the gaps with the middle pieces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outer Rim
&lt;/h2&gt;

&lt;p&gt;To start with we will be doing just the beginning and end stages with a magic "stuff" in the middle. The goal here is to force us to fill in that gap such that it makes logical sense and flows. If we were to start with the middle and work outwards we might assume we are given more than we are or that the end result is easier than we want.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If you know UML you can use it here, I do not and just pick shapes that I like for different nodes. Our flow chart will never be so intense we need most of what UML offers. If you ever feel you need to do full UML you probably just want to split your entire task.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CdvxlJUB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/dd7fsnrbyaz312u54i8g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CdvxlJUB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/dd7fsnrbyaz312u54i8g.png" alt="Beginning and the end stages in a flow chart" width="147" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Plug the hole
&lt;/h2&gt;

&lt;p&gt;As we do our next stage we want to get as many of our supported features as possible but only from a high-level description. We do not want to go into technical details here or try and explain every conditional situation. At the end of this, we can have another review with users or project leads all while speaking our native language.&lt;/p&gt;

&lt;p&gt;The longer we can go without writing code the better. This might sound "unagile" or "waterfally" as we are spending so much time upfront but this should be cleared up later. ( If not, ask in the comments )&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8EGMdObx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/pyw40c7hw6e9y9h6n2sz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8EGMdObx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/pyw40c7hw6e9y9h6n2sz.png" alt="All stages of our process up to now as a flow chart" width="260" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;p&gt;If you notice I did not explicitly mention how to find the cost of the tickets or for what reasons a ticket would be unavailable. At this moment, I am choosing to hold off on those details. Because at this stage all that would do is cloud the flow and cause it to balloon in time required. This is all meant to be done quickly. We can get a pretty good understanding of flow with simple notes like this more than a full book.&lt;/p&gt;

&lt;p&gt;We are also only focusing on the path that assumes all conditions are valid and no edge cases are hit. That is, we do not handle if the customer does not give us enough money or the ticket is not available. We will be handling these later.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>workflow</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
