Skip to content

Instantly share code, notes, and snippets.

@sbchapin
Last active August 10, 2023 01:02
Show Gist options
  • Save sbchapin/fcf99ba437ab99ef77c28b9c162b6292 to your computer and use it in GitHub Desktop.
Save sbchapin/fcf99ba437ab99ef77c28b9c162b6292 to your computer and use it in GitHub Desktop.
Semantic release examples

Trunk-based

Given a main branch used in a trunk-based development strategy, here is how semantic release can fit in:

%%{init: { 
    'logLevel': 'debug',
    'theme': 'default' , 
    'themeVariables': {
        'git0': '#777',
        'git1': '#D75E2A',
        'git2': '#9ACB27',
        'git3': '#2A4092',
        'git4': '#9ACB27',
        'git5': '#9ACB27'
    } 
} }%%
gitGraph
        %% Setup:
        commit id: "(the past)" tag: "1.2.3"

        %% ------------
        %% -- bugfix --
        %% ------------
        branch TIX-237-pencil-pressure-bug
        checkout TIX-237-pencil-pressure-bug
        commit id: "fix(pencil): pressure no longer breaks graphite"
        %% On-merge of the bugfix branch, release (CI should do this on PR merge with Semantic-Release, detecting the "fix(pencil):")
        checkout main
        merge TIX-237-pencil-pressure-bug
        commit id: "(semrel: 1.2.3 -> 1.2.4)" tag: "1.2.4"

        %% -------------
        %% -- feature --
        %% -------------
        branch TIX-199-pencil-width-support
        checkout TIX-199-pencil-width-support
        commit id: "feat(pencil): add 'graphiteWidth' option"
        %% On-merge of the feature branch, release (CI should do this on PR merge with Semantic-Release, detecting the "feat(pencil):")
        checkout main
        merge TIX-199-pencil-width-support
        commit id: "(semrel: 1.2.4 -> 1.3.0)" tag: "1.3.0"

        %% ----------------------
        %% -- breaking-changes --
        %% ----------------------
        branch TIX-827-pencil2-feature-complete
        checkout TIX-827-pencil2-feature-complete
        commit id: "feat(pencil): add static rubber grip"
        commit id: "feat(pencil): add metal pocket clip"
        commit id: "breaking(pencil): remove 'graphiteWidth' option"
        %% On-merge of the feature branch, release (CI should do this on PR merge with Semantic-Release, detecting the "feat(pencil):"  and "breaking(pencil):")
        checkout main
        merge TIX-827-pencil2-feature-complete
        commit id: "(semrel: 1.3.0 -> 2.0.0)" tag: "2.0.0"

        %% ----------------
        %% -- user-error --
        %% ----------------
        branch TIX-921-pencil2-documentation
        checkout TIX-921-pencil2-documentation
        commit id: "forgetting to use convention"
        %% On-merge of the feature branch Semantic-Release detects no changes, and releases nothing
        checkout main
        merge TIX-921-pencil2-documentation id: "semrel doesnt trigger"
        checkout TIX-921-pencil2-documentation
        commit id: "chore(pencil): remembering this time, it was documentation"
        %% On-merge of the feature branch Semantic-Release again detects no changes other than a chore, and releases nothing
        checkout main
        merge TIX-921-pencil2-documentation id: "again, semrel doesnt trigger"
        branch TIX-199-pencil2-width-support
        checkout TIX-199-pencil2-width-support
        commit id: "feat(pencil): adding 'graphiteWidth' option back"
        %% On-merge of the feature branch, release (CI should do this on PR merge with Semantic-Release, detecting the "feat(pencil):")
        checkout main
        merge TIX-199-pencil2-width-support
        commit id: "(semrel: 2.0.0 -> 2.1.0)" tag: "2.1.0"
Loading

Pros/Cons

  • πŸ‘ Easy to implement in CI
  • πŸ‘ Easy to describe to people
  • πŸ‘Ž Difficult to hotfix production
  • πŸ‘Ž Goes "straight to prod", or you must manage staging/prod outside of your CI/CD flow from git
  • πŸ‘Ž Snapshots or "incubation" have to have side-branching strategies

Prescription:

Probably use this if you release often and aren't scared to deploy new features to production, and/or if stuff breaks very infrequently.

Probably don't use this if you are a library author, if you have a very large surface area to support in your application, and/or if you need git branches to mirror your environments (prod, staging).

Gitflow-based

Given a main branch and a develop branch used in a gitflow-based development strategy, here is how semantic release can fit in:

%%{init: { 
    'logLevel': 'debug',
    'theme': 'default' , 
    'themeVariables': {
        'git0': '#777',
        'git1': '#D75E2A',
        'git2': '#AAA',
        'git3': '#9ACB27',
        'git4': '#2A4092',
        'git5': '#9ACB27',
        'git6': '#9ACB27'
    } 
} }%%
gitGraph
        %% Setup:
        commit id: "(the past)" tag: "1.2.3"
        branch TIX-237-pencil-pressure-bug %% put this between main and develop
        branch develop

        checkout develop
        commit id: "other development" %% to illustrate that there are things happening outside the bugfix

        %% ------------
        %% -- hotfix --
        %% ------------
        checkout TIX-237-pencil-pressure-bug
        commit id: "fix(pencil): pressure no longer breaks graphite"
        %% Cross-merge the hotfix branch (CI should do this with Semantic-Release, detecting the "fix(pencil):")
        checkout main
        merge TIX-237-pencil-pressure-bug
        checkout develop
        merge TIX-237-pencil-pressure-bug tag: "1.2.4-prerelease"
        checkout main
        commit id: "(semrel: 1.2.3 -> 1.2.4)" tag: "1.2.4"

        %% -------------
        %% -- feature --
        %% -------------
        checkout develop
        branch TIX-199-pencil-width-support
        checkout TIX-199-pencil-width-support
        commit id: "feat(pencil): add 'graphiteWidth' option"
        %% On-merge of the feature branch, release (CI should do this on PR merge with Semantic-Release, detecting the "feat(pencil):")
        checkout develop
        merge TIX-199-pencil-width-support
        commit id: "(semrel: 1.2.4 -> 1.3.0)" tag: "1.3.0-prerelease"
        checkout main
        merge develop tag: "1.3.0"

        %% ----------------------
        %% -- breaking-changes --
        %% ----------------------
        checkout develop
        branch TIX-827-pencil2-feature-complete
        checkout TIX-827-pencil2-feature-complete
        commit id: "feat(pencil): add static rubber grip"
        commit id: "feat(pencil): add metal pocket clip"
        commit id: "breaking(pencil): remove 'graphiteWidth' option"
        %% On-merge of the feature branch, release (CI should do this on PR merge with Semantic-Release, detecting the "feat(pencil):"  and "breaking(pencil):")
        checkout develop
        merge TIX-827-pencil2-feature-complete
        commit id: "(semrel: 1.3.0 -> 2.0.0)" tag: "2.0.0-prerelease"
        checkout main
        merge develop tag: "2.0.0"

        %% ----------------
        %% -- user-error --
        %% ----------------
        checkout develop
        branch TIX-921-pencil2-documentation
        checkout TIX-921-pencil2-documentation
        commit id: "forgetting to use convention"
        %% On-merge of the feature branch Semantic-Release detects no changes, and releases nothing
        checkout develop
        merge TIX-921-pencil2-documentation id: "semrel doesnt trigger"
        checkout TIX-921-pencil2-documentation
        commit id: "chore(pencil): remembering this time, it was documentation"
        %% On-merge of the feature branch Semantic-Release again detects no changes other than a chore, and releases nothing
        checkout develop
        merge TIX-921-pencil2-documentation id: "again, semrel doesnt trigger"
        branch TIX-199-pencil2-width-support
        checkout TIX-199-pencil2-width-support
        commit id: "feat(pencil): adding 'graphiteWidth' option back"
        %% On-merge of the feature branch, release (CI should do this on PR merge with Semantic-Release, detecting the "feat(pencil):")
        checkout develop
        merge TIX-199-pencil2-width-support
        commit id: "(semrel: 2.0.0 -> 2.1.0)" tag: "2.1.0-prerelease"
        checkout main
        merge develop tag: "2.1.0"
Loading

Pros/Cons

  • πŸ‘Ž More difficult to implement in CI (consider the hotfix cross-merge and how to remediate when things can't automerge)
  • πŸ‘Ž Difficult to describe or substantiate to people (especially juniors and non-developers)
  • πŸ‘ Easy to hotfix production
  • πŸ‘ Can mirror your environments where main is prod and develop is staging, allowing for complete CI/CD flows off of git
  • πŸ‘ Snapshots or "incubation" are directly supported on develop

Prescription:

Probably use this if you release only when you need to, are scared to deploy new features to production, you need staging builds or prereleases, and/or if stuff breaks very frequently and needs thorough vetting before deployment/release.

Probably don't use this if you have a lot of people with less git experience, and/or if you have a simple application.

Gitflow-based (for library and LTS App authors)

Sometimes complex isn't complex enough.

If you have to support a library (and subsequently a lot of old library versions) or if you have to support many minor versions of an application for a long period of time, you will need to support hotfixes, and more importantly you will not want to reimplement those hotfixes repeatedly.

So, if you have a need for backports of hotfixes (or features), consider extending the above gitflow diagram, but use channels to tighten down your versions or version ranges (depending on how you want to push your artifacts) and use maintenance branches to let semantic release do the hard work of applying backports.

This likely means having one main branch and N release-{your_methodology_here} branches instead of one main branch and one staging branch. This will allow you to have virtually the same diagram as above, but Semantic Release can perform the cross-merges between the maintenance branches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment