@dbx-tools/projen 0.9.68 → 0.9.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.ts +1 -1
- package/package.json +4 -4
- package/tasks/release.ts +111 -9
package/index.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
|
|
5
5
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/projen";
|
|
6
|
-
export const PACKAGE_VERSION = "0.9.
|
|
6
|
+
export const PACKAGE_VERSION = "0.9.69";
|
|
7
7
|
export * as barrels from "./src/barrels.ts";
|
|
8
8
|
export * as bunApp from "./src/bun-app.ts";
|
|
9
9
|
export * as bunWorkflow from "./src/bun-workflow.ts";
|
package/package.json
CHANGED
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@clack/prompts": "^1.7.0",
|
|
33
|
-
"@dbx-tools/core": "^0.9.
|
|
34
|
-
"@dbx-tools/path": "^0.9.
|
|
35
|
-
"@dbx-tools/shared-core": "^0.9.
|
|
33
|
+
"@dbx-tools/core": "^0.9.69",
|
|
34
|
+
"@dbx-tools/path": "^0.9.69",
|
|
35
|
+
"@dbx-tools/shared-core": "^0.9.69",
|
|
36
36
|
"commander": "^15.0.0",
|
|
37
37
|
"concurrently": "^10.0.3",
|
|
38
38
|
"constructs": "^10.6.0",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"main": "index.ts",
|
|
56
56
|
"license": "Apache-2.0",
|
|
57
|
-
"version": "0.9.
|
|
57
|
+
"version": "0.9.69",
|
|
58
58
|
"types": "index.ts",
|
|
59
59
|
"type": "module",
|
|
60
60
|
"exports": {
|
package/tasks/release.ts
CHANGED
|
@@ -41,6 +41,106 @@ function assertAncestor(root: string, ancestor: string, descendant: string, mess
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
/** Parse a GitHub repository slug from an HTTPS or SSH remote URL. */
|
|
45
|
+
export function githubRepositoryFromRemoteUrl(remoteUrl: string): string | undefined {
|
|
46
|
+
const value = remoteUrl.trim().replace(/\.git$/, "");
|
|
47
|
+
const https = /^https?:\/\/github\.com\/([^/]+)\/([^/]+)$/i.exec(value);
|
|
48
|
+
if (https) return `${https[1]}/${https[2]}`;
|
|
49
|
+
const ssh = /^(?:ssh:\/\/)?git@([^/:]+)[:/]([^/]+)\/([^/]+)$/i.exec(value);
|
|
50
|
+
if (!ssh || !/^github(?:[.-].+)?$/i.test(ssh[1]!)) return undefined;
|
|
51
|
+
return `${ssh[2]}/${ssh[3]}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Infer the `gh auth` account encoded by a `git@github-<account>:` SSH alias. */
|
|
55
|
+
export function githubAccountFromRemoteUrl(remoteUrl: string): string | undefined {
|
|
56
|
+
return /^git@github-([^:]+):/i.exec(remoteUrl.trim())?.[1];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function githubApiEnvironment(root: string, remoteUrl: string): NodeJS.ProcessEnv | undefined {
|
|
60
|
+
const account = githubAccountFromRemoteUrl(remoteUrl);
|
|
61
|
+
if (!account) return undefined;
|
|
62
|
+
const token = captureTaskCommand(
|
|
63
|
+
root,
|
|
64
|
+
"gh",
|
|
65
|
+
["auth", "token", "--hostname", "github.com", "--user", account],
|
|
66
|
+
{ check: true, stderr: "inherit" },
|
|
67
|
+
);
|
|
68
|
+
return token ? { ...process.env, GH_TOKEN: token } : undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function pushAnnotatedReleaseTag(options: {
|
|
72
|
+
readonly annotation: string;
|
|
73
|
+
readonly branch: string;
|
|
74
|
+
readonly head: string;
|
|
75
|
+
readonly remote: string;
|
|
76
|
+
readonly root: string;
|
|
77
|
+
readonly tag: string;
|
|
78
|
+
}): void {
|
|
79
|
+
const { annotation, branch, head, remote, root, tag } = options;
|
|
80
|
+
runTaskCommand(root, "git", ["tag", "--annotate", tag, "--message", annotation]);
|
|
81
|
+
const remoteUrl = captureTaskCommand(root, "git", ["remote", "get-url", remote], {
|
|
82
|
+
check: true,
|
|
83
|
+
});
|
|
84
|
+
const repository = githubRepositoryFromRemoteUrl(remoteUrl);
|
|
85
|
+
if (!repository || !taskCommandSucceeds(root, "gh", ["--version"])) {
|
|
86
|
+
runTaskCommand(root, "git", ["push", remote, `refs/tags/${tag}`]);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const githubEnv = githubApiEnvironment(root, remoteUrl);
|
|
90
|
+
|
|
91
|
+
const remoteBranch = captureTaskCommand(
|
|
92
|
+
root,
|
|
93
|
+
"git",
|
|
94
|
+
["ls-remote", remote, `refs/heads/${branch}`],
|
|
95
|
+
{ check: true },
|
|
96
|
+
)
|
|
97
|
+
.split(/\s+/)[0]
|
|
98
|
+
?.trim();
|
|
99
|
+
if (remoteBranch !== head) {
|
|
100
|
+
throw new Error(`cannot tag ${repository}: ${remote}/${branch} does not equal local HEAD`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const tagObject = captureTaskCommand(
|
|
104
|
+
root,
|
|
105
|
+
"gh",
|
|
106
|
+
[
|
|
107
|
+
"api",
|
|
108
|
+
"--method",
|
|
109
|
+
"POST",
|
|
110
|
+
`repos/${repository}/git/tags`,
|
|
111
|
+
"-f",
|
|
112
|
+
`tag=${tag}`,
|
|
113
|
+
"-f",
|
|
114
|
+
`message=${annotation}`,
|
|
115
|
+
"-f",
|
|
116
|
+
`object=${head}`,
|
|
117
|
+
"-f",
|
|
118
|
+
"type=commit",
|
|
119
|
+
"--jq",
|
|
120
|
+
".sha",
|
|
121
|
+
],
|
|
122
|
+
{ check: true, env: githubEnv, stderr: "inherit" },
|
|
123
|
+
);
|
|
124
|
+
if (!tagObject) throw new Error(`GitHub did not return an annotated tag object for ${tag}`);
|
|
125
|
+
runTaskCommand(
|
|
126
|
+
root,
|
|
127
|
+
"gh",
|
|
128
|
+
[
|
|
129
|
+
"api",
|
|
130
|
+
"--method",
|
|
131
|
+
"POST",
|
|
132
|
+
`repos/${repository}/git/refs`,
|
|
133
|
+
"-f",
|
|
134
|
+
`ref=refs/tags/${tag}`,
|
|
135
|
+
"-f",
|
|
136
|
+
`sha=${tagObject}`,
|
|
137
|
+
"--silent",
|
|
138
|
+
],
|
|
139
|
+
{ env: githubEnv },
|
|
140
|
+
);
|
|
141
|
+
logger.info(`created ${tag} through the GitHub API`, { repository, sha: head });
|
|
142
|
+
}
|
|
143
|
+
|
|
44
144
|
function prepareReleaseBranch(options: {
|
|
45
145
|
readonly branch: string;
|
|
46
146
|
readonly remote: string;
|
|
@@ -191,17 +291,19 @@ export async function runRelease(
|
|
|
191
291
|
}
|
|
192
292
|
|
|
193
293
|
runTaskCommand(root, "git", ["push", remote, `HEAD:${branch}`]);
|
|
194
|
-
runTaskCommand(root, "git", [
|
|
195
|
-
"tag",
|
|
196
|
-
"--annotate",
|
|
197
|
-
tag,
|
|
198
|
-
"--message",
|
|
199
|
-
releaseTagAnnotation(tag, selection),
|
|
200
|
-
]);
|
|
201
294
|
try {
|
|
202
|
-
|
|
295
|
+
pushAnnotatedReleaseTag({
|
|
296
|
+
annotation: releaseTagAnnotation(tag, selection),
|
|
297
|
+
branch,
|
|
298
|
+
head,
|
|
299
|
+
remote,
|
|
300
|
+
root,
|
|
301
|
+
tag,
|
|
302
|
+
});
|
|
203
303
|
} catch (error) {
|
|
204
|
-
|
|
304
|
+
if (taskCommandSucceeds(root, "git", ["rev-parse", "--verify", `refs/tags/${tag}`])) {
|
|
305
|
+
runTaskCommand(root, "git", ["tag", "--delete", tag]);
|
|
306
|
+
}
|
|
205
307
|
throw error;
|
|
206
308
|
}
|
|
207
309
|
logger.success(`released ${tag}`, { sha: head });
|