RELEASING

Notes for hledger release managers and maintainers.

Goals

2024

  • Make releasing easier

2023

  • Make releasing easyier

2022

  • Update/consolidate release process docs
  • Establish routine monthly release cadence
  • Make releasing easy

Release types

hledger major releases happen each quarter, normally at the start of the third month (see past releases). Bugfix releases follow when needed. Preview releases may happen in the other months if wanted.

Major release
A.B
Bugfix release
A.B.C
Fixup release
A.B.C.D
Preview release
A.B.99.D
Contains:New features, breaking changesOnly bug fixesTrivial packaging fixes, no software changesEarly snapshot of the next major release
When:Third month of quarter: March, June, September, DecemberWhen neededNeverFirst & second months of quarter
Deliverables:
Changelogs
Github release
Binaries
Hackage release
Install page
hledger-install
Regression bounty
Release notes
Web manuals
Announcements

Release manager activities

These have complex interdependencies and sequencing constraints. Chunk, separate, routinise, document and automate them as far as possible.

Softwareselecting changes, packages, release dates; coordinating contributions; ensuring release readiness
Branch Managementcoordinating main and release branch, local and remote repos, CI branches
Version Bumpingchoosing and applying new version numbers and related things like tags, github releases, urls, ghc and dep versions, stackage resolvers, everywhere needed
Docscommand help, manuals, changelogs, release notes, github release notes, install page, install scripts, announcements, process docs
Testinglocal testing, CI testing, extra release-specific testing
Artifactsgenerating binaries, zip files, github releases etc.
Publishinguploading, pushing, making visible, finalising
Announcingvarious announcement stages and channels

Glossary

Some terminology useful when precision is needed, eg in release scripts.

General

release
A snapshot of the software and related artifacts like executable binaries, which is named, tagged, documented, announced, and usually picked up by packaging systems on various platforms.

version control system, VCS
A tool used for storing and sharing and viewing the history and different lines of development of a software project, or other set of files. hledger uses Git.

repository, repo
A set of files being stored and managed by a VCS. Often published on a repository hosting service, such as Github.

working copy, clone
A local copy of a repository's files. Typically each developer has one or more of these, and can share changes easily with the official public repository.

branch
Some VCS's, including Git, can store multiple branching lines of development within one repository. A working copy can be quickly switched to a different branch to show its content.

master, main
The main branch in a repo, usually named master or main. Pull requests are usually relative to this.

pull request, PR
A request to merge a development branch with master, and any related discussion. On Github, these are kept alongside issues in the issue tracker.

continuous integration, CI
Automated actions that run when new code is pushed to a shared repo, such as running tests or producing binaries. On Github this is called Github Actions and action scripts are called workflows.

release engineering
https://en.wikipedia.org/wiki/Release_engineering

hledger-specific

package
A releasable unit of Haskell software. hledger has several core packages usually released together: hledger-lib, hledger, hledger-ui, hledger-web.

hledger version number
A 2-4 part dotted number naming a hledger release or hledger package version: MA.JOR[.MINOR[.FIXUP]] or MA.JOR.99[.PREVIEW] where 99 means "unreleased (MAJOR+1)". See examples below.

hledger version string
A line of text describing a hledger binary, shown by --version. It contains program name, version number, commit hash and date, machine architecture etc. Eg: hledger 1.24.1-g7799d526b-20211210, mac-x86_64

Full release
A release of all four core hledger packages (hledger-lib, hledger, hledger-ui, hledger-web). Major and preview releases are always full releases.

Partial release
A release of just some of the hledger packages. Bugfix and fixup releases are sometimes partial.

Single-version release
A release where all packages have the same version. Major and preview releases are always single-version.

Mixed-version release
A release where the packages have different versions, because of a previous partial release. Bugfix and fixup releases are sometimes mixed-version.

changelog
A CHANGES.md file listing the release history and the changes in each release. There is one for each hledger package and one for the hledger project as a whole.

release notes
The Release Notes page on the hledger website: the combined release history of the core hledger packages, showing user visible changes only.

Releases and builds

