Skip to content

Commit 9f28f09

Browse files
committed
Merge branch 'initialize-git-notes'
2 parents 90b585b + 6c98229 commit 9f28f09

File tree

5 files changed

+85
-1
lines changed

5 files changed

+85
-1
lines changed

initialize-git-notes/action.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: 'Initialize the Git notes'
2+
description: 'Creates initial, mostly empty Git notes for GitGitGadget to store its state in.'
3+
author: 'Johannes Schindelin'
4+
inputs:
5+
config:
6+
description: 'The GitGitGadget configuration to use (see https://github.com/gitgitgadget/gitgitgadget/blob/HEAD/lib/project-config.ts)'
7+
default: '' # sadly, ${{ vars.CONFIG }} does not work, and documentation about what contexts are permissible here is sorely missing
8+
pr-repo-token:
9+
description: 'The access token to work on the repository that holds PRs and state'
10+
required: true
11+
initial-user:
12+
description: 'The user that is initially the only one allowed to use GitGitGadget in the given project'
13+
default: ${{ github.actor }}
14+
required: true
15+
runs:
16+
using: 'node20'
17+
main: './index.js'
18+
branding:
19+
icon: 'git-commit'
20+
color: 'orange'

initialize-git-notes/index.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
async function run() {
2+
const { CIHelper } = await import("../dist/index.js")
3+
4+
const ci = new CIHelper()
5+
6+
await ci.setupGitHubAction({
7+
createGitNotes: true,
8+
})
9+
}
10+
11+
run()

lib/ci-helper.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ export class CIHelper {
103103
needsUpstreamBranches?: boolean;
104104
needsMailToCommitNotes?: boolean;
105105
createOrUpdateCheckRun?: boolean | "post";
106+
createGitNotes?: boolean;
106107
}): Promise<void> {
107108
// configure the Git committer information
108109
process.env.GIT_CONFIG_PARAMETERS = [
@@ -136,6 +137,9 @@ export class CIHelper {
136137
}
137138

138139
if (setupOptions?.createOrUpdateCheckRun) {
140+
if (setupOptions?.createGitNotes) {
141+
throw new Error(`Cannot use createOrUpdateCheckRun and createGitNotes at the same time`);
142+
}
139143
return await this.createOrUpdateCheckRun(setupOptions.createOrUpdateCheckRun === "post");
140144
}
141145

@@ -169,6 +173,47 @@ export class CIHelper {
169173
]) {
170174
await git(["config", key, value], { workDir: this.workDir });
171175
}
176+
if (setupOptions?.createGitNotes) {
177+
if (
178+
setupOptions.needsMailToCommitNotes ||
179+
setupOptions.needsUpstreamBranches ||
180+
setupOptions.needsMailingListMirror
181+
) {
182+
throw new Error("`createGitNotes` cannot be combined with any other options");
183+
}
184+
const initialUser = core.getInput("initial-user");
185+
console.time("verify that Git notes do not yet exist");
186+
const existingNotes = await git(
187+
[
188+
"ls-remote",
189+
"origin",
190+
GitNotes.defaultNotesRef,
191+
"refs/notes/mail-to-commit",
192+
"refs/notes/commit-to-mail",
193+
],
194+
{
195+
workDir: this.workDir,
196+
},
197+
);
198+
if (existingNotes !== "") {
199+
throw new Error(`Git notes already exist in ${this.workDir}:\n${existingNotes}`);
200+
}
201+
console.timeEnd("verify that Git notes do not yet exist");
202+
console.time("create the initial Git notes and push them");
203+
for (const key of ["mail-to-commit", "commit-to-mail"]) {
204+
const notes = new GitNotes(this.workDir, `refs/notes/${key}`);
205+
await notes.initializeWithEmptyCommit();
206+
await notes.push(this.urlRepo, this.notesPushToken);
207+
}
208+
const options: IGitGitGadgetOptions = {
209+
allowedUsers: [initialUser],
210+
};
211+
await this.notes.set("", options, true);
212+
await this.notes.push(this.urlRepo, this.notesPushToken);
213+
console.timeEnd("create the initial Git notes and push them");
214+
return;
215+
}
216+
172217
console.time("fetch Git notes");
173218
const notesRefs = [GitNotes.defaultNotesRef];
174219
if (setupOptions?.needsMailToCommitNotes) {

lib/git-notes.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@ export class GitNotes {
120120
return notes.replace(/^[^]*\n\n/, "");
121121
}
122122

123+
public async initializeWithEmptyCommit(): Promise<void> {
124+
const emptyTree = await git(["hash-object", "-t", "tree", "--stdin"], { stdin: "", workDir: this.workDir });
125+
const emptyCommit = await git(["commit-tree", "-m", "Initial empty commit", emptyTree], {
126+
workDir: this.workDir,
127+
});
128+
await git(["update-ref", this.notesRef, emptyCommit, ""], { workDir: this.workDir });
129+
}
130+
123131
public async update(url: string): Promise<void> {
124132
if (this.notesRef.match(/^refs\/notes\/(gitgitgadget|commit-to-mail|mail-to-commit)$/)) {
125133
await git(["fetch", "--no-tags", url, `+${this.notesRef}:${this.notesRef}`], { workDir: this.workDir });

lib/mail-archive-helper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ export class MailArchiveGitHelper {
269269
throw new Error(
270270
[
271271
"Mail archive email commit tip not set. ",
272-
"Please run `misc-helper init-email-commit-tip` to set the value.",
272+
"Please run the `initialize-git-notes` workflow to set the value.",
273273
].join(""),
274274
);
275275
}

0 commit comments

Comments
 (0)