Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s
97 lines
3.3 KiB
Haskell
Executable File
97 lines
3.3 KiB
Haskell
Executable File
#!/usr/bin/env nix-shell
|
|
#!nix-shell -i runhaskell --packages 'haskellPackages.ghcWithPackages (ps: [ps.aeson ps.aeson-pretty ps.directory ps.process ps.optparse-applicative])'
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
{-# LANGUAGE RecordWildCards #-}
|
|
|
|
module Main where
|
|
|
|
import Options.Applicative
|
|
import System.FilePath (takeDirectory, (</>))
|
|
import System.Process (readProcess)
|
|
import Data.Aeson (object, (.=))
|
|
import Data.Aeson.Encode.Pretty (encodePretty', Config(..), defConfig, Indent(..), keyOrder)
|
|
import qualified Data.ByteString.Lazy.Char8 as BL
|
|
import qualified Data.Map.Strict as Map
|
|
import Control.Monad (forM)
|
|
import qualified Data.Text as T
|
|
|
|
data Options = Options
|
|
{ scriptPath :: FilePath
|
|
, channel :: String
|
|
}
|
|
|
|
optionsParser :: Parser Options
|
|
optionsParser = Options
|
|
<$> argument str
|
|
( metavar "SCRIPT_PATH"
|
|
<> help "The path to the script" )
|
|
<*> argument channelReader
|
|
( metavar "CHANNEL"
|
|
<> help "The release channel (main or stable)" )
|
|
|
|
channelReader :: ReadM String
|
|
channelReader = eitherReader $ \arg ->
|
|
if arg `elem` ["main", "stable"]
|
|
then Right arg
|
|
else Left "CHANNEL must be one of: main, stable"
|
|
|
|
-- Custom configuration for pretty-printing JSON
|
|
prettyConfig :: Config
|
|
prettyConfig = defConfig
|
|
{ confIndent = Spaces 2
|
|
, confCompare = keyOrder ["archMap", "fetchurlAttrSet", "platformList", "version"]
|
|
}
|
|
|
|
main :: IO ()
|
|
main = do
|
|
let opts = info (optionsParser <**> helper)
|
|
( fullDesc
|
|
<> progDesc "Updates the sources-{main|stable}.json files based on the upstream release channel"
|
|
<> header "update.hs - Haskell script with argument parsing" )
|
|
|
|
-- Parse the command-line arguments
|
|
Options {..} <- execParser opts
|
|
|
|
-- Process the arguments
|
|
let scriptDir = takeDirectory scriptPath
|
|
let outputFile = scriptDir </> ("sources-" ++ channel ++ ".json")
|
|
|
|
-- Fetch current version
|
|
let baseUrl = "https://cli.upbound.io/" ++ channel
|
|
currentVersion <- readProcess "curl" ["-s", baseUrl ++ "/current/version"] ""
|
|
let version = filter (\x -> x /= 'v' && x /= '\n') currentVersion -- Remove the leading 'v' and the new line char
|
|
|
|
-- Architecture mapping
|
|
let archMapping = Map.fromList
|
|
[ ("aarch64-darwin", "darwin_arm64")
|
|
, ("x86_64-darwin", "darwin_amd64")
|
|
, ("aarch64-linux", "linux_arm64")
|
|
, ("x86_64-linux", "linux_amd64")
|
|
]
|
|
|
|
-- Build platformList
|
|
let platformList = Map.keys archMapping
|
|
|
|
-- Build fetchurlAttrSet
|
|
fetchurlAttrSet <- fmap Map.fromList $ forM ["docker-credential-up", "up"] $ \cmd -> do
|
|
attrs <- forM (Map.toList archMapping) $ \(key, arch) -> do
|
|
let url = baseUrl ++ "/v" ++ version ++ "/bundle/" ++ cmd ++ "/" ++ arch ++ ".tar.gz"
|
|
_hash <- readProcess "nix-prefetch-url" [url] ""
|
|
let hash = T.unpack $ T.strip $ T.pack _hash
|
|
_sha256Hash <- readProcess "nix" ["hash", "convert", hash, "--hash-algo", "sha256"] ""
|
|
let sha256Hash = T.unpack $ T.strip $ T.pack _sha256Hash
|
|
return (key, object ["hash" .= sha256Hash, "url" .= url])
|
|
return (cmd, object attrs)
|
|
|
|
-- Write output to JSON
|
|
let output = object
|
|
[ "version" .= version
|
|
, "platformList" .= platformList
|
|
, "archMap" .= archMapping
|
|
, "fetchurlAttrSet" .= fetchurlAttrSet
|
|
]
|
|
BL.writeFile outputFile $ BL.snoc (encodePretty' prettyConfig output) '\n'
|
|
|
|
putStrLn $ "Output written to: " ++ outputFile
|