mirror of
https://github.com/ilyakooo0/compaREST.git
synced 2024-09-11 06:25:40 +03:00
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
This commit is contained in:
parent
df894c0d88
commit
c7159b1f76
56
.github/workflows/github-actions-image.yaml
vendored
Normal file
56
.github/workflows/github-actions-image.yaml
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
name: Github Action Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
pull_request:
|
||||||
|
branches: [master]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-github-action-image:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Increase swap
|
||||||
|
run: |
|
||||||
|
free -h
|
||||||
|
|
||||||
|
sudo swapoff /mnt/swapfile
|
||||||
|
sudo fallocate -l 12G /mnt/swapfile
|
||||||
|
sudo mkswap /mnt/swapfile
|
||||||
|
sudo swapon /mnt/swapfile
|
||||||
|
|
||||||
|
free -h
|
||||||
|
|
||||||
|
- name: Install Nix
|
||||||
|
uses: cachix/install-nix-action@v12
|
||||||
|
with:
|
||||||
|
extra_nix_config: |
|
||||||
|
trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
|
||||||
|
substituters = https://hydra.iohk.io https://cache.nixos.org/
|
||||||
|
|
||||||
|
- name: Login to Cachix
|
||||||
|
uses: cachix/cachix-action@v8
|
||||||
|
with:
|
||||||
|
name: octopod
|
||||||
|
signingKey: ${{ secrets.CACHIX_SIGNING_KEY }}
|
||||||
|
|
||||||
|
- name: Build Github Action Docker Image
|
||||||
|
run: |
|
||||||
|
nix-build -A compaRESTGithubAction -j auto -o image
|
||||||
|
|
||||||
|
- name: Log into Docker Hub
|
||||||
|
if: github.ref == 'refs/heads/master'
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||||
|
|
||||||
|
- name: Upload Image to Docker Hub
|
||||||
|
if: github.ref == 'refs/heads/master'
|
||||||
|
run: |
|
||||||
|
docker load -i image
|
||||||
|
docker push typeable/comparest-github-action:latest
|
@ -1,4 +1,4 @@
|
|||||||
name: Haskell CI
|
name: Linux binary
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -27,7 +27,7 @@ jobs:
|
|||||||
free -h
|
free -h
|
||||||
|
|
||||||
sudo swapoff /mnt/swapfile
|
sudo swapoff /mnt/swapfile
|
||||||
sudo fallocate -l 12G /mnt/swapfile
|
sudo fallocate -l 13G /mnt/swapfile
|
||||||
sudo mkswap /mnt/swapfile
|
sudo mkswap /mnt/swapfile
|
||||||
sudo swapon /mnt/swapfile
|
sudo swapon /mnt/swapfile
|
||||||
|
|
47
action.yaml
Normal file
47
action.yaml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
name: compaREST
|
||||||
|
author: Typeable
|
||||||
|
description: API reliability checker
|
||||||
|
inputs:
|
||||||
|
GITHUB_TOKEN:
|
||||||
|
description: "The GitHub access token (e.g. secrets.GITHUB_TOKEN) used to create or update the comment. This defaults to {{ github.token }}."
|
||||||
|
default: "${{ github.token }}"
|
||||||
|
required: false
|
||||||
|
repo:
|
||||||
|
description: The owner of the repo in which to post the comment.
|
||||||
|
default: "${{ github.repository }}"
|
||||||
|
required: false
|
||||||
|
pull_request:
|
||||||
|
description: The pull request in which to post the comment.
|
||||||
|
default: "${{ github.event.pull_request.number }}"
|
||||||
|
required: false
|
||||||
|
project_name:
|
||||||
|
description: The name of the project to which the API pertains.
|
||||||
|
required: true
|
||||||
|
footer:
|
||||||
|
description: A footer that can be appended to the comment.
|
||||||
|
required: false
|
||||||
|
default: ""
|
||||||
|
old:
|
||||||
|
description: The path to old specification of the API.
|
||||||
|
required: true
|
||||||
|
new:
|
||||||
|
description: The path to new specification of the API.
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: "docker"
|
||||||
|
image: "typeable/comparest-github-action:latest"
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: "${{ inputs.GITHUB_TOKEN }}"
|
||||||
|
REPO: "${{ inputs.repo }}"
|
||||||
|
PR_NUMBER: "${{ inputs.pull_request }}"
|
||||||
|
PROJECT_NAME: "${{ inputs.project_name }}"
|
||||||
|
FOOTER: "${{ inputs.footer }}"
|
||||||
|
ROOT: "/github/workspace"
|
||||||
|
OLD: "${{ inputs.old }}"
|
||||||
|
NEW: "${{ inputs.new }}"
|
||||||
|
pre-entrypoint: "/bin/pre"
|
||||||
|
entrypoint: "/bin/run"
|
||||||
|
|
||||||
|
branding:
|
||||||
|
icon: crosshair
|
||||||
|
color: gray-dark
|
@ -14,6 +14,7 @@ import OpenAPI.Checker.Run
|
|||||||
import System.Exit
|
import System.Exit
|
||||||
import System.IO
|
import System.IO
|
||||||
import Text.Pandoc hiding (report)
|
import Text.Pandoc hiding (report)
|
||||||
|
import Text.Pandoc.Builder
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
@ -47,7 +48,7 @@ main = do
|
|||||||
}
|
}
|
||||||
(report, status) = runReport reportConfig (a, b)
|
(report, status) = runReport reportConfig (a, b)
|
||||||
case mode opts of
|
case mode opts of
|
||||||
Just _ -> either handler pure <=< runExceptT $ write report
|
Just _ -> either handler pure <=< runExceptT $ write $ doc report
|
||||||
Nothing -> pure ()
|
Nothing -> pure ()
|
||||||
when (signalExitCode opts) $
|
when (signalExitCode opts) $
|
||||||
case status of
|
case status of
|
||||||
|
56
default.nix
56
default.nix
@ -1,33 +1,71 @@
|
|||||||
{ sources ? import ./nix/sources.nix
|
{ sources ? import ./nix/sources.nix
|
||||||
, haskellNix ? import sources.haskellNix { inherit system; }
|
, haskellNix ? import sources.haskellNix { inherit system; }
|
||||||
, pkgs ? import haskellNix.sources.nixpkgs-2105 (haskellNix.nixpkgsArgs // {inherit system;})
|
, pkgs ? import haskellNix.sources.nixpkgs-2105 (haskellNix.nixpkgsArgs // { inherit system; })
|
||||||
, system ? builtins.currentSystem
|
, system ? builtins.currentSystem
|
||||||
|
, nix-filter ? import sources.nix-filter
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
hsPkgs = pkgs.haskell-nix.stackProject {
|
hsPkgs = pkgs.haskell-nix.stackProject {
|
||||||
src = ./.;
|
src = nix-filter {
|
||||||
|
root = ./.;
|
||||||
|
name = "compaREST";
|
||||||
|
include = [
|
||||||
|
./stack.yaml
|
||||||
|
./stack.yaml.lock
|
||||||
|
./openapi-diff.cabal
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
modules = [
|
modules = [
|
||||||
{
|
{
|
||||||
dontStrip = false;
|
dontStrip = false;
|
||||||
dontPatchELF = false;
|
dontPatchELF = false;
|
||||||
enableDeadCodeElimination = true;
|
enableDeadCodeElimination = true;
|
||||||
|
packages.openapi-diff.src = nix-filter {
|
||||||
|
root = ./.;
|
||||||
|
name = "compaREST-src";
|
||||||
|
include = with nix-filter; [
|
||||||
|
(./openapi-diff.cabal)
|
||||||
|
(inDirectory ./test)
|
||||||
|
(inDirectory ./src)
|
||||||
|
(inDirectory ./app)
|
||||||
|
(inDirectory ./github-action)
|
||||||
|
./awsm-css/dist/awsm.min.css
|
||||||
|
./LICENSE
|
||||||
|
];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
compaREST-static = pkgs.runCommand "compaREST-static" { } ''
|
staticify = name: drv: pkgs.runCommand name { } ''
|
||||||
mkdir $out
|
mkdir -p $out/bin
|
||||||
cp ${hsPkgs.projectCross.musl64.hsPkgs.openapi-diff.components.exes.openapi-diff + "/bin/openapi-diff"} $out/compaREST
|
cp ${drv + "/bin"}/* $out/bin
|
||||||
|
|
||||||
${pkgs.nukeReferences}/bin/nuke-refs $out/compaREST
|
${pkgs.nukeReferences}/bin/nuke-refs $out/bin/*
|
||||||
'';
|
'';
|
||||||
|
|
||||||
compaREST = pkgs.dockerTools.buildImage {
|
compaREST = pkgs.dockerTools.buildImage {
|
||||||
name = "compaREST";
|
name = "compaREST";
|
||||||
contents = [compaREST-static];
|
contents = [ (staticify "compaREST-static" hsPkgs.projectCross.musl64.hsPkgs.openapi-diff.components.exes.openapi-diff) ];
|
||||||
config = {
|
config = {
|
||||||
Entrypoint = [ "/compaREST" ];
|
Entrypoint = [ "/bin/openapi-diff" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
in compaREST
|
compaRESTGithubAction =
|
||||||
|
let
|
||||||
|
action = staticify "compaREST-github-action-static" hsPkgs.projectCross.musl64.hsPkgs.openapi-diff.components.exes.comparest-github-action;
|
||||||
|
wrapped = pkgs.runCommand "wrapped-compaREST-github-action" { buildInputs = [ pkgs.makeWrapper ]; } ''
|
||||||
|
makeWrapper ${action}/bin/comparest-github-action $out/bin/pre --add-flags "pre"
|
||||||
|
makeWrapper ${action}/bin/comparest-github-action $out/bin/run --add-flags "run"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
pkgs.dockerTools.buildImage {
|
||||||
|
name = "typeable/comparest-github-action";
|
||||||
|
tag = "latest";
|
||||||
|
contents = [ wrapped pkgs.cacert ];
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
{ inherit compaREST compaRESTGithubAction; }
|
||||||
|
55
github-action/CompaREST/GitHub/API.hs
Normal file
55
github-action/CompaREST/GitHub/API.hs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
module CompaREST.GitHub.API
|
||||||
|
( mapComment,
|
||||||
|
createOrUpdateComment,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import CompaREST.GitHub.Action.Config
|
||||||
|
import Control.Monad
|
||||||
|
import Control.Monad.Freer
|
||||||
|
import Control.Monad.Freer.GitHub
|
||||||
|
import Control.Monad.Freer.Reader
|
||||||
|
import Data.Foldable
|
||||||
|
import Data.Proxy
|
||||||
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Vector as V
|
||||||
|
import GitHub
|
||||||
|
import qualified GitHub as GH
|
||||||
|
|
||||||
|
findComment :: Members '[GitHub, Reader Config] effs => Eff effs (Maybe GH.IssueComment)
|
||||||
|
findComment = do
|
||||||
|
Config {..} <- ask
|
||||||
|
comments <- sendGitHub $ GH.commentsR repoOwner repoName issue GH.FetchAll
|
||||||
|
htmlComment <- getHTMLComment
|
||||||
|
let tryStripPrefix :: GH.IssueComment -> Maybe GH.IssueComment
|
||||||
|
tryStripPrefix c@GH.IssueComment {issueCommentBody = (T.stripSuffix htmlComment -> Just b)} =
|
||||||
|
Just $ c {GH.issueCommentBody = b}
|
||||||
|
tryStripPrefix _ = Nothing
|
||||||
|
pure . (V.!? 0) $ V.mapMaybe tryStripPrefix comments
|
||||||
|
|
||||||
|
mapComment :: Members '[GitHub, Reader Config] effs => (Text -> Text) -> Eff effs ()
|
||||||
|
mapComment f = do
|
||||||
|
findComment
|
||||||
|
>>= traverse_
|
||||||
|
( \comment -> do
|
||||||
|
Config {..} <- ask
|
||||||
|
htmlComment <- getHTMLComment
|
||||||
|
sendGitHub $ editCommentR repoOwner repoName (GH.mkId Proxy $ GH.issueCommentId comment) ((<> htmlComment) . f $ GH.issueCommentBody comment)
|
||||||
|
pure ()
|
||||||
|
)
|
||||||
|
|
||||||
|
createOrUpdateComment :: Members '[GitHub, Reader Config] effs => Text -> Eff effs ()
|
||||||
|
createOrUpdateComment body' = do
|
||||||
|
Config {..} <- ask
|
||||||
|
htmlComment <- getHTMLComment
|
||||||
|
let body = body' <> htmlComment
|
||||||
|
void $
|
||||||
|
findComment >>= \case
|
||||||
|
Just comment -> sendGitHub $ editCommentR repoOwner repoName (GH.mkId Proxy $ GH.issueCommentId comment) body
|
||||||
|
Nothing -> sendGitHub $ createCommentR repoOwner repoName issue body
|
||||||
|
|
||||||
|
getHTMLComment :: Member (Reader Config) effs => Eff effs Text
|
||||||
|
getHTMLComment = do
|
||||||
|
name <- asks projectName
|
||||||
|
pure $ "\n\n<!-- compaREST comment – " <> name <> " -->"
|
43
github-action/CompaREST/GitHub/Action/Config.hs
Normal file
43
github-action/CompaREST/GitHub/Action/Config.hs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
module CompaREST.GitHub.Action.Config
|
||||||
|
( Config (..),
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Data.Proxy
|
||||||
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import qualified GitHub as GH
|
||||||
|
|
||||||
|
import System.Envy
|
||||||
|
|
||||||
|
data Config = Config
|
||||||
|
{ githubToken :: GH.Auth
|
||||||
|
, repoOwner :: GH.Name GH.Owner
|
||||||
|
, repoName :: GH.Name GH.Repo
|
||||||
|
, issue :: GH.IssueNumber
|
||||||
|
, projectName :: Text
|
||||||
|
, footerText :: Text
|
||||||
|
, root :: FilePath
|
||||||
|
}
|
||||||
|
|
||||||
|
instance FromEnv Config where
|
||||||
|
fromEnv _ = do
|
||||||
|
token <- GH.OAuth <$> env "GITHUB_TOKEN"
|
||||||
|
(owner, repo) <-
|
||||||
|
T.split (== '/') <$> env "REPO" >>= \case
|
||||||
|
[owner, name] -> pure (owner, name)
|
||||||
|
_ -> fail "malformed repo"
|
||||||
|
issue <- GH.IssueNumber <$> env "PR_NUMBER"
|
||||||
|
projectName <- env "PROJECT_NAME"
|
||||||
|
footerText <- env "FOOTER"
|
||||||
|
root <- envMaybe "ROOT" .!= "."
|
||||||
|
pure $
|
||||||
|
Config
|
||||||
|
{ githubToken = token
|
||||||
|
, repoOwner = GH.mkName Proxy owner
|
||||||
|
, repoName = GH.mkName Proxy repo
|
||||||
|
, issue = issue
|
||||||
|
, projectName = projectName
|
||||||
|
, footerText = footerText
|
||||||
|
, root = root
|
||||||
|
}
|
27
github-action/Control/Monad/Freer/GitHub.hs
Normal file
27
github-action/Control/Monad/Freer/GitHub.hs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
module Control.Monad.Freer.GitHub
|
||||||
|
( GitHub (..),
|
||||||
|
runGitHub,
|
||||||
|
sendGitHub,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Control.Monad.Freer
|
||||||
|
import Control.Monad.Freer.Error
|
||||||
|
import Control.Monad.IO.Class
|
||||||
|
import Data.Aeson
|
||||||
|
import GitHub hiding (Error)
|
||||||
|
import qualified GitHub as GH
|
||||||
|
|
||||||
|
data GitHub r where
|
||||||
|
SendGHRequest :: FromJSON x => Request 'RW x -> GitHub x
|
||||||
|
|
||||||
|
runGitHub :: (Member (Error GH.Error) effs, MonadIO (Eff effs)) => Auth -> Eff (GitHub ': effs) ~> Eff effs
|
||||||
|
runGitHub auth =
|
||||||
|
interpret
|
||||||
|
( \(SendGHRequest req) ->
|
||||||
|
liftIO (executeRequest auth req)
|
||||||
|
>>= either throwError pure
|
||||||
|
)
|
||||||
|
|
||||||
|
sendGitHub :: (FromJSON x, Member GitHub effs) => Request 'RW x -> Eff effs x
|
||||||
|
sendGitHub req = send $ SendGHRequest req
|
87
github-action/Main.hs
Normal file
87
github-action/Main.hs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
module Main (main) where
|
||||||
|
|
||||||
|
import CompaREST.GitHub.API
|
||||||
|
import CompaREST.GitHub.Action.Config
|
||||||
|
import Control.Exception
|
||||||
|
import Control.Monad.Freer
|
||||||
|
import Control.Monad.Freer.Error
|
||||||
|
import Control.Monad.Freer.GitHub
|
||||||
|
import Control.Monad.Freer.Reader
|
||||||
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Yaml.Aeson as Yaml
|
||||||
|
import qualified GitHub as GH
|
||||||
|
import OpenAPI.Checker.Run
|
||||||
|
import System.Environment
|
||||||
|
import System.Envy (decodeEnv)
|
||||||
|
import System.FilePath ((</>))
|
||||||
|
import Text.Pandoc (runPure)
|
||||||
|
import Text.Pandoc.Builder
|
||||||
|
import Text.Pandoc.Options
|
||||||
|
import Text.Pandoc.Writers
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
cfg <- decodeEnv >>= either error pure
|
||||||
|
getArgs >>= \case
|
||||||
|
["pre"] -> runPre cfg
|
||||||
|
["run"] -> do
|
||||||
|
oldFile <- getEnv "OLD"
|
||||||
|
newFile <- getEnv "NEW"
|
||||||
|
runRun cfg (root cfg </> oldFile) (root cfg </> newFile)
|
||||||
|
_ -> error "Invalid arguments."
|
||||||
|
|
||||||
|
runner :: Config -> Eff '[GitHub, Error GH.Error, Reader Config, IO] a -> IO a
|
||||||
|
runner cfg =
|
||||||
|
runM @IO . runReader cfg
|
||||||
|
. flip (handleError @GH.Error) (error . displayException)
|
||||||
|
. runGitHub (githubToken cfg)
|
||||||
|
|
||||||
|
runPre :: Config -> IO ()
|
||||||
|
runPre cfg =
|
||||||
|
runner cfg $
|
||||||
|
mapComment
|
||||||
|
(markdown (header 4 "⏳ Report might not be accurate. Attempting to update." <> horizontalRule) <>)
|
||||||
|
|
||||||
|
runRun :: Config -> FilePath -> FilePath -> IO ()
|
||||||
|
runRun cfg old' new' = runner cfg $ do
|
||||||
|
old <- Yaml.decodeFileThrow old'
|
||||||
|
new <- Yaml.decodeFileThrow new'
|
||||||
|
let reportConfig =
|
||||||
|
ReportConfig
|
||||||
|
{ treeStyle = FoldingBlockquotesTreeStyle
|
||||||
|
, reportMode = All
|
||||||
|
}
|
||||||
|
(report, status) = runReport reportConfig (old, new)
|
||||||
|
|
||||||
|
summaryDetail s d =
|
||||||
|
rawHtml "<details>"
|
||||||
|
<> rawHtml "<summary>"
|
||||||
|
<> s
|
||||||
|
<> rawHtml "</summary>"
|
||||||
|
<> d
|
||||||
|
<> rawHtml "</details>"
|
||||||
|
where
|
||||||
|
rawHtml = rawBlock "html"
|
||||||
|
|
||||||
|
message =
|
||||||
|
header 3 (text $ "⛄ compaREST – " <> projectName cfg)
|
||||||
|
<> if old == new
|
||||||
|
then header 1 "✅ The API did not change"
|
||||||
|
else
|
||||||
|
header
|
||||||
|
1
|
||||||
|
( case status of
|
||||||
|
BreakingChanges -> "⚠️ Breaking changes found!"
|
||||||
|
NoBreakingChanges -> "No breaking changes found ✨"
|
||||||
|
OnlyUnsupportedChanges -> "🤷 Couldn't determine compatibility"
|
||||||
|
)
|
||||||
|
<> summaryDetail (plain "ℹ️ Details") report
|
||||||
|
messageBody = markdown message <> "\n\n" <> footerText cfg
|
||||||
|
createOrUpdateComment messageBody
|
||||||
|
|
||||||
|
markdown :: Blocks -> Text
|
||||||
|
markdown =
|
||||||
|
either (error . displayException) id
|
||||||
|
. runPure
|
||||||
|
. writeHtml5String def
|
||||||
|
. doc
|
@ -5,10 +5,10 @@
|
|||||||
"homepage": "https://input-output-hk.github.io/haskell.nix",
|
"homepage": "https://input-output-hk.github.io/haskell.nix",
|
||||||
"owner": "input-output-hk",
|
"owner": "input-output-hk",
|
||||||
"repo": "haskell.nix",
|
"repo": "haskell.nix",
|
||||||
"rev": "8c587f90d2986f87a8212c3469521db512bc7ed9",
|
"rev": "1992b910e9b4d880e1f4639f4fe7266bceb9a5ad",
|
||||||
"sha256": "0a4mz47ccvl1nl2p08zbn33i1vmak4bjr4z6wqzzflnq90hg5a0s",
|
"sha256": "15w3wixjnb52f7cj3s94fy0zc0l1gc94p3n2wyq3qqxj10hvirfw",
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://github.com/input-output-hk/haskell.nix/archive/8c587f90d2986f87a8212c3469521db512bc7ed9.tar.gz",
|
"url": "https://github.com/input-output-hk/haskell.nix/archive/1992b910e9b4d880e1f4639f4fe7266bceb9a5ad.tar.gz",
|
||||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||||
},
|
},
|
||||||
"niv": {
|
"niv": {
|
||||||
@ -22,5 +22,17 @@
|
|||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://github.com/nmattia/niv/archive/e0ca65c81a2d7a4d82a189f1e23a48d59ad42070.tar.gz",
|
"url": "https://github.com/nmattia/niv/archive/e0ca65c81a2d7a4d82a189f1e23a48d59ad42070.tar.gz",
|
||||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||||
|
},
|
||||||
|
"nix-filter": {
|
||||||
|
"branch": "master",
|
||||||
|
"description": "a small self-container source filtering lib",
|
||||||
|
"homepage": "",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "nix-filter",
|
||||||
|
"rev": "3c9e33ed627e009428197b07216613206f06ed80",
|
||||||
|
"sha256": "19w142crrkywxynmyw4rhz4nglrg64yjawfkw3j91qwkwbfjds84",
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://github.com/numtide/nix-filter/archive/3c9e33ed627e009428197b07216613206f06ed80.tar.gz",
|
||||||
|
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,6 @@ common common-options
|
|||||||
-fconstraint-solver-iterations=0
|
-fconstraint-solver-iterations=0
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
build-depends: base >= 4.12.0.0 && < 4.16
|
build-depends: base >= 4.12.0.0 && < 4.16
|
||||||
, bytestring
|
|
||||||
, text
|
, text
|
||||||
|
|
||||||
default-extensions: ApplicativeDo
|
default-extensions: ApplicativeDo
|
||||||
@ -111,6 +110,7 @@ library
|
|||||||
, file-embed
|
, file-embed
|
||||||
, data-default
|
, data-default
|
||||||
, ordered-containers
|
, ordered-containers
|
||||||
|
, bytestring
|
||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
exposed-modules: Data.HList
|
exposed-modules: Data.HList
|
||||||
, OpenAPI.Checker.Behavior
|
, OpenAPI.Checker.Behavior
|
||||||
@ -167,6 +167,7 @@ executable openapi-diff
|
|||||||
, aeson
|
, aeson
|
||||||
, containers
|
, containers
|
||||||
, doctemplates
|
, doctemplates
|
||||||
|
, pandoc-types
|
||||||
ghc-options: -threaded
|
ghc-options: -threaded
|
||||||
-rtsopts
|
-rtsopts
|
||||||
-with-rtsopts=-N
|
-with-rtsopts=-N
|
||||||
@ -174,6 +175,29 @@ executable openapi-diff
|
|||||||
FormatHeuristic
|
FormatHeuristic
|
||||||
OpenAPI.Checker.Options
|
OpenAPI.Checker.Options
|
||||||
|
|
||||||
|
executable comparest-github-action
|
||||||
|
import: common-options
|
||||||
|
hs-source-dirs: github-action
|
||||||
|
main-is: Main.hs
|
||||||
|
build-depends:
|
||||||
|
openapi-diff
|
||||||
|
, pandoc
|
||||||
|
, yaml
|
||||||
|
, aeson
|
||||||
|
, github
|
||||||
|
, freer-simple
|
||||||
|
, vector
|
||||||
|
, pandoc-types
|
||||||
|
, envy
|
||||||
|
, filepath
|
||||||
|
ghc-options: -threaded
|
||||||
|
-rtsopts
|
||||||
|
-with-rtsopts=-N
|
||||||
|
other-modules:
|
||||||
|
Control.Monad.Freer.GitHub
|
||||||
|
CompaREST.GitHub.API
|
||||||
|
CompaREST.GitHub.Action.Config
|
||||||
|
|
||||||
test-suite openapi-diff-test
|
test-suite openapi-diff-test
|
||||||
import: common-options
|
import: common-options
|
||||||
type: exitcode-stdio-1.0
|
type: exitcode-stdio-1.0
|
||||||
@ -193,6 +217,7 @@ test-suite openapi-diff-test
|
|||||||
, pandoc
|
, pandoc
|
||||||
, data-default
|
, data-default
|
||||||
, lens
|
, lens
|
||||||
|
, pandoc-types
|
||||||
ghc-options: -threaded
|
ghc-options: -threaded
|
||||||
-rtsopts
|
-rtsopts
|
||||||
-with-rtsopts=-N
|
-with-rtsopts=-N
|
||||||
|
@ -104,7 +104,7 @@ data ReportTreeStyle = HeadersTreeStyle | FoldingBlockquotesTreeStyle
|
|||||||
twoRowTable :: [(Inlines, Inlines)] -> Blocks
|
twoRowTable :: [(Inlines, Inlines)] -> Blocks
|
||||||
twoRowTable x = simpleTable (para . fst <$> x) [para . snd <$> x]
|
twoRowTable x = simpleTable (para . fst <$> x) [para . snd <$> x]
|
||||||
|
|
||||||
generateReport :: ReportConfig -> ReportInput -> (Pandoc, ReportStatus)
|
generateReport :: ReportConfig -> ReportInput -> (Blocks, ReportStatus)
|
||||||
generateReport cfg inp =
|
generateReport cfg inp =
|
||||||
let
|
let
|
||||||
schemaIssuesPresent = not $ P.null $ schemaIssues inp
|
schemaIssuesPresent = not $ P.null $ schemaIssues inp
|
||||||
@ -116,7 +116,6 @@ generateReport cfg inp =
|
|||||||
OnlyErrors -> False
|
OnlyErrors -> False
|
||||||
builder = buildReport cfg
|
builder = buildReport cfg
|
||||||
report =
|
report =
|
||||||
doc $
|
|
||||||
header 1 "Summary"
|
header 1 "Summary"
|
||||||
<> twoRowTable
|
<> twoRowTable
|
||||||
(when'
|
(when'
|
||||||
|
@ -11,6 +11,7 @@ import OpenAPI.Checker.Paths
|
|||||||
import OpenAPI.Checker.Report
|
import OpenAPI.Checker.Report
|
||||||
import OpenAPI.Checker.Subtree
|
import OpenAPI.Checker.Subtree
|
||||||
import OpenAPI.Checker.Validate.OpenApi ()
|
import OpenAPI.Checker.Validate.OpenApi ()
|
||||||
|
import Text.Pandoc.Builder
|
||||||
|
|
||||||
runChecker :: (OpenApi, OpenApi) -> CheckerOutput
|
runChecker :: (OpenApi, OpenApi) -> CheckerOutput
|
||||||
runChecker (client, server) =
|
runChecker (client, server) =
|
||||||
@ -26,5 +27,5 @@ runChecker (client, server) =
|
|||||||
}
|
}
|
||||||
run p c = either id mempty . runCompatFormula . checkCompatibility Root HNil $ toPC p c
|
run p c = either id mempty . runCompatFormula . checkCompatibility Root HNil $ toPC p c
|
||||||
|
|
||||||
runReport :: ReportConfig -> (OpenApi, OpenApi) -> (Pandoc, ReportStatus)
|
runReport :: ReportConfig -> (OpenApi, OpenApi) -> (Blocks, ReportStatus)
|
||||||
runReport cfg = generateReport cfg . segregateIssues . runChecker
|
runReport cfg = generateReport cfg . segregateIssues . runChecker
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
resolver: lts-18.2
|
resolver: lts-18.4
|
||||||
|
|
||||||
extra-deps:
|
extra-deps:
|
||||||
- open-union-0.4.0.0
|
- open-union-0.4.0.0
|
||||||
- type-fun-0.1.3
|
- type-fun-0.1.3
|
||||||
|
- github-0.26
|
||||||
|
- base16-bytestring-0.1.1.7
|
||||||
|
- http-link-header-1.0.3.1
|
||||||
|
|
||||||
apply-ghc-options: everything
|
apply-ghc-options: everything
|
||||||
rebuild-ghc-options: true
|
rebuild-ghc-options: true
|
||||||
|
@ -18,9 +18,30 @@ packages:
|
|||||||
sha256: b977d42525f0b4223959918d18e7905085283e937493c395077b608cd19b42c1
|
sha256: b977d42525f0b4223959918d18e7905085283e937493c395077b608cd19b42c1
|
||||||
original:
|
original:
|
||||||
hackage: type-fun-0.1.3
|
hackage: type-fun-0.1.3
|
||||||
|
- completed:
|
||||||
|
hackage: github-0.26@sha256:a9d4046325c3eb28cdc7bef2c3f5bb213328caeae0b7dce6f51de655f0bffaa1,7162
|
||||||
|
pantry-tree:
|
||||||
|
size: 7511
|
||||||
|
sha256: b71aab2984b268030c9e2617043575681134c1fe60dffbd5596e659c0a3e9aec
|
||||||
|
original:
|
||||||
|
hackage: github-0.26
|
||||||
|
- completed:
|
||||||
|
hackage: base16-bytestring-0.1.1.7@sha256:0021256a9628971c08da95cb8f4d0d72192f3bb8a7b30b55c080562d17c43dd3,2231
|
||||||
|
pantry-tree:
|
||||||
|
size: 454
|
||||||
|
sha256: 2dc99cd67293b09204098202d0bdcdcf89d2b8c69ce6c8f4e31deadbdab2a7f9
|
||||||
|
original:
|
||||||
|
hackage: base16-bytestring-0.1.1.7
|
||||||
|
- completed:
|
||||||
|
hackage: http-link-header-1.0.3.1@sha256:9917c26635a46eff5d36c5344a4ae42fad2b5de79c0e300363bddd5eec66facd,1937
|
||||||
|
pantry-tree:
|
||||||
|
size: 990
|
||||||
|
sha256: 155feaf856daf5b55491048c8c4726ba765a8fe79263ebdbfc82f6c385a15715
|
||||||
|
original:
|
||||||
|
hackage: http-link-header-1.0.3.1
|
||||||
snapshots:
|
snapshots:
|
||||||
- completed:
|
- completed:
|
||||||
size: 585392
|
size: 585817
|
||||||
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/2.yaml
|
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/4.yaml
|
||||||
sha256: 7abb45c0cc5eb349448b66d8753655542d45d387ad26970419282eab3d860724
|
sha256: ea3a318eafa9e9cc56bfbe46099fd0d54d32641ab7bbe1d182ed8f5de39f804c
|
||||||
original: lts-18.2
|
original: lts-18.4
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
module Spec.Golden.TraceTree
|
module Spec.Golden.TraceTree
|
||||||
( tests
|
( tests,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
@ -14,6 +14,7 @@ import OpenAPI.Checker.Run
|
|||||||
import OpenAPI.Checker.Validate.OpenApi ()
|
import OpenAPI.Checker.Validate.OpenApi ()
|
||||||
import Spec.Golden.Extra
|
import Spec.Golden.Extra
|
||||||
import Test.Tasty (TestTree, testGroup)
|
import Test.Tasty (TestTree, testGroup)
|
||||||
|
import Text.Pandoc.Builder
|
||||||
import Text.Pandoc.Class
|
import Text.Pandoc.Class
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Writers
|
import Text.Pandoc.Writers
|
||||||
@ -37,7 +38,7 @@ tests = do
|
|||||||
"report.md"
|
"report.md"
|
||||||
("a.yaml", "b.yaml")
|
("a.yaml", "b.yaml")
|
||||||
Yaml.decodeFileThrow
|
Yaml.decodeFileThrow
|
||||||
(runPandoc . writeMarkdown def {writerExtensions = githubMarkdownExtensions} . fst . runReport def)
|
(runPandoc . writeMarkdown def {writerExtensions = githubMarkdownExtensions} . doc . fst . runReport def)
|
||||||
|
|
||||||
return $ testGroup "Golden tests" [traceTreeTests, reportTests]
|
return $ testGroup "Golden tests" [traceTreeTests, reportTests]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user