Skip to content

Commit

Permalink
Improve release note automation for monorepo (#1420)
Browse files Browse the repository at this point in the history
  • Loading branch information
vinistock authored Feb 28, 2024
1 parent 1000ae5 commit 97dd8ad
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 25 deletions.
22 changes: 0 additions & 22 deletions .github/release.yml

This file was deleted.

69 changes: 68 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ on:
types: [published]

jobs:
release:
publish:
if: ${{ startsWith(github.ref, 'refs/tags/vscode-ruby-lsp') }}
runs-on: ubuntu-latest

steps:
Expand Down Expand Up @@ -78,3 +79,69 @@ jobs:
run: |
yarn run package
node_modules/.bin/ovsx publish vscode-ruby-lsp.vsix -p ${{ secrets.OPENVSX_TOKEN }} --yarn
- name: Update release notes
uses: actions/github-script@v6
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
script: |
const { data } = await github.rest.repos.listReleases({
owner: context.repo.owner,
repo: context.repo.repo,
});
const previousRelease = data.find((release) => release.tag_name.startsWith("vscode-ruby-lsp"));
const { data: commits } = await github.rest.repos.compareCommits({
owner: context.repo.owner,
repo: context.repo.repo,
base: previousRelease.tag_name,
head: "${{ github.ref }}"
});
const pullRequests = commits.map((commit) => {
const { data: response } = await octokit.request(`GET /repos/shopify/ruby-lsp/commits/${commit.sha}/pulls`);
{ title: response.title, url: response.html_url, labels: response.labels.map((label) => label.name) }
});
const relevantPulls = pullRequests.filter((pull) => {
return pull.labels.some((label) => label === "vscode") &&
!pull.labels.some((label) => label === "dependencies") &&
!pull.labels.some((label) => label === "chore")
});
const breakingChanges = relevantPulls.filter((pull) => pull.labels.some((label) => label === "breaking-change"));
const bugFixes = relevantPulls.filter((pull) => pull.labels.some((label) => label === "bugfix"));
const enhancements = relevantPulls.filter((pull) => pull.labels.some((label) => label === "enhancement"));
const otherChanges = relevantPulls.filter((pull) => !pull.labels.some((label) => ["bugfix", "enhancement", "breaking-change"].includes(label)));
const content = `# ${{ github.ref_name }}\n`;
if (breakingChanges.length > 0) {
content += `## 🚧 Breaking Changes\n\n${breakingChanges.map((pull) => `- ${pull.title} (${pull.url})`).join("\n")}\n\n`;
}
if (enhancements.length > 0) {
content += `## ✨ Enhancements\n\n${enhancements.map((pull) => `- ${pull.title} (${pull.url})`).join("\n")}\n\n`;
}
if (bugFixes.length > 0) {
content += `## 🐛 Bug Fixes\n\n${bugFixes.map((pull) => `- ${pull.title} (${pull.url})`).join("\n")}\n\n`;
}
if (otherChanges.length > 0) {
content += `## 📦 Other Changes\n\n${otherChanges.map((pull) => `- ${pull.title} (${pull.url})`).join("\n")}\n\n`;
}
const { data: id } = await github.rest.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag: "${{ github.ref }}",
});
await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: id,
body: content
});
53 changes: 51 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:

jobs:
publish:
if: ${{ ! startsWith(github.ref, 'refs/tags/vscode-ruby-lsp') }}
runs-on: ubuntu-latest

steps:
Expand All @@ -18,10 +19,58 @@ jobs:
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
script: |
const { data } = await github.rest.repos.listReleases({
owner: context.repo.owner,
repo: context.repo.repo,
});
const previousRelease = data.find((release) => !release.tag_name.startsWith("vscode-ruby-lsp"));
const { data: commits } = await github.rest.repos.compareCommits({
owner: context.repo.owner,
repo: context.repo.repo,
base: previousRelease.tag_name,
head: "${{ github.ref }}"
});
const pullRequests = commits.map((commit) => {
const { data: response } = await octokit.request(`GET /repos/shopify/ruby-lsp/commits/${commit.sha}/pulls`);
{ title: response.title, url: response.html_url, labels: response.labels.map((label) => label.name) }
});
const relevantPulls = pullRequests.filter((pull) => {
return pull.labels.some((label) => label === "server") &&
!pull.labels.some((label) => label === "dependencies") &&
!pull.labels.some((label) => label === "chore")
});
const breakingChanges = relevantPulls.filter((pull) => pull.labels.some((label) => label === "breaking-change"));
const bugFixes = relevantPulls.filter((pull) => pull.labels.some((label) => label === "bugfix"));
const enhancements = relevantPulls.filter((pull) => pull.labels.some((label) => label === "enhancement"));
const otherChanges = relevantPulls.filter((pull) => !pull.labels.some((label) => ["bugfix", "enhancement", "breaking-change"].includes(label)));
const content = `# ${{ github.ref_name }}\n`;
if (breakingChanges.length > 0) {
content += `## 🚧 Breaking Changes\n\n${breakingChanges.map((pull) => `- ${pull.title} (${pull.url})`).join("\n")}\n\n`;
}
if (enhancements.length > 0) {
content += `## ✨ Enhancements\n\n${enhancements.map((pull) => `- ${pull.title} (${pull.url})`).join("\n")}\n\n`;
}
if (bugFixes.length > 0) {
content += `## 🐛 Bug Fixes\n\n${bugFixes.map((pull) => `- ${pull.title} (${pull.url})`).join("\n")}\n\n`;
}
if (otherChanges.length > 0) {
content += `## 📦 Other Changes\n\n${otherChanges.map((pull) => `- ${pull.title} (${pull.url})`).join("\n")}\n\n`;
}
await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: "${{ github.ref }}",
name: "${{ github.ref_name }}",
generate_release_notes: true
})
body: content
});
44 changes: 44 additions & 0 deletions .github/workflows/require_labels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Pull Request Labels

on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]

jobs:
check-labels:
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@v4
- name: Check for Pull Request Labels
shell: bash
run: |
pr_labels=$(gh pr view --json labels --jq ".labels[] .name" ${{ github.event.pull_request.number }})
type_labels=("documentation" "bugfix" "chore" "enhancement" "dependencies" "breaking-change")
category_labels=("server" "vscode")
matched=0
for label in $pr_labels; do
if [[ "${type_labels[@]}" =~ "${label}" ]]; then
matched=1
break
fi
done
if [ $matched -eq 0 ]; then
echo "Please label this PR with one of the following types: ${type_labels[@]}"
exit 1
fi
for label in $pr_labels; do
if [[ "${category_labels[@]}" =~ "${label}" ]]; then
matched=1
break
fi
done
if [ $matched -eq 0 ]; then
echo "Please label this PR with one of the following categories: ${category_labels[@]}"
exit 1
fi

0 comments on commit 97dd8ad

Please sign in to comment.