Track merge commits to correctly identify releases

This commit is contained in:
Yuri Sizov
2023-03-23 14:52:26 +01:00
parent eee4aaf526
commit 02746a9cda
3 changed files with 70 additions and 24 deletions

View File

@@ -28,6 +28,7 @@ const API_RATE_LIMIT = `
`;
const GIT_HEAD_COMMIT_RE = RegExp("^commit ([a-zA-Z0-9-_]+)$");
const GIT_HEAD_MERGE_RE = RegExp("^Merge: (.+) (.+)$");
const GIT_HEAD_AUTHOR_RE = RegExp("^Author: (.+)$");
const GIT_HEAD_COMMITTER_RE = RegExp("^Commit: (.+)$");
const GIT_BODY_LINE_RE = RegExp("^[\\s]{2,}(.*)$");
@@ -98,7 +99,7 @@ class DataFetcher {
async countCommitHistory(fromCommit, toCommit) {
try {
const { stdout, stderr } = await exec(`git log --pretty=oneline --no-merges ${fromCommit}..${toCommit}`, { cwd: `./temp/${this.data_repo}` });
const { stdout, stderr } = await exec(`git log --pretty=oneline ${fromCommit}..${toCommit}`, { cwd: `./temp/${this.data_repo}` });
const commitHistory = stdout.trimEnd();
await this._logResponse(commitHistory, "_commit_shortlog", LogFormat.Raw);
@@ -112,7 +113,7 @@ class DataFetcher {
async getCommitHistory(fromCommit, toCommit) {
try {
const { stdout, stderr } = await exec(`git log --pretty=full --no-merges ${fromCommit}..${toCommit}`, { cwd: `./temp/${this.data_repo}` });
const { stdout, stderr } = await exec(`git log --pretty=full ${fromCommit}..${toCommit}`, { cwd: `./temp/${this.data_repo}` });
const commitHistory = stdout;
await this._logResponse(commitHistory, "_commit_history", LogFormat.Raw);
@@ -312,6 +313,7 @@ class DataProcessor {
_getCommitObject() {
return {
"hash": "",
"is_merge": false,
"authored_by": [],
"author_raw": "",
@@ -426,6 +428,13 @@ class DataProcessor {
continue;
}
// Check if this is a merge commit.
matches = line.match(GIT_HEAD_MERGE_RE);
if (matches) {
commit.is_merge = true;
continue;
}
// Parse the authorship information.
matches = line.match(GIT_HEAD_AUTHOR_RE);
if (matches) {
@@ -483,8 +492,6 @@ class DataProcessor {
console.error(` Error parsing commit log: Expected to received ${logSize} commits, but got ${this.log.length} instead.`);
process.exitCode = ExitCodes.ParseFailure;
}
return Object.keys(this.commits);
}
processCommits(commitsRaw, targetRepo) {
@@ -576,6 +583,21 @@ class DataProcessor {
process.exitCode = ExitCodes.ParseFailure;
}
}
getCommitHashes() {
const commitHashes = [];
for (let commitHash in this.commits) {
const commit = this.commits[commitHash];
if (commit.is_merge) {
continue;
}
commitHashes.push(commitHash);
}
return commitHashes;
}
}
class DataIO {
@@ -755,9 +777,13 @@ async function main() {
// cherry-pick, and not the original commit. We can rely on the commit message body
// containing a certain string, from which we can take the original commit hash.
const commitHashes = dataProcessor.processLog(commitLog, commitLogSize);
dataProcessor.processLog(commitLog, commitLogSize);
checkForExit();
// This method returns only non-merge commits; we don't need to fetch anything about
// merge commits. We only need them for commit history.
const commitHashes = dataProcessor.getCommitHashes();
// Third, we generate a query to the GraphQL API to fetch the information about
// linked PRs. GraphQL API doesn't have a filter to extract data for a list of
// commit hashes, but it supports having multiple sub-queries within the same request,

View File

@@ -2,22 +2,26 @@
"name": "4.0.1",
"ref": "4.0.1-stable",
"from_ref": "4.0-stable",
"article": "https://godotengine.org/article/maintenance-release-godot-4-0-1/",
"releases": [
{
"name": "rc1",
"ref": "d23922ffebe48f29126c003411495737d07e5a9f",
"from_ref": "4.0-stable"
"from_ref": "4.0-stable",
"article": "https://godotengine.org/article/release-candidate-godot-4-0-1-rc-1/"
},
{
"name": "rc2",
"ref": "6970257cffc6790f4d7e847e87e5cab9e252874e",
"from_ref": "d23922ffebe48f29126c003411495737d07e5a9f"
"from_ref": "d23922ffebe48f29126c003411495737d07e5a9f",
"article": "https://godotengine.org/article/release-candidate-godot-4-0-1-rc-2/"
},
{
"name": "stable",
"ref": "4.0.1-stable",
"from_ref": "6970257cffc6790f4d7e847e87e5cab9e252874e"
"from_ref": "6970257cffc6790f4d7e847e87e5cab9e252874e",
"article": "https://godotengine.org/article/maintenance-release-godot-4-0-1/"
}
]
}

View File

@@ -116,13 +116,25 @@ export default class EntryComponent extends LitElement {
const [...commitLog] = versionData.log;
commitLog.reverse();
version.commit_log = commitLog;
// We need to filter out all merge commits for display and the count.
version.commit_log = [];
commitLog.forEach((commitHash) => {
const commit = versionData.commits[commitHash];
if (commit.is_merge) {
return; // Continue.
}
version.commit_log.push(commitHash);
});
version.releases.forEach((release) => {
release.commit_log = [];
let counting = false;
commitLog.forEach((commitHash, index) => {
if (counting) {
const commit = versionData.commits[commitHash];
// We need to filter out all merge commits for display and the count.
if (counting && !commit.is_merge) {
release.commit_log.push(commitHash);
}
@@ -133,8 +145,12 @@ export default class EntryComponent extends LitElement {
if (release.from_ref === version.from_ref && index === 0) {
counting = true;
// HACK: Exclude the lower end by default, but include for the first range.
if (!commit.is_merge) {
// It shouldn't be possible for the first commit to be a merge commit,
// but let's guard anyway.
release.commit_log.push(commitHash);
}
}
else if (commitHash === release.from_ref) {
counting = true;
}