git.iko.soy/typeable/compaREST
on master help sign in
GitHub actions (#118)

* Initial stab at github actions * Fixed docker images * Added run * old new * update * Updated * Fixed (?) * Added certs * Proper safe head * Use proper API * Added project name * Updated docker image * Started reading the right comments * Added docker image to CI * Renamed CI thing * Increased swap * Fixed tests * Fixed docker hub * Added conditionals back in * minor refinements

commitc7159b1f769f25f2d788b06bde6c782eba2a05ca authoriko <ilyakooo0@gmail.com> dateFri 6 Aug 2021, 11:49 (5 years ago) parentdf894c0
16 files changed+442−26
.github/workflows/github-actions-image.yaml+56 .github/workflows/haskell.yml → .github/workflows/linux-binary.yaml+2−2 action.yaml+47 app/Main.hs+2−1 default.nix+47−9 github-action/CompaREST/GitHub/API.hs+55 github-action/CompaREST/GitHub/Action/Config.hs+43 github-action/Control/Monad/Freer/GitHub.hs+27 github-action/Main.hs+87 nix/sources.json+15−3 openapi-diff.cabal+26−1 src/OpenAPI/Checker/Report.hs+1−2 src/OpenAPI/Checker/Run.hs+2−1 stack.yaml+4−1 stack.yaml.lock+25−4 test/Spec/Golden/TraceTree.hs+3−2
.github/workflows/github-actions-image.yamlnew file+56
@@ -0,0 +1,56 @@
1+name: Github Action Docker Image
2+
3+on:
4+ push:
5+ branches: [master]
6+ pull_request:
7+ branches: [master]
8+
9+jobs:
10+ build-github-action-image:
11+ runs-on: ubuntu-latest
12+
13+ steps:
14+ - uses: actions/checkout@v2
15+ with:
16+ submodules: recursive
17+ - name: Increase swap
18+ run: |
19+ free -h
20+
21+ sudo swapoff /mnt/swapfile
22+ sudo fallocate -l 12G /mnt/swapfile
23+ sudo mkswap /mnt/swapfile
24+ sudo swapon /mnt/swapfile
25+
26+ free -h
27+
28+ - name: Install Nix
29+ uses: cachix/install-nix-action@v12
30+ with:
31+ extra_nix_config: |
32+ trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
33+ substituters = https://hydra.iohk.io https://cache.nixos.org/
34+
35+ - name: Login to Cachix
36+ uses: cachix/cachix-action@v8
37+ with:
38+ name: octopod
39+ signingKey: ${{ secrets.CACHIX_SIGNING_KEY }}
40+
41+ - name: Build Github Action Docker Image
42+ run: |
43+ nix-build -A compaRESTGithubAction -j auto -o image
44+
45+ - name: Log into Docker Hub
46+ if: github.ref == 'refs/heads/master'
47+ uses: docker/login-action@v1
48+ with:
49+ username: ${{ secrets.DOCKER_HUB_USERNAME }}
50+ password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
51+
52+ - name: Upload Image to Docker Hub
53+ if: github.ref == 'refs/heads/master'
54+ run: |
55+ docker load -i image
56+ docker push typeable/comparest-github-action:latest
.github/workflows/haskell.yml → .github/workflows/linux-binary.yamlrenamed+2−2
@@ -1,4 +1,4 @@
1−name: Haskell CI
1+name: Linux binary
22
33on:
44 push:
@@ -27,7 +27,7 @@ jobs:
2727 free -h
2828
2929 sudo swapoff /mnt/swapfile
30− sudo fallocate -l 12G /mnt/swapfile
30+ sudo fallocate -l 13G /mnt/swapfile
3131 sudo mkswap /mnt/swapfile
3232 sudo swapon /mnt/swapfile
3333
action.yamlnew file+47
@@ -0,0 +1,47 @@
1+name: compaREST
2+author: Typeable
3+description: API reliability checker
4+inputs:
5+ GITHUB_TOKEN:
6+ description: "The GitHub access token (e.g. secrets.GITHUB_TOKEN) used to create or update the comment. This defaults to {{ github.token }}."
7+ default: "${{ github.token }}"
8+ required: false
9+ repo:
10+ description: The owner of the repo in which to post the comment.
11+ default: "${{ github.repository }}"
12+ required: false
13+ pull_request:
14+ description: The pull request in which to post the comment.
15+ default: "${{ github.event.pull_request.number }}"
16+ required: false
17+ project_name:
18+ description: The name of the project to which the API pertains.
19+ required: true
20+ footer:
21+ description: A footer that can be appended to the comment.
22+ required: false
23+ default: ""
24+ old:
25+ description: The path to old specification of the API.
26+ required: true
27+ new:
28+ description: The path to new specification of the API.
29+ required: true
30+runs:
31+ using: "docker"
32+ image: "typeable/comparest-github-action:latest"
33+ env:
34+ GITHUB_TOKEN: "${{ inputs.GITHUB_TOKEN }}"
35+ REPO: "${{ inputs.repo }}"
36+ PR_NUMBER: "${{ inputs.pull_request }}"
37+ PROJECT_NAME: "${{ inputs.project_name }}"
38+ FOOTER: "${{ inputs.footer }}"
39+ ROOT: "/github/workspace"
40+ OLD: "${{ inputs.old }}"
41+ NEW: "${{ inputs.new }}"
42+ pre-entrypoint: "/bin/pre"
43+ entrypoint: "/bin/run"
44+
45+branding:
46+ icon: crosshair
47+ color: gray-dark
app/Main.hs+2−1
@@ -14,6 +14,7 @@ import OpenAPI.Checker.Run
1414import System.Exit
1515import System.IO
1616import Text.Pandoc hiding (report)
17+import Text.Pandoc.Builder
1718
1819main :: IO ()
1920main = do
@@ -47,7 +48,7 @@ main = do
4748 }
4849 (report, status) = runReport reportConfig (a, b)
4950 case mode opts of
50− Just _ -> either handler pure <=< runExceptT $ write report
51+ Just _ -> either handler pure <=< runExceptT $ write $ doc report
5152 Nothing -> pure ()
5253 when (signalExitCode opts) $
5354 case status of
default.nix+47−9
@@ -1,33 +1,71 @@
11{ sources ? import ./nix/sources.nix
22, haskellNix ? import sources.haskellNix { inherit system; }
3−, pkgs ? import haskellNix.sources.nixpkgs-2105 (haskellNix.nixpkgsArgs // {inherit system;})
3+, pkgs ? import haskellNix.sources.nixpkgs-2105 (haskellNix.nixpkgsArgs // { inherit system; })
44, system ? builtins.currentSystem
5+, nix-filter ? import sources.nix-filter
56}:
67let
78 hsPkgs = pkgs.haskell-nix.stackProject {
8− src = ./.;
9+ src = nix-filter {
10+ root = ./.;
11+ name = "compaREST";
12+ include = [
13+ ./stack.yaml
14+ ./stack.yaml.lock
15+ ./openapi-diff.cabal
16+ ];
17+ };
918
1019 modules = [
1120 {
1221 dontStrip = false;
1322 dontPatchELF = false;
1423 enableDeadCodeElimination = true;
24+ packages.openapi-diff.src = nix-filter {
25+ root = ./.;
26+ name = "compaREST-src";
27+ include = with nix-filter; [
28+ (./openapi-diff.cabal)
29+ (inDirectory ./test)
30+ (inDirectory ./src)
31+ (inDirectory ./app)
32+ (inDirectory ./github-action)
33+ ./awsm-css/dist/awsm.min.css
34+ ./LICENSE
35+ ];
36+ };
1537 }
1638 ];
1739 };
1840
19− compaREST-static = pkgs.runCommand "compaREST-static" { } ''
20− mkdir $out
21− cp ${hsPkgs.projectCross.musl64.hsPkgs.openapi-diff.components.exes.openapi-diff + "/bin/openapi-diff"} $out/compaREST
41+ staticify = name: drv: pkgs.runCommand name { } ''
42+ mkdir -p $out/bin
43+ cp ${drv + "/bin"}/* $out/bin
2244
23− ${pkgs.nukeReferences}/bin/nuke-refs $out/compaREST
45+ ${pkgs.nukeReferences}/bin/nuke-refs $out/bin/*
2446 '';
47+
2548 compaREST = pkgs.dockerTools.buildImage {
2649 name = "compaREST";
27− contents = [compaREST-static];
50+ contents = [ (staticify "compaREST-static" hsPkgs.projectCross.musl64.hsPkgs.openapi-diff.components.exes.openapi-diff) ];
2851 config = {
29− Entrypoint = [ "/compaREST" ];
52+ Entrypoint = [ "/bin/openapi-diff" ];
3053 };
3154 };
3255
33−in compaREST
56+ compaRESTGithubAction =
57+ let
58+ action = staticify "compaREST-github-action-static" hsPkgs.projectCross.musl64.hsPkgs.openapi-diff.components.exes.comparest-github-action;
59+ wrapped = pkgs.runCommand "wrapped-compaREST-github-action" { buildInputs = [ pkgs.makeWrapper ]; } ''
60+ makeWrapper ${action}/bin/comparest-github-action $out/bin/pre --add-flags "pre"
61+ makeWrapper ${action}/bin/comparest-github-action $out/bin/run --add-flags "run"
62+ '';
63+ in
64+ pkgs.dockerTools.buildImage {
65+ name = "typeable/comparest-github-action";
66+ tag = "latest";
67+ contents = [ wrapped pkgs.cacert ];
68+ };
69+
70+in
71+{ inherit compaREST compaRESTGithubAction; }
github-action/CompaREST/GitHub/API.hsnew file+55
@@ -0,0 +1,55 @@
1+module CompaREST.GitHub.API
2+ ( mapComment,
3+ createOrUpdateComment,
4+ )
5+where
6+
7+import CompaREST.GitHub.Action.Config
8+import Control.Monad
9+import Control.Monad.Freer
10+import Control.Monad.Freer.GitHub
11+import Control.Monad.Freer.Reader
12+import Data.Foldable
13+import Data.Proxy
14+import Data.Text (Text)
15+import qualified Data.Text as T
16+import qualified Data.Vector as V
17+import GitHub
18+import qualified GitHub as GH
19+
20+findComment :: Members '[GitHub, Reader Config] effs => Eff effs (Maybe GH.IssueComment)
21+findComment = do
22+ Config {..} <- ask
23+ comments <- sendGitHub $ GH.commentsR repoOwner repoName issue GH.FetchAll
24+ htmlComment <- getHTMLComment
25+ let tryStripPrefix :: GH.IssueComment -> Maybe GH.IssueComment
26+ tryStripPrefix c@GH.IssueComment {issueCommentBody = (T.stripSuffix htmlComment -> Just b)} =
27+ Just $ c {GH.issueCommentBody = b}
28+ tryStripPrefix _ = Nothing
29+ pure . (V.!? 0) $ V.mapMaybe tryStripPrefix comments
30+
31+mapComment :: Members '[GitHub, Reader Config] effs => (Text -> Text) -> Eff effs ()
32+mapComment f = do
33+ findComment
34+ >>= traverse_
35+ ( \comment -> do
36+ Config {..} <- ask
37+ htmlComment <- getHTMLComment
38+ sendGitHub $ editCommentR repoOwner repoName (GH.mkId Proxy $ GH.issueCommentId comment) ((<> htmlComment) . f $ GH.issueCommentBody comment)
39+ pure ()
40+ )
41+
42+createOrUpdateComment :: Members '[GitHub, Reader Config] effs => Text -> Eff effs ()
43+createOrUpdateComment body' = do
44+ Config {..} <- ask
45+ htmlComment <- getHTMLComment
46+ let body = body' <> htmlComment
47+ void $
48+ findComment >>= \case
49+ Just comment -> sendGitHub $ editCommentR repoOwner repoName (GH.mkId Proxy $ GH.issueCommentId comment) body
50+ Nothing -> sendGitHub $ createCommentR repoOwner repoName issue body
51+
52+getHTMLComment :: Member (Reader Config) effs => Eff effs Text
53+getHTMLComment = do
54+ name <- asks projectName
55+ pure $ "\n\n<!-- compaREST comment – " <> name <> " -->"
github-action/CompaREST/GitHub/Action/Config.hsnew file+43
@@ -0,0 +1,43 @@
1+module CompaREST.GitHub.Action.Config
2+ ( Config (..),
3+ )
4+where
5+
6+import Data.Proxy
7+import Data.Text (Text)
8+import qualified Data.Text as T
9+import qualified GitHub as GH
10+
11+import System.Envy
12+
13+data Config = Config
14+ { githubToken :: GH.Auth
15+ , repoOwner :: GH.Name GH.Owner
16+ , repoName :: GH.Name GH.Repo
17+ , issue :: GH.IssueNumber
18+ , projectName :: Text
19+ , footerText :: Text
20+ , root :: FilePath
21+ }
22+
23+instance FromEnv Config where
24+ fromEnv _ = do
25+ token <- GH.OAuth <$> env "GITHUB_TOKEN"
26+ (owner, repo) <-
27+ T.split (== '/') <$> env "REPO" >>= \case
28+ [owner, name] -> pure (owner, name)
29+ _ -> fail "malformed repo"
30+ issue <- GH.IssueNumber <$> env "PR_NUMBER"
31+ projectName <- env "PROJECT_NAME"
32+ footerText <- env "FOOTER"
33+ root <- envMaybe "ROOT" .!= "."
34+ pure $
35+ Config
36+ { githubToken = token
37+ , repoOwner = GH.mkName Proxy owner
38+ , repoName = GH.mkName Proxy repo
39+ , issue = issue
40+ , projectName = projectName
41+ , footerText = footerText
42+ , root = root
43+ }
github-action/Control/Monad/Freer/GitHub.hsnew file+27
@@ -0,0 +1,27 @@
1+module Control.Monad.Freer.GitHub
2+ ( GitHub (..),
3+ runGitHub,
4+ sendGitHub,
5+ )
6+where
7+
8+import Control.Monad.Freer
9+import Control.Monad.Freer.Error
10+import Control.Monad.IO.Class
11+import Data.Aeson
12+import GitHub hiding (Error)
13+import qualified GitHub as GH
14+
15+data GitHub r where
16+ SendGHRequest :: FromJSON x => Request 'RW x -> GitHub x
17+
18+runGitHub :: (Member (Error GH.Error) effs, MonadIO (Eff effs)) => Auth -> Eff (GitHub ': effs) ~> Eff effs
19+runGitHub auth =
20+ interpret
21+ ( \(SendGHRequest req) ->
22+ liftIO (executeRequest auth req)
23+ >>= either throwError pure
24+ )
25+
26+sendGitHub :: (FromJSON x, Member GitHub effs) => Request 'RW x -> Eff effs x
27+sendGitHub req = send $ SendGHRequest req
github-action/Main.hsnew file+87
@@ -0,0 +1,87 @@
1+module Main (main) where
2+
3+import CompaREST.GitHub.API
4+import CompaREST.GitHub.Action.Config
5+import Control.Exception
6+import Control.Monad.Freer
7+import Control.Monad.Freer.Error
8+import Control.Monad.Freer.GitHub
9+import Control.Monad.Freer.Reader
10+import Data.Text (Text)
11+import qualified Data.Yaml.Aeson as Yaml
12+import qualified GitHub as GH
13+import OpenAPI.Checker.Run
14+import System.Environment
15+import System.Envy (decodeEnv)
16+import System.FilePath ((</>))
17+import Text.Pandoc (runPure)
18+import Text.Pandoc.Builder
19+import Text.Pandoc.Options
20+import Text.Pandoc.Writers
21+
22+main :: IO ()
23+main = do
24+ cfg <- decodeEnv >>= either error pure
25+ getArgs >>= \case
26+ ["pre"] -> runPre cfg
27+ ["run"] -> do
28+ oldFile <- getEnv "OLD"
29+ newFile <- getEnv "NEW"
30+ runRun cfg (root cfg </> oldFile) (root cfg </> newFile)
31+ _ -> error "Invalid arguments."
32+
33+runner :: Config -> Eff '[GitHub, Error GH.Error, Reader Config, IO] a -> IO a
34+runner cfg =
35+ runM @IO . runReader cfg
36+ . flip (handleError @GH.Error) (error . displayException)
37+ . runGitHub (githubToken cfg)
38+
39+runPre :: Config -> IO ()
40+runPre cfg =
41+ runner cfg $
42+ mapComment
43+ (markdown (header 4 "⏳ Report might not be accurate. Attempting to update." <> horizontalRule) <>)
44+
45+runRun :: Config -> FilePath -> FilePath -> IO ()
46+runRun cfg old' new' = runner cfg $ do
47+ old <- Yaml.decodeFileThrow old'
48+ new <- Yaml.decodeFileThrow new'
49+ let reportConfig =
50+ ReportConfig
51+ { treeStyle = FoldingBlockquotesTreeStyle
52+ , reportMode = All
53+ }
54+ (report, status) = runReport reportConfig (old, new)
55+
56+ summaryDetail s d =
57+ rawHtml "<details>"
58+ <> rawHtml "<summary>"
59+ <> s
60+ <> rawHtml "</summary>"
61+ <> d
62+ <> rawHtml "</details>"
63+ where
64+ rawHtml = rawBlock "html"
65+
66+ message =
67+ header 3 (text $ "⛄ compaREST – " <> projectName cfg)
68+ <> if old == new
69+ then header 1 "✅ The API did not change"
70+ else
71+ header
72+ 1
73+ ( case status of
74+ BreakingChanges -> "⚠️ Breaking changes found!"
75+ NoBreakingChanges -> "No breaking changes found ✨"
76+ OnlyUnsupportedChanges -> "🤷 Couldn't determine compatibility"
77+ )
78+ <> summaryDetail (plain "ℹ️ Details") report
79+ messageBody = markdown message <> "\n\n" <> footerText cfg
80+ createOrUpdateComment messageBody
81+
82+markdown :: Blocks -> Text
83+markdown =
84+ either (error . displayException) id
85+ . runPure
86+ . writeHtml5String def
87+ . doc
nix/sources.json+15−3
@@ -5,10 +5,10 @@
55 "homepage": "https://input-output-hk.github.io/haskell.nix",
66 "owner": "input-output-hk",
77 "repo": "haskell.nix",
8− "rev": "8c587f90d2986f87a8212c3469521db512bc7ed9",
9− "sha256": "0a4mz47ccvl1nl2p08zbn33i1vmak4bjr4z6wqzzflnq90hg5a0s",
8+ "rev": "1992b910e9b4d880e1f4639f4fe7266bceb9a5ad",
9+ "sha256": "15w3wixjnb52f7cj3s94fy0zc0l1gc94p3n2wyq3qqxj10hvirfw",
1010 "type": "tarball",
11− "url": "https://github.com/input-output-hk/haskell.nix/archive/8c587f90d2986f87a8212c3469521db512bc7ed9.tar.gz",
11+ "url": "https://github.com/input-output-hk/haskell.nix/archive/1992b910e9b4d880e1f4639f4fe7266bceb9a5ad.tar.gz",
1212 "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
1313 },
1414 "niv": {
@@ -22,5 +22,17 @@
2222 "type": "tarball",
2323 "url": "https://github.com/nmattia/niv/archive/e0ca65c81a2d7a4d82a189f1e23a48d59ad42070.tar.gz",
2424 "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
25+ },
26+ "nix-filter": {
27+ "branch": "master",
28+ "description": "a small self-container source filtering lib",
29+ "homepage": "",
30+ "owner": "numtide",
31+ "repo": "nix-filter",
32+ "rev": "3c9e33ed627e009428197b07216613206f06ed80",
33+ "sha256": "19w142crrkywxynmyw4rhz4nglrg64yjawfkw3j91qwkwbfjds84",
34+ "type": "tarball",
35+ "url": "https://github.com/numtide/nix-filter/archive/3c9e33ed627e009428197b07216613206f06ed80.tar.gz",
36+ "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
2537 }
2638}
openapi-diff.cabal+26−1
@@ -38,7 +38,6 @@ common common-options
3838 -fconstraint-solver-iterations=0
3939 default-language: Haskell2010
4040 build-depends: base >= 4.12.0.0 && < 4.16
41− , bytestring
4241 , text
4342
4443 default-extensions: ApplicativeDo
@@ -111,6 +110,7 @@ library
111110 , file-embed
112111 , data-default
113112 , ordered-containers
113+ , bytestring
114114 hs-source-dirs: src
115115 exposed-modules: Data.HList
116116 , OpenAPI.Checker.Behavior
@@ -167,6 +167,7 @@ executable openapi-diff
167167 , aeson
168168 , containers
169169 , doctemplates
170+ , pandoc-types
170171 ghc-options: -threaded
171172 -rtsopts
172173 -with-rtsopts=-N
@@ -174,6 +175,29 @@ executable openapi-diff
174175 FormatHeuristic
175176 OpenAPI.Checker.Options
176177
178+executable comparest-github-action
179+ import: common-options
180+ hs-source-dirs: github-action
181+ main-is: Main.hs
182+ build-depends:
183+ openapi-diff
184+ , pandoc
185+ , yaml
186+ , aeson
187+ , github
188+ , freer-simple
189+ , vector
190+ , pandoc-types
191+ , envy
192+ , filepath
193+ ghc-options: -threaded
194+ -rtsopts
195+ -with-rtsopts=-N
196+ other-modules:
197+ Control.Monad.Freer.GitHub
198+ CompaREST.GitHub.API
199+ CompaREST.GitHub.Action.Config
200+
177201test-suite openapi-diff-test
178202 import: common-options
179203 type: exitcode-stdio-1.0
@@ -193,6 +217,7 @@ test-suite openapi-diff-test
193217 , pandoc
194218 , data-default
195219 , lens
220+ , pandoc-types
196221 ghc-options: -threaded
197222 -rtsopts
198223 -with-rtsopts=-N
src/OpenAPI/Checker/Report.hs+1−2
@@ -104,7 +104,7 @@ data ReportTreeStyle = HeadersTreeStyle | FoldingBlockquotesTreeStyle
104104twoRowTable :: [(Inlines, Inlines)] -> Blocks
105105twoRowTable x = simpleTable (para . fst <$> x) [para . snd <$> x]
106106
107−generateReport :: ReportConfig -> ReportInput -> (Pandoc, ReportStatus)
107+generateReport :: ReportConfig -> ReportInput -> (Blocks, ReportStatus)
108108generateReport cfg inp =
109109 let
110110 schemaIssuesPresent = not $ P.null $ schemaIssues inp
@@ -116,7 +116,6 @@ generateReport cfg inp =
116116 OnlyErrors -> False
117117 builder = buildReport cfg
118118 report =
119− doc $
120119 header 1 "Summary"
121120 <> twoRowTable
122121 (when'
src/OpenAPI/Checker/Run.hs+2−1
@@ -11,6 +11,7 @@ import OpenAPI.Checker.Paths
1111import OpenAPI.Checker.Report
1212import OpenAPI.Checker.Subtree
1313import OpenAPI.Checker.Validate.OpenApi ()
14+import Text.Pandoc.Builder
1415
1516runChecker :: (OpenApi, OpenApi) -> CheckerOutput
1617runChecker (client, server) =
@@ -26,5 +27,5 @@ runChecker (client, server) =
2627 }
2728 run p c = either id mempty . runCompatFormula . checkCompatibility Root HNil $ toPC p c
2829
29−runReport :: ReportConfig -> (OpenApi, OpenApi) -> (Pandoc, ReportStatus)
30+runReport :: ReportConfig -> (OpenApi, OpenApi) -> (Blocks, ReportStatus)
3031runReport cfg = generateReport cfg . segregateIssues . runChecker
stack.yaml+4−1
@@ -1,8 +1,11 @@
1−resolver: lts-18.2
1+resolver: lts-18.4
22
33extra-deps:
44 - open-union-0.4.0.0
55 - type-fun-0.1.3
6+ - github-0.26
7+ - base16-bytestring-0.1.1.7
8+ - http-link-header-1.0.3.1
69
710apply-ghc-options: everything
811rebuild-ghc-options: true
stack.yaml.lock+25−4
@@ -18,9 +18,30 @@ packages:
1818 sha256: b977d42525f0b4223959918d18e7905085283e937493c395077b608cd19b42c1
1919 original:
2020 hackage: type-fun-0.1.3
21+- completed:
22+ hackage: github-0.26@sha256:a9d4046325c3eb28cdc7bef2c3f5bb213328caeae0b7dce6f51de655f0bffaa1,7162
23+ pantry-tree:
24+ size: 7511
25+ sha256: b71aab2984b268030c9e2617043575681134c1fe60dffbd5596e659c0a3e9aec
26+ original:
27+ hackage: github-0.26
28+- completed:
29+ hackage: base16-bytestring-0.1.1.7@sha256:0021256a9628971c08da95cb8f4d0d72192f3bb8a7b30b55c080562d17c43dd3,2231
30+ pantry-tree:
31+ size: 454
32+ sha256: 2dc99cd67293b09204098202d0bdcdcf89d2b8c69ce6c8f4e31deadbdab2a7f9
33+ original:
34+ hackage: base16-bytestring-0.1.1.7
35+- completed:
36+ hackage: http-link-header-1.0.3.1@sha256:9917c26635a46eff5d36c5344a4ae42fad2b5de79c0e300363bddd5eec66facd,1937
37+ pantry-tree:
38+ size: 990
39+ sha256: 155feaf856daf5b55491048c8c4726ba765a8fe79263ebdbfc82f6c385a15715
40+ original:
41+ hackage: http-link-header-1.0.3.1
2142snapshots:
2243- completed:
23− size: 585392
24− url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/2.yaml
25− sha256: 7abb45c0cc5eb349448b66d8753655542d45d387ad26970419282eab3d860724
26− original: lts-18.2
44+ size: 585817
45+ url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/4.yaml
46+ sha256: ea3a318eafa9e9cc56bfbe46099fd0d54d32641ab7bbe1d182ed8f5de39f804c
47+ original: lts-18.4
test/Spec/Golden/TraceTree.hs+3−2
@@ -1,5 +1,5 @@
11module Spec.Golden.TraceTree
2− ( tests
2+ ( tests,
33 )
44where
55
@@ -14,6 +14,7 @@ import OpenAPI.Checker.Run
1414import OpenAPI.Checker.Validate.OpenApi ()
1515import Spec.Golden.Extra
1616import Test.Tasty (TestTree, testGroup)
17+import Text.Pandoc.Builder
1718import Text.Pandoc.Class
1819import Text.Pandoc.Options
1920import Text.Pandoc.Writers
@@ -37,7 +38,7 @@ tests = do
3738 "report.md"
3839 ("a.yaml", "b.yaml")
3940 Yaml.decodeFileThrow
40− (runPandoc . writeMarkdown def {writerExtensions = githubMarkdownExtensions} . fst . runReport def)
41+ (runPandoc . writeMarkdown def {writerExtensions = githubMarkdownExtensions} . doc . fst . runReport def)
4142
4243 return $ testGroup "Golden tests" [traceTreeTests, reportTests]
4344