Chore: update changelog workflow (#90608)

* try integrating

* pass tags

* change section order

* use better terminology

* one more attempt

* keep delimiters

* attempt to patch changelog

* quotes, bash quotes...

* use proper content file

* parens around date

* time for a pr

* first checkout, then create user

* add latest input

* git push

* use square brackets

* formatting

* update release-pr

* fix typo

* try sparse checkout

* fetch depth zero

* clean up after changelog generator
This commit is contained in:
Serge Zaitsev authored and GitHub committed 2024-07-19 18:27:59 +02:00
1 parent 8f54e3bfb7
commit f8b092aba6
4 files changed
+171 -51

No files matched your search

@@ -1,13 +1,13 @@
name: Changelog generator
description: Generates and publishes a changelog for the given release version
inputs:
version:
description: Version number
target:
description: Target tag, branch or commit hash for the changelog
required: true
prev_version:
description: Previous version number
previous:
description: Previous tag, branch or commit hash to start changelog from
required: false
token:
github_token:
description: GitHub token with read/write access to all necessary repositories
required: true
output_file:
+29 -27
View File
@@ -52,17 +52,20 @@ const getPreviousVersion = async (version) => {
.filter((tag) => tag)
.sort(semverCompare)
.find((tag) => semverCompare(tag, semverParse(version)) > 0);
return prev;
if (!prev) {
throw `Could not find previous git tag for ${version}`;
}
return prev[4];
};
// A helper for Github GraphQL API endpoint
const graphql = async (token, query, variables) => {
const graphql = async (ghtoken, query, variables) => {
const { env } = process;
const results = await fetch('https://api.github.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
Authorization: `Bearer ${ghtoken}`,
},
body: JSON.stringify({ query, variables }),
});
@@ -76,7 +79,7 @@ const graphql = async (token, query, variables) => {
// "commitish" items and get a list of PRs in between them.
const getCommitishDate = async (name, owner, target) => {
const result = await graphql(
token,
ghtoken,
`
query getCommitDate($owner: String!, $name: String!, $target: String!) {
repository(owner: $owner, name: $name) {
@@ -96,9 +99,8 @@ const getCommitishDate = async (name, owner, target) => {
// Using Github GraphQL API get a list of PRs between the two "commitish" items.
// This resoves the "since" item's timestamp first and iterates over all PRs
// till "target" using naïve pagination.
const getHistory = async (name, owner, target, since) => {
const sinceDate = await getCommitishDate(name, owner, since);
LOG(`Fetching ${owner}/${name} PRs since ${since} (${sinceDate}) till ${target}`);
const getHistory = async (name, owner, target, sinceDate) => {
LOG(`Fetching ${owner}/${name} PRs since ${sinceDate} till ${target}`);
const query = `
query findCommitsWithAssociatedPullRequests(
$name: String!
@@ -150,7 +152,7 @@ const getHistory = async (name, owner, target, since) => {
let cursor;
let nodes = [];
for (;;) {
const result = await graphql(token, query, {
const result = await graphql(ghtoken, query, {
name,
owner,
target,
@@ -173,11 +175,11 @@ const getHistory = async (name, owner, target, since) => {
// feature, deprecation, breaking change and plugin fixes/enhancements).
//
// PR grouping relies on Github labels only, not on the PR contents.
const getChangeLogItems = async (name, owner, from, to) => {
const getChangeLogItems = async (name, owner, sinceDate, to) => {
// check if a node contains a certain label
const hasLabel = ({ labels }, label) => labels.nodes.some(({ name }) => name === label);
// get all the PRs between the two "commitish" items
const history = await getHistory(name, owner, to, from);
const history = await getHistory(name, owner, to, sinceDate);
const items = history.flatMap((node) => {
// discard PRs without a "changelog" label
@@ -216,20 +218,26 @@ const getChangeLogItems = async (name, owner, from, to) => {
// ======================================================
LOG(`Changelog action started`);
const version = process.argv[2] || process.env.INPUT_VERSION;
LOG(`Target version: ${version}`);
const prevVersion = process.argv[3] || process.env.INPUT_PREV_VERSION || (await getPreviousVersion(version));
LOG(`Previous version: ${prevVersion}`);
const token = process.env.GITHUB_TOKEN || process.env.INPUT_TOKEN;
if (!token) {
throw 'GITHUB_TOKEN is not set and "token" input is empty';
const ghtoken = process.env.GITHUB_TOKEN || process.env.INPUT_GITHUB_TOKEN;
if (!ghtoken) {
throw 'GITHUB_TOKEN is not set and "github_token" input is empty';
}
const target = process.argv[2] || process.env.INPUT_TARGET;
LOG(`Target tag/branch/commit: ${target}`);
const previous = process.argv[3] || process.env.INPUT_PREVIOUS || (await getPreviousVersion(target));
LOG(`Previous tag/commit: ${previous}`);
const sinceDate = await getCommitishDate('grafana', 'grafana', previous);
LOG(`Previous tag/commit timestamp: ${sinceDate}`);
// Get all changelog items from Grafana OSS
const oss = await getChangeLogItems('grafana', 'grafana', prevVersion, version);
const oss = await getChangeLogItems('grafana', 'grafana', sinceDate, target);
// Get all changelog items from Grafana Enterprise
const entr = await getChangeLogItems('grafana-enterprise', 'grafana', prevVersion, version);
const entr = await getChangeLogItems('grafana-enterprise', 'grafana', sinceDate, target);
LOG(`Found OSS PRs: ${oss.length}`);
LOG(`Found Enterprise PRs: ${entr.length}`);
@@ -251,13 +259,10 @@ const changelog = [...oss, ...entr]
return changelog;
},
{
version,
breaking: [],
plugins: [],
bugfixes: [],
features: [],
// looks like JS doesn't have a nicer way to format date as YYYY-MM-DD
releaseDate: new Date().toISOString().split('T')[0],
}
);
@@ -287,12 +292,10 @@ ${items
`;
// Render all present sections for the given changelog
return `# ${changelog.version} (${changelog.releaseDate})
${section('Breaking changes', changelog.breaking)}
return `${section('Features and enhancements', changelog.features)}
${section('Bug fixes', changelog.bugfixes)}
${section('Breaking changes', changelog.breaking)}
${section('Plugin development fixes & changes', changelog.plugins)}
${section('Features and enhancements', changelog.features)}
`;
};
@@ -314,4 +317,3 @@ if (process.env.INPUT_OUTPUT_FILE) {
LOG(`Output to ${process.env.INPUT_OUTPUT_FILE}`);
writeFileSync(process.env.INPUT_OUTPUT_FILE, md);
}