Major release
Major releases include new features and incompatible API changes, and normally happen at the start of each quarter's third month (3/1, 6/1, 9/1, 12/1). Example version number: 1.25

Bugfix release
Bugfix releases include only bug fixes, without API changes. These happen when needed, to fix significant bugs in the previous major release. Example version number: 1.25.2 ("second bugfix release for 1.25")

Fixup release
Fixup releases fix packaging errors, with no changes to the hledger software. These should be rare. Example version number: 1.25.0.1 or 1.25.2.1 ("first fixup release for 1.25 / 1.25.2")

Preview release
A preview of the upcoming major release for testers/early adopters, and a test of the release process, published on Github. Not a formal hledger release, eg not published on Hackage, usually not packaged, no bugfix releases, no regression bounties, not shown in release notes. These typically appear in the quarter's first and second month if needed. Example version number: 1.25.99.1 ("preview 1 of 1.26")

CI binaries
Temporary downloadable binaries produced by a run of the linux/mac/windows workflows in the hledger repo. This may happen periodically, eg weekly. Downloading requires a Github login.

Dev build
A local developer build of unreleased code. This is typically in master or a development/PR branch. Example version number: 1.25.99 ("unreleased 1.26-dev")

Repos and branches

hledger repo
The hledger git repository, containing the hledger software, reference manuals, and developer docs. https://github.com/simonmichael/hledger

site repo
The hledger_website git repository, containing most of the hledger website which appears at https://hledger.org. Usually checked out under the hledger repo as site/. https://github.com/simonmichael/hledger_website

finance repo
The hledger_finance git repository, containing the hledger project's financial ledger. Usually checked out under the hledger repo as finance/. https://github.com/simonmichael/hledger_finance

master
The branch named master in the hledger repo; the main line of hledger development. Pull requests are usually relative to this.

release branch
Branches named MA.JOR-branch in the hledger repo, eg 1.25-branch. Releases and release previews are always made from a release branch.

Release artifacts / value chain

Higher things depend on lower things. Release readiness and the release process go from the bottom of this diagram to the top.

release diagram

Checklist

