Skip to content

Commit 06e50b0

Browse files
committed
release script
1 parent df6ce70 commit 06e50b0

1 file changed

Lines changed: 128 additions & 0 deletions

File tree

scripts/release.sh

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#!/bin/bash
2+
3+
# Refresh the JetBrains plugin change notes from the latest Zoo Code release,
4+
# then run the normal build with the same command-line arguments.
5+
6+
set -euo pipefail
7+
8+
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9+
readonly PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
10+
readonly PLUGIN_XML="$PROJECT_ROOT/jetbrains_plugin/src/main/resources/META-INF/plugin.xml"
11+
readonly ZOO_CODE_REPOSITORY="Zoo-Code-Org/Zoo-Code"
12+
readonly GITHUB_API="https://api.github.com"
13+
14+
DRY_RUN=false
15+
for argument in "$@"; do
16+
if [[ "$argument" == "-n" || "$argument" == "--dry-run" ]]; then
17+
DRY_RUN=true
18+
break
19+
fi
20+
done
21+
22+
log() {
23+
printf '[release] %s\n' "$1" >&2
24+
}
25+
26+
die() {
27+
printf '[release] ERROR: %s\n' "$1" >&2
28+
exit 1
29+
}
30+
31+
command -v curl >/dev/null 2>&1 || die "curl is required"
32+
command -v node >/dev/null 2>&1 || die "Node.js is required"
33+
[[ -f "$PLUGIN_XML" ]] || die "Plugin descriptor not found: $PLUGIN_XML"
34+
35+
temporary_directory="$(mktemp -d)"
36+
trap 'rm -rf "$temporary_directory"' EXIT
37+
38+
release_json="$temporary_directory/release.json"
39+
markdown_request="$temporary_directory/markdown-request.json"
40+
release_notes_html="$temporary_directory/release-notes.html"
41+
42+
github_headers=(
43+
-H "Accept: application/vnd.github+json"
44+
-H "X-GitHub-Api-Version: 2022-11-28"
45+
-H "User-Agent: Zoo-Code-JetBrains-release-script"
46+
)
47+
48+
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
49+
github_headers+=(-H "Authorization: Bearer $GITHUB_TOKEN")
50+
fi
51+
52+
log "Fetching the latest Zoo Code release"
53+
curl --fail --silent --show-error --location --retry 3 \
54+
"${github_headers[@]}" \
55+
"$GITHUB_API/repos/$ZOO_CODE_REPOSITORY/releases/latest" \
56+
--output "$release_json"
57+
58+
release_name="$(node - "$release_json" <<'NODE'
59+
const fs = require("fs");
60+
const release = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
61+
62+
if (!release.body || !release.body.trim()) {
63+
console.error("The latest Zoo Code release does not contain release notes");
64+
process.exit(1);
65+
}
66+
67+
process.stdout.write(release.name || release.tag_name || "latest release");
68+
NODE
69+
)" || die "Unable to read the latest Zoo Code release"
70+
71+
node - "$release_json" "$ZOO_CODE_REPOSITORY" > "$markdown_request" <<'NODE'
72+
const fs = require("fs");
73+
const release = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
74+
75+
process.stdout.write(JSON.stringify({
76+
text: release.body,
77+
mode: "gfm",
78+
context: process.argv[3],
79+
}));
80+
NODE
81+
82+
log "Rendering release notes for $release_name"
83+
curl --fail --silent --show-error --location --retry 3 \
84+
"${github_headers[@]}" \
85+
-H "Content-Type: application/json" \
86+
--request POST \
87+
--data-binary "@$markdown_request" \
88+
"$GITHUB_API/markdown" \
89+
--output "$release_notes_html"
90+
91+
[[ -s "$release_notes_html" ]] || die "GitHub returned empty rendered release notes"
92+
93+
if [[ "$DRY_RUN" == "true" ]]; then
94+
log "Dry run: would update change notes in $PLUGIN_XML"
95+
else
96+
node - "$PLUGIN_XML" "$release_notes_html" <<'NODE'
97+
const fs = require("fs");
98+
99+
const pluginXmlPath = process.argv[2];
100+
const releaseNotesPath = process.argv[3];
101+
const pluginXml = fs.readFileSync(pluginXmlPath, "utf8");
102+
const releaseNotes = fs.readFileSync(releaseNotesPath, "utf8").trim();
103+
const changeNotesPattern = /(<change-notes><!\[CDATA\[)[\s\S]*?(\]\]><\/change-notes>)/;
104+
105+
if (!changeNotesPattern.test(pluginXml)) {
106+
console.error(`Could not find the <change-notes> CDATA block in ${pluginXmlPath}`);
107+
process.exit(1);
108+
}
109+
110+
// Keep the descriptor readable and prevent release text from closing its CDATA block.
111+
const indentedNotes = releaseNotes
112+
.replaceAll("]]>", "]]&gt;")
113+
.split("\n")
114+
.map(line => ` ${line}`)
115+
.join("\n");
116+
const updatedPluginXml = pluginXml.replace(
117+
changeNotesPattern,
118+
`$1\n${indentedNotes}\n $2`,
119+
);
120+
121+
fs.writeFileSync(pluginXmlPath, updatedPluginXml);
122+
NODE
123+
124+
log "Updated JetBrains change notes from $release_name"
125+
fi
126+
127+
log "Running the build script"
128+
exec "$SCRIPT_DIR/build.sh" "$@"

0 commit comments

Comments
 (0)