├── .ctags ├── .gitattributes ├── .github └── workflows │ └── dhall.yml ├── .gitignore ├── LICENSE ├── README.md ├── Shakefile.hs ├── TODO.md ├── ats-ci.dhall ├── dhall-ci.dhall ├── egison-ci.dhall ├── example.dhall ├── futhark-ci.dhall ├── haskell-ci.dhall ├── python-ci.dhall ├── self-ci.dhall ├── toml-ci.dhall └── yaml-ci.dhall /.ctags: -------------------------------------------------------------------------------- 1 | --langdef=DHALL 2 | --langmap=DHALL:.dhall 3 | --regex-DHALL=/let *([[:lower:]][[:alnum:]_]+)/\1/f,function/ 4 | --regex-DHALL=/let *([[:upper:]][[:alnum:]_]+)/\1/t,type/ 5 | --regex-DHALL=/< *([[:upper:]][[:alnum:]_]+)/\1/t,type/ 6 | --regex-DHALL=/\| *([[:upper:]][[:alnum:]_]+)/\1/t,type/ 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | .github/workflows/*.yaml linguist-vendored 2 | -------------------------------------------------------------------------------- /.github/workflows/dhall.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | build: 3 | "runs-on": "ubuntu-18.04" 4 | steps: 5 | - uses: "actions/checkout@v1" 6 | - id: "setup-haskell-cabal" 7 | uses: "actions/setup-haskell@v1.1" 8 | with: 9 | "cabal-version": '3.2' 10 | "enable-stack": false 11 | "ghc-version": '8.8.3' 12 | - uses: "actions/cache@v1" 13 | with: 14 | key: "${{ runner.os }}-${{ matrix.ghc }}-cabal" 15 | path: "${{ steps.setup-haskell-cabal.outputs.cabal-store }}" 16 | - name: Install dhall 17 | run: | 18 | cabal update 19 | cd "$(mktemp -d /tmp/dhall-XXX)" 20 | cabal install dhall 21 | - name: "Install dhall-to-yaml &c." 22 | run: | 23 | cabal update 24 | cd "$(mktemp -d /tmp/dhall-XXX)" 25 | cabal install dhall-yaml 26 | - name: Check Dhall 27 | run: | 28 | export PATH=$HOME/.cabal/bin:$PATH 29 | dhall --file haskell-ci.dhall 30 | dhall --file ats-ci.dhall 31 | dhall --file toml-ci.dhall 32 | dhall --file self-ci.dhall 33 | dhall --file python-ci.dhall 34 | dhall --file yaml-ci.dhall 35 | dhall --file egison-ci.dhall 36 | dhall --file futhark-ci.dhall 37 | - name: Check Dhall can be converted to YAML 38 | run: | 39 | export PATH=$HOME/.cabal/bin:$PATH 40 | dhall-to-yaml-ng --file self-ci.dhall 41 | dhall-to-yaml-ng --file example.dhall 42 | name: Dhall CI 43 | 'on': 44 | - push 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | tags 2 | *.swp 3 | .shake 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Vanessa McHale (c) 2019 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # github-actions-dhall 2 | 3 | This is a demonstration using Dhall to generate YAML for 4 | github actions. 5 | 6 | github-actions-dhall is 7 | [self-hosting](https://github.com/vmchale/github-actions-dhall/blob/master/self-ci.dhall). 8 | 9 | ## Example 10 | 11 | ### Haskell 12 | 13 | Store the following in `example.dhall`: 14 | 15 | ```dhall 16 | let haskellCi = https://raw.githubusercontent.com/vmchale/github-actions-dhall/master/haskell-ci.dhall 17 | 18 | in haskellCi.generalCi 19 | haskellCi.matrixSteps 20 | ( Some 21 | { ghc = 22 | [ haskellCi.GHC.GHC8101 23 | , haskellCi.GHC.GHC883 24 | , haskellCi.GHC.GHC865 25 | ] 26 | , cabal = [ haskellCi.Cabal.Cabal32 ] 27 | } 28 | ) 29 | : haskellCi.CI.Type 30 | ``` 31 | 32 | Then, generate YAML with `dhall-to-yaml --file example.dhall` 33 | 34 | ```yaml 35 | jobs: 36 | build: 37 | runs-on: ubuntu-18.04 38 | steps: 39 | - uses: "actions/checkout@v1" 40 | - id: setup-haskell-cabal 41 | uses: "actions/setup-haskell@v1.1" 42 | with: 43 | cabal-version: "${{ matrix.cabal }}" 44 | ghc-version: "${{ matrix.ghc }}" 45 | - uses: "actions/cache@v1" 46 | with: 47 | key: "${{ runner.os }}-${{ matrix.ghc }}-cabal" 48 | path: "${{ steps.setup-haskell-cabal.outputs.cabal-store }}" 49 | - name: Install dependencies 50 | run: | 51 | cabal update 52 | cabal build --enable-tests --enable-benchmarks --only-dependencies 53 | - name: build 54 | run: cabal build --enable-tests --enable-benchmarks 55 | - name: test 56 | run: cabal test 57 | - name: haddock 58 | run: cabal haddock 59 | strategy: 60 | matrix: 61 | cabal: 62 | - '3.2' 63 | ghc: 64 | - '8.10.1' 65 | - '8.8.3' 66 | - '8.6.5' 67 | name: Haskell CI 68 | on: 69 | - push 70 | ``` 71 | 72 | Have a look at 73 | [hlint-lib](https://github.com/vmchale/hlint-lib/blob/master/self-ci.dhall) for 74 | a more "organic" example. 75 | -------------------------------------------------------------------------------- /Shakefile.hs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env cabal 2 | {- cabal: 3 | build-depends: base, shake-dhall, shake 4 | default-language: Haskell2010 5 | ghc-options: -Wall -threaded -rtsopts "-with-rtsopts=-I0 -qg -qb" 6 | -} 7 | 8 | import Development.Shake 9 | import Development.Shake.Dhall 10 | 11 | main :: IO () 12 | main = shakeArgs shakeOptions { shakeFiles = ".shake", shakeLint = Just LintBasic, shakeChange = ChangeModtimeAndDigestInput } $ do 13 | want [ ".github/workflows/dhall.yml" ] 14 | 15 | "docs" ~> 16 | command [] "dhall-docs" ["--input", ".", "--output-link", "docs"] 17 | 18 | ".github/workflows/dhall.yml" %> \out -> do 19 | let inp = "self-ci.dhall" 20 | needDhall [inp] 21 | command [] "dhall-to-yaml-ng" ["--file", inp, "--output", out] 22 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | - [ ] See: 2 | https://github.com/alexcrichton/bzip2-rs/blob/master/.github/workflows/main.yml 3 | for rust? 4 | -------------------------------------------------------------------------------- /ats-ci.dhall: -------------------------------------------------------------------------------- 1 | let haskellCi = ./haskell-ci.dhall 2 | 3 | let concatSep = 4 | https://raw.githubusercontent.com/dhall-lang/dhall-lang/9f259cd68870b912fbf2f2a08cd63dc3ccba9dc3/Prelude/Text/concatSep sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58 5 | 6 | let optionalFold = 7 | https://raw.githubusercontent.com/dhall-lang/dhall-lang/87993319329f3c00920d6e882365276925a4aa6a/Prelude/Optional/fold.dhall sha256:c5b9d72f6f62bdaa0e196ac1c742cc175cd67a717b880fb8aec1333a5a4132cf 8 | 9 | let atspkgInstall = 10 | haskellCi.BuildStep.Name 11 | { name = "Install atspkg" 12 | , run = 13 | '' 14 | curl -sSl https://raw.githubusercontent.com/vmchale/atspkg/master/bash/install.sh | sh -s 15 | '' 16 | } 17 | 18 | let mkPkgArgs = 19 | λ(pkgArgs : Optional Text) → 20 | optionalFold Text pkgArgs Text (λ(x : Text) → " --pkg-args ${x}") "" 21 | 22 | let mkTgts = concatSep " " 23 | 24 | let atsBuildTargets = 25 | λ(targets : List Text) → 26 | λ(pkgArgs : Optional Text) → 27 | haskellCi.BuildStep.Name 28 | { name = "Build ATS" 29 | , run = 30 | '' 31 | export PATH=$HOME/.local/bin:$PATH 32 | atspkg -V 33 | atspkg build -vv${mkPkgArgs pkgArgs} ${mkTgts targets} 34 | '' 35 | } 36 | 37 | let atsCheckPkg = 38 | haskellCi.BuildStep.Name 39 | { name = "Check pkg.dhall" 40 | , run = 41 | '' 42 | export PATH=$HOME/.local/bin:$PATH 43 | atspkg check pkg.dhall 44 | '' 45 | } 46 | 47 | let atsBuild = atsBuildTargets ([] : List Text) 48 | 49 | let atsTestTargets = 50 | λ(targets : List Text) → 51 | λ(pkgArgs : Optional Text) → 52 | haskellCi.BuildStep.Name 53 | { name = "Test ATS" 54 | , run = 55 | '' 56 | export PATH=$HOME/.local/bin:$PATH 57 | atspkg test -vv${mkPkgArgs pkgArgs} ${mkTgts targets} 58 | '' 59 | } 60 | 61 | let atsTest = atsTestTargets ([] : List Text) 62 | 63 | let atsSteps = 64 | λ(steps : List haskellCi.BuildStep) → 65 | haskellCi.ciNoMatrix steps ⫽ { name = "ATS CI" } 66 | 67 | let atsCi = 68 | atsSteps [ haskellCi.checkout, atspkgInstall, atsBuild (None Text) ] 69 | : haskellCi.CI.Type 70 | 71 | in { atspkgInstall 72 | , atsBuild 73 | , atsBuildTargets 74 | , atsTest 75 | , atsCi 76 | , atsSteps 77 | , atsCheckPkg 78 | , checkout = haskellCi.checkout 79 | , CI = haskellCi.CI 80 | , BuildStep = haskellCi.BuildStep 81 | , Event = haskellCi.Event 82 | } 83 | -------------------------------------------------------------------------------- /dhall-ci.dhall: -------------------------------------------------------------------------------- 1 | let haskellCi = ./haskell-ci.dhall 2 | 3 | let concatMap = 4 | https://raw.githubusercontent.com/dhall-lang/dhall-lang/9f259cd68870b912fbf2f2a08cd63dc3ccba9dc3/Prelude/Text/concatMap sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f 5 | 6 | let dhallInstall = 7 | haskellCi.BuildStep.Name 8 | { name = "Install dhall" 9 | , run = 10 | '' 11 | cabal update 12 | cd "$(mktemp -d /tmp/dhall-XXX)" 13 | cabal install dhall 14 | '' 15 | } 16 | 17 | let dhallYamlInstall = 18 | haskellCi.BuildStep.Name 19 | { name = "Install dhall-to-yaml &c." 20 | , run = 21 | '' 22 | cabal update 23 | cd "$(mktemp -d /tmp/dhall-XXX)" 24 | cabal install dhall-yaml 25 | '' 26 | } 27 | 28 | let checkDhall = 29 | λ(dhalls : List Text) → 30 | haskellCi.BuildStep.Name 31 | { name = "Check Dhall" 32 | , run = 33 | '' 34 | export PATH=$HOME/.cabal/bin:$PATH 35 | '' 36 | ++ concatMap 37 | Text 38 | ( λ(d : Text) → 39 | '' 40 | dhall --file ${d} 41 | '' 42 | ) 43 | dhalls 44 | } 45 | 46 | let checkDhallYaml = 47 | λ(dhalls : List Text) → 48 | haskellCi.BuildStep.Name 49 | { name = "Check Dhall can be converted to YAML" 50 | , run = 51 | '' 52 | export PATH=$HOME/.cabal/bin:$PATH 53 | '' 54 | ++ concatMap 55 | Text 56 | ( λ(d : Text) → 57 | '' 58 | dhall-to-yaml-ng --file ${d} 59 | '' 60 | ) 61 | dhalls 62 | } 63 | 64 | let dhallSteps = 65 | λ(steps : List haskellCi.BuildStep) → 66 | haskellCi.ciNoMatrix 67 | ( [ haskellCi.checkout 68 | , haskellCi.haskellEnv haskellCi.latestEnv 69 | , haskellCi.cache 70 | , dhallInstall 71 | ] 72 | # steps 73 | ) 74 | ⫽ { name = "Dhall CI" } 75 | : haskellCi.CI.Type 76 | 77 | let dhallCi = 78 | λ(dhalls : List Text) → 79 | dhallSteps [ checkDhall dhalls ] : haskellCi.CI.Type 80 | 81 | in { dhallInstall 82 | , dhallYamlInstall 83 | , dhallCi 84 | , checkDhall 85 | , checkDhallYaml 86 | , dhallSteps 87 | , CI = haskellCi.CI.Type 88 | , BuildStep = haskellCi.BuildStep 89 | , Event = haskellCi.Event 90 | } 91 | -------------------------------------------------------------------------------- /egison-ci.dhall: -------------------------------------------------------------------------------- 1 | let haskellCi = ./haskell-ci.dhall 2 | 3 | let concatMap = 4 | https://raw.githubusercontent.com/dhall-lang/dhall-lang/9f259cd68870b912fbf2f2a08cd63dc3ccba9dc3/Prelude/Text/concatMap sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f 5 | 6 | let egiInstall = 7 | haskellCi.BuildStep.Name 8 | { name = "Install egison" 9 | , run = 10 | '' 11 | cabal update 12 | cabal install egison 13 | '' 14 | } 15 | 16 | let checkEgi = 17 | λ(egis : List Text) 18 | → haskellCi.BuildStep.Name 19 | { name = "Check Egison files" 20 | , run = 21 | '' 22 | export PATH=$HOME/.cabal/bin:$PATH 23 | '' 24 | ++ concatMap 25 | Text 26 | ( λ(d : Text) 27 | → '' 28 | egison --test ${d} 29 | '' 30 | ) 31 | egis 32 | } 33 | 34 | let egiSteps = 35 | λ(steps : List haskellCi.BuildStep) 36 | → haskellCi.ciNoMatrix 37 | ( [ haskellCi.checkout 38 | , haskellCi.haskellEnv haskellCi.latestEnv 39 | , haskellCi.cache 40 | , egiInstall 41 | ] 42 | # steps 43 | ) 44 | ⫽ { name = "Egison CI" } 45 | : haskellCi.CI.Type 46 | 47 | let egiCi = λ(egis : List Text) → egiSteps [ checkEgi egis ] : haskellCi.CI.Type 48 | 49 | in { egiInstall 50 | , egiCi 51 | , checkEgi 52 | , egiSteps 53 | , CI = haskellCi.CI.Type 54 | , BuildStep = haskellCi.BuildStep 55 | , Event = haskellCi.Event 56 | } 57 | -------------------------------------------------------------------------------- /example.dhall: -------------------------------------------------------------------------------- 1 | let haskellCi = 2 | ./haskell-ci.dhall sha256:48c4cdf0faac0d1fd40884ff938abb3f1e8049e09a032fbec24e8ca337ce6ff9 3 | 4 | in haskellCi.generalCi 5 | haskellCi.matrixSteps 6 | ( Some 7 | { ghc = 8 | [ haskellCi.GHC.GHC8101 9 | , haskellCi.GHC.GHC883 10 | , haskellCi.GHC.GHC865 11 | ] 12 | , cabal = [ haskellCi.Cabal.Cabal32 ] 13 | } 14 | ) 15 | : haskellCi.CI.Type 16 | -------------------------------------------------------------------------------- /futhark-ci.dhall: -------------------------------------------------------------------------------- 1 | let haskellCi = ./haskell-ci.dhall 2 | 3 | let concatMap = 4 | https://raw.githubusercontent.com/dhall-lang/dhall-lang/9f259cd68870b912fbf2f2a08cd63dc3ccba9dc3/Prelude/Text/concatMap sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f 5 | 6 | let futharkInstall = 7 | haskellCi.BuildStep.Name 8 | { name = "Install Futhark" 9 | , run = 10 | '' 11 | cabal update 12 | cd "$(mktemp -d /tmp/futhark-XXX)" 13 | cabal install futhark --constraint='megaparsec < 8.0.0' 14 | '' 15 | } 16 | 17 | let futharkPkgDeps = 18 | haskellCi.BuildStep.Name 19 | { name = "Install Futhark package dependencies" 20 | , run = 21 | '' 22 | futhark pkg sync 23 | '' 24 | } 25 | 26 | let checkFuthark = 27 | λ(futs : List Text) 28 | → haskellCi.BuildStep.Name 29 | { name = "Check Futhark" 30 | , run = 31 | '' 32 | export PATH=$HOME/.cabal/bin:$PATH 33 | '' 34 | ++ concatMap 35 | Text 36 | ( λ(d : Text) 37 | → '' 38 | futhark check ${d} 39 | '' 40 | ) 41 | futs 42 | } 43 | 44 | let futharkSteps = 45 | λ(steps : List haskellCi.BuildStep) 46 | → haskellCi.ciNoMatrix 47 | ( [ haskellCi.checkout 48 | , haskellCi.haskellEnv haskellCi.latestEnv 49 | , haskellCi.cache 50 | , futharkInstall 51 | ] 52 | # steps 53 | ) 54 | ⫽ { name = "Futhark CI" } 55 | 56 | let futharkCi = 57 | λ(futs : List Text) 58 | → futharkSteps [ checkFuthark futs ] : haskellCi.CI.Type 59 | 60 | in { CI = haskellCi.CI.Type 61 | , futharkSteps 62 | , checkFuthark 63 | , futharkCi 64 | , futharkPkgDeps 65 | } 66 | -------------------------------------------------------------------------------- /haskell-ci.dhall: -------------------------------------------------------------------------------- 1 | let map = 2 | https://raw.githubusercontent.com/dhall-lang/dhall-lang/9f259cd68870b912fbf2f2a08cd63dc3ccba9dc3/Prelude/List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680 3 | 4 | let mapOptional = 5 | https://raw.githubusercontent.com/dhall-lang/dhall-lang/87993319329f3c00920d6e882365276925a4aa6a/Prelude/Optional/map sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa 6 | 7 | let concatSep = 8 | https://raw.githubusercontent.com/dhall-lang/dhall-lang/9f259cd68870b912fbf2f2a08cd63dc3ccba9dc3/Prelude/Text/concatSep sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58 9 | 10 | let GHC = < GHC7103 | GHC802 | GHC822 | GHC844 | GHC865 | GHC883 | GHC8101 > 11 | 12 | let Cabal = < Cabal32 | Cabal30 | Cabal24 | Cabal22 | Cabal20 > 13 | 14 | let OS = < Ubuntu1804 | Ubuntu1604 | MacOS | Windows > 15 | 16 | let VersionInfo = 17 | { Type = 18 | { ghc-version : Optional Text 19 | , cabal-version : Optional Text 20 | , stack-version : Optional Text 21 | , enable-stack : Optional Bool 22 | , stack-no-global : Optional Bool 23 | , stack-setup-ghc : Optional Bool 24 | } 25 | , default = 26 | { ghc-version = Some "8.10.1" 27 | , cabal-version = Some "3.2" 28 | , stack-version = None Text 29 | , enable-stack = Some False 30 | , stack-no-global = None Bool 31 | , stack-setup-ghc = None Bool 32 | } 33 | } 34 | 35 | let PyInfo = { python-version : Text, architecture : Optional Text } 36 | 37 | let CacheCfg = 38 | { Type = { path : Text, key : Text, restoreKeys : Optional Text } 39 | , default.restoreKeys = None Text 40 | } 41 | 42 | let BuildStep = 43 | < Uses : 44 | { uses : Text 45 | , id : Optional Text 46 | , `with` : Optional VersionInfo.Type 47 | } 48 | | Name : { name : Text, run : Text } 49 | | UseCache : { uses : Text, `with` : CacheCfg.Type } 50 | | UsePy : { uses : Text, `with` : PyInfo } 51 | | AwsEnv : 52 | { name : Text 53 | , run : Text 54 | , env : { AWS_ACCESS_KEY_ID : Text, AWS_SECRET_ACCESS_KEY : Text } 55 | } 56 | > 57 | 58 | let DhallVersion = { ghc-version : GHC, cabal-version : Cabal } 59 | 60 | let Matrix = { matrix : { ghc : List Text, cabal : List Text } } 61 | 62 | let DhallMatrix = 63 | { Type = { ghc : List GHC, cabal : List Cabal } 64 | , default = { ghc = [ GHC.GHC865 ], cabal = [ Cabal.Cabal32 ] } 65 | } 66 | 67 | let Event = < push | release | pull_request > 68 | 69 | let CI = 70 | { Type = 71 | { name : Text 72 | , on : List Event 73 | , jobs : 74 | { build : 75 | { runs-on : Text 76 | , steps : List BuildStep 77 | , strategy : Optional Matrix 78 | } 79 | } 80 | } 81 | , default = { name = "Haskell CI", on = [ Event.push ] } 82 | } 83 | 84 | let printGhc = 85 | λ(ghc : GHC) → 86 | merge 87 | { GHC7103 = "7.10.3" 88 | , GHC802 = "8.0.2" 89 | , GHC822 = "8.2.2" 90 | , GHC844 = "8.4.4" 91 | , GHC865 = "8.6.5" 92 | , GHC883 = "8.8.3" 93 | , GHC8101 = "8.10.1" 94 | } 95 | ghc 96 | 97 | let printOS = 98 | λ(os : OS) → 99 | merge 100 | { Windows = "windows-latest" 101 | , Ubuntu1804 = "ubuntu-18.04" 102 | , Ubuntu1604 = "ubuntu-16.04" 103 | , MacOS = "macos-latest" 104 | } 105 | os 106 | 107 | let printCabal = 108 | λ(cabal : Cabal) → 109 | merge 110 | { Cabal32 = "3.2" 111 | , Cabal30 = "3.0" 112 | , Cabal24 = "2.4" 113 | , Cabal22 = "2.2" 114 | , Cabal20 = "2.0" 115 | } 116 | cabal 117 | 118 | let printEnv = 119 | λ(v : DhallVersion) → 120 | VersionInfo::{ 121 | , ghc-version = Some (printGhc v.ghc-version) 122 | , cabal-version = Some (printCabal v.cabal-version) 123 | } 124 | 125 | let printMatrix = 126 | λ(v : DhallMatrix.Type) → 127 | { ghc = map GHC Text printGhc v.ghc 128 | , cabal = map Cabal Text printCabal v.cabal 129 | } 130 | 131 | let cache = 132 | BuildStep.UseCache 133 | { uses = "actions/cache@v1" 134 | , `with` = 135 | { path = "\${{ steps.setup-haskell-cabal.outputs.cabal-store }}" 136 | , key = "\${{ runner.os }}-\${{ matrix.ghc }}-cabal" 137 | , restoreKeys = None Text 138 | } 139 | } 140 | 141 | let stackCache = 142 | BuildStep.UseCache 143 | { uses = "actions/cache@v1" 144 | , `with` = 145 | { path = "~/.stack" 146 | , key = "\${{ runner.os }}-\${{ matrix.ghc }}-stack" 147 | , restoreKeys = None Text 148 | } 149 | } 150 | 151 | let checkout = 152 | BuildStep.Uses 153 | { uses = "actions/checkout@v1" 154 | , id = None Text 155 | , `with` = None VersionInfo.Type 156 | } 157 | 158 | let haskellEnv = 159 | λ(v : VersionInfo.Type) → 160 | BuildStep.Uses 161 | { uses = "actions/setup-haskell@v1.1" 162 | , id = Some "setup-haskell-cabal" 163 | , `with` = Some v 164 | } 165 | 166 | let defaultEnv = 167 | printEnv { ghc-version = GHC.GHC883, cabal-version = Cabal.Cabal32 } 168 | 169 | let latestEnv = 170 | printEnv { ghc-version = GHC.GHC883, cabal-version = Cabal.Cabal32 } 171 | 172 | let matrixOS = "\${{ matrix.operating-system }}" 173 | 174 | let matrixEnv = 175 | VersionInfo::{ 176 | , ghc-version = Some "\${{ matrix.ghc }}" 177 | , cabal-version = Some "\${{ matrix.cabal }}" 178 | } 179 | 180 | let stackEnv = 181 | { ghc-version = Some "8.6.5" 182 | , cabal-version = None Text 183 | , stack-version = Some "latest" 184 | , enable-stack = Some True 185 | , stack-no-global = Some True 186 | , stack-setup-ghc = None Bool 187 | } 188 | : VersionInfo.Type 189 | 190 | let mkMatrix = λ(st : DhallMatrix.Type) → { matrix = printMatrix st } : Matrix 191 | 192 | let hlintDirs = 193 | λ(dirs : List Text) → 194 | let bashDirs = concatSep " " dirs 195 | 196 | in BuildStep.Name 197 | { name = "Run hlint" 198 | , run = 199 | "curl -sSL https://raw.github.com/ndmitchell/hlint/master/misc/run.sh | sh -s ${bashDirs}" 200 | } 201 | 202 | let cabalDeps = 203 | BuildStep.Name 204 | { name = "Install dependencies" 205 | , run = 206 | '' 207 | cabal update 208 | cabal build --enable-tests --enable-benchmarks --only-dependencies 209 | '' 210 | } 211 | 212 | let cmdWithFlags = 213 | λ(cmd : Text) → 214 | λ(subcommand : Text) → 215 | λ(flags : List Text) → 216 | let flagStr = concatSep " " flags 217 | 218 | in BuildStep.Name 219 | { name = subcommand, run = "${cmd} ${subcommand} ${flagStr}" } 220 | 221 | let cabalWithFlags = cmdWithFlags "cabal" 222 | 223 | let cabalBuildWithFlags = cabalWithFlags "build" 224 | 225 | let cabalBuild = cabalBuildWithFlags [ "--enable-tests", "--enable-benchmarks" ] 226 | 227 | let stackWithFlags = cmdWithFlags "stack" 228 | 229 | let stackBuildWithFlags = stackWithFlags "build" 230 | 231 | let stackBuild = 232 | stackBuildWithFlags 233 | [ "--bench", "--test", "--no-run-tests", "--no-run-benchmarks" ] 234 | 235 | let cabalTest = cabalWithFlags "test" ([] : List Text) 236 | 237 | let stackTest = stackWithFlags "test" ([] : List Text) 238 | 239 | let cabalTestProfiling = cabalWithFlags "test" [ "--enable-profiling" ] 240 | 241 | let cabalTestCoverage = cabalWithFlags "test" [ "--enable-coverage" ] 242 | 243 | let cabalDoc = cabalWithFlags "haddock" ([] : List Text) 244 | 245 | let generalCi = 246 | λ(sts : List BuildStep) → 247 | λ(mat : Optional DhallMatrix.Type) → 248 | CI::{ 249 | , jobs.build = 250 | { runs-on = printOS OS.Ubuntu1804 251 | , steps = sts 252 | , strategy = mapOptional DhallMatrix.Type Matrix mkMatrix mat 253 | } 254 | } 255 | : CI.Type 256 | 257 | let ciNoMatrix = λ(sts : List BuildStep) → generalCi sts (None DhallMatrix.Type) 258 | 259 | let stepsEnv = 260 | λ(v : VersionInfo.Type) → 261 | [ checkout 262 | , haskellEnv v 263 | , cache 264 | , cabalDeps 265 | , cabalBuild 266 | , cabalTest 267 | , cabalDoc 268 | ] 269 | : List BuildStep 270 | 271 | let stackSteps = 272 | [ checkout, haskellEnv stackEnv, stackCache, stackBuild, stackTest ] 273 | : List BuildStep 274 | 275 | let matrixSteps = stepsEnv matrixEnv : List BuildStep 276 | 277 | let defaultSteps = stepsEnv defaultEnv : List BuildStep 278 | 279 | let hlintAction = 280 | λ(dirs : List Text) → 281 | generalCi [ checkout, hlintDirs dirs ] (None DhallMatrix.Type) 282 | ⫽ { name = "HLint checks" } 283 | : CI.Type 284 | 285 | let defaultCi = generalCi defaultSteps (None DhallMatrix.Type) : CI.Type 286 | 287 | in { VersionInfo 288 | , BuildStep 289 | , Matrix 290 | , CI 291 | , GHC 292 | , Cabal 293 | , DhallVersion 294 | , DhallMatrix 295 | , CacheCfg 296 | , OS 297 | , PyInfo 298 | , Event 299 | , cabalDoc 300 | , cabalTest 301 | , cabalDeps 302 | , cabalBuild 303 | , cabalWithFlags 304 | , cabalBuildWithFlags 305 | , cabalTestProfiling 306 | , cabalTestCoverage 307 | , checkout 308 | , haskellEnv 309 | , defaultEnv 310 | , latestEnv 311 | , matrixEnv 312 | , defaultCi 313 | , generalCi 314 | , mkMatrix 315 | , printMatrix 316 | , printEnv 317 | , printGhc 318 | , printCabal 319 | , printOS 320 | , stepsEnv 321 | , matrixOS 322 | , matrixSteps 323 | , defaultSteps 324 | , hlintDirs 325 | , hlintAction 326 | , ciNoMatrix 327 | , cache 328 | , stackEnv 329 | , stackWithFlags 330 | , stackSteps 331 | , stackBuild 332 | , stackTest 333 | , stackCache 334 | } 335 | -------------------------------------------------------------------------------- /python-ci.dhall: -------------------------------------------------------------------------------- 1 | let haskellCi = ./haskell-ci.dhall 2 | 3 | let mapOptional = 4 | https://raw.githubusercontent.com/dhall-lang/dhall-lang/87993319329f3c00920d6e882365276925a4aa6a/Prelude/Optional/map sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa 5 | 6 | let PyArch = < X86 | X64 > 7 | 8 | let PyVer = < Py3 | Py2 | PyPy2 | PyPy3 > 9 | 10 | let PyInfoDhall = 11 | { Type = { python-version : PyVer, architecture : Optional PyArch } 12 | , default = { python-version = PyVer.Py3, architecture = None PyArch } 13 | } 14 | 15 | let printPyVer = 16 | λ(pyVer : PyVer) → 17 | merge 18 | { Py2 = "2.x", Py3 = "3.x", PyPy2 = "pypy2", PyPy3 = "pypy3" } 19 | pyVer 20 | 21 | let printPyArch = λ(pyArch : PyArch) → merge { X86 = "x86", X64 = "x64" } pyArch 22 | 23 | let printPyInfoDhall = 24 | λ(pyInfo : PyInfoDhall.Type) → 25 | { python-version = printPyVer pyInfo.python-version 26 | , architecture = mapOptional PyArch Text printPyArch pyInfo.architecture 27 | } 28 | 29 | let wheelInstall = 30 | haskellCi.BuildStep.Name 31 | { name = "Install wheel" 32 | , run = 33 | '' 34 | pip install wheel --upgrade 35 | '' 36 | } 37 | 38 | in { PyInfo = haskellCi.PyInfo 39 | , PyInfoDhall 40 | , PyArch 41 | , PyVer 42 | , BuildStep = haskellCi.BuildStep 43 | , CI = haskellCi.CI 44 | , Event = haskellCi.Event 45 | , printPyInfoDhall 46 | , printPyArch 47 | , printPyVer 48 | , ciNoMatrix = haskellCi.ciNoMatrix 49 | , checkout = haskellCi.checkout 50 | , wheelInstall 51 | } 52 | -------------------------------------------------------------------------------- /self-ci.dhall: -------------------------------------------------------------------------------- 1 | let dhallCi = ./dhall-ci.dhall 2 | 3 | in dhallCi.dhallSteps 4 | [ dhallCi.dhallYamlInstall 5 | , dhallCi.checkDhall 6 | [ "haskell-ci.dhall" 7 | , "ats-ci.dhall" 8 | , "toml-ci.dhall" 9 | , "self-ci.dhall" 10 | , "python-ci.dhall" 11 | , "yaml-ci.dhall" 12 | , "egison-ci.dhall" 13 | , "futhark-ci.dhall" 14 | ] 15 | , dhallCi.checkDhallYaml [ "self-ci.dhall", "example.dhall" ] 16 | ] 17 | ⫽ { on = [ dhallCi.Event.push ] } 18 | : dhallCi.CI 19 | -------------------------------------------------------------------------------- /toml-ci.dhall: -------------------------------------------------------------------------------- 1 | let haskellCi = ./haskell-ci.dhall 2 | 3 | let concatSep = 4 | https://raw.githubusercontent.com/dhall-lang/dhall-lang/9f259cd68870b912fbf2f2a08cd63dc3ccba9dc3/Prelude/Text/concatSep sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58 5 | 6 | let checkToml = 7 | λ(tomlFiles : List Text) 8 | → let bashDirs = concatSep " --file " tomlFiles 9 | 10 | in haskellCi.BuildStep.Name 11 | { name = "Check TOML" 12 | , run = 13 | "curl -sL https://raw.githubusercontent.com/vmchale/tomlcheck/master/sh/check | sh -s ${bashDirs}" 14 | } 15 | 16 | let tomlCi = 17 | λ(tomlFiles : List Text) 18 | → haskellCi.generalCi 19 | [ haskellCi.checkout, checkToml tomlFiles ] 20 | (None haskellCi.DhallMatrix.Type) 21 | ⫽ { name = "Toml check" } 22 | : haskellCi.CI.Type 23 | 24 | in { checkToml, tomlCi, CI = haskellCi.CI.Type } 25 | -------------------------------------------------------------------------------- /yaml-ci.dhall: -------------------------------------------------------------------------------- 1 | let pyCi = ./python-ci.dhall 2 | 3 | let concatSep = 4 | https://raw.githubusercontent.com/dhall-lang/dhall-lang/9f259cd68870b912fbf2f2a08cd63dc3ccba9dc3/Prelude/Text/concatSep sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58 5 | 6 | let installYamllint = 7 | pyCi.BuildStep.Name 8 | { name = "Install yamllint" 9 | , run = 10 | '' 11 | pip install yamllint --upgrade 12 | '' 13 | } 14 | 15 | let checkYaml = 16 | λ(yamlFiles : List Text) 17 | → let yamlArgs = concatSep " " yamlFiles 18 | 19 | in pyCi.BuildStep.Name 20 | { name = "Check YAML" 21 | , run = 22 | '' 23 | export PATH=$HOME/.local/bin:$PATH 24 | yamllint ${yamlArgs} 25 | '' 26 | } 27 | 28 | let yamlCi = 29 | λ(yamlFiles : List Text) 30 | → pyCi.ciNoMatrix 31 | [ pyCi.checkout 32 | , pyCi.wheelInstall 33 | , installYamllint 34 | , checkYaml yamlFiles 35 | ] 36 | ⫽ { name = "YAML check" } 37 | : pyCi.CI.Type 38 | 39 | in { checkYaml, yamlCi, CI = pyCi.CI.Type, Event = pyCi.Event } 40 | --------------------------------------------------------------------------------