Waypoints and required artifacts.

  • product
    • blocking defects resolved
    • desired improvements landed and stabilised
    • building and passing tests with current ghcs, deps, and stackage snapshots
    • building and passing tests on all platforms
      just relbin (or push to github binaries[-*] branch)
  • product docs and metadata
    • release branch
    • version strings (in **/.version, */.version.m4, */package.yaml)
    • cabal files x 4 (hledger*/hledger*.cabal)
      just relbranch
    • options help texts up to date (in CliOptions.hs, UIOptions.hs, WebOptions.hs)
    • embedded manuals x 3
      • generaloptions macro (in doc/common.m4)
      • tool specific options in manuals (hledger*/hledger*.m4.md > # Options)
      • man page dates (*/.date.m4)
      • man (hledger*/hledger*.1)
      • info (hledger*/hledger*.info)
      • text (hledger*/hledger*.txt)
        ./Shake manuals -c
    • embedded tldr pages synced with upstream (doc/tldr/*)
      just tldr-diff
    • embedded asciinema demos (hledger/embeddedfiles/*.cast)
    • shell completions (hledger/shell-completion/hledger-completion.bash)
      just completions, commit any changes
    • changelogs x 5 (**/CHANGES.md)
      just changelogs [-c]
      just changelogs-finalise
  • release docs and artifacts
    • draft binaries building started
      just relbin
    • hledger.org html manuals x 3 (site/src/VER/*.md)
      just site-manuals-snapshot VER
      update site/Makefile, site/js/site.js, site/hledger.org.caddy
    • release notes @ hledger.org (doc/relnotes.md)
      just relnotes,
      select & transform with md-issue-refs,
      uniquify issue refs,
      unwrap long lines,
      add author github nicks,
      commit
    • github binary install docs up to date and pre-tested (doc/ghrelnotes.md)
    • hledger-install up to date and pre-tested (hledger-install/hledger-install.sh)
      ./Shake hledger-install-version,
      check/update dep versions,
      select/test snapshot version
    • hledger.org Install page up to date and pre-tested (site/src/install.md)
    • draft announcement for chat / mail list (doc/ANNOUNCE)
    • draft announcement for mastodon (doc/ANNOUNCE.masto)
    • release tags
      just reltags
    • release binaries built from tag
      just relbin
  • published
    • all packages uploaded correctly to hackage
      just hackageupload
    • hledger-install merged to master and pushed to github
    • site repo pushed to github and hledger.org, new manuals rendering correctly
    • release branch and tags pushed to github
      just reltags-push
    • github release with release binaries attached (https://github.com/simonmichael/hledger/releases/new)
      should be autocreated by the above; if not, https://github.com/simonmichael/hledger/releases/new, just ghrelnotes, paste, download release binaries, upload release binaries, review
      publish
    • install instructions tested and working
      • hledger-install
      • stack
      • cabal
      • source checkout
      • github release > How to install, each platform
    • announced
  • cleanup and support
    • remaining relevant release branch work merged to master
    • new dev tag/versions/man dates in master
      j devtag
    • pta.o project stats updated
    • process notes updated/cleaned
    • monitor/support/handle issues:
      issue tracker, matrix, irc, mail list, forum, reddit

After release, it's a good time for:

  • finance repo updates
  • hledger.org doc updates
  • pta.o doc updates

How-to notes

More detailed procedure notes.

General tips

  • Release, or practice releasing, often to improve the process.

  • Use and continually update RELEASING.md. Document procedures and gotchas to save time and enable automation in future.

  • Also the diagram (RELEASING.canvas, made with Obsidian).

  • But don't document prematurely or in too much detail.

  • Make things a little better each time through: simpler, more reliable, better documented, more automated, easier, faster, cheaper, higher quality.

  • Optionally save this file as RELEASING2.md and update notes there until after release, if it's interfering with git branch switching.

  • Use and update scripts, in Justfile, Shake.hs, tools/ etc.

  • Do all releases from a release branch.

  • Update dev changelogs frequently in master. Finalise changelogs in the release branch. Merge back to master after release. (Related older doc: CHANGELOGS)

  • All release binaries should be built from the release-tagged commit. The binaries' --version output should match the release tag and release date.

  • Try to do only full releases including all four main hledger packages; partial releases add complexity.

  • Try to avoid pre-announcing a hard release date. It will always take more time than you think, if you go late you might miss your intended date in many timezones, and there's no point adding unnecessary pressure.

  • The biggest potential time sinks are:

    • reviewing/relearning the process/docs/infrastructure
    • updating/improving the process/docs/infrastructure
    • preparing changelogs
    • building binaries for all platforms
    • troubleshooting github workflow issues
    • followup work due to release mistakes, bugs in new features, or regressions
  • Hard/risky/intensive tasks should happen without time pressure; during the final countdown, things should be easy.

Check release readiness

Prepare release

In main repo, release branch:

  1. Create/switch to release branch, update versions/dates/docs: just relprep NEW (single-version releases; for mixed-version releases, take more care)
  2. If not the first release in this branch, cherry-pick changes from master: magit l o ..master (minor releases)
  3. Update shell completions: make -C hledger/shell-completion
  4. (Could start building/testing/fixing release binaries/workflows/caches here, it takes time: just relbin)
  5. Update install script: hledger-install/hledger-install.sh
  6. Update changelogs (**/CHANGES.md): ./Shake changelogs, manually edit, ./Shake changelogs -c
  7. Update release notes (doc/relnotes*): tools/relnotes.hs, select & transform with md-issue-refs, uniquify issue refs, add github nicks to authors, commit
    TODO: tools/relnotes.hs: last release's summary, headings, unwrap long lines md-issue-refs: uniquify
  8. Update announcements (doc/ANNOUNCE*) (major releases)
  9. Build/test release binaries: just relbin. Troubleshoot/repeat as needed.

In site repo:

  1. Update config in hledger.org.caddy (@oldmanpath, @unversionedmanpath, any new redirects) (major releases, usually)
  2. Update online manuals: bump versions in site/Makefile, site/js/site.js, make -C site snapshot-NEW (major releases) TODO: snapshot: don't switch to master, don't discard uncommitted changes, record git hash in commit message, clarify late update procedure
  3. Update install page: site/src/install.md
  4. Don't push yet. Keep in local branch if needed.

In main repo, master:

  1. Cherry-pick the hledger-install update, and other finished useful updates, from the release branch (maybe not release docs yet): magit l o LASTREL..REL-branch
  2. Bump version in master (major releases)
  3. Add a new dev tag on the "bump version to ..." commit (magit t t REL.99)

Publish release

In main repo, release branch:

  1. Build final release binaries (just relbin) and tag the release (just reltag)
  2. Push release branch & tags (not more than 5 tags at once):
    git push github HEAD REL hledger-REL hledger-lib-REL
    git push github HEAD hledger-ui-REL hledger-web-REL
    Don't push all tags (don't push the dev tag; if you do, manually delete the corresponding draft release.)
  3. release.yml creates a draft release when the REL tag is pushed. Check/fix its content. TODO: fix release.yml
  4. Publish on hackage (final check): just hackageupload
  5. Publish github release

