Skip to content

Automate hackage releases #1310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jneira opened this issue Feb 5, 2021 · 18 comments · Fixed by #2163
Closed

Automate hackage releases #1310

jneira opened this issue Feb 5, 2021 · 18 comments · Fixed by #2163
Assignees
Labels
CI Continuous integration type: enhancement New feature or request

Comments

@jneira
Copy link
Member

jneira commented Feb 5, 2021

The steps needed to make the release are:

  1. Identify changes of each subpackage and check if they can break downstream ones
  2. Bump up the package version accordingly and propagate it to the bounds of downstream packages
  3. Make pr(o several prs) with those changes, ensuring the order of dependencies
  4. Cherry pick those changes onto the github release commit as a branch
  5. Check the subpackage builds succesfully in that branch (and test it?)
  6. Do a cabal check && cabal haddock subpackage && cabal sdist subpackage
  7. Do a cabal upload subpackage (we can use https://github.com/haskell-actions/hackage-publish)

I think the steps 5, 6 and 7 could be automated in ci, uploading package candidates to do a final review and publish all of them.

Not sure how could we automate 1-4 though. Maybe doing a git diff per subpackage and update version bounds of .cabal files with some form of grep&sed (bumping out version as always breaking with no fine grained pvp considerations as suggested by @michaelpj)

There are projects with lot of subpackages and maybe they have been some work to automate this, as pointed by @wz1000.
For example amazonka. Afaics they have a Makefile that includes upload of packages: https://github.com/brendanhay/amazonka/blob/develop/Makefile

@jneira jneira added type: enhancement New feature or request CI Continuous integration type: refactor labels Feb 5, 2021
@ndmitchell
Copy link
Collaborator

Note that step 1 is optional. The PVP says you MUST increase the bounds IF you have incompatible changes. There's nothing to stop you increasing the bounds ALWAYS. Moreover, I don't see a huge heap of value in keeping the bounds as broad as possible, given we do a monolithic release, and people should always use the latest stuff together.

I'd simplify by writing tooling to bump all bounds, including propagating downstream dependency bounds, in one atomic go.

What special testing should a release get? Ideally none, because we're so confident in our tests :)

@michaelpj
Copy link
Collaborator

Neil said exactly what I tried to say on the other issue but much better :)

As another angle: we don't gain anything much from fine-grained bounds wrangling between plugins. At best, that might allow someone to use a newer version of a plugin with an old version of HLS. But do we actually care much about this usecase? If the versions of HLS and the plugins move in lockstep (as if they were one package!)... would anyone actually mind? I don't think so. Maybe later in the future we might care about this.

So my vote goes to: one version for HLS and all the plugins (all the plugins in this repo, anyway).

@pepeiborra
Copy link
Collaborator

But note that bumping everything up and propagating all the way up to the haskell-language-server.cabal descriptor only works if all the packages are uploaded to Hackage at the same time. Plugins that have not been uploaded to Hackage after bumping will be filtered out by cabal install haskell-language-server, assuming the flags stay flexible, or make the cabal solver fail if the flags become rigid. So automating cabal upload is a hard pre-requisite.

@jneira
Copy link
Member Author

jneira commented Feb 5, 2021

At best, that might allow someone to use a newer version of a plugin with an old version of HLS.

Well i can imagine some users could assemble their version of the hls executable to use our plugins and some private ones.
They will not be able to stick to an older ghcide version (maybe cause their plugins would be broken) and get plugin fixes, as we will bump everything and all plugins will require last ghcide/hls-plugin-api version even if they work against the older ones.

But i dont know if that use case exists in the real world tbh so we can wait for real requests.

So if we bump up everything (including package with absolutely no changes? that seems weird for me) we could do it as part of the github release project, for example.

@michaelpj
Copy link
Collaborator

I tried to build HLS 0.9 from Hackage today. Cabal picked ghcide-0.7.5.0, which HLS doesn't actually compile against due to it including some of the hiedb changes.

Now, we can constantly keep adding upper bounds to things when we notice problems like this... or we can accept the reality that the packages in this project are all tested together in a single version configuration, and installing anything else is unlikely to work.

My proposal is still to just give everything the same version X and require ghcide == X and so on everywhere. This is effectively an expanded version of what would happen if all the libraries were all public libraries of the same cabal package, which would IMO be a much better fit as soon as we can actually put such packages on Hackage...

@pepeiborra
Copy link
Collaborator

Proposal sounds reasonable! Do we have any volunteers to implement it?

For the time being, I have made a Hackage revision with the updated constraints.

