Skip to content

Commit 6524655

Browse files
committed
release script: support multiple architectures (#433)
1 parent 272b95a commit 6524655

File tree

1 file changed

+96
-53
lines changed

1 file changed

+96
-53
lines changed

scripts/release/release.hs

+96-53
Original file line numberDiff line numberDiff line change
@@ -49,27 +49,37 @@ main =
4949
gStackPackageDescription <-
5050
packageDescription <$> readPackageDescription silent "stack.cabal"
5151
gGithubAuthToken <- lookupEnv githubAuthTokenEnvVar
52-
gLocalInstallRoot <- getStackPath "local-install-root"
53-
gProjectRoot <- getStackPath "project-root"
5452
gGitRevCount <- length . lines <$> readProcess "git" ["rev-list", "HEAD"] ""
5553
gGitSha <- trim <$> readProcess "git" ["rev-parse", "HEAD"] ""
5654
gHomeDir <- getHomeDirectory
5755
RunGHC gScriptPath <- getScriptPath
5856
let gGpgKey = "9BEFB442"
5957
gAllowDirty = False
6058
gGithubReleaseTag = Nothing
61-
return $ Just $ rules (foldl (flip id) Global{..} flags) args
59+
Platform arch _ = buildPlatform
60+
gArch = arch
61+
gBinarySuffix = ""
62+
gLocalInstallRoot = "" -- Set to real value below.
63+
gProjectRoot = "" -- Set to real value velow.
64+
global0 = foldl (flip id) Global{..} flags
65+
-- Need to get paths after options since the '--arch' argument can effect them.
66+
localInstallRoot' <- getStackPath global0 "local-install-root"
67+
projectRoot' <- getStackPath global0 "project-root"
68+
let global = global0
69+
{ gLocalInstallRoot = localInstallRoot'
70+
, gProjectRoot = projectRoot' }
71+
return $ Just $ rules global args
6272
where
63-
getStackPath path = do
64-
out <- readProcess "stack" ["path", "--" ++ path] ""
73+
getStackPath global path = do
74+
out <- readProcess stackProgName (stackArgs global ++ ["path", "--" ++ path]) ""
6575
return $ trim $ fromMaybe out $ stripPrefix (path ++ ":") out
6676

6777
-- | Additional command-line options.
6878
options :: [OptDescr (Either String (Global -> Global))]
6979
options =
7080
[ Option "" [gpgKeyOptName]
7181
(ReqArg (\v -> Right $ \g -> g{gGpgKey = v}) "USER-ID")
72-
"GPG user ID to sign distribution package with"
82+
"GPG user ID to sign distribution package with."
7383
, Option "" [allowDirtyOptName] (NoArg $ Right $ \g -> g{gAllowDirty = True})
7484
"Allow a dirty working tree for release."
7585
, Option "" [githubAuthTokenOptName]
@@ -79,7 +89,17 @@ options =
7989
" environment variable).")
8090
, Option "" [githubReleaseTagOptName]
8191
(ReqArg (\v -> Right $ \g -> g{gGithubReleaseTag = Just v}) "TAG")
82-
"Github release tag to upload to." ]
92+
"Github release tag to upload to."
93+
, Option "" [archOptName]
94+
(ReqArg
95+
(\v -> case simpleParse v of
96+
Nothing -> Left $ "Unknown architecture in --arch option: " ++ v
97+
Just arch -> Right $ \g -> g{gArch = arch})
98+
"ARCHITECTURE")
99+
"Architecture to build (e.g. 'i386' or 'x86_64')."
100+
, Option "" [binarySuffixOptName]
101+
(ReqArg (\v -> Right $ \g -> g{gBinarySuffix = v}) "SUFFIX")
102+
"Extra suffix to add to binary executable archive filename." ]
83103

84104
-- | Shake rules.
85105
rules :: Global -> [String] -> Rules ()
@@ -96,13 +116,13 @@ rules global@Global{..} args = do
96116
removeFilesAfter releaseDir ["//*"]
97117

98118
phony checkPhony $
99-
need [releaseCheckDir </> stackExeFileName]
119+
need [releaseCheckDir </> binaryExeFileName]
100120

101121
phony uploadPhony $
102-
mapM_ (\f -> need [releaseDir </> f <.> uploadExt]) releaseFileNames
122+
mapM_ (\f -> need [releaseDir </> f <.> uploadExt]) binaryFileNames
103123

104124
phony buildPhony $
105-
mapM_ (\f -> need [releaseDir </> f]) releaseFileNames
125+
mapM_ (\f -> need [releaseDir </> f]) binaryFileNames
106126

107127
forM_ distros $ \distro -> do
108128