In main repo, master:

  1. Push master: just push

In site repo:

  1. Push to github (& site): git push github or magit P p

In hledger.org cloudflare caching settings:

  1. Custom Purge https://hledger.org/js/site.js (major release)

On hledger.org VPS: (major release, usually)

  1. Restart caddy to enable new redirects
  2. Test https://hledger.org/hledger.html redirect
  3. Test manuals are displaying and highlighting the new version
  4. If needed, make buildall

Announce

(major releases, others if needed)

  1. Update hledger entry at https://plaintextaccounting.org/#pta-apps
  2. hledger matrix & irc chats
  3. PTA forum
  4. hledger mail list (& optionally haskell-cafe)
  5. mastodon with #hledger and #plaintextaccounting tags

Post release

  1. Cherry-pick any final useful updates from the release branch (eg release docs): magit l o LASTREL..REL-branch
  2. Add/commit any process updates: doc/RELEASING.md
  3. Monitor packaging status (stackage, brew, docker, linux, nix etc); keep install page updated
  4. Monitor, follow up on issues, especially regressions; keep doc/REGRESSIONS.md updated

Up-to-date tools

  • Check for consistent stackage snapshot(s) and extra deps used in stack.yaml, Shake.hs, hledger-install.sh, bin scripts, tools scripts
  • Shake binary is up to date ./Shake.hs
  • hpack --version matches the one in stack --version

Local tests

  • just test
  • just doctest
  • just haddocktest

CI tests

  • push to a PR, wait for green
  • or push to ci branch, wait for green at https://ci.hledger.org
  • or just push (pushes to ci, then to master)

Release branch tests

  • just test
  • stack exec -- hledger --version, check version, hash, release date, no '+'
  • stack exec -- hledger help | tail, check version, month matches release

Download release binaries

With all platform binary tests green on same commit

  • clear out any old hledger* from local Downloads dir
  • in each github binary job: in safari, right click the artifact, Download linked file
  • optional: unpack and save the github binaries for local platform (mac-arm64)
  • optional: also build native local binaries from that same commit: just installallas VER

Update Install page

In site repo:

  • update install.md
    • query-replace OLD -> NEW in
      • "current hledger release"
      • CI binaries badges/links, including linux-static-arm32v7 if built
      • "building from source"
      • stack install command
      • cabal install command
    • query-replace OLD-brightgreen -> OLD-red
    • only after release binaries are built (preferably after release is published): update --version outputs (version, hash, date, but not platform)
    • final output line from hledger test (run local build and in terminal for normal speed)
    • Total count from make functest
    • preview
    • commit: install: NEW

Update RELEASING.png

  • edit RELEASING.canvas in obsidian
  • CMD-p > Export as image, don't show logo
  • commit

Monitor packaging status, update Install page

  • homebrew - expect badge to update soon
  • docker - expect/merge PR
  • nix - expect badge to update after a few days; can check with make nix-hledger-version
  • linux distros - once in a while, follow the links & search for newer versions, update

Update hledger in stackage

Update homebrew formula

Usually automatic; contacts: chenrui, other past packagers, Athas on #haskell