Validate all tags in CI, wrt #135
This commit is contained in:
parent
b2843da016
commit
68731892cc
63
.github/workflows/bindists.yaml
vendored
63
.github/workflows/bindists.yaml
vendored
@ -18,6 +18,11 @@ on:
|
||||
required: true
|
||||
default: ghcup-0.0.7.yaml
|
||||
type: string
|
||||
channel:
|
||||
description: Distribution channel (main|prerelease|nightly)
|
||||
required: true
|
||||
default: Main
|
||||
type: string
|
||||
env:
|
||||
BOOTSTRAP_HASKELL_NONINTERACTIVE: 1
|
||||
BOOTSTRAP_HASKELL_MINIMAL: 1
|
||||
@ -25,6 +30,7 @@ env:
|
||||
TOOL: ${{ github.event.inputs.tool }}
|
||||
VERSION: ${{ github.event.inputs.version }}
|
||||
METADATA_FILE: ${{ github.event.inputs.metadataFile }}
|
||||
CHANNEL: ${{ github.event.inputs.channel }}
|
||||
jobs:
|
||||
bindist-install:
|
||||
name: linux-${{ matrix.image }}
|
||||
@ -143,6 +149,63 @@ jobs:
|
||||
with:
|
||||
args: sh -c '.github/workflows/install-bindist.sh'
|
||||
|
||||
validate:
|
||||
name: ghcup-gen check
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GHC: 9.2.8
|
||||
CABAL: 3.10.1.0
|
||||
steps:
|
||||
- name: create ~/.local/bin
|
||||
run: mkdir -p "$HOME/.local/bin"
|
||||
shell: bash
|
||||
|
||||
- name: Add ~/.local/bin to PATH
|
||||
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
|
||||
- name: install yamllint
|
||||
run: pip install yamllint
|
||||
|
||||
- name: Update cabal cache
|
||||
run: cabal update
|
||||
shell: bash
|
||||
|
||||
- name: Install requirements
|
||||
shell: sh
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
export TZ=Asia/Singapore
|
||||
sudo apt-get update && sudo apt-get install -y curl bash git gnupg libarchive-dev
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Cache Cabal
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-cabal
|
||||
with:
|
||||
path: |
|
||||
~/.cabal/store
|
||||
~/.cabal/packages
|
||||
key: v2-${{ runner.os }}-${{ env.GHC }}-${{ env.CABAL }}-build-${{ hashFiles('cabal.project') }}
|
||||
restore-keys: |
|
||||
v2-${{ runner.os }}-${{ env.GHC }}-${{ env.CABAL }}-build-${{ hashFiles('cabal.project') }}
|
||||
v2-${{ runner.os }}-${{ env.GHC }}-${{ env.CABAL }}-build-
|
||||
v2-${{ runner.os }}-${{ env.GHC }}
|
||||
|
||||
- name: Install ghcup-gen
|
||||
run: |
|
||||
ghcup run --cabal 3.10.1.0 --ghc 9.2.8 --install -- cabal install --installdir="$HOME/.local/bin" --overwrite-policy=always --install-method=copy ghcup-gen
|
||||
shell: bash
|
||||
|
||||
- name: Check yaml
|
||||
run: |
|
||||
ghcup-gen -- check -f ${{ env.METADATA_FILE }} --channel ${{ env.CHANNEL }}
|
||||
yamllint ${{ env.METADATA_FILE }}
|
||||
python3 -c "import yaml ; stream = open('${{ env.METADATA_FILE }}', 'r') ; yaml.safe_load(stream)"
|
||||
shell: bash
|
||||
|
||||
signature-test:
|
||||
name: Test signatures
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -48,5 +48,7 @@ ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup
|
||||
### Understanding tags
|
||||
|
||||
Tags are documented [here](https://github.com/haskell/ghcup-hs/blob/master/lib/GHCup/Types.hs). Search for `data Tag`.
|
||||
Some tags are unique. Uniqueness is checked by cabal run ghcup-gen -- check -f ghcup-<yaml-ver>.yaml`.
|
||||
Some tags are unique. Uniqueness is checked by `cabal run ghcup-gen -- check -f ghcup-<yaml-ver>.yaml`.
|
||||
|
||||
If you want to check prereleases, do: `cabal run ghcup-gen -- check -f ghcup-prereleases-<yaml-ver>.yaml --channel=prerelease`
|
||||
|
||||
|
@ -7,7 +7,7 @@ package ghcup
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/haskell/ghcup-hs.git
|
||||
tag: fd6ff9f8ece147bb4527843822462c72824e8ba7
|
||||
tag: e27fed09f3eb4b0b72ce7825c65f16a4202a2399
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0
|
||||
|
@ -105,11 +105,30 @@ inputP :: Parser Input
|
||||
inputP = fileInput <|> stdInput
|
||||
|
||||
data ValidateYAMLOpts = ValidateYAMLOpts
|
||||
{ vInput :: Maybe Input
|
||||
{ vChannel :: DistributionChannel
|
||||
, vInput :: Maybe Input
|
||||
}
|
||||
|
||||
validateYAMLOpts :: Parser ValidateYAMLOpts
|
||||
validateYAMLOpts = ValidateYAMLOpts <$> optional inputP
|
||||
validateYAMLOpts = ValidateYAMLOpts <$> channelParser <*> optional inputP
|
||||
|
||||
channelParser :: Parser DistributionChannel
|
||||
channelParser =
|
||||
option
|
||||
(eitherReader chanP)
|
||||
(long "channel" <> metavar "CHANNEL" <> help
|
||||
"Signal which distribution channel the YAML denotes: (main | prerelease | nightly). Main is defaul."
|
||||
<> value MainChan
|
||||
)
|
||||
where
|
||||
chanP :: String -> Either String DistributionChannel
|
||||
chanP s' | t == T.pack "main" = Right MainChan
|
||||
| t == T.pack "prerelease" = Right PrereleaseChan
|
||||
| t == T.pack "prereleases" = Right PrereleaseChan
|
||||
| t == T.pack "nightly" = Right NightlyChan
|
||||
| t == T.pack "nightlies" = Right NightlyChan
|
||||
| otherwise = Left ("Unknown channel value: " <> s')
|
||||
where t = T.toLower (T.pack s')
|
||||
|
||||
tarballFilterP :: Parser TarballFilter
|
||||
tarballFilterP = option readm $
|
||||
@ -205,7 +224,7 @@ main = do
|
||||
|
||||
_ <- customExecParser (prefs showHelpOnError) (info (opts <**> helper) idm)
|
||||
>>= \Options {..} -> case optCommand of
|
||||
ValidateYAML vopts -> withValidateYamlOpts vopts validate
|
||||
ValidateYAML vopts@ValidateYAMLOpts{ .. } -> withValidateYamlOpts vopts (validate vChannel)
|
||||
ValidateTarballs vopts tarballFilter -> withValidateYamlOpts vopts (validateTarballs tarballFilter)
|
||||
GenerateHlsGhc vopts format output -> withValidateYamlOpts vopts (generateHLSGhc format output)
|
||||
GenerateToolTable vopts output -> withValidateYamlOpts vopts (generateTable output)
|
||||
|
@ -51,6 +51,11 @@ data ValidationError = InternalError String
|
||||
|
||||
instance Exception ValidationError
|
||||
|
||||
data DistributionChannel = MainChan
|
||||
| PrereleaseChan
|
||||
| NightlyChan
|
||||
deriving (Show, Eq)
|
||||
|
||||
|
||||
addError :: (MonadReader (IORef Int) m, MonadIO m, Monad m) => m ()
|
||||
addError = do
|
||||
@ -66,8 +71,9 @@ validate :: ( Monad m
|
||||
, MonadUnliftIO m
|
||||
, HasGHCupInfo env
|
||||
)
|
||||
=> m ExitCode
|
||||
validate = do
|
||||
=> DistributionChannel
|
||||
-> m ExitCode
|
||||
validate distroChannel = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- getGHCupInfo
|
||||
|
||||
ref <- liftIO $ newIORef 0
|
||||
@ -95,33 +101,36 @@ validate = do
|
||||
lift $ logInfo "All good"
|
||||
pure ExitSuccess
|
||||
where
|
||||
checkHasRequiredPlatforms t v tags arch pspecs = do
|
||||
let v' = prettyVer v
|
||||
arch' = prettyShow arch
|
||||
when (Linux UnknownLinux `notElem` pspecs) $ do
|
||||
lift $ logError $
|
||||
"Linux UnknownLinux missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
||||
addError
|
||||
when ((Darwin `notElem` pspecs) && arch == A_64) $ do
|
||||
lift $ logError $ "Darwin missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
||||
addError
|
||||
when ((FreeBSD `notElem` pspecs) && arch == A_64) $ lift $ logWarn $
|
||||
"FreeBSD missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
||||
when (Windows `notElem` pspecs && arch == A_64) $ do
|
||||
lift $ logError $ "Windows missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
||||
addError
|
||||
checkHasRequiredPlatforms t v tags arch pspecs
|
||||
-- relax requirements for prerelease and nightly channels
|
||||
| distroChannel `elem` [PrereleaseChan, NightlyChan] = pure ()
|
||||
| otherwise = do
|
||||
let v' = prettyVer v
|
||||
arch' = prettyShow arch
|
||||
when (Linux UnknownLinux `notElem` pspecs) $ do
|
||||
lift $ logError $
|
||||
"Linux UnknownLinux missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
||||
addError
|
||||
when ((Darwin `notElem` pspecs) && arch == A_64) $ do
|
||||
lift $ logError $ "Darwin missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
||||
addError
|
||||
when ((FreeBSD `notElem` pspecs) && arch == A_64) $ lift $ logWarn $
|
||||
"FreeBSD missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
||||
when (Windows `notElem` pspecs && arch == A_64) $ do
|
||||
lift $ logError $ "Windows missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
||||
addError
|
||||
|
||||
-- alpine needs to be set explicitly, because
|
||||
-- we cannot assume that "Linux UnknownLinux" runs on Alpine
|
||||
-- (although it could be static)
|
||||
when (Linux Alpine `notElem` pspecs) $
|
||||
case t of
|
||||
GHCup | arch `elem` [A_64, A_32] -> lift (logError $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch)) >> addError
|
||||
Cabal | v > [vver|2.4.1.0|]
|
||||
, arch `elem` [A_64, A_32] -> lift (logError $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch)) >> addError
|
||||
GHC | Latest `elem` tags || Recommended `elem` tags
|
||||
, arch `elem` [A_64, A_32] -> lift (logError $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch))
|
||||
_ -> lift $ logWarn $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch)
|
||||
-- alpine needs to be set explicitly, because
|
||||
-- we cannot assume that "Linux UnknownLinux" runs on Alpine
|
||||
-- (although it could be static)
|
||||
when (Linux Alpine `notElem` pspecs) $
|
||||
case t of
|
||||
GHCup | arch `elem` [A_64, A_32] -> lift (logError $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch)) >> addError
|
||||
Cabal | v > [vver|2.4.1.0|]
|
||||
, arch `elem` [A_64, A_32] -> lift (logError $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch)) >> addError
|
||||
GHC | Latest `elem` tags || Recommended `elem` tags
|
||||
, arch `elem` [A_64, A_32] -> lift (logError $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch))
|
||||
_ -> lift $ logWarn $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch)
|
||||
|
||||
checkUniqueTags tool = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
@ -145,12 +154,15 @@ validate = do
|
||||
lift $ logError $ "Tags not unique for " <> T.pack (prettyShow tool) <> ": " <> T.pack (prettyShow xs)
|
||||
addError
|
||||
where
|
||||
isUniqueTag Latest = True
|
||||
isUniqueTag Recommended = True
|
||||
isUniqueTag Old = False
|
||||
isUniqueTag Prerelease = False
|
||||
isUniqueTag (Base _) = False
|
||||
isUniqueTag (UnknownTag _) = False
|
||||
isUniqueTag Latest = True
|
||||
isUniqueTag Recommended = True
|
||||
isUniqueTag Old = False
|
||||
isUniqueTag Prerelease = False
|
||||
isUniqueTag LatestPrerelease = True
|
||||
isUniqueTag Nightly = False
|
||||
isUniqueTag LatestNightly = True
|
||||
isUniqueTag (Base _) = False
|
||||
isUniqueTag (UnknownTag _) = False
|
||||
|
||||
checkGHCVerIsValid = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
@ -166,12 +178,21 @@ validate = do
|
||||
checkMandatoryTags tool = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
let allTags = _viTags =<< M.elems (availableToolVersions dls tool)
|
||||
forM_ [Latest, Recommended] $ \t -> case t `elem` allTags of
|
||||
forM_ (mandatoryTags tool) $ \t -> case t `elem` allTags of
|
||||
False -> do
|
||||
lift $ logError $ "Tag " <> T.pack (prettyShow t) <> " missing from " <> T.pack (prettyShow tool)
|
||||
addError
|
||||
True -> pure ()
|
||||
|
||||
mandatoryTags tool
|
||||
-- due to a quirk, even for ghcup prereleases we need the 'latest' tag
|
||||
-- https://github.com/haskell/ghcup-hs/issues/891
|
||||
| tool == GHCup = [Latest, Recommended]
|
||||
| otherwise = case distroChannel of
|
||||
MainChan -> [Latest, Recommended]
|
||||
PrereleaseChan -> [LatestPrerelease]
|
||||
NightlyChan -> [LatestNightly]
|
||||
|
||||
-- all GHC versions must have a base tag
|
||||
checkGHCHasBaseVersion = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
|
Loading…
Reference in New Issue
Block a user