@jneira
Copy link
Member Author

jneira commented Feb 13, 2021

well if we all agree in do it that way, we could do it in the next hls release

@michaelpj
Copy link
Collaborator

For the time being, I have made a Hackage revision with the updated constraints.

Sadly, ^>=0.7.3 appears to mean 0.7.3 < x < 0.8, rather than 0.7.3 < x < 0.7.4...

@pepeiborra
Copy link
Collaborator

Revised it to ==0.7.3, sorry about that

@michaelpj
Copy link
Collaborator

The plugins which depend on ghcide also need those bounds 😅 Otherwise you get both versions of ghcide being built, and the plugin depends on the new one and fails.

At this point I think it's maybe not worth fixing it and we should just try the "pin everything to one consistent version" approach for the next release.

@pepeiborra
Copy link
Collaborator

That seems surprising, shouldn't Cabal try to come up with a plan that only builds every package once, if possible?
If that's not the default, are there any Cabal flags that can be used to enforce such behaviour?

@michaelpj
Copy link
Collaborator

Ignore me: on closer inspection I was still getting ghcide-0.7.4 as a dependency of haskell-language-server itself, somehow I'm still not getting the Hackage revision or something. I do see ghcide-0.7.3 being built too, but I think that might be for an executable instead.

@pepeiborra
Copy link
Collaborator

This is the plan cabal computes for me. It includes only ghcde-0.7.3 as expected:

