1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-09-22 20:04:38 +00:00

Improve build process on macOS

This commit is contained in:
Tobias
2026-09-05 15:30:49 +02:00
parent 72ee74e84a
commit 8a79de5255
10 changed files with 141 additions and 5 deletions

View File

@@ -268,6 +268,10 @@ for (const variant in BUILD_VARIANTS) {
"bundle." + variant + ".from-darwin",
gulp.series(buildName, "standalone." + variant + ".build-from-darwin")
);
gulp.task(
"bundle." + variant + ".all",
gulp.series(buildName, "standalone." + variant + ".build-all")
);
}
// serve
@@ -300,6 +304,7 @@ gulp.task(
"bundle.standalone-steam-china.from-windows"
)
);
gulp.task("bundle.steam.all", gulp.series("utils.cleanBuildOutputFolder", "bundle.standalone-steam.all"));
gulp.task(
"bundle.steam-demo.from-darwin",
gulp.series("utils.cleanBuildOutputFolder", "bundle.standalone-steam-demo.from-darwin")

View File

@@ -112,6 +112,7 @@
"postcss-preset-env": "^6.5.0",
"postcss-round-subpixels": "^1.2.0",
"postcss-unprefix": "^2.1.3",
"resedit": "1.7.2",
"sass-unused": "^0.3.0",
"strip-json-comments": "^3.0.1",
"trim": "^0.0.1",

View File

@@ -9,6 +9,17 @@ const buildutils = require("./buildutils");
const execSync = require("child_process").execSync;
const electronNotarize = require("electron-notarize");
const { BUILD_VARIANTS } = require("./build_variants");
const { applyWin32Resources } = require("./win32-resources");
// electron-packager edits win32 exe resources through rcedit, requiring wine on non-windows hosts otherwise.
const useRcedit = process.platform === "win32";
if (!useRcedit) {
const rceditPath = require.resolve("rcedit", {
paths: [path.dirname(require.resolve("electron-packager"))],
});
require(rceditPath);
require.cache[rceditPath].exports = async () => {};
}
let signAsync;
try {
@@ -120,16 +131,19 @@ function gulptasksStandalone($, gulp) {
asar = { unpackDir: privateArtifactsPath };
}
const icon = path.join(electronBaseDir, "favicon");
packager({
dir: tempDestBuildDir,
electronVersion: pj.dependencies.electron,
appCopyright: "tobspr Games",
appVersion: getVersion(),
buildVersion: "1.0.0",
icon,
arch,
platform,
asar: asar,
executableName: "shapezio",
icon: path.join(electronBaseDir, "favicon"),
name: "shapez",
out: tempDestDir,
overwrite: true,
@@ -160,6 +174,16 @@ function gulptasksStandalone($, gulp) {
return;
}
if (platform === "win32" && !useRcedit) {
console.log("Applying win32 icon and version info via resedit");
applyWin32Resources(path.join(appPath, "shapezio.exe"), {
icon: icon + ".ico",
version: getVersion(),
productName: "shapez",
company: "tobspr Games",
});
}
if (variantData.steamAppId) {
fs.writeFileSync(
path.join(appPath, "LICENSE"),
@@ -215,6 +239,13 @@ function gulptasksStandalone($, gulp) {
() => {
const appFile = path.join(tempDestDir, "shapez-darwin-x64");
const appFileInner = path.join(appFile, "shapez.app");
if (!process.env.SHAPEZ_CLI_APPLE_CERT_NAME) {
console.warn("SHAPEZ_CLI_APPLE_CERT_NAME not set, skipping signing and notarization");
cb();
return;
}
console.warn("++ Signing ++");
if (variantData.steamAppId) {
@@ -263,7 +294,7 @@ function gulptasksStandalone($, gulp) {
electronNotarize
.notarize({
appPath: path.join(appFile, "shapez.app"),
tool: "legacy",
tool: "notarytool",
appBundleId: "tobspr.shapezio.standalone",
appleId: process.env.SHAPEZ_CLI_APPLE_ID,
@@ -293,6 +324,16 @@ function gulptasksStandalone($, gulp) {
taskPrefix + ".build-from-darwin",
gulp.series(taskPrefix + ".prepare", gulp.parallel(taskPrefix + ".package.darwin64"))
);
// All three platforms on one machine (win32 needs wine for rcedit on non-windows hosts)
gulp.task(
taskPrefix + ".build-all",
gulp.series(
taskPrefix + ".prepare",
taskPrefix + ".package.darwin64",
taskPrefix + ".package.win64",
taskPrefix + ".package.linux64"
)
);
}
// Steam helpers

View File

@@ -0,0 +1,16 @@
"appbuild"
{
"appid" "1318690"
"desc" "$BUILD_DESC$"
"buildoutput" "$TMP_DIR$"
"contentroot" ""
"setlive" ""
"preview" "0"
"local" ""
"depots"
{
"1318691" "$VDF_DIR$/standalone-windows.vdf"
"1318692" "$VDF_DIR$/standalone-linux.vdf"
"1318693" "$VDF_DIR$/standalone-darwin.vdf"
}
}

View File

@@ -1,7 +1,7 @@
"DepotBuildConfig"
{
"DepotID" "1318693"
"contentroot" "$BUNDLE_DIR$\standalone-steam\shapez-darwin-x64"
"contentroot" "$BUNDLE_DIR$/standalone-steam/shapez-darwin-x64"
"FileMapping"
{
"LocalPath" "*"

View File

@@ -1,7 +1,7 @@
"DepotBuildConfig"
{
"DepotID" "1318692"
"contentroot" "$BUNDLE_DIR$\standalone-steam\shapez-linux-x64"
"contentroot" "$BUNDLE_DIR$/standalone-steam/shapez-linux-x64"
"FileMapping"
{
"LocalPath" "*"

View File

@@ -1,7 +1,7 @@
"DepotBuildConfig"
{
"DepotID" "1318691"
"contentroot" "$BUNDLE_DIR$\standalone-steam\shapez-win32-x64"
"contentroot" "$BUNDLE_DIR$/standalone-steam/shapez-win32-x64"
"FileMapping"
{
"LocalPath" "*"

6
gulp/steampipe/upload-all.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
set -e
cd "$(dirname "$0")/.."
mkdir -p steampipe/built_vdfs steampipe/tmp
yarn gulp standalone.prepareVDF
steamcmd +login "$STEAM_UPLOAD_SHAPEZ_ID" $STEAM_UPLOAD_SHAPEZ_USER +run_app_build "$PWD/steampipe/built_vdfs/app-all.vdf" +quit

55
gulp/win32-resources.js Normal file
View File

@@ -0,0 +1,55 @@
// Sets icon and version info on a packaged Windows executable without rcedit/wine,
// so Windows builds can be produced from macOS or Linux hosts.
const fs = require("fs");
const ResEdit = require("resedit");
const LANG_EN_US = 1033;
const CODEPAGE_UNICODE = 1200;
const ICON_GROUP_ID = 1;
/**
* @param {string} exePath
* @param {{ icon: string, version: string, productName: string, company: string }} opts
*/
function applyWin32Resources(exePath, opts) {
const exe = ResEdit.NtExecutable.from(fs.readFileSync(exePath));
const res = ResEdit.NtExecutableResource.from(exe);
const iconFile = ResEdit.Data.IconFile.from(fs.readFileSync(opts.icon));
ResEdit.Resource.IconGroupEntry.replaceIconsForResource(
res.entries,
ICON_GROUP_ID,
LANG_EN_US,
iconFile.icons.map(icon => icon.data)
);
const parts = opts.version.split(".").map(part => parseInt(part, 10) || 0);
while (parts.length < 4) {
parts.push(0);
}
const [major, minor, patch, build] = parts;
const existing = ResEdit.Resource.VersionInfo.fromEntries(res.entries);
const versionInfo = existing.length > 0 ? existing[0] : ResEdit.Resource.VersionInfo.createEmpty();
versionInfo.setFileVersion(major, minor, patch, build, LANG_EN_US);
versionInfo.setProductVersion(major, minor, patch, build, LANG_EN_US);
versionInfo.setStringValues(
{ lang: LANG_EN_US, codepage: CODEPAGE_UNICODE },
{
FileDescription: opts.productName,
ProductName: opts.productName,
CompanyName: opts.company,
LegalCopyright: opts.company,
OriginalFilename: "shapezio.exe",
InternalName: "shapezio",
FileVersion: opts.version,
ProductVersion: opts.version,
}
);
versionInfo.outputToResourceEntries(res.entries);
res.outputResource(exe);
fs.writeFileSync(exePath, Buffer.from(exe.generate()));
}
module.exports = { applyWin32Resources };

View File

@@ -9383,6 +9383,11 @@ pbkdf2@^3.0.3:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
pe-library@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/pe-library/-/pe-library-0.4.1.tgz#e269be0340dcb13aa6949d743da7d658c3e2fbea"
integrity sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz"
@@ -10850,6 +10855,13 @@ requires-port@^1.0.0:
resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz"
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
resedit@1.7.2:
version "1.7.2"
resolved "https://registry.yarnpkg.com/resedit/-/resedit-1.7.2.tgz#b1041170b99811710c13f949c7d225871de4cc78"
integrity sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==
dependencies:
pe-library "^0.4.1"
resolve-cwd@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz"