mirror of
https://github.com/xmonad/xmonad.git
synced 2025-05-19 08:30:21 -07:00
Merge pull request #308 from liskin/release-infra
Automate and document releasing to Hackage + couple cleanups
This commit is contained in:
commit
05aeef0dc2
115
.github/workflows/haskell-ci-hackage.patch
vendored
Normal file
115
.github/workflows/haskell-ci-hackage.patch
vendored
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
Piggy-back on the haskell-ci workflow for automatic releases to Hackage.
|
||||||
|
|
||||||
|
This extends the workflow with two additional triggers:
|
||||||
|
|
||||||
|
* When a release is created on GitHub, a candidate release is uploaded to
|
||||||
|
Hackage and docs are submitted for it as Hackage can't build them itself
|
||||||
|
(https://github.com/haskell/hackage-server/issues/925).
|
||||||
|
|
||||||
|
* To make a final release, the workflow can be triggered manually by entering
|
||||||
|
the correct version number matching the version in the cabal file. This is
|
||||||
|
here because promoting the candidate on Hackage discards the uploaded docs
|
||||||
|
(https://github.com/haskell/hackage-server/issues/70).
|
||||||
|
|
||||||
|
The automation uses a special Hackage user: https://hackage.haskell.org/user/xmonad
|
||||||
|
and each repo (X11, xmonad, xmonad-contrib) has its own HACKAGE_API_KEY token
|
||||||
|
set in GitHub repository secrets.
|
||||||
|
|
||||||
|
--- .github/workflows/haskell-ci.yml.orig
|
||||||
|
+++ .github/workflows/haskell-ci.yml
|
||||||
|
@@ -14,8 +14,17 @@
|
||||||
|
#
|
||||||
|
name: Haskell-CI
|
||||||
|
on:
|
||||||
|
- - push
|
||||||
|
- - pull_request
|
||||||
|
+ push:
|
||||||
|
+ pull_request:
|
||||||
|
+ release:
|
||||||
|
+ types:
|
||||||
|
+ - published
|
||||||
|
+ workflow_dispatch:
|
||||||
|
+ inputs:
|
||||||
|
+ version:
|
||||||
|
+ # releases to Hackage are final and cannot be reverted, thus require
|
||||||
|
+ # manual entry of version as a poor man's mistake avoidance
|
||||||
|
+ description: version (must match version in cabal file)
|
||||||
|
jobs:
|
||||||
|
linux:
|
||||||
|
name: Haskell-CI - Linux - ${{ matrix.compiler }}
|
||||||
|
@@ -28,6 +37,7 @@
|
||||||
|
include:
|
||||||
|
- compiler: ghc-9.0.1
|
||||||
|
allow-failure: false
|
||||||
|
+ upload: true
|
||||||
|
- compiler: ghc-8.10.4
|
||||||
|
allow-failure: false
|
||||||
|
- compiler: ghc-8.8.4
|
||||||
|
@@ -171,8 +181,66 @@
|
||||||
|
${CABAL} -vnormal check
|
||||||
|
- name: haddock
|
||||||
|
run: |
|
||||||
|
- $CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
|
||||||
|
+ $CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH --haddock-for-hackage --builddir $GITHUB_WORKSPACE/haddock all
|
||||||
|
- name: unconstrained build
|
||||||
|
run: |
|
||||||
|
rm -f cabal.project.local
|
||||||
|
$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
|
||||||
|
+ - name: upload artifacts (sdist)
|
||||||
|
+ if: matrix.upload
|
||||||
|
+ uses: actions/upload-artifact@v2
|
||||||
|
+ with:
|
||||||
|
+ path: ${{ github.workspace }}/sdist/*.tar.gz
|
||||||
|
+ - name: upload artifacts (haddock)
|
||||||
|
+ if: matrix.upload
|
||||||
|
+ uses: actions/upload-artifact@v2
|
||||||
|
+ with:
|
||||||
|
+ path: ${{ github.workspace }}/haddock/*-docs.tar.gz
|
||||||
|
+ - name: hackage upload (candidate)
|
||||||
|
+ if: matrix.upload && github.event_name == 'release'
|
||||||
|
+ run: |
|
||||||
|
+ set -ex
|
||||||
|
+ PACKAGE_VERSION="${PACKAGE_VERSION#v}"
|
||||||
|
+ curl \
|
||||||
|
+ --silent --show-error --fail \
|
||||||
|
+ --header "Accept: text/plain" \
|
||||||
|
+ --header "Authorization: X-ApiKey $HACKAGE_API_KEY" \
|
||||||
|
+ --form package=@"${GITHUB_WORKSPACE}/sdist/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz" \
|
||||||
|
+ https://hackage.haskell.org/packages/candidates/
|
||||||
|
+ curl \
|
||||||
|
+ --silent --show-error --fail \
|
||||||
|
+ -X PUT \
|
||||||
|
+ --header "Accept: text/plain" \
|
||||||
|
+ --header "Authorization: X-ApiKey $HACKAGE_API_KEY" \
|
||||||
|
+ --header "Content-Type: application/x-tar" \
|
||||||
|
+ --header "Content-Encoding: gzip" \
|
||||||
|
+ --data-binary @"${GITHUB_WORKSPACE}/haddock/${PACKAGE_NAME}-${PACKAGE_VERSION}-docs.tar.gz" \
|
||||||
|
+ https://hackage.haskell.org/package/${PACKAGE_NAME}-${PACKAGE_VERSION}/candidate/docs
|
||||||
|
+ env:
|
||||||
|
+ HACKAGE_API_KEY: ${{ secrets.HACKAGE_API_KEY }}
|
||||||
|
+ PACKAGE_NAME: ${{ github.event.repository.name }}
|
||||||
|
+ PACKAGE_VERSION: ${{ github.event.release.tag_name }}
|
||||||
|
+ - name: hackage upload (release)
|
||||||
|
+ if: matrix.upload && github.event_name == 'workflow_dispatch'
|
||||||
|
+ run: |
|
||||||
|
+ set -ex
|
||||||
|
+ PACKAGE_VERSION="${PACKAGE_VERSION#v}"
|
||||||
|
+ curl \
|
||||||
|
+ --silent --show-error --fail \
|
||||||
|
+ --header "Accept: text/plain" \
|
||||||
|
+ --header "Authorization: X-ApiKey $HACKAGE_API_KEY" \
|
||||||
|
+ --form package=@"${GITHUB_WORKSPACE}/sdist/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz" \
|
||||||
|
+ https://hackage.haskell.org/packages/
|
||||||
|
+ curl \
|
||||||
|
+ --silent --show-error --fail \
|
||||||
|
+ -X PUT \
|
||||||
|
+ --header "Accept: text/plain" \
|
||||||
|
+ --header "Authorization: X-ApiKey $HACKAGE_API_KEY" \
|
||||||
|
+ --header "Content-Type: application/x-tar" \
|
||||||
|
+ --header "Content-Encoding: gzip" \
|
||||||
|
+ --data-binary @"${GITHUB_WORKSPACE}/haddock/${PACKAGE_NAME}-${PACKAGE_VERSION}-docs.tar.gz" \
|
||||||
|
+ https://hackage.haskell.org/package/${PACKAGE_NAME}-${PACKAGE_VERSION}/docs
|
||||||
|
+ env:
|
||||||
|
+ HACKAGE_API_KEY: ${{ secrets.HACKAGE_API_KEY }}
|
||||||
|
+ PACKAGE_NAME: ${{ github.event.repository.name }}
|
||||||
|
+ PACKAGE_VERSION: ${{ github.event.inputs.version }}
|
74
.github/workflows/haskell-ci.yml
vendored
74
.github/workflows/haskell-ci.yml
vendored
@ -14,8 +14,17 @@
|
|||||||
#
|
#
|
||||||
name: Haskell-CI
|
name: Haskell-CI
|
||||||
on:
|
on:
|
||||||
- push
|
push:
|
||||||
- pull_request
|
pull_request:
|
||||||
|
release:
|
||||||
|
types:
|
||||||
|
- published
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
# releases to Hackage are final and cannot be reverted, thus require
|
||||||
|
# manual entry of version as a poor man's mistake avoidance
|
||||||
|
description: version (must match version in cabal file)
|
||||||
jobs:
|
jobs:
|
||||||
linux:
|
linux:
|
||||||
name: Haskell-CI - Linux - ${{ matrix.compiler }}
|
name: Haskell-CI - Linux - ${{ matrix.compiler }}
|
||||||
@ -28,6 +37,7 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- compiler: ghc-9.0.1
|
- compiler: ghc-9.0.1
|
||||||
allow-failure: false
|
allow-failure: false
|
||||||
|
upload: true
|
||||||
- compiler: ghc-8.10.4
|
- compiler: ghc-8.10.4
|
||||||
allow-failure: false
|
allow-failure: false
|
||||||
- compiler: ghc-8.8.4
|
- compiler: ghc-8.8.4
|
||||||
@ -171,8 +181,66 @@ jobs:
|
|||||||
${CABAL} -vnormal check
|
${CABAL} -vnormal check
|
||||||
- name: haddock
|
- name: haddock
|
||||||
run: |
|
run: |
|
||||||
$CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
|
$CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH --haddock-for-hackage --builddir $GITHUB_WORKSPACE/haddock all
|
||||||
- name: unconstrained build
|
- name: unconstrained build
|
||||||
run: |
|
run: |
|
||||||
rm -f cabal.project.local
|
rm -f cabal.project.local
|
||||||
$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
|
$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
|
||||||
|
- name: upload artifacts (sdist)
|
||||||
|
if: matrix.upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
path: ${{ github.workspace }}/sdist/*.tar.gz
|
||||||
|
- name: upload artifacts (haddock)
|
||||||
|
if: matrix.upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
path: ${{ github.workspace }}/haddock/*-docs.tar.gz
|
||||||
|
- name: hackage upload (candidate)
|
||||||
|
if: matrix.upload && github.event_name == 'release'
|
||||||
|
run: |
|
||||||
|
set -ex
|
||||||
|
PACKAGE_VERSION="${PACKAGE_VERSION#v}"
|
||||||
|
curl \
|
||||||
|
--silent --show-error --fail \
|
||||||
|
--header "Accept: text/plain" \
|
||||||
|
--header "Authorization: X-ApiKey $HACKAGE_API_KEY" \
|
||||||
|
--form package=@"${GITHUB_WORKSPACE}/sdist/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz" \
|
||||||
|
https://hackage.haskell.org/packages/candidates/
|
||||||
|
curl \
|
||||||
|
--silent --show-error --fail \
|
||||||
|
-X PUT \
|
||||||
|
--header "Accept: text/plain" \
|
||||||
|
--header "Authorization: X-ApiKey $HACKAGE_API_KEY" \
|
||||||
|
--header "Content-Type: application/x-tar" \
|
||||||
|
--header "Content-Encoding: gzip" \
|
||||||
|
--data-binary @"${GITHUB_WORKSPACE}/haddock/${PACKAGE_NAME}-${PACKAGE_VERSION}-docs.tar.gz" \
|
||||||
|
https://hackage.haskell.org/package/${PACKAGE_NAME}-${PACKAGE_VERSION}/candidate/docs
|
||||||
|
env:
|
||||||
|
HACKAGE_API_KEY: ${{ secrets.HACKAGE_API_KEY }}
|
||||||
|
PACKAGE_NAME: ${{ github.event.repository.name }}
|
||||||
|
PACKAGE_VERSION: ${{ github.event.release.tag_name }}
|
||||||
|
- name: hackage upload (release)
|
||||||
|
if: matrix.upload && github.event_name == 'workflow_dispatch'
|
||||||
|
run: |
|
||||||
|
set -ex
|
||||||
|
PACKAGE_VERSION="${PACKAGE_VERSION#v}"
|
||||||
|
curl \
|
||||||
|
--silent --show-error --fail \
|
||||||
|
--header "Accept: text/plain" \
|
||||||
|
--header "Authorization: X-ApiKey $HACKAGE_API_KEY" \
|
||||||
|
--form package=@"${GITHUB_WORKSPACE}/sdist/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz" \
|
||||||
|
https://hackage.haskell.org/packages/
|
||||||
|
curl \
|
||||||
|
--silent --show-error --fail \
|
||||||
|
-X PUT \
|
||||||
|
--header "Accept: text/plain" \
|
||||||
|
--header "Authorization: X-ApiKey $HACKAGE_API_KEY" \
|
||||||
|
--header "Content-Type: application/x-tar" \
|
||||||
|
--header "Content-Encoding: gzip" \
|
||||||
|
--data-binary @"${GITHUB_WORKSPACE}/haddock/${PACKAGE_NAME}-${PACKAGE_VERSION}-docs.tar.gz" \
|
||||||
|
https://hackage.haskell.org/package/${PACKAGE_NAME}-${PACKAGE_VERSION}/docs
|
||||||
|
env:
|
||||||
|
HACKAGE_API_KEY: ${{ secrets.HACKAGE_API_KEY }}
|
||||||
|
PACKAGE_NAME: ${{ github.event.repository.name }}
|
||||||
|
PACKAGE_VERSION: ${{ github.event.inputs.version }}
|
||||||
|
@ -59,58 +59,59 @@
|
|||||||
|
|
||||||
## Release Procedures
|
## Release Procedures
|
||||||
|
|
||||||
When the time comes to release another version of XMonad and Contrib...
|
When the time comes to release another version of xmonad and xmonad-contrib:
|
||||||
|
|
||||||
1. Create a release branch (e.g., `release-0.XX`).
|
1. Update the version number in all the `*.cabal` files and let the CI
|
||||||
|
verify that it all builds together.
|
||||||
|
|
||||||
This will allow you to separate the release process from main
|
2. Review documentation files and make sure they are accurate:
|
||||||
development. Changes you make on this branch will be merged back
|
|
||||||
into `master` as one of the last steps.
|
|
||||||
|
|
||||||
2. Update the version number in the `*.cabal` files and verify
|
- [`README.md`](README.md)
|
||||||
dependencies and documentation. This includes the `tested-with:`
|
- [`CHANGES.md`](CHANGES.md)
|
||||||
field.
|
- [`INSTALL.md`](INSTALL.md)
|
||||||
|
- [`man/xmonad.1.markdown.in`](man/xmonad.1.markdown.in)
|
||||||
|
- [haddocks](https://xmonad.github.io/xmonad-docs/)
|
||||||
|
|
||||||
3. Use the [packdeps][] tool to ensure you have the dependency
|
If the manpage changes, wait for the CI to rebuild the rendered outputs.
|
||||||
versions correct. If you need to update the version of a
|
|
||||||
dependency then you should rebuild and retest.
|
|
||||||
|
|
||||||
4. Review documentation files and make sure they are accurate:
|
3. Check dependency bounds. In particular, [packdeps][] can be used to check
|
||||||
|
if any new versions are excluded by the upper bounds specified.
|
||||||
|
Also, make sure that `tested-with:` covers several recent releases of
|
||||||
|
GHC, and that `.github/workflows/stack.yml` tests with several recent
|
||||||
|
revisions of [Stackage][] LTS.
|
||||||
|
|
||||||
- `README.md`
|
4. Create a release on GitHub:
|
||||||
- `CHANGES.md`
|
|
||||||
- and the `example-config.hs` in the `xmonad-testing` repo
|
|
||||||
|
|
||||||
5. Generate the manpage:
|
- https://github.com/xmonad/xmonad/releases/new
|
||||||
|
- https://github.com/xmonad/xmonad-contrib/releases/new
|
||||||
|
|
||||||
* `cabal configure` with the `-fgeneratemanpage` flag
|
CI will upload a release candidate to Hackage. Check again that
|
||||||
* Build the project
|
everything looks good. To publish a final release, run the CI workflow
|
||||||
* Run the `generatemanpage` tool from the top level of this repo
|
once again with the correct version number:
|
||||||
* Review the man page: `man -l man/xmonad.1`
|
|
||||||
|
|
||||||
6. Tag the repository with the release version (e.g., `v0.13`)
|
- https://github.com/xmonad/xmonad/actions/workflows/haskell-ci.yml
|
||||||
|
- https://github.com/xmonad/xmonad-contrib/actions/workflows/haskell-ci.yml
|
||||||
|
|
||||||
7. Build the project tarballs (`cabal sdist`)
|
See [haskell-ci-hackage.patch][] for details about the release infrastructure.
|
||||||
|
|
||||||
8. Upload the packages to Hackage (`cabal upload`)
|
5. Update the website:
|
||||||
|
|
||||||
9. Merge the release branches into `master`
|
- Post a [new release announcement][web-announce]
|
||||||
|
- Check install instructions, guided tour, keybindings cheat sheet, …
|
||||||
|
|
||||||
10. Update the website:
|
7. Post announcement to:
|
||||||
|
|
||||||
* Generate and push haddocks with `xmonad-web/gen-docs.sh`
|
- [XMonad mailing list](https://mail.haskell.org/mailman/listinfo/xmonad)
|
||||||
|
- [Haskell Cafe](https://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe)
|
||||||
|
- [Haskell Discourse](https://discourse.haskell.org/)
|
||||||
|
|
||||||
* Check that `tour.html` and `intro.html` are up to date, and
|
See [old announcements][old-announce] for inspiration.
|
||||||
mention all core bindings
|
|
||||||
|
|
||||||
11. Update the topic for the IRC channel (`#xmonad`)
|
[packdeps]: https://hackage.haskell.org/package/packdeps
|
||||||
|
[Stackage]: https://www.stackage.org/
|
||||||
12. Send the `announce-0.XX.txt` file to:
|
[haskell-ci-hackage.patch]: .github/workflows/haskell-ci-hackage.patch
|
||||||
|
[web-announce]: https://github.com/xmonad/xmonad-web/tree/gh-pages/news/_posts
|
||||||
- XMonad mailing list
|
[old-announce]: https://github.com/xmonad/xmonad-web/tree/55614349421ebafaef4a47424fcb16efa80ff768
|
||||||
- Haskell Cafe
|
|
||||||
|
|
||||||
[packdeps]: http://hackage.haskell.org/package/packdeps
|
|
||||||
|
|
||||||
## Website and Other Accounts
|
## Website and Other Accounts
|
||||||
|
|
||||||
|
@ -5,6 +5,9 @@ apt:
|
|||||||
libxrandr-dev
|
libxrandr-dev
|
||||||
libxss-dev
|
libxss-dev
|
||||||
|
|
||||||
|
github-patches:
|
||||||
|
.github/workflows/haskell-ci-hackage.patch
|
||||||
|
|
||||||
raw-project
|
raw-project
|
||||||
package xmonad
|
package xmonad
|
||||||
flags: +pedantic
|
flags: +pedantic
|
||||||
|
@ -39,7 +39,7 @@ import XMonad.Operations
|
|||||||
import XMonad.ManageHook
|
import XMonad.ManageHook
|
||||||
import qualified XMonad.StackSet as W
|
import qualified XMonad.StackSet as W
|
||||||
import Data.Bits ((.|.))
|
import Data.Bits ((.|.))
|
||||||
import Data.Default
|
import Data.Default.Class
|
||||||
import Data.Monoid
|
import Data.Monoid
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import System.Exit
|
import System.Exit
|
||||||
|
@ -43,7 +43,7 @@ import Control.Monad.State
|
|||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Data.Semigroup
|
import Data.Semigroup
|
||||||
import Data.Traversable (for)
|
import Data.Traversable (for)
|
||||||
import Data.Default
|
import Data.Default.Class
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import System.IO
|
import System.IO
|
||||||
import System.Info
|
import System.Info
|
||||||
|
12
xmonad.cabal
12
xmonad.cabal
@ -35,10 +35,11 @@ build-type: Simple
|
|||||||
extra-source-files: README.md
|
extra-source-files: README.md
|
||||||
CHANGES.md
|
CHANGES.md
|
||||||
CONFIG
|
CONFIG
|
||||||
|
CONTRIBUTING.md
|
||||||
|
INSTALL.md
|
||||||
|
MAINTAINERS.md
|
||||||
STYLE
|
STYLE
|
||||||
tests/*.hs
|
TUTORIAL.md
|
||||||
tests/Properties/*.hs
|
|
||||||
tests/Properties/Layout/*.hs
|
|
||||||
man/xmonad.1.markdown
|
man/xmonad.1.markdown
|
||||||
man/xmonad.1
|
man/xmonad.1
|
||||||
man/xmonad.1.html
|
man/xmonad.1.html
|
||||||
@ -71,7 +72,7 @@ library
|
|||||||
build-depends: base >= 4.9 && < 5
|
build-depends: base >= 4.9 && < 5
|
||||||
, X11 >= 1.10 && < 1.11
|
, X11 >= 1.10 && < 1.11
|
||||||
, containers
|
, containers
|
||||||
, data-default
|
, data-default-class
|
||||||
, directory
|
, directory
|
||||||
, filepath
|
, filepath
|
||||||
, mtl
|
, mtl
|
||||||
@ -79,7 +80,6 @@ library
|
|||||||
, setlocale
|
, setlocale
|
||||||
, transformers >= 0.3
|
, transformers >= 0.3
|
||||||
, unix
|
, unix
|
||||||
, utf8-string >= 0.3 && < 1.1
|
|
||||||
ghc-options: -funbox-strict-fields -Wall -Wno-unused-do-bind
|
ghc-options: -funbox-strict-fields -Wall -Wno-unused-do-bind
|
||||||
|
|
||||||
-- Keep this in sync with the oldest version in 'tested-with'
|
-- Keep this in sync with the oldest version in 'tested-with'
|
||||||
@ -91,7 +91,7 @@ library
|
|||||||
|
|
||||||
executable xmonad
|
executable xmonad
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
build-depends: base, X11, mtl, unix, xmonad
|
build-depends: base, xmonad
|
||||||
ghc-options: -Wall -Wno-unused-do-bind
|
ghc-options: -Wall -Wno-unused-do-bind
|
||||||
|
|
||||||
-- Keep this in sync with the oldest version in 'tested-with'
|
-- Keep this in sync with the oldest version in 'tested-with'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user