diff --git a/README.md b/README.md index ab8b4aaf..710839d4 100644 --- a/README.md +++ b/README.md @@ -8,31 +8,52 @@ There is also legacy Travis-CI configuration generator, which is unmaintained. or [`ghcup`](https://www.haskell.org/ghcup/) to install GHC and `cabal-install`. -GHC-7.0.1 — GHC-9.2.1 are supported. +GHC-7.0.1 — GHC-9.4.2 are supported. ### Quick-start instructions -* Step 1: Clone and install this project in/from any directory +haskell-ci can be installed either with Cabal or with Nix, depending on your +preference: - ```bash - $ git clone https://github.com/haskell-CI/haskell-ci.git - $ cd haskell-ci - $ cabal new-install haskell-ci:exe:haskell-ci - ``` +#### Installation: Cabal - or +Either install from a Git clone: - ```bash - cabal new-install haskell-ci - ``` +```bash +$ git clone https://github.com/haskell-CI/haskell-ci.git +$ cd haskell-ci +$ cabal new-install haskell-ci:exe:haskell-ci +``` + +or from Hackage: + +```bash +cabal new-install haskell-ci +``` + +#### Installation: Nix + +Either get haskell-ci from nixpkgs (may be older): + +``` +$ nix run nixpkgs#haskell-ci -- --help +``` + +or use the flake to build it from source: + +``` +$ nix run github:haskell-ci/haskell-ci -- --help +``` -* Step 2: Change directories to your project: +#### Setup on your project + +* Step 1: Change directories to your project: ```bash $ cd path/to/your-project ``` -* Step 3: Edit your project's `*.cabal` file to add a `Tested-With` line, such as this one: +* Step 2: Edit your project's `*.cabal` file to add a `Tested-With` line, such as this one: ```bash $ cat your-project.cabal @@ -43,7 +64,7 @@ GHC-7.0.1 — GHC-9.2.1 are supported. Add as many or as few GHC versions to test as you want. -* Step 4: Generate a workflow file for your project: +* Step 3: Generate a workflow file for your project: ```bash $ # You run the following command from your project's directory, even @@ -61,7 +82,7 @@ GHC-7.0.1 — GHC-9.2.1 are supported. `*.cabal` files and generates a configuration that tests each compiler version you listed in parallel. -* Step 5: Create a branch with your new CI configuration file and push your branch: +* Step 4: Create a branch with your new CI configuration file and push your branch: ```bash $ git checkout master # Check out `master` @@ -72,7 +93,7 @@ GHC-7.0.1 — GHC-9.2.1 are supported. $ git push -u origin new-ci # Push your branch upstream ``` -* Step 6: Fix the build +* Step 5: Fix the build If you're lucky, your repository will build for every compiler version you listed. If that's the case, then just merge your changes into `master`: @@ -105,3 +126,30 @@ Real-world Examples - [aeson](https://github.com/haskell/aeson) - [lens](https://github.com/ekmett/lens) - [unordered-containers](https://github.com/haskell-unordered-containers/unordered-containers) + +## Contributing + +There is a Nix flake to easily get the exact environment required, which you +can use like so, once you've [installed the Nix package manager][nix-install]: + +``` +$ nix develop +``` + +This will give you an environment with an appropriate compiler and cabal to +work on haskell-ci. + +### Care and feeding of the Nix flake + +There's a lockfile at `flake.lock` containing all the inputs including the +nixpkgs set. + +You can update the nixpkgs version like so: + +``` +$ nix flake lock --update-input nixpkgs +``` + +Then test building the flake to see if anything went awry. + +[nix-install]: https://nixos.org/download.html#download-nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..d9392e17 --- /dev/null +++ b/flake.lock @@ -0,0 +1,43 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1659877975, + "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1663494472, + "narHash": "sha256-fSowlaoXXWcAM8m9wA6u+eTJJtvruYHMA+Lb/tFi/qM=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "f677051b8dc0b5e2a9348941c99eea8c4b0ff28f", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..d02d2b97 --- /dev/null +++ b/flake.nix @@ -0,0 +1,105 @@ +{ + description = "Scripts for setting up CI for Haskell"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + nixConfig.allow-import-from-derivation = true; # cabal2nix uses IFD + + outputs = { self, nixpkgs, flake-utils }: + let + ghcVer = "ghc902"; + makeHaskellOverlay = overlay: final: prev: { + haskell = prev.haskell // { + packages = prev.haskell.packages // { + ${ghcVer} = prev.haskell.packages."${ghcVer}".override (oldArgs: { + overrides = + prev.lib.composeExtensions (oldArgs.overrides or (_: _: { })) + (overlay prev); + }); + }; + }; + }; + + out = system: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ self.overlays.default ]; + }; + + in + { + packages = rec { + default = haskell-ci; + haskell-ci = pkgs.haskell.lib.justStaticExecutables pkgs.haskell.packages.${ghcVer}.haskell-ci; + }; + + checks = { + inherit (self.packages.${system}) haskell-ci; + }; + + # for debugging + inherit pkgs; + + devShells.default = + let haskellPackages = pkgs.haskell.packages.${ghcVer}; + in + haskellPackages.shellFor { + packages = p: [ self.packages.${system}.haskell-ci ]; + withHoogle = true; + buildInputs = with haskellPackages; [ + # just commented out because they take extra time to build + # given the overrides below: + # + # haskell-language-server + # fourmolu + + # broken on this nixpkgs version + # ghcid + cabal-install + ] ++ (with pkgs; [ + sqlite + ]); + # Change the prompt to show that you are in a devShell + # shellHook = "export PS1='\\e[1;34mdev > \\e[0m'"; + }; + }; + in + flake-utils.lib.eachDefaultSystem out // { + # this stuff is *not* per-system + overlays = { + default = makeHaskellOverlay (prev: hfinal: hprev: + let + hlib = prev.haskell.lib; + # filter paths so that readme changes don't force rebuilds + filteredSource = prev.lib.sourceByRegex ./. [ + "^.*\\.hs$" + "^.*\\.cabal$" + + "LICENSE" + "CHANGELOG\\.md" + + "^src.*$" + "^cli.*$" + "^test.*$" + "^fixtures.*$" + ]; + in + { + haskell-ci = hprev.callCabal2nix "haskell-ci" filteredSource { + # this has to be overridden like this because it is looking + # villainy directly in the face to override Cabal + Cabal-syntax = hfinal.Cabal-syntax_3_8_1_0; + }; + + # these are just old in the default nixpkgs configuration + base-compat = hfinal.base-compat_0_12_2; + base-compat-batteries = hfinal.base-compat-batteries_0_12_2; + optparse-applicative = hfinal.optparse-applicative_0_17_0_0; + }); + }; + }; +}