Files
open-design/.github/scripts/release/r2/summary.sh
PerishFireandGitHub 976edaf38e test: harden e2e smoke and release reports (#1140)
* test: harden e2e inspect specs

* test: wire e2e release reports

* chore: bump packaged beta base to 0.6.1

* test: run release smoke vitest directly

* test: add suite-owned tools-dev lifecycle

* ci: harden stable release packaging

* fix(release,e2e): gate stable signing on verify and harden suite cleanup

- restore `needs: [metadata, verify]` on the stable release `build_mac`,
  `build_mac_intel`, `build_win`, and `build_linux` jobs so Apple
  signing/notarization and Windows release builds cannot run before
  pnpm guard, typecheck, and layout checks complete on the metadata commit.
- in `runToolsDevSuite`, drop the `started` flag and always attempt
  `stopToolsDevWeb` in `finally`; record stop errors in diagnostics, and
  when the test body succeeded, escalate the stop failure to the suite
  result and rethrow — so orphan daemon/web processes from an interrupted
  `startToolsDevWeb` or a broken shutdown can no longer pass silently.

Addresses PR #1140 review feedback from lefarcen and mrcfps.
2026-05-11 13:11:16 +08:00

228 lines
7.3 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"),
};
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 }]),
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