$ cabal install haskell-language-server --dry-run
Resolving dependencies...
Build profile: -w ghc-8.10.2 -O1
In order, the following would be built (use -v for more details):
 - Diff-0.4.0 (lib) (requires build)
 - base-compat-0.11.2 (lib) (requires build)
 - base-orphans-0.8.4 (lib) (requires build)
 - base16-bytestring-0.1.1.7 (lib) (requires build)
 - clock-0.8.2 (lib) (requires build)
 - cmdargs-0.10.21 (lib) (requires download & build)
 - cryptohash-sha1-0.11.100.1 (lib) (requires build)
 - czipwith-1.0.1.3 (lib) (requires build)
 - dlist-1.0 (lib) (requires build)
 - filemanip-0.3.6.3 (lib:filemanip) (requires download & build)
 - fingertree-0.1.4.2 (lib) (requires build)
 - ghc-paths-0.1.0.12 (lib:ghc-paths) (requires build)
 - ghc-source-gen-0.4.0.0 (lib) (requires build)
 - ghc-trace-events-0.1.2.1 (lib) (requires build)
 - githash-0.1.5.0 (lib) (requires build)
 - happy-1.20.0 (exe:happy) (requires build)
 - heaps-0.3.6.1 (lib) (requires build)
 - hscolour-1.24.4 (lib:hscolour) (requires build)
 - hashable-1.3.0.0 (lib) (requires build)
 - js-dgtable-0.5.2 (lib) (requires build)
 - js-flot-0.8.3 (lib) (requires build)
 - js-jquery-3.3.1 (lib) (requires build)
 - logict-0.7.0.3 (lib) (requires build)
 - alex-3.2.6 (exe:alex) (requires build)
 - microlens-0.4.12.0 (lib) (requires build)
 - indexed-profunctors-0.1 (lib) (requires build)
 - indexed-traversable-0.1.1 (lib) (requires build)
 - ansi-terminal-0.10.3 (lib) (requires build)
 - unsafe-0.0 (lib:unsafe) (requires build)
 - integer-logarithms-1.0.3.1 (lib) (requires build)
 - network-3.1.0.1 (lib:network) (requires build)
 - polyparse-1.13 (lib) (requires download & build)
 - parallel-3.2.2.0 (lib) (requires build)
 - primes-0.2.1.0 (lib:primes) (requires build)
 - primitive-0.7.1.0 (lib) (requires build)
 - parser-combinators-1.3.0 (lib) (requires download & build)
 - prettyprinter-1.7.0 (lib) (requires build)
 - refact-0.3.0.2 (lib) (requires build)
 - reflection-2.1.6 (lib) (requires build)
 - random-1.1 (lib) (requires build)
 - rope-utf16-splay-0.3.2.0 (lib) (requires download & build)
 - safe-exceptions-0.1.7.1 (lib) (requires build)
 - splitmix-0.1.0.3 (lib) (requires build)
 - sorted-list-0.2.1.0 (lib) (requires build)
 - syb-0.7.2.1 (lib) (requires build)
 - tagged-0.8.6.1 (lib) (requires build)
 - th-abstraction-0.4.2.0 (lib) (requires build)
 - th-compat-0.1.1 (lib) (requires download & build)
 - transformers-compat-0.6.6 (lib) (requires build)
 - void-0.7.3 (lib) (requires build)
 - zlib-0.6.2.2 (lib) (requires build)
 - gitrev-1.3.1 (lib) (requires build)
 - base-compat-batteries-0.11.2 (lib) (requires build)
 - time-compat-1.9.5 (lib) (requires build)
 - extra-1.7.9 (lib) (requires build)
 - data-default-instances-dlist-0.0.1 (lib:data-default-instances-dlist) (requires build)
 - haskell-src-exts-1.23.1 (lib) (requires build)
 - async-2.2.2 (lib) (requires build)
 - psqueues-0.2.7.2 (lib) (requires build)
 - opentelemetry-0.6.1 (lib) (requires build)
 - unordered-containers-0.2.13.0 (lib) (requires build)
 - data-fix-0.3.1 (lib) (requires download & build)
 - case-insensitive-1.2.1.0 (lib) (requires build)
 - ghc-lib-parser-8.10.4.20210206 (lib) (requires download & build)
 - generic-lens-core-2.1.0.0 (lib) (requires build)
 - ansi-wl-pprint-0.6.9 (lib) (requires build)
 - network-bsd-2.8.1.0 (lib) (requires build)
 - cpphs-1.20.9.1 (lib) (requires download & build)
 - vector-0.12.2.0 (lib) (requires build)
 - scientific-0.3.6.2 (lib) (requires build)
 - resourcet-1.2.4.2 (lib) (requires build)
 - prettyprinter-ansi-terminal-1.1.2 (lib) (requires build)
 - temporary-1.3 (lib) (requires build)
 - uuid-types-1.0.3 (lib) (requires build)
 - with-utf8-1.0.2.1 (lib) (requires build)
 - ghc-check-0.5.0.3 (lib) (requires build)
 - QuickCheck-2.14.2 (lib) (requires build)
 - data-tree-print-0.1.0.2 (lib) (requires build)
 - distributive-0.6.2.1 (lib) (requires build)
 - microlens-th-0.4.3.9 (lib) (requires build)
 - network-uri-2.6.4.1 (lib) (requires download & build)
 - transformers-base-0.4.5.2 (lib) (requires build)
 - mmorph-1.1.4 (lib) (requires build)
 - MonadRandom-0.5.2 (lib) (requires build)
 - Glob-0.10.1 (lib) (requires build)
 - filepattern-0.1.2 (lib) (requires build)
 - data-default-0.7.1.1 (lib:data-default) (requires build)
 - typed-process-0.2.6.0 (lib) (requires build)
 - streaming-commons-0.2.2.1 (lib) (requires build)
 - uniplate-1.6.13 (lib) (requires build)
 - ormolu-0.1.4.1 (lib) (requires build)
 - optparse-applicative-0.15.1.0 (lib) (requires build)
 - hslogger-1.3.1.0 (lib) (requires build)
 - vector-algorithms-0.8.0.4 (lib) (requires build)
 - math-functions-0.3.4.1 (lib) (requires build)
 - monoid-subclasses-1.0.1 (lib) (requires build)
 - monad-memo-0.5.3 (lib) (requires build)
 - hashtables-1.2.4.1 (lib) (requires build)
 - attoparsec-0.13.2.5 (lib) (requires download & build)
 - megaparsec-9.0.1 (lib) (requires build)
 - pretty-simple-4.0.0.0 (lib:pretty-simple) (requires download & build)
 - comonad-5.0.8 (lib) (requires build)
 - monad-control-1.0.2.3 (lib:monad-control) (requires build)
 - refinery-0.3.0.0 (lib) (requires build)
 - random-shuffle-0.0.4 (lib:random-shuffle) (requires build)
 - shake-0.19.4 (lib) (requires build)
 - ghc-lib-parser-ex-8.10.0.19 (lib) (requires download & build)
 - optparse-simple-0.1.1.3 (lib) (requires build)
 - mono-traversable-1.0.15.1 (lib) (requires build)
 - mwc-random-0.14.0.0 (lib) (requires build)
 - fuzzy-0.1.0.0 (lib) (requires build)
 - heapsize-0.3.0.1 (lib) (requires build)
 - bifunctors-5.5.10 (lib) (requires build)
 - multistate-0.8.0.3 (lib) (requires build)
 - conduit-1.3.4 (lib) (requires build)
 - assoc-1.0.2 (lib) (requires build)
 - semigroupoids-5.3.5 (lib) (requires build)
 - profunctors-5.6.1 (lib) (requires build)
 - libyaml-0.1.2 (lib) (requires build)
 - conduit-extra-1.3.5 (lib) (requires build)
 - these-1.1.1.1 (lib) (requires build)
 - strict-list-0.1.5 (lib) (requires build)
 - invariant-0.5.4 (lib) (requires build)
 - generic-lens-2.1.0.0 (lib) (requires build)
 - free-5.1.6 (lib) (requires build)
 - foldl-1.4.10 (lib) (requires build)
 - strict-0.4.0.1 (lib) (requires build)
 - deque-0.4.3 (lib) (requires build)
 - monad-dijkstra-0.1.1.3 (lib) (requires build)
 - ghc-exactprint-0.6.3.4 (lib) (requires build)
 - adjunctions-4.4 (lib) (requires build)
 - aeson-1.5.5.1 (lib) (requires build)
 - butcher-1.3.3.2 (lib) (requires build)
 - retrie-0.1.1.1 (lib) (requires build)
 - apply-refact-0.9.0.0 (lib) (requires build)
 - kan-extensions-5.2.1 (lib) (requires build)
 - yaml-0.11.5.0 (lib) (requires build)
 - floskell-0.10.5 (lib) (requires build)
 - HsYAML-aeson-0.2.0.0 (lib) (requires build)
 - lens-4.19.2 (lib:lens) (requires build)
 - implicit-hie-0.1.2.5 (lib) (requires build)
 - hlint-3.2.7 (lib) (requires download & build)
 - hie-bios-0.7.3 (lib) (requires download & build)
 - brittany-0.13.1.0 (lib) (requires build)
 - stylish-haskell-0.12.2.0 (lib) (requires build)
 - fourmolu-0.3.0.0 (lib) (requires build)
 - haskell-lsp-types-0.23.0.0 (lib) (requires build)
 - implicit-hie-cradle-0.3.0.2 (lib) (requires build)
 - haskell-lsp-0.23.0.0 (lib) (requires build)
 - hls-plugin-api-0.7.0.0 (lib) (requires download & build)
 - ghcide-0.7.3.0 (lib) (requires download & build)
 - haskell-language-server-0.9.0.0 (lib) (requires download & build)
 - hls-eval-plugin-0.2.0.0 (lib) (requires download & build)
 - hls-tactics-plugin-0.5.1.0 (lib) (requires download & build)
 - hls-splice-plugin-0.3.0.0 (lib) (requires download & build)
 - hls-retrie-plugin-0.1.1.0 (lib) (requires download & build)
 - hls-hlint-plugin-0.2.0.0 (lib) (requires download & build)
 - hls-haddock-comments-plugin-0.1.1.0 (lib) (requires download & build)
 - hls-class-plugin-0.1.0.1 (lib) (requires build)
 - haskell-language-server-0.9.0.0 (exe:haskell-language-server-wrapper) (requires download & build)
 - haskell-language-server-0.9.0.0 (exe:haskell-language-server) (requires download & build)

