1{-# LANGUAGE NoImplicitPrelude #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE RecordWildCards #-}
4module Stackage.CompleteBuild
10import Data.Default.Class (def)
11import Data.Semigroup (Max (..), Option (..))
12import Data.Text.Read (decimal)
14import Data.Yaml (decodeFileEither, encodeFile)
15import Network.HTTP.Client
16import Network.HTTP.Client.TLS (tlsManagerSettings)
17import Stackage.BuildConstraints
18import Stackage.BuildPlan
19import Stackage.CheckBuildPlan
20import Stackage.PerformBuild
21import Stackage.Prelude
22import Stackage.ServerBundle
23import Stackage.UpdateBuildPlan
25import System.IO (BufferMode (LineBuffering), hSetBuffering)
27data BuildType = Nightly | LTS BumpType
28 deriving (Show, Read, Eq, Ord)
30data BumpType = Major | Minor
31 deriving (Show, Read, Eq, Ord)
33data Settings = Settings
35 , planFile :: FilePath
36 , buildDir :: FilePath
38 , title :: Text -> Text -- ^ GHC version -> title
40 , setArgs :: Text -> UploadBundle -> UploadBundle
44getSettings :: Manager -> BuildType -> IO Settings
45getSettings man Nightly = do
46 day <- tshow . utctDay <$> getCurrentTime
47 let slug' = "nightly-" ++ day
48 plan' <- defaultBuildConstraints man >>= newBuildPlan
50 { planFile = fpFromText ("nightly-" ++ day) <.> "yaml"
51 , buildDir = fpFromText $ "builds/stackage-nightly-" ++ day
52 , logDir = fpFromText $ "logs/stackage-nightly-" ++ day
53 , title = \ghcVer -> concat
60 , setArgs = \ghcVer ub -> ub { ubNightly = Just ghcVer }
62 , postBuild = return ()
64getSettings man (LTS bumpType) = do
65 Option mlts <- fmap (fmap getMax) $ runResourceT
67 $$ foldMapC (Option . fmap Max . parseLTSVer . filename)
69 (new, plan') <- case bumpType of
74 Just (LTSVer x _) -> LTSVer (x + 1) 0
75 plan' <- defaultBuildConstraints man >>= newBuildPlan
78 old <- maybe (error "No LTS plans found in current directory") return mlts
79 oldplan <- decodeFileEither (fpToString $ renderLTSVer old)
80 >>= either throwM return
81 let new = incrLTSVer old
82 plan' <- updateBuildPlan oldplan
85 let newfile = renderLTSVer new
89 , buildDir = fpFromText $ "builds/stackage-lts-" ++ tshow new
90 , logDir = fpFromText $ "logs/stackage-lts-" ++ tshow new
91 , title = \ghcVer -> concat
97 , slug = "lts-" ++ tshow new
98 , setArgs = \_ ub -> ub { ubLTS = Just $ tshow new }
101 let git args = withCheckedProcess
102 (proc "git" args) $ \ClosedStream Inherited Inherited ->
104 putStrLn "Committing new LTS file to Git"
105 git ["add", fpToString newfile]
106 git ["commit", "-m", "Added new LTS release: " ++ show new]
107 putStrLn "Pushing to Git repository"
111data LTSVer = LTSVer !Int !Int
113instance Show LTSVer where
114 show (LTSVer x y) = concat [show x, ".", show y]
115incrLTSVer :: LTSVer -> LTSVer
116incrLTSVer (LTSVer x y) = LTSVer x (y + 1)
118parseLTSVer :: FilePath -> Maybe LTSVer
120 w <- stripPrefix "lts-" $ fpToText fp
121 x <- stripSuffix ".yaml" w
122 Right (major, y) <- Just $ decimal x
123 z <- stripPrefix "." y
124 Right (minor, "") <- Just $ decimal z
125 return $ LTSVer major minor
126renderLTSVer :: LTSVer -> FilePath
127renderLTSVer lts = fpFromText $ concat
133-- | Generate and check a new build plan, but do not execute it.
137justCheck = withManager tlsManagerSettings $ \man -> do
138 putStrLn "Loading build constraints"
139 bc <- defaultBuildConstraints man
141 putStrLn "Creating build plan"
142 plan <- newBuildPlan bc
144 putStrLn $ "Writing build plan to check-plan.yaml"
145 encodeFile "check-plan.yaml" plan
147 putStrLn "Checking plan"
150 putStrLn "Plan seems valid!"
152completeBuild :: BuildType -> IO ()
153completeBuild buildType = withManager tlsManagerSettings $ \man -> do
154 hSetBuffering stdout LineBuffering
156 putStrLn $ "Loading settings for: " ++ tshow buildType
157 Settings {..} <- getSettings man buildType
159 putStrLn $ "Writing build plan to: " ++ fpToText planFile
160 encodeFile (fpToString planFile) plan
162 putStrLn "Checking build plan"
165 putStrLn "Performing build"
166 let pb = PerformBuild
168 , pbInstallDest = buildDir
170 , pbLog = hPut stdout
172 , pbGlobalInstall = False
174 performBuild pb >>= mapM_ putStrLn
176 putStrLn "Uploading bundle to Stackage Server"
177 token <- readFile "/auth-token"
179 let ghcVer = display $ siGhcVersion $ bpSystemInfo plan
180 (ident, mloc) <- flip uploadBundle man $ setArgs ghcVer def
181 { ubContents = serverBundle now (title ghcVer) slug plan
182 , ubAuthToken = decodeUtf8 token
184 putStrLn $ "New ident: " ++ unSnapshotIdent ident
186 putStrLn $ "Track progress at: " ++ loc
188 postBuild `catchAny` print
190 putStrLn "Uploading docs to Stackage Server"
191 res1 <- uploadDocs UploadDocs
193 , udAuthToken = decodeUtf8 token
194 , udDocs = pbDocDir pb
197 putStrLn $ "Doc upload response: " ++ tshow res1
199 ecreds <- tryIO $ readFile "/hackage-creds"
200 case map encodeUtf8 $ words $ decodeUtf8 $ either (const "") id ecreds of
201 [username, password] -> do
202 putStrLn "Uploading as Hackage distro"
203 res2 <- uploadHackageDistro plan username password man
204 putStrLn $ "Distro upload response: " ++ tshow res2
205 _ -> putStrLn "No creds found, skipping Hackage distro upload"
207 putStrLn "Uploading doc map"
208 uploadDocMap UploadDocMap
210 , udmAuthToken = decodeUtf8 token
211 , udmSnapshot = ident
212 , udmDocDir = pbDocDir pb
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list