@@ -121,64 +141,64 @@ rules global@Global{..} args = do
121141
uploadToGithubRelease global (dropExtension out)
122142
copyFile' (dropExtension out) out
123143

124-
releaseCheckDir </> stackExeFileName %> \out -> do
125-
need [installBinDir </> stackExeFileName]
144+
releaseCheckDir </> binaryExeFileName %> \out -> do
145+
need [installBinDir </> stackOrigExeFileName]
126146
Stdout dirty <- cmd "git status --porcelain"
127147
when (not gAllowDirty && not (null (trim dirty))) $
128148
error ("Working tree is dirty. Use --" ++ allowDirtyOptName ++ " option to continue anyway.")
129-
let instExeFile = installBinDir </> stackExeFileName
130-
tmpExeFile = installBinDir </> stackExeFileName <.> "tmp"
149+
let instExeFile = installBinDir </> stackOrigExeFileName
150+
tmpExeFile = installBinDir </> stackOrigExeFileName <.> "tmp"
131151
--EKB FIXME: once 'stack install --path' implemented, use it instead of this temp file.
132152
liftIO $ renameFile instExeFile tmpExeFile
133153
actionFinally
134154
(do opt <- addPath [installBinDir] []
135-
() <- cmd opt "stack build"
136-
() <- cmd opt "stack clean"
137-
() <- cmd opt "stack build --pedantic"
138-
() <- cmd opt "stack test --flag stack:integration-tests"
155+
() <- cmd opt stackProgName (stackArgs global) "build"
156+
() <- cmd opt stackProgName (stackArgs global) "clean"
157+
() <- cmd opt stackProgName (stackArgs global) "build --pedantic"
158+
() <- cmd opt stackProgName (stackArgs global) "test --flag stack:integration-tests"
139159
return ())
140160
(renameFile tmpExeFile instExeFile)
141-
copyFileChanged (installBinDir </> stackExeFileName) out
161+
copyFileChanged (installBinDir </> stackOrigExeFileName) out
142162

143-
releaseDir </> releaseExeZipFileName %> \out -> do
144-
need [releaseDir </> stackExeFileName]
145-
putNormal $ "zip " ++ (releaseDir </> stackExeFileName)
163+
releaseDir </> binaryExeZipFileName %> \out -> do
164+
need [releaseDir </> binaryExeFileName]
165+
putNormal $ "zip " ++ (releaseDir </> binaryExeFileName)
146166
liftIO $ do
147-
entry <- Zip.readEntry [] (releaseDir </> stackExeFileName)
148-
let entry' = entry{Zip.eRelativePath = stackExeFileName}
167+
entry <- Zip.readEntry [] (releaseDir </> binaryExeFileName)
168+
let entry' = entry{Zip.eRelativePath = binaryExeFileName}
149169
archive = Zip.addEntryToArchive entry' Zip.emptyArchive
150170
L8.writeFile out (Zip.fromArchive archive)
151171

152-
releaseDir </> releaseExeGzFileName %> \out -> do
153-
need [releaseDir </> stackExeFileName]
154-
putNormal $ "gzip " ++ (releaseDir </> stackExeFileName)
172+
releaseDir </> binaryExeGzFileName %> \out -> do
173+
need [releaseDir </> binaryExeFileName]
174+
putNormal $ "gzip " ++ (releaseDir </> binaryExeFileName)
155175
liftIO $ do
156-
fc <- L8.readFile (releaseDir </> stackExeFileName)
176+
fc <- L8.readFile (releaseDir </> binaryExeFileName)
157177
L8.writeFile out $ GZip.compress fc
158178

159-
releaseDir </> stackExeFileName %> \out -> do
160-
need [installBinDir </> stackExeFileName]
179+
releaseDir </> binaryExeFileName %> \out -> do
180+
need [installBinDir </> stackOrigExeFileName]
161181
case platformOS of
162182
Windows ->
163183
-- Windows doesn't have or need a 'strip' command, so skip it.
164-
liftIO $ copyFile (installBinDir </> stackExeFileName) out
184+
liftIO $ copyFile (installBinDir </> stackOrigExeFileName) out
165185
Linux ->
166186
cmd "strip -p --strip-unneeded --remove-section=.comment -o"
167-
[out, installBinDir </> stackExeFileName]
187+
[out, installBinDir </> stackOrigExeFileName]
168188
_ ->
169189
cmd "strip -o"
170-
[out, installBinDir </> stackExeFileName]
190+
[out, installBinDir </> stackOrigExeFileName]
171191

172-
releaseDir </> releaseExeCompressedAscFileName %> \out -> do
192+
releaseDir </> binaryExeCompressedAscFileName %> \out -> do
173193
need [out -<.> ""]
174194
_ <- liftIO $ tryJust (guard . isDoesNotExistError) (removeFile out)
175195
cmd "gpg --detach-sig --armor"
176196
[ "-u", gGpgKey
177-
, out -<.> "" ]
197+
, dropExtension out ]
178198

