Simple Hackage release workflow for package maintainers

Version on this page:
LTS Haskell 21.13:
Stackage Nightly 2023-09-24:
Latest on Hackage:

See all snapshots hkgr appears in

GPL-3.0-only licensed by Jens Petersen
Maintained by
This version can be pinned in stack with:hkgr-,1504

Module documentation for

There are no documented modules for this package.


Hackage GPL-3 license Build status

hkgr (pronounced “hackager”) is a tool for making releases of Haskell packages on Hackage.


$ hkgr
Hackage Release tool

Usage: hkgr [--version] COMMAND
  'Hackager' is a tool for easy Hackage package release workflow

Available options:
  -h,--help                Show this help text
  --version                Show version

Available commands:
  tagdist                  'git tag' version and 'cabal sdist' tarball
  upload                   'cabal upload' candidate tarball to Hackage
  publish                  Publish to Hackage ('cabal upload --publish')
  upload-haddock           Upload candidate documentation to Hackage
  publish-haddock          Publish documentation to Hackage
  version                  Show the package version from .cabal file


You are preparing for a release…

So you commit changes to your package and push them to check CI results:

$ git commit -m "new release"
$ git push


Now you want to make a dist tarball, which is done from a git tag:

$ hkgr tagdist

The tagdist command first reads the current package version (from the .cabal file in the current directory), and uses that to git tag. It then runs cabal sdist from a temporary pristine checkout of the tag to generate the dist tarball.

If the tag already exists (eg if you already ran tagdist earlier), and you need to add commits to the release you can use --force to move the tag to the latest commit and generate a new tarball off that, otherwise tagdist refuses to run again to prevent accidently overwriting the tag and dist tarball.

One should not be able to tagdist on an already published (ie released) version.

(If sdist fails for some reason then hkgr tries to reset the tag.)


If all is good, it’s time for a candidate release:

$ hkgr upload

This uploads a candidate dist tarball to Hackage: this can be repeated.

Haddock draft documentation can also be uploaded if desired:

$ hkgr upload-haddock


Once you are happy, you can release to Hackage:

$ hkgr publish

If it succeeds then hkgr creates a “published lockfile” in dist/, and the git tag is pushed to origin.

(Then hkgr will refuse to do further commands on the released version.)

Optionally one can publish haddock docs:

$ hkgr publish-haddock


hkgr uses cabal-install, git, and also hlint if available.


Changelog (2020-02-11)

  • assert that cabal-install installed
  • run hlint in git checkout instead of working tree

0.2.4 (2019-10-05)

  • git push before publishing
  • only push up to tag

0.2.3 (2019-09-30)

  • push git tag
  • hlint is now a warning not an error
  • prefix version tags with v
  • surround git diff output with quote lines
  • catch exception for sdist

0.2.2 (2019-07-06)

  • run hlint before git tag
  • relax force sdist when no existing tarball
  • show git diff to warn project dirty

0.2.1 (2019-06-24)

  • fix creation of published symlink lockfile
  • tagdist before cabal upload if no tarball

0.2 (2019-06-24)

  • merge tag and dist commands into tagdist
  • if sdist fails then reset tag
  • drop push-tags command

0.1 (2019-06-24)

  • add published lock file: prevents tagging/dist/upload after publish
  • tag before sdist if no tag
  • push tag after publishing

0.0 (2019-06-08)

  • Initially created.