1#!/usr/bin/env node --redirect-warnings=/dev/null
2
3// This script should be ran before `bump-zed-minor-versions`
4
5// Prints the changelogs for all preview releases associated with the most
6// recent preview minor version.
7
8// Future TODO: Have the script perform deduplication of lines that were
9// included in both past stable and preview patches that shouldn't be mentioned
10// again in this week's stable minor release.
11
12// Future TODO: Get changelogs for latest cherry-picked commits on preview and
13// stable that didn't make it into a release, as they were cherry picked
14
15const { execFileSync } = require("child_process");
16let { GITHUB_ACCESS_TOKEN } = process.env;
17const GITHUB_TAGS_API_URL = "https://api.github.com/repos/zed-industries/zed/releases/tags";
18const DIVIDER = "-".repeat(80);
19
20main();
21
22async function main() {
23 if (!GITHUB_ACCESS_TOKEN) {
24 try {
25 GITHUB_ACCESS_TOKEN = execFileSync("gh", ["auth", "token"]).toString();
26 } catch (error) {
27 console.log(error);
28 console.log("No GITHUB_ACCESS_TOKEN and no `gh auth token`");
29 process.exit(1);
30 }
31 }
32
33 const allTags = execFileSync("git", ["tag", "--sort", "-committerdate"], { encoding: "utf8" })
34 .split("\n")
35 .filter((t) => t.length > 0);
36 const latestPreviewTag = allTags.filter((t) => t.startsWith("v") && t.endsWith("-pre"))[0];
37 const latestPreviewMinorVersion = latestPreviewTag.split(".")[1];
38 const latestPreviewTagRegex = new RegExp(`^v(\\d+)\\.(${latestPreviewMinorVersion})\\.(\\d+)-pre$`);
39
40 const parsedPreviewTags = allTags
41 .map((tag) => {
42 const match = tag.match(latestPreviewTagRegex);
43 if (match) {
44 return {
45 tag,
46 version: {
47 major: parseInt(match[1]),
48 minor: parseInt(match[2]),
49 patch: parseInt(match[3]),
50 },
51 };
52 }
53 return null;
54 })
55 .filter((item) => item !== null)
56 .sort((a, b) => a.version.patch - b.version.patch);
57
58 const matchingPreviewTags = parsedPreviewTags.map((item) => item.tag);
59
60 console.log("Fetching release information for preview tags:");
61 console.log(DIVIDER);
62
63 for (const tag of matchingPreviewTags) {
64 const releaseApiUrl = `${GITHUB_TAGS_API_URL}/${tag}`;
65
66 try {
67 const response = await fetch(releaseApiUrl, {
68 headers: {
69 Authorization: `token ${GITHUB_ACCESS_TOKEN}`,
70 },
71 });
72
73 if (!response.ok) {
74 console.log(`Failed to fetch release for ${tag}: ${response.status}`);
75 continue;
76 }
77
78 const release = await response.json();
79
80 console.log(`\nRelease: ${release.name || tag}`);
81 console.log(`Tag: ${tag}`);
82 console.log(`Published: ${release.published_at}`);
83 console.log(`URL: ${release.html_url}`);
84 console.log("\nRelease Notes:");
85 console.log(release.body || "No release notes");
86 console.log(DIVIDER);
87 } catch (error) {
88 console.log(`Error fetching release for ${tag}:`, error.message);
89 }
90 }
91
92 const patchUpdateTags = parsedPreviewTags.filter((tag) => tag.version.patch != 0).map((tag) => tag.tag);
93
94 console.log();
95 console.log("Please review the release notes associated with the following patch versions:");
96 for (const tag of patchUpdateTags) {
97 console.log(`- ${tag}`);
98 }
99 console.log("Remove items that have already been mentioned in the current published stable versions.");
100 console.log("https://github.com/zed-industries/zed/releases?q=prerelease%3Afalse&expanded=true");
101}