179-
installBinDir </> stackExeFileName %> \_ -> do
199+
installBinDir </> stackOrigExeFileName %> \_ -> do
180200
alwaysRerun
181-
cmd "stack build"
201+
cmd stackProgName (stackArgs global) "build"
182202

183203
forM_ distros $ \distro0 -> do
184204

@@ -252,17 +272,17 @@ rules global@Global{..} args = do
252272
distroVersionDockerDir dv = distroVersionDir dv </> "docker"
253273
distroVersionDir DistroVersion{..} = releaseDir </> dvDistro </> dvVersion
254274

255-
stackExeFileName = stackProgName <.> exe
256-
releaseFileNames = [releaseExeCompressedFileName, releaseExeCompressedAscFileName]
257-
releaseExeCompressedAscFileName = releaseExeCompressedFileName <.> ascExt
258-
releaseExeCompressedFileName =
275+
stackOrigExeFileName = stackProgName <.> exe
276+
binaryFileNames = [binaryExeCompressedFileName, binaryExeCompressedAscFileName]
277+
binaryExeCompressedAscFileName = binaryExeCompressedFileName <.> ascExt
278+
binaryExeCompressedFileName =
259279
case platformOS of
260-
Windows -> releaseExeZipFileName
261-
_ -> releaseExeGzFileName
262-
releaseExeZipFileName = releaseExeFileNameNoExt <.> zipExt
263-
releaseExeGzFileName = releaseExeFileName <.> gzExt
264-
releaseExeFileName = releaseExeFileNameNoExt <.> exe
265-
releaseExeFileNameNoExt = releaseName global
280+
Windows -> binaryExeZipFileName
281+
_ -> binaryExeGzFileName
282+
binaryExeZipFileName = binaryExeFileNameNoExt <.> zipExt
283+
binaryExeGzFileName = binaryExeFileName <.> gzExt
284+
binaryExeFileName = binaryExeFileNameNoExt <.> exe
285+
binaryExeFileNameNoExt = binaryName global
266286
distroPackageFileName distro
267287
| distroPackageExt distro == debExt =
268288
concat [stackProgName, "_", distroPackageVersionStr distro, "_amd64"] <.> debExt
@@ -422,16 +442,25 @@ buildDockerImage buildDir imageTag out = do
422442
return (trim imageIdOut)
423443

424444
-- | Name of the release binary (e.g. @stack-x.y.x-arch-os@)
425-
releaseName :: Global -> String
426-
releaseName global = concat [stackProgName, "-", stackVersionStr global, "-", platformName]
445+
binaryName :: Global -> String
446+
binaryName global@Global{..} =
447+
concat
448+
[ stackProgName
449+
, "-"
450+
, stackVersionStr global
451+
, "-"
452+
, platformName global
453+
, if null gBinarySuffix then "" else "-" ++ gBinarySuffix ]
427454

428455
-- | String representation of stack package version.
429456
stackVersionStr :: Global -> String
430-
stackVersionStr = display . pkgVersion . package . gStackPackageDescription
457+
stackVersionStr =
458+
display . pkgVersion . package . gStackPackageDescription
431459

432460
-- | Name of current platform.
433-
platformName :: String
434-
platformName = display buildPlatform
461+
platformName :: Global -> String
462+
platformName Global{..} =
463+
display (Platform gArch platformOS)
435464

436465
-- | Current operating system.
437466
platformOS :: OS
@@ -463,6 +492,18 @@ gpgKeyOptName = "gpg-key"
463492
allowDirtyOptName :: String
464493
allowDirtyOptName = "allow-dirty"
465494

495+
-- | @--arch@ command-line option name.
496+
archOptName :: String
497+
archOptName = "arch"
498+
499+
-- | @--binary-suffix@ command-line option name.
500+
binarySuffixOptName :: String
501+
binarySuffixOptName = "binary-suffix"
502+
503+
-- | Arguments to pass to all 'stack' invocations.
504+
stackArgs :: Global -> [String]
505+
stackArgs Global{..} = ["--arch=" ++ display gArch]
506+
466507
-- | Name of the 'stack' program.
467508
stackProgName :: FilePath
468509
stackProgName = "stack"
@@ -505,4 +546,6 @@ data Global = Global
505546
, gProjectRoot :: !FilePath
506547
, gHomeDir :: !FilePath
507548
, gScriptPath :: !FilePath
508-
}
549+
, gArch :: !Arch
550+
, gBinarySuffix :: !String }
551+
deriving (Show)

0 commit comments

Comments
 (0)