mirror of
https://github.com/nexu-io/open-design.git
synced 2026-05-31 19:04:39 +07:00
Adds a new `--to zip` (and `--to all`) tools-pack Windows build target that produces a portable `.zip` from the cached `win-unpacked` tree using the bundled 7z. The zip lays files at the archive root so users can extract it anywhere and launch `Open Design.exe` without going through the NSIS installer, addressing the no-install download request. Release plumbing is updated to publish the portable zip and its sha256 beside the existing installer on R2 for beta, preview, and stable channels (default on, gated by `WINDOWS_INCLUDE_ZIP`/`WIN_INCLUDE_ZIP`). The electron-updater `latest.yml` feed continues to point only at the installer; the zip is a manual-download convenience and is intentionally excluded from the in-app updater. Closes #1121 Generated-By: looper 0.0.0-dev (runner=worker, agent=claude-code) Co-authored-by: libertecode <libertecode@proton.me>
231 lines
7.4 KiB
Bash
231 lines
7.4 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
for name in BASE_VERSION ENABLE_LINUX ENABLE_MAC ENABLE_MAC_INTEL ENABLE_WIN GITHUB_STEP_SUMMARY RELEASE_CHANNEL RELEASE_SIGNED RELEASE_VERSION STATE_SOURCE; do
|
|
if [ -z "${!name:-}" ]; then
|
|
echo "$name is required" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
node --input-type=module <<'NODE' >> "$GITHUB_STEP_SUMMARY"
|
|
import { readFileSync } from "node:fs";
|
|
|
|
const env = process.env;
|
|
const enabled = (name) => env[name] === "true";
|
|
const macArtifactMode = env.MAC_ARTIFACT_MODE ?? "dmg-and-zip";
|
|
const optional = (name) => {
|
|
const value = env[name];
|
|
return value == null || value.length === 0 ? null : value;
|
|
};
|
|
const joinUrl = (base, path) => {
|
|
if (base == null) {
|
|
return null;
|
|
}
|
|
return `${base.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
};
|
|
|
|
const reportUrl = optional("R2_REPORT_URL");
|
|
const reportZipUrl = optional("R2_REPORT_ZIP_URL");
|
|
const platformReport = (platform) => reportUrl == null ? null : {
|
|
manifest: joinUrl(reportUrl, `${platform}/manifest.json`),
|
|
screenshot: joinUrl(reportUrl, `${platform}/screenshots/open-design-${platform}-smoke.png`),
|
|
vitestLog: joinUrl(reportUrl, `${platform}/vitest.log`),
|
|
};
|
|
|
|
const platforms = {
|
|
mac: {
|
|
enabled: enabled("ENABLE_MAC"),
|
|
signed: env.RELEASE_SIGNED === "true",
|
|
},
|
|
win: {
|
|
enabled: enabled("ENABLE_WIN"),
|
|
signed: false,
|
|
},
|
|
linux: {
|
|
enabled: enabled("ENABLE_LINUX"),
|
|
signed: false,
|
|
},
|
|
macIntel: {
|
|
enabled: enabled("ENABLE_MAC_INTEL"),
|
|
signed: env.MAC_INTEL_SIGNED === "true",
|
|
},
|
|
};
|
|
|
|
if (platforms.mac.enabled) {
|
|
platforms.mac.artifacts = {
|
|
dmg: optional("R2_MAC_DMG_URL"),
|
|
};
|
|
if (macArtifactMode !== "dmg-only") {
|
|
platforms.mac.artifacts.zip = optional("R2_MAC_ZIP_URL");
|
|
}
|
|
platforms.mac.feed = macArtifactMode === "dmg-only" ? null : optional("R2_MAC_FEED_URL");
|
|
platforms.mac.e2e = platformReport("mac");
|
|
}
|
|
if (platforms.win.enabled) {
|
|
platforms.win.artifacts = {
|
|
installer: optional("R2_WIN_INSTALLER_URL"),
|
|
portableZip: optional("R2_WIN_PORTABLE_ZIP_URL"),
|
|
};
|
|
platforms.win.feed = optional("R2_WIN_FEED_URL");
|
|
platforms.win.e2e = platformReport("win");
|
|
}
|
|
if (platforms.linux.enabled) {
|
|
platforms.linux.artifacts = {
|
|
appImage: optional("R2_LINUX_APPIMAGE_URL"),
|
|
};
|
|
platforms.linux.feed = null;
|
|
}
|
|
if (platforms.macIntel.enabled) {
|
|
platforms.macIntel.artifacts = {
|
|
dmg: optional("R2_MAC_INTEL_DMG_URL"),
|
|
zip: optional("R2_MAC_INTEL_ZIP_URL"),
|
|
};
|
|
platforms.macIntel.feed = null;
|
|
}
|
|
|
|
const githubReleaseEnabled = env.GITHUB_RELEASE_ENABLED === "true";
|
|
const versionTag = optional("VERSION_TAG");
|
|
const titleCase = (value) => `${value.slice(0, 1).toUpperCase()}${value.slice(1)}`;
|
|
const md = (value) => String(value).replaceAll("|", "\\|").replaceAll("\n", " ");
|
|
const code = (value) => value == null || value === "" ? "-" : `\`${md(value)}\``;
|
|
const link = (label, url) => url == null || url === "" ? "-" : `[${md(label)}](${url})`;
|
|
const linkList = (items) => {
|
|
const links = items
|
|
.filter((item) => item.url != null && item.url !== "")
|
|
.map((item) => link(item.label, item.url));
|
|
|
|
return links.length === 0 ? "-" : links.join("<br>");
|
|
};
|
|
const boolLabel = (value) => value ? "Yes" : "No";
|
|
const platformStatus = (platform, label) => {
|
|
if (!platform.enabled) {
|
|
return "Skipped";
|
|
}
|
|
return platform.signed ? `${label} signed` : label;
|
|
};
|
|
|
|
const overviewRows = [
|
|
["Channel", code(env.RELEASE_CHANNEL)],
|
|
["Version", code(env.RELEASE_VERSION)],
|
|
["Base version", code(env.BASE_VERSION)],
|
|
["State source", code(env.STATE_SOURCE)],
|
|
["Mac signed", boolLabel(env.RELEASE_SIGNED === "true")],
|
|
["Linux enabled", boolLabel(platforms.linux.enabled)],
|
|
];
|
|
if (env.RELEASE_CHANNEL === "nightly") {
|
|
overviewRows.push(["Nightly number", code(env.NIGHTLY_NUMBER)]);
|
|
}
|
|
|
|
const overviewTable = [
|
|
"| Field | Value |",
|
|
"| --- | --- |",
|
|
...overviewRows.map(([field, value]) => `| ${md(field)} | ${value} |`),
|
|
].join("\n");
|
|
|
|
const releaseLinks = [
|
|
["Latest metadata", optional("R2_METADATA_URL")],
|
|
["Version metadata", optional("R2_VERSION_METADATA_URL")],
|
|
]
|
|
.filter(([, url]) => url != null)
|
|
.map(([label, url]) => `- ${link(label, url)}`);
|
|
|
|
const platformRows = [
|
|
[
|
|
"macOS arm64",
|
|
platformStatus(platforms.mac, "Published"),
|
|
linkList([
|
|
{ label: "DMG", url: platforms.mac.artifacts?.dmg },
|
|
{ label: "ZIP", url: platforms.mac.artifacts?.zip },
|
|
]),
|
|
link("latest-mac.yml", platforms.mac.feed),
|
|
],
|
|
[
|
|
"Windows x64",
|
|
platformStatus(platforms.win, "Published"),
|
|
linkList([
|
|
{ label: "Installer", url: platforms.win.artifacts?.installer },
|
|
{ label: "Portable ZIP", url: platforms.win.artifacts?.portableZip },
|
|
]),
|
|
link("latest.yml", platforms.win.feed),
|
|
],
|
|
[
|
|
"Linux x64",
|
|
platformStatus(platforms.linux, "Published"),
|
|
linkList([{ label: "AppImage", url: platforms.linux.artifacts?.appImage }]),
|
|
"-",
|
|
],
|
|
[
|
|
"macOS x64 (Intel)",
|
|
platformStatus(platforms.macIntel, "Published"),
|
|
linkList([
|
|
{ label: "DMG", url: platforms.macIntel.artifacts?.dmg },
|
|
{ label: "ZIP", url: platforms.macIntel.artifacts?.zip },
|
|
]),
|
|
"-",
|
|
],
|
|
];
|
|
|
|
const platformTable = [
|
|
"| Platform | Status | Assets | Feed |",
|
|
"| --- | --- | --- | --- |",
|
|
...platformRows.map((row) => `| ${row.map(md).join(" | ")} |`),
|
|
].join("\n");
|
|
|
|
const reportRows = reportZipUrl == null
|
|
? [
|
|
[
|
|
"macOS arm64",
|
|
platforms.mac.enabled ? "Published" : "Skipped",
|
|
linkList([
|
|
{ label: "manifest", url: platforms.mac.e2e?.manifest },
|
|
{ label: "screenshot", url: platforms.mac.e2e?.screenshot },
|
|
{ label: "vitest.log", url: platforms.mac.e2e?.vitestLog },
|
|
]),
|
|
],
|
|
[
|
|
"Windows x64",
|
|
platforms.win.enabled ? "Published" : "Skipped",
|
|
linkList([
|
|
{ label: "manifest", url: platforms.win.e2e?.manifest },
|
|
{ label: "screenshot", url: platforms.win.e2e?.screenshot },
|
|
{ label: "vitest.log", url: platforms.win.e2e?.vitestLog },
|
|
]),
|
|
],
|
|
["Linux x64", platforms.linux.enabled ? "Not collected" : "Skipped", "-"],
|
|
[
|
|
"macOS x64 (Intel)",
|
|
platforms.macIntel.enabled ? "Published" : "Skipped",
|
|
"-",
|
|
],
|
|
]
|
|
: [["report.zip", "Published", link("download", reportZipUrl)]];
|
|
|
|
const reportTable = [
|
|
reportZipUrl == null ? "| Platform | Status | Links |" : "| Bundle | Status | Link |",
|
|
"| --- | --- | --- |",
|
|
...reportRows.map((row) => `| ${row.map(md).join(" | ")} |`),
|
|
].join("\n");
|
|
|
|
const repository = optional("GITHUB_REPOSITORY");
|
|
const githubReleaseSection = githubReleaseEnabled && versionTag != null
|
|
? [
|
|
"### GitHub release",
|
|
"",
|
|
`- Tag: ${code(versionTag)}`,
|
|
repository == null ? null : `- Release: ${link(versionTag, `https://github.com/${repository}/releases/tag/${versionTag}`)}`,
|
|
].filter((line) => line != null).join("\n")
|
|
: "";
|
|
|
|
const templatePath = optional("SUMMARY_TEMPLATE_PATH") ?? ".github/scripts/release/r2/summary.md";
|
|
const template = readFileSync(templatePath, "utf8");
|
|
const output = template
|
|
.replaceAll("{{TITLE}}", `${titleCase(env.RELEASE_CHANNEL)} release ${env.RELEASE_VERSION}`)
|
|
.replaceAll("{{OVERVIEW_TABLE}}", overviewTable)
|
|
.replaceAll("{{RELEASE_LINKS}}", releaseLinks.length === 0 ? "- None" : releaseLinks.join("\n"))
|
|
.replaceAll("{{PLATFORM_TABLE}}", platformTable)
|
|
.replaceAll("{{REPORT_TABLE}}", reportTable)
|
|
.replaceAll("{{GITHUB_RELEASE_SECTION}}", githubReleaseSection);
|
|
|
|
console.log(output.trimEnd());
|
|
NODE
|