Have the CI server draft the release notes (#10700)
While I don't expect these to be useful for our weekly minor releases, I hope that this will save a step for people doing mid-week patches. Release Notes: - N/A
This commit is contained in:
parent
41c8f2caa6
commit
4c3178e7a8
3 changed files with 127 additions and 11 deletions
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
|
@ -205,6 +205,7 @@ jobs:
|
||||||
echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
|
echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
script/draft-release-notes "$version" "$channel" > target/release-notes.md
|
||||||
|
|
||||||
- name: Generate license file
|
- name: Generate license file
|
||||||
run: script/generate-licenses
|
run: script/generate-licenses
|
||||||
|
@ -248,7 +249,7 @@ jobs:
|
||||||
target/aarch64-apple-darwin/release/Zed-aarch64.dmg
|
target/aarch64-apple-darwin/release/Zed-aarch64.dmg
|
||||||
target/x86_64-apple-darwin/release/Zed-x86_64.dmg
|
target/x86_64-apple-darwin/release/Zed-x86_64.dmg
|
||||||
target/release/Zed.dmg
|
target/release/Zed.dmg
|
||||||
body: ""
|
body_file: target/release-notes.md
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
|
|
@ -17,25 +17,31 @@ You will need write access to the Zed repository to do this:
|
||||||
- Run `./script/bump-zed-minor-versions` and push the tags
|
- Run `./script/bump-zed-minor-versions` and push the tags
|
||||||
and branches as instructed.
|
and branches as instructed.
|
||||||
- Wait for the builds to appear at https://github.com/zed-industries/zed/releases (typically takes around 30 minutes)
|
- Wait for the builds to appear at https://github.com/zed-industries/zed/releases (typically takes around 30 minutes)
|
||||||
- Copy the release notes from the previous Preview release(s) to the current Stable release.
|
- While you're waiting:
|
||||||
- Write new release notes for Preview. `/script/get-preview-channel-changes` can help with this, but you'll need to edit and format the output to make it good.
|
- Start creating the new release notes for preview. You can start with the output of `./script/get-preview-channel-changes`.
|
||||||
- Download the artifacts for each release and test that you can run them locally.
|
- Start drafting the release tweets.
|
||||||
- Publish the releases.
|
- Once the builds are ready:
|
||||||
|
- Copy the release notes from the previous Preview release(s) to the current Stable release.
|
||||||
|
- Download the artifacts for each release and test that you can run them locally.
|
||||||
|
- Publish the releases on GitHub.
|
||||||
|
- Tweet the tweets (Credentials are in 1password).
|
||||||
|
|
||||||
## Patch release process
|
## Patch release process
|
||||||
|
|
||||||
If your PR fixes a panic or a crash, you should cherry-pick it to the current stable and preview branches. If your PR fixes a regression in recently released code, you should cherry-pick it to the appropriate branch.
|
If your PR fixes a panic or a crash, you should cherry-pick it to the current stable and preview branches. If your PR fixes a regression in recently released code, you should cherry-pick it to preview.
|
||||||
|
|
||||||
You will need write access to the Zed repository to do this:
|
You will need write access to the Zed repository to do this:
|
||||||
|
|
||||||
- Cherry pick them onto the correct branch. You can either do this manually, or leave a comment of the form `/cherry-pick v0.XXX.x` on the PR, and the GitHub bot should do it for you.
|
- Send a PR containing your change to `main` as normal.
|
||||||
- Run `./script/trigger-release {preview|stable}`
|
- Leave a comment on the PR `/cherry-pick v0.XXX.x`. Once your PR is merged, the Github bot will send a PR to the branch.
|
||||||
|
- In case of a merge conflict, you will have to cherry-pick manually and push the change to the `v0.XXX.x` branch.
|
||||||
|
- After the commits are cherry-picked onto the branch, run `./script/trigger-release {preview|stable}`. This will bump the version numbers, create a new release tag, and kick off a release build.
|
||||||
- Wait for the builds to appear at https://github.com/zed-industries/zed/releases (typically takes around 30 minutes)
|
- Wait for the builds to appear at https://github.com/zed-industries/zed/releases (typically takes around 30 minutes)
|
||||||
- Add release notes using the `Release notes:` section of each cherry-picked PR.
|
- Proof-read and edit the release notes as needed.
|
||||||
- Download the artifacts for each release and test that you can run them locally.
|
- Download the artifacts for each release and test that you can run them locally.
|
||||||
- Publish the release.
|
- Publish the release.
|
||||||
|
|
||||||
## Nightly release process
|
## Nightly release process
|
||||||
|
|
||||||
- Merge your changes to main
|
In addition to the public releases, we also have a nightly build that we encourage employees to use.
|
||||||
- Run `./script/trigger-release {nightly}`
|
Nightly is released by cron once a day, and can be shipped as often as you'd like. There are no release notes or announcements, so you can just merge your changes to main and run `./script/trigger-release nightly`.
|
||||||
|
|
109
script/draft-release-notes
Executable file
109
script/draft-release-notes
Executable file
|
@ -0,0 +1,109 @@
|
||||||
|
#!/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);
|
||||||
|
}
|
||||||
|
|
||||||
|
let priorVersion = [parts[0], parts[1], parts[2] - 1].join(".");
|
||||||
|
let suffix = "";
|
||||||
|
|
||||||
|
if (channel == "preview") {
|
||||||
|
suffix = "-pre";
|
||||||
|
if (parts[2] == 0) {
|
||||||
|
priorVersion = [parts[0], parts[1] - 1, 0].join(".");
|
||||||
|
}
|
||||||
|
} else if (!tagExists("v${priorVersion}")) {
|
||||||
|
console.log("Copy the release notes from preview.");
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let [tag, priorTag] = [`v${version}${suffix}`, `v${priorVersion}${suffix}`];
|
||||||
|
|
||||||
|
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");
|
||||||
|
console.log("<!-- ");
|
||||||
|
console.log(missing.join("\n"));
|
||||||
|
console.log(skipped.join("\n"));
|
||||||
|
console.log("-->");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCommits(oldTag, newTag) {
|
||||||
|
const pullRequestNumbers = execFileSync(
|
||||||
|
"git",
|
||||||
|
["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;
|
||||||
|
}
|
||||||
|
|
||||||
|
function tagExists(tag) {
|
||||||
|
try {
|
||||||
|
execFileSync("git", ["rev-parse", "--verify", tag]);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue