128 lines · 3.2 KB · Text
RawDownload
#!/usr/bin/env node --redirect-warnings=/dev/null const { execFileSync } = require("child_process"); main(); async function main() {  let version = process.argv[2];  let channel = process.argv[3];  let parts = version.split(".");   if (    process.argv.length != 4 ||    parts.length != 3 ||    parts.find((part) => isNaN(part)) != null ||    (channel != "stable" && channel != "preview")  ) {    console.log("Usage: draft-release-notes <version> {stable|preview}");    process.exit(1);  }   // currently we can only draft notes for patch releases.  if (parts[2] == 0) {    process.exit(0);  }   let priorVersion = [parts[0], parts[1], parts[2] - 1].join(".");  let suffix = channel == "preview" ? "-pre" : "";  let [tag, priorTag] = [`v${version}${suffix}`, `v${priorVersion}${suffix}`];   try {    execFileSync("rm", ["-rf", "target/shallow_clone"]);    execFileSync("git", [      "clone",      "https://github.com/zed-industries/zed",      "target/shallow_clone",      "--filter=tree:0",      "--no-checkout",      "--branch",      tag,      "--depth",      100,    ]);    execFileSync("git", [      "-C",      "target/shallow_clone",      "rev-parse",      "--verify",      tag,    ]);    execFileSync("git", [      "-C",      "target/shallow_clone",      "rev-parse",      "--verify",      priorTag,    ]);  } catch (e) {    console.error(e.stderr.toString());    process.exit(1);  }   const newCommits = getCommits(priorTag, tag);   let releaseNotes = [];  let missing = [];  let skipped = [];   for (const commit of newCommits) {    let link = "https://github.com/zed-industries/zed/pull/" + commit.pr;    let notes = commit.releaseNotes;    if (commit.pr == "") {      link = "https://github.com/zed-industries/zed/commits/" + commit.hash;    } else if (!notes.includes("zed-industries/zed/issues")) {      notes = notes + " ([#" + commit.pr + "](" + link + "))";    }     if (commit.releaseNotes == "") {      missing.push("- MISSING " + commit.firstLine + " " + link);    } else if (commit.releaseNotes.startsWith("- N/A")) {      skipped.push("- N/A " + commit.firstLine + " " + link);    } else {      releaseNotes.push(notes);    }  }   console.log(releaseNotes.join("\n") + "\n");} function getCommits(oldTag, newTag) {  const pullRequestNumbers = execFileSync(    "git",    [      "-C",      "target/shallow_clone",      "log",      `${oldTag}..${newTag}`,      "--format=DIVIDER\n%H|||%B",    ],    { encoding: "utf8" },  )    .replace(/\r\n/g, "\n")    .split("DIVIDER\n")    .filter((commit) => commit.length > 0)    .map((commit) => {      let [hash, firstLine] = commit.split("\n")[0].split("|||");      let cherryPick = firstLine.match(/\(cherry-pick #([0-9]+)\)/)?.[1] || "";      let pr = firstLine.match(/\(#(\d+)\)$/)?.[1] || "";      let releaseNotes = (commit.split(/Release notes:.*\n/i)[1] || "")        .split("\n\n")[0]        .trim()        .replace(/\n(?![\n-])/g, " ");       if (releaseNotes.includes("<public_issue_number_if_exists>")) {        releaseNotes = "";      }       return {        hash,        pr,        cherryPick,        releaseNotes,        firstLine,      };    });   return pullRequestNumbers;}