Skip to content

Commit 0f14024

Browse files
committed
unify Unix/Windows build scripts with crossplatform PowerShell
1 parent e76e995 commit 0f14024

File tree

10 files changed

+311
-543
lines changed

10 files changed

+311
-543
lines changed

.github/workflows/build-smapi.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ jobs:
9595
9696
Write-Host "This is a dev version. Building as version: $updatedVersion"
9797
98-
bash build/unix/set-smapi-version.sh "$updatedVersion"
99-
Write-Host 'Version updated using build/unix/set-smapi-version.sh.'
98+
./build/scripts/set-smapi-version.ps1 "$updatedVersion"
99+
Write-Host 'Version updated.'
100100
101101
- name: Checkout game reference assemblies
102102
run: |
@@ -106,7 +106,7 @@ jobs:
106106
shell: pwsh
107107
run: |
108108
Write-Host "Building SMAPI $env:VERSION."
109-
bash build/unix/prepare-install-package.sh "$env:VERSION"
109+
./build/scripts/prepare-install-package.ps1 "$env:VERSION"
110110
111111
- name: Rename build zips
112112
run: |
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function In-Place-Regex {
1+
function In-Place-Regex {
22
param (
33
[Parameter(Mandatory)][string]$Path,
44
[Parameter(Mandatory)][string]$Search,
Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
#
2+
#
3+
# Note: On Windows, this script *does not* set Linux permissions. The final changes are handled by the
4+
# finalize-install-package.sh file in WSL.
5+
#
6+
#
7+
8+
. "$PSScriptRoot/lib/in-place-regex.ps1"
9+
10+
11+
##########
12+
## Find the game folder
13+
##########
14+
if ($IsWindows) {
15+
$possibleGamePaths=(
16+
# GOG
17+
"C:\Program Files\GalaxyClient\Games\Stardew Valley",
18+
"C:\Program Files\GOG Galaxy\Games\Stardew Valley",
19+
"C:\Program Files\GOG Games\Stardew Valley",
20+
"C:\Program Files (x86)\GalaxyClient\Games\Stardew Valley",
21+
"C:\Program Files (x86)\GOG Galaxy\Games\Stardew Valley",
22+
"C:\Program Files (x86)\GOG Games\Stardew Valley",
23+
24+
# Steam
25+
"C:\Program Files\Steam\steamapps\common\Stardew Valley",
26+
"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley"
27+
)
28+
}
29+
else {
30+
$possibleGamePaths=(
31+
# override
32+
"$HOME/StardewValley",
33+
34+
# Linux
35+
"$HOME/GOG Games/Stardew Valley/game",
36+
"$HOME/.steam/steam/steamapps/common/Stardew Valley",
37+
"$HOME/.local/share/Steam/steamapps/common/Stardew Valley",
38+
"$HOME/.var/app/com.valvesoftware.Steam/data/Steam/steamapps/common/Stardew Valley",
39+
40+
# macOS
41+
"/Applications/Stardew Valley.app/Contents/MacOS",
42+
"$HOME/Library/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS"
43+
)
44+
}
45+
46+
$gamePath = ""
47+
foreach ($possibleGamePath in $possibleGamePaths) {
48+
if (Test-Path $possibleGamePath -PathType Container) {
49+
$gamePath = $possibleGamePath
50+
break
51+
}
52+
}
53+
54+
55+
##########
56+
## Preset values
57+
##########
58+
# paths
59+
$bundleModNames = "ConsoleCommands", "SaveBackup"
60+
61+
# build configuration
62+
$buildConfig = "Release"
63+
$framework = "net6.0"
64+
$folders = "linux", "macOS", "windows"
65+
$runtimes = @{ linux = "linux-x64"; macOS = "osx-x64"; windows = "win-x64" }
66+
$msBuildPlatformNames = @{ linux = "Unix"; macOS = "OSX"; windows = "Windows_NT" }
67+
68+
# version number
69+
$version = $args[0]
70+
if (!$version) {
71+
$version = Read-Host "SMAPI release version (like '4.0.0')"
72+
}
73+
74+
# Windows-only build
75+
$windowsOnly = $false
76+
if ($IsWindows) {
77+
foreach ($arg in $args) {
78+
if ($arg -eq "--windows-only") {
79+
$windowsOnly = $true
80+
$folders = "windows"
81+
$runtimes = @{ windows = "win-x64" }
82+
$msBuildPlatformNames = @{ windows = "Windows_NT" }
83+
}
84+
}
85+
}
86+
87+
88+
##########
89+
## Move to SMAPI root
90+
##########
91+
Set-Location "$PSScriptRoot/../.."
92+
93+
94+
##########
95+
## Clear old build files
96+
##########
97+
Write-Output "Clearing old builds..."
98+
Write-Output "-------------------------------------------------"
99+
100+
foreach ($path in (Get-ChildItem -Recurse -Include ('bin', 'obj'))) {
101+
Write-Output "$path"
102+
Remove-Item -Recurse -Force "$path"
103+
}
104+
Write-Output ""
105+
106+
107+
##########
108+
## Compile files
109+
##########
110+
. "$PSScriptRoot/set-smapi-version.ps1" "$version"
111+
foreach ($folder in $folders) {
112+
$runtime = $runtimes[$folder]
113+
$msbuildPlatformName = $msBuildPlatformNames[$folder]
114+
115+
Write-Output "Compiling SMAPI for $folder..."
116+
Write-Output "-------------------------------------------------"
117+
dotnet publish src/SMAPI --configuration $buildConfig -v minimal --runtime "$runtime" --framework "$framework" -p:OS="$msbuildPlatformName" -p:TargetFrameworks="$framework" -p:GamePath="$gamePath" -p:CopyToGameFolder="false" --self-contained true
118+
Write-Output ""
119+
Write-Output ""
120+
121+
Write-Output "Compiling installer for $folder..."
122+
Write-Output "-------------------------------------------------"
123+
dotnet publish src/SMAPI.Installer --configuration $buildConfig -v minimal --runtime "$runtime" --framework "$framework" -p:OS="$msbuildPlatformName" -p:TargetFrameworks="$framework" -p:GamePath="$gamePath" -p:CopyToGameFolder="false" --self-contained true
124+
Write-Output ""
125+
Write-Output ""
126+
127+
foreach ($modName in $bundleModNames) {
128+
Write-Output "Compiling $modName for $folder..."
129+
Write-Output "-------------------------------------------------"
130+
dotnet publish src/SMAPI.Mods.$modName --configuration $buildConfig -v minimal --runtime "$runtime" --framework "$framework" -p:OS="$msbuildPlatformName" -p:TargetFrameworks="$framework" -p:GamePath="$gamePath" -p:CopyToGameFolder="false" --self-contained false
131+
Write-Output ""
132+
Write-Output ""
133+
}
134+
}
135+
136+
137+
##########
138+
## Prepare install package
139+
##########
140+
Write-Output "Preparing install package..."
141+
Write-Output "----------------------------"
142+
143+
# init paths
144+
$installAssets = "src/SMAPI.Installer/assets"
145+
$packagePath = "bin/SMAPI installer"
146+
$packageDevPath = "bin/SMAPI installer for developers"
147+
148+
# init structure
149+
foreach ($folder in $folders) {
150+
$folderPath = "$packagePath/internal/$folder/bundle/smapi-internal"
151+
152+
if ($IsWindows) {
153+
# On Windows, mkdir creates parent directories automatically and the --parents argument isn't recognized.
154+
mkdir "$folderPath" > $null
155+
}
156+
else
157+
{
158+
mkdir "$folderPath" --parents
159+
}
160+
}
161+
162+
# copy base installer files
163+
foreach ($name in @("install on Linux.sh", "install on macOS.command", "install on Windows.bat", "README.txt")) {
164+
if ($windowsOnly -and ($name -eq "install on Linux.sh" -or $name -eq "install on macOS.command")) {
165+
continue;
166+
}
167+
168+
Copy-Item "$installAssets/$name" "$packagePath"
169+
}
170+
171+
# copy per-platform files
172+
foreach ($folder in $folders) {
173+
$runtime = $runtimes[$folder]
174+
175+
# get paths
176+
$smapiBin = "src/SMAPI/bin/$buildConfig/$runtime/publish"
177+
$internalPath = "$packagePath/internal/$folder"
178+
$bundlePath = "$internalPath/bundle"
179+
180+
# installer files
181+
Copy-Item "src/SMAPI.Installer/bin/$buildConfig/$runtime/publish/*" "$internalPath" -Recurse
182+
Remove-Item -Recurse -Force "$internalPath/assets"
183+
184+
# runtime config for SMAPI
185+
# This is identical to the one generated by the build, except that the min runtime version is
186+
# set to 6.0.0 (instead of whatever version it was built with) and rollForward is set to latestMinor instead of
187+
# minor.
188+
Copy-Item "$installAssets/runtimeconfig.json" "$bundlePath/StardewModdingAPI.runtimeconfig.json"
189+
190+
# installer DLL config
191+
if ($folder -eq "windows") {
192+
Copy-Item "$installAssets/windows-exe-config.xml" "$packagePath/internal/windows/install.exe.config"
193+
}
194+
195+
# bundle root files
196+
foreach ($name in @("StardewModdingAPI", "StardewModdingAPI.dll", "StardewModdingAPI.xml", "steam_appid.txt")) {
197+
if ($name -eq "StardewModdingAPI" -and $folder -eq "windows") {
198+
$name = "$name.exe"
199+
}
200+
201+
Copy-Item "$smapiBin/$name" "$bundlePath"
202+
}
203+
204+
# bundle i18n
205+
Copy-Item -Recurse "$smapiBin/i18n" "$bundlePath/smapi-internal"
206+
207+
# bundle smapi-internal
208+
foreach ($name in @("0Harmony.dll", "0Harmony.xml", "Markdig.dll", "Mono.Cecil.dll", "Mono.Cecil.Mdb.dll", "Mono.Cecil.Pdb.dll", "MonoMod.Common.dll", "Newtonsoft.Json.dll", "Pathoschild.Http.Client.dll", "Pintail.dll", "TMXTile.dll", "SMAPI.Toolkit.dll", "SMAPI.Toolkit.xml", "SMAPI.Toolkit.CoreInterfaces.dll", "SMAPI.Toolkit.CoreInterfaces.xml", "System.Net.Http.Formatting.dll")) {
209+
Copy-Item "$smapiBin/$name" "$bundlePath/smapi-internal"
210+
}
211+
212+
if ($folder -eq "windows") {
213+
Copy-Item "$smapiBin/VdfConverter.dll" "$bundlePath/smapi-internal"
214+
}
215+
216+
Copy-Item "$smapiBin/SMAPI.blacklist.json" "$bundlePath/smapi-internal/blacklist.json"
217+
Copy-Item "$smapiBin/SMAPI.config.json" "$bundlePath/smapi-internal/config.json"
218+
Copy-Item "$smapiBin/SMAPI.metadata.json" "$bundlePath/smapi-internal/metadata.json"
219+
if ($folder -eq "linux" -or $folder -eq "macOS") {
220+
Copy-Item "$installAssets/unix-launcher.sh" "$bundlePath"
221+
}
222+
else {
223+
Copy-Item "$installAssets/windows-exe-config.xml" "$bundlePath/StardewModdingAPI.exe.config"
224+
}
225+
226+
# copy bundled mods
227+
foreach ($modName in $bundleModNames) {
228+
$fromPath = "src/SMAPI.Mods.$modName/bin/$buildConfig/$runtime/publish"
229+
$targetPath = "$bundlePath/Mods/$modName"
230+
231+
if ($IsWindows) {
232+
# On Windows, mkdir creates parent directories automatically and the --parents argument isn't recognized.
233+
mkdir "$targetPath" > $null
234+
}
235+
else
236+
{
237+
mkdir "$targetPath" --parents
238+
}
239+
240+
Copy-Item "$fromPath/$modName.dll" "$targetPath"
241+
Copy-Item "$fromPath/manifest.json" "$targetPath"
242+
if (Test-Path "$fromPath/i18n" -PathType Container) {
243+
Copy-Item -Recurse "$fromPath/i18n" "$targetPath"
244+
}
245+
}
246+
}
247+
248+
# mark scripts executable
249+
if ($IsWindows) {
250+
Write-Warning "Can't set Unix file permissions on Windows. This may cause issues for Linux/macOS players."
251+
}
252+
else {
253+
ForEach ($path in @("install on Linux.sh", "install on macOS.command", "bundle/unix-launcher.sh")) {
254+
if (Test-Path "$packagePath/$path" -PathType Leaf) {
255+
chmod 755 "$packagePath/$path"
256+
}
257+
}
258+
}
259+
260+
# split into main + for-dev folders
261+
Copy-Item -Recurse "$packagePath" "$packageDevPath"
262+
foreach ($folder in $folders) {
263+
# disable developer mode in main package
264+
In-Place-Regex -Path "$packagePath/internal/$folder/bundle/smapi-internal/config.json" -Search "`"DeveloperMode`": true" -Replace "`"DeveloperMode`": false"
265+
266+
# convert bundle folder into final 'install.dat' files
267+
if ($windowsOnly)
268+
{
269+
foreach ($path in @("$packagePath/internal/$folder", "$packageDevPath/internal/$folder"))
270+
{
271+
Compress-Archive -Path "$path/bundle/*" -CompressionLevel Optimal -DestinationPath "$path/install.dat"
272+
Remove-Item -Recurse -Force "$path/bundle"
273+
}
274+
}
275+
}
276+
277+
278+
###########
279+
### Create release zips
280+
###########
281+
# rename folders
282+
Move-Item "$packagePath" "bin/SMAPI $version installer"
283+
Move-Item "$packageDevPath" "bin/SMAPI $version installer for developers"
284+
285+
# package files
286+
Compress-Archive -Path "bin/SMAPI $version installer" -DestinationPath "bin/SMAPI $version installer.zip" -CompressionLevel Optimal
287+
Compress-Archive -Path "bin/SMAPI $version installer for developers" -DestinationPath "bin/SMAPI $version installer for developers.zip" -CompressionLevel Optimal
288+
289+
Write-Output ""
290+
Write-Output "Done! See docs/technical/smapi.md to create the release zips."
Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
#
2-
#
3-
# This is the PowerShell equivalent of ../unix/set-smapi-version.sh.
4-
# When making changes, both scripts should be updated.
5-
#
6-
#
7-
8-
91
. "$PSScriptRoot\lib\in-place-regex.ps1"
102

113
# get version number
@@ -15,7 +7,7 @@ if (!$version) {
157
}
168

179
# move to SMAPI root
18-
cd "$PSScriptRoot/../.."
10+
Set-Location "$PSScriptRoot/../.."
1911

2012
# apply changes
2113
In-Place-Regex -Path "build/common.targets" -Search "<Version>.+</Version>" -Replace "<Version>$version</Version>"

0 commit comments

Comments
 (0)