@michaelpj
Copy link
Collaborator

well if we all agree in do it that way, we could do it in the next hls release

Just an annoyance about this that occurred to me: for cabal to be happy we'd have to pick a version higher than any version used by any of the packages currently, and some of the plugins are already at 1.something, so we'd have to go into the major version 1 era for HLS. Not sure how we feel about that (IMO it's easily v1-worthy).

@jneira
Copy link
Member Author

jneira commented Feb 18, 2021

I was thinking in that lately, I think it is a good moment to let hls be (young) adult
😬

Maybe we could do the definitive bound to 1.0 for all packages just before the incoming GitHub release
What do you think @Ailrun @alanz @pepeiborra and the rest?

@Ailrun
Copy link
Member

Ailrun commented Feb 19, 2021

I'm good for that, especially if <1 version causes some problems.

Just an annoyance about this that occurred to me: for cabal to be happy we'd have to pick a version higher than any version used by any of the packages currently, and some of the plugins are already at 1.

BTW, @michaelpj, which plugin did you mean? It looks like at least in HLS repo there is no plugin with the major version 1...

@pepeiborra
Copy link
Collaborator

Now that the 1.0 release is complete, are there any plans to actually upload it to Hackage?

@jneira
Copy link
Member Author

jneira commented Sep 6, 2021

I am working on this here: https://github.com/jneira/haskell-language-server/tree/release-hackage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI Continuous integration type: enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants