1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-03-02 03:39:21 +00:00

Build, sign, notarise, & upload on OS X (#687)

* sign & notarise darwin package

* upload bundle as github release

* allow unsigned build and full build with release

* deref darwin bundle symlinks only when building on win32

Windows [mangles symlinks](https://github.com/electron/electron-packager/issues/71). Currently we work around this by placing several copies of the frameworks in OS X app bundles (see 1e5aa3867d). However:

- This is invalid: the framework toplevel must [only contain symlinks](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html). `codesign` [refuses to sign](https://stackoverflow.com/questions/25969946/osx-10-9-5-code-signing-v2-signing-a-framework-with-bundle-format-is-ambiguou) this invalid structure.

- It seriously bloats the bundle.

Since there's no fix for the Windows misbehaviour, keep the workaround, but only when cross-building on win32 for darwin; and log a warning.
This commit is contained in:
LeopoldTal
2020-09-27 23:14:43 +02:00
committed by GitHub
parent d27e9226be
commit b9b8592a07
7 changed files with 255 additions and 2 deletions

View File

@@ -25,6 +25,14 @@ module.exports = {
});
},
getTag() {
try {
return execSync("git describe --tag --exact-match").toString("ascii");
} catch (e) {
throw new Error('Current git HEAD is not a version tag');
}
},
getVersion() {
return trim(fs.readFileSync(path.join(__dirname, "..", "version")).toString());
},

12
gulp/entitlements.plist Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.debugger</key>
<true/>
</dict>
</plist>

View File

@@ -42,6 +42,10 @@ const envVars = [
"SHAPEZ_CLI_STAGING_FTP_PW",
"SHAPEZ_CLI_LIVE_FTP_USER",
"SHAPEZ_CLI_LIVE_FTP_PW",
"SHAPEZ_CLI_APPLE_ID",
"SHAPEZ_CLI_APPLE_CERT_NAME",
"SHAPEZ_CLI_GITHUB_USER",
"SHAPEZ_CLI_GITHUB_TOKEN",
];
for (let i = 0; i < envVars.length; ++i) {
@@ -78,6 +82,9 @@ docs.gulptasksDocs($, gulp, buildFolder);
const standalone = require("./standalone");
standalone.gulptasksStandalone($, gulp, buildFolder);
const releaseUploader = require("./release-uploader");
releaseUploader.gulptasksReleaseUploader($, gulp, buildFolder);
const translations = require("./translations");
translations.gulptasksTranslations($, gulp, buildFolder);
@@ -299,6 +306,17 @@ gulp.task(
gulp.series("utils.cleanup", "step.standalone-prod.all", "step.postbuild")
);
// OS X build and release upload
gulp.task(
"build.darwin64-prod",
gulp.series(
"build.standalone-prod",
"standalone.prepare",
"standalone.package.prod.darwin64",
"standalone.uploadRelease.darwin64"
)
);
// Deploying!
gulp.task(
"main.deploy.alpha",

66
gulp/release-uploader.js Normal file
View File

@@ -0,0 +1,66 @@
const path = require("path");
const fs = require("fs");
const execSync = require("child_process").execSync;
const { Octokit } = require("@octokit/rest");
const buildutils = require("./buildutils");
function gulptasksReleaseUploader($, gulp, buildFolder) {
const standaloneDir = path.join(__dirname, "..", "tmp_standalone_files");
const darwinApp = path.join(standaloneDir, "shapez.io-standalone-darwin-x64", "shapez.io-standalone.app");
const dmgName = "shapez.io-standalone.dmg";
const dmgPath = path.join(standaloneDir, "shapez.io-standalone-darwin-x64", dmgName);
gulp.task("standalone.uploadRelease.darwin64.cleanup", () => {
return gulp.src(dmgPath, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
});
gulp.task("standalone.uploadRelease.darwin64.compress", cb => {
console.log("Packaging disk image", dmgPath);
execSync(`hdiutil create -format UDBZ -srcfolder ${darwinApp} ${dmgPath}`);
cb();
});
gulp.task("standalone.uploadRelease.darwin64.upload", async cb => {
const currentTag = buildutils.getTag();
const octokit = new Octokit({
auth: process.env.SHAPEZ_CLI_GITHUB_TOKEN
});
const createdRelease = await octokit.request("POST /repos/{owner}/{repo}/releases", {
owner: process.env.SHAPEZ_CLI_GITHUB_USER,
repo: "shapez.io",
tag_name: currentTag,
name: currentTag,
draft: true
});
const { data: { id, upload_url } } = createdRelease;
console.log(`Created release ${id} for tag ${currentTag}`);
const dmgContents = fs.readFileSync(dmgPath);
const dmgSize = fs.statSync(dmgPath).size;
console.log("Uploading", dmgContents.length / 1024 / 1024, "MB to", upload_url);
await octokit.request({
method: "POST",
url: upload_url,
headers: {
"content-type": "application/x-apple-diskimage"
},
name: dmgName,
data: dmgContents
});
cb();
});
gulp.task("standalone.uploadRelease.darwin64",
gulp.series(
"standalone.uploadRelease.darwin64.cleanup",
"standalone.uploadRelease.darwin64.compress",
"standalone.uploadRelease.darwin64.upload"
));
}
module.exports = { gulptasksReleaseUploader };

View File

@@ -1,3 +1,4 @@
require('colors');
const packager = require("electron-packager");
const path = require("path");
const { getVersion } = require("./buildutils");
@@ -80,8 +81,9 @@ function gulptasksStandalone($, gulp) {
* @param {'win32'|'linux'|'darwin'} platform
* @param {'x64'|'ia32'} arch
* @param {function():void} cb
* @param {boolean=} isRelease
*/
function packageStandalone(platform, arch, cb) {
function packageStandalone(platform, arch, cb, isRelease = true) {
const tomlFile = fs.readFileSync(path.join(__dirname, ".itch.toml"));
packager({
@@ -99,6 +101,20 @@ function gulptasksStandalone($, gulp) {
overwrite: true,
appBundleId: "io.shapez.standalone",
appCategoryType: "public.app-category.games",
...(isRelease && platform === "darwin" && {
osxSign: {
identity: process.env.SHAPEZ_CLI_APPLE_CERT_NAME,
"hardened-runtime": true,
hardenedRuntime: true,
entitlements: 'entitlements.plist',
'entitlements-inherit': 'entitlements.plist',
'signature-flags': 'library'
},
osxNotarize: {
appleId: process.env.SHAPEZ_CLI_APPLE_ID,
appleIdPassword: "@keychain:SHAPEZ_CLI_APPLE_ID"
}
})
}).then(
appPaths => {
console.log("Packages created:", appPaths);
@@ -123,7 +139,11 @@ function gulptasksStandalone($, gulp) {
fs.chmodSync(path.join(appPath, "play.sh"), 0o775);
}
if (platform === "darwin") {
if (process.platform === "win32" && platform === "darwin") {
console.warn("Cross-building for macOS on Windows: dereferencing symlinks.\n".red +
"This will nearly double app size and make code signature invalid. Sorry!\n".red.bold +
"For more information, see " + "https://github.com/electron/electron-packager/issues/71".underline);
// Clear up framework folders
fs.writeFileSync(
path.join(appPath, "play.sh"),
@@ -175,6 +195,7 @@ function gulptasksStandalone($, gulp) {
gulp.task("standalone.package.prod.linux64", cb => packageStandalone("linux", "x64", cb));
gulp.task("standalone.package.prod.linux32", cb => packageStandalone("linux", "ia32", cb));
gulp.task("standalone.package.prod.darwin64", cb => packageStandalone("darwin", "x64", cb));
gulp.task("standalone.package.prod.darwin64.unsigned", cb => packageStandalone("darwin", "x64", cb, false));
gulp.task(
"standalone.package.prod",