@smoothbricks/cli 0.1.0 → 0.2.0
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/README.md +338 -88
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +136 -22
- package/dist/devenv/index.d.ts +10 -0
- package/dist/devenv/index.d.ts.map +1 -0
- package/dist/devenv/index.js +27 -0
- package/dist/lib/cli-package.d.ts +4 -0
- package/dist/lib/cli-package.d.ts.map +1 -0
- package/dist/lib/cli-package.js +15 -0
- package/dist/lib/devenv.d.ts +6 -0
- package/dist/lib/devenv.d.ts.map +1 -0
- package/dist/lib/devenv.js +82 -0
- package/dist/lib/run.d.ts +5 -0
- package/dist/lib/run.d.ts.map +1 -1
- package/dist/lib/run.js +13 -0
- package/dist/lib/workspace.d.ts +20 -1
- package/dist/lib/workspace.d.ts.map +1 -1
- package/dist/lib/workspace.js +87 -7
- package/dist/monorepo/commit-msg.d.ts +8 -1
- package/dist/monorepo/commit-msg.d.ts.map +1 -1
- package/dist/monorepo/commit-msg.js +85 -7
- package/dist/monorepo/index.d.ts +24 -2
- package/dist/monorepo/index.d.ts.map +1 -1
- package/dist/monorepo/index.js +136 -15
- package/dist/monorepo/lockfile.d.ts +5 -1
- package/dist/monorepo/lockfile.d.ts.map +1 -1
- package/dist/monorepo/lockfile.js +45 -5
- package/dist/monorepo/managed-files.d.ts +1 -1
- package/dist/monorepo/managed-files.d.ts.map +1 -1
- package/dist/monorepo/managed-files.js +28 -11
- package/dist/monorepo/nx-sync.d.ts +2 -1
- package/dist/monorepo/nx-sync.d.ts.map +1 -1
- package/dist/monorepo/nx-sync.js +8 -2
- package/dist/monorepo/package-hygiene.d.ts +6 -2
- package/dist/monorepo/package-hygiene.d.ts.map +1 -1
- package/dist/monorepo/package-hygiene.js +12 -4
- package/dist/monorepo/package-policy.d.ts +25 -2
- package/dist/monorepo/package-policy.d.ts.map +1 -1
- package/dist/monorepo/package-policy.js +1289 -27
- package/dist/monorepo/packed-manifest.d.ts +4 -0
- package/dist/monorepo/packed-manifest.d.ts.map +1 -0
- package/dist/monorepo/packed-manifest.js +51 -0
- package/dist/monorepo/packed-package.d.ts +3 -0
- package/dist/monorepo/packed-package.d.ts.map +1 -1
- package/dist/monorepo/packed-package.js +69 -31
- package/dist/monorepo/packs/index.d.ts +20 -1
- package/dist/monorepo/packs/index.d.ts.map +1 -1
- package/dist/monorepo/packs/index.js +240 -18
- package/dist/monorepo/publish-workflow.d.ts +82 -0
- package/dist/monorepo/publish-workflow.d.ts.map +1 -0
- package/dist/monorepo/publish-workflow.js +336 -0
- package/dist/monorepo/tool-validation.d.ts +22 -0
- package/dist/monorepo/tool-validation.d.ts.map +1 -0
- package/dist/monorepo/tool-validation.js +399 -0
- package/dist/nx/index.d.ts +24 -0
- package/dist/nx/index.d.ts.map +1 -0
- package/dist/nx/index.js +94 -0
- package/dist/nx-version-actions.cjs +25 -0
- package/dist/nx-version-actions.d.cts +6 -0
- package/dist/nx-version-actions.d.cts.map +1 -0
- package/dist/release/bootstrap-npm-packages.d.ts +19 -0
- package/dist/release/bootstrap-npm-packages.d.ts.map +1 -0
- package/dist/release/bootstrap-npm-packages.js +58 -0
- package/dist/release/candidates.d.ts +11 -0
- package/dist/release/candidates.d.ts.map +1 -0
- package/dist/release/candidates.js +181 -0
- package/dist/release/core.d.ts +51 -0
- package/dist/release/core.d.ts.map +1 -0
- package/dist/release/core.js +97 -0
- package/dist/release/github-release.d.ts +46 -0
- package/dist/release/github-release.d.ts.map +1 -0
- package/dist/release/github-release.js +97 -0
- package/dist/release/index.d.ts +39 -5
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +763 -130
- package/dist/release/npm-auth.d.ts +16 -0
- package/dist/release/npm-auth.d.ts.map +1 -0
- package/dist/release/npm-auth.js +39 -0
- package/dist/release/orchestration.d.ts +49 -0
- package/dist/release/orchestration.d.ts.map +1 -0
- package/dist/release/orchestration.js +113 -0
- package/dist/release/publish-plan.d.ts +17 -0
- package/dist/release/publish-plan.d.ts.map +1 -0
- package/dist/release/publish-plan.js +15 -0
- package/dist/release/retag-unpublished.d.ts +34 -0
- package/dist/release/retag-unpublished.d.ts.map +1 -0
- package/dist/release/retag-unpublished.js +77 -0
- package/managed/raw/git-format-staged.yml +54 -0
- package/managed/raw/tooling/git-hooks/commit-msg.sh +1 -1
- package/managed/raw/tooling/git-hooks/pre-commit.sh +2 -7
- package/managed/templates/github/actions/setup-devenv/action.yml +1 -7
- package/managed/templates/github/workflows/ci.yml +3 -0
- package/package.json +37 -4
- package/src/cli.ts +193 -40
- package/src/devenv/index.test.ts +49 -0
- package/src/devenv/index.ts +38 -0
- package/src/lib/cli-package.ts +18 -0
- package/src/lib/devenv.test.ts +28 -0
- package/src/lib/devenv.ts +89 -0
- package/src/lib/run.ts +19 -0
- package/src/lib/workspace.ts +117 -7
- package/src/monorepo/__tests__/nx-version-actions.test.ts +75 -0
- package/src/monorepo/__tests__/publish-workflow.test.ts +322 -0
- package/src/monorepo/commit-msg.test.ts +45 -0
- package/src/monorepo/commit-msg.ts +107 -7
- package/src/monorepo/index.ts +181 -15
- package/src/monorepo/lockfile.ts +52 -7
- package/src/monorepo/managed-files.ts +43 -13
- package/src/monorepo/nx-sync.ts +9 -2
- package/src/monorepo/package-hygiene.test.ts +34 -0
- package/src/monorepo/package-hygiene.ts +26 -4
- package/src/monorepo/package-policy.test.ts +902 -0
- package/src/monorepo/package-policy.ts +1527 -25
- package/src/monorepo/packed-manifest.ts +67 -0
- package/src/monorepo/packed-package.ts +90 -31
- package/src/monorepo/packs/index.test.ts +189 -0
- package/src/monorepo/packs/index.ts +314 -19
- package/src/monorepo/publish-workflow.ts +422 -0
- package/src/monorepo/setup-test-tracing.test.ts +120 -0
- package/src/monorepo/tool-validation.test.ts +261 -0
- package/src/monorepo/tool-validation.ts +462 -0
- package/src/nx/index.test.ts +64 -0
- package/src/nx/index.ts +119 -0
- package/src/nx-version-actions.cts +36 -0
- package/src/release/__tests__/bootstrap-npm-packages.test.ts +127 -0
- package/src/release/__tests__/candidates.test.ts +217 -0
- package/src/release/__tests__/core-properties.test.ts +149 -0
- package/src/release/__tests__/core-scenarios.test.ts +187 -0
- package/src/release/__tests__/core.test.ts +73 -0
- package/src/release/__tests__/fixture-repo.test.ts +314 -0
- package/src/release/__tests__/github-release.test.ts +149 -0
- package/src/release/__tests__/helpers/fixture-repo.ts +114 -0
- package/src/release/__tests__/npm-auth.test.ts +120 -0
- package/src/release/__tests__/orchestration.test.ts +246 -0
- package/src/release/__tests__/publish-plan.test.ts +67 -0
- package/src/release/__tests__/retag-unpublished.test.ts +160 -0
- package/src/release/__tests__/trust-publisher.test.ts +133 -0
- package/src/release/bootstrap-npm-packages.ts +88 -0
- package/src/release/candidates.ts +225 -0
- package/src/release/core.ts +171 -0
- package/src/release/github-release.ts +134 -0
- package/src/release/index.ts +974 -138
- package/src/release/npm-auth.ts +93 -0
- package/src/release/orchestration.ts +196 -0
- package/src/release/publish-plan.ts +37 -0
- package/src/release/retag-unpublished.ts +122 -0
- package/managed/raw/.git-format-staged.yml +0 -47
- package/managed/templates/github/workflows/publish.yml +0 -136
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { isRecord } from '../lib/json.js';
|
|
2
|
+
import { releaseTag } from './core.js';
|
|
3
|
+
const releasableManifestKeys = [
|
|
4
|
+
'author',
|
|
5
|
+
'bin',
|
|
6
|
+
'browser',
|
|
7
|
+
'bugs',
|
|
8
|
+
'cpu',
|
|
9
|
+
'dependencies',
|
|
10
|
+
'description',
|
|
11
|
+
'engines',
|
|
12
|
+
'exports',
|
|
13
|
+
'files',
|
|
14
|
+
'funding',
|
|
15
|
+
'homepage',
|
|
16
|
+
'imports',
|
|
17
|
+
'keywords',
|
|
18
|
+
'license',
|
|
19
|
+
'main',
|
|
20
|
+
'module',
|
|
21
|
+
'name',
|
|
22
|
+
'optionalDependencies',
|
|
23
|
+
'os',
|
|
24
|
+
'peerDependencies',
|
|
25
|
+
'peerDependenciesMeta',
|
|
26
|
+
'publishConfig',
|
|
27
|
+
'repository',
|
|
28
|
+
'sideEffects',
|
|
29
|
+
'types',
|
|
30
|
+
'typesVersions',
|
|
31
|
+
];
|
|
32
|
+
export async function autoReleaseCandidatePackages(shell, packages) {
|
|
33
|
+
const candidates = [];
|
|
34
|
+
for (const pkg of packages) {
|
|
35
|
+
if (await isAutoReleaseCandidate(shell, pkg)) {
|
|
36
|
+
candidates.push(pkg);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return candidates;
|
|
40
|
+
}
|
|
41
|
+
async function isAutoReleaseCandidate(shell, pkg) {
|
|
42
|
+
const tagRef = `refs/tags/${releaseTag(pkg)}`;
|
|
43
|
+
if (await shell.gitRefExists(tagRef)) {
|
|
44
|
+
return packageHasReleasableChangesSince(shell, tagRef, pkg);
|
|
45
|
+
}
|
|
46
|
+
return shell.packageHasHistory(pkg.path);
|
|
47
|
+
}
|
|
48
|
+
async function packageHasReleasableChangesSince(shell, ref, pkg) {
|
|
49
|
+
const changedFiles = await shell.packageChangedFilesSince(ref, pkg.path);
|
|
50
|
+
if (changedFiles.length === 0) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const currentManifest = await shell.currentPackageJson(pkg.path);
|
|
54
|
+
const buildInputPatterns = await shell.packageBuildInputPatterns(pkg.projectName, pkg.path);
|
|
55
|
+
for (const changedFile of changedFiles) {
|
|
56
|
+
if (changedFile === 'package.json') {
|
|
57
|
+
const previousManifest = await shell.packageJsonAtRef(ref, pkg.path);
|
|
58
|
+
if (!previousManifest || !currentManifest || releasableManifestChanged(previousManifest, currentManifest)) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (isReleasablePackagePath(changedFile, currentManifest, buildInputPatterns)) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
function releasableManifestChanged(previousManifest, currentManifest) {
|
|
70
|
+
for (const key of releasableManifestKeys) {
|
|
71
|
+
if (!stableJsonEqual(previousManifest[key], currentManifest[key])) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
function isReleasablePackagePath(path, manifest, buildInputPatterns) {
|
|
78
|
+
return (isBuildInputPath(path, buildInputPatterns) || isPackageMetadataPath(path) || isManifestFilesPath(path, manifest));
|
|
79
|
+
}
|
|
80
|
+
function isBuildInputPath(path, patterns) {
|
|
81
|
+
if (isReleaseIgnoredBuildInputPath(path)) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
let matched = false;
|
|
85
|
+
for (const pattern of patterns) {
|
|
86
|
+
const excluded = pattern.startsWith('!');
|
|
87
|
+
const rawPattern = excluded ? pattern.slice(1) : pattern;
|
|
88
|
+
if (matchesBuildInputPattern(path, rawPattern)) {
|
|
89
|
+
matched = !excluded;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return matched;
|
|
93
|
+
}
|
|
94
|
+
function matchesBuildInputPattern(path, pattern) {
|
|
95
|
+
const normalized = pattern.replace(/^\.\//, '').replace(/\/$/, '');
|
|
96
|
+
if (!normalized) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return globPatternToRegExp(normalized).test(path);
|
|
100
|
+
}
|
|
101
|
+
function globPatternToRegExp(pattern) {
|
|
102
|
+
let source = '^';
|
|
103
|
+
for (let index = 0; index < pattern.length; index += 1) {
|
|
104
|
+
const char = pattern[index];
|
|
105
|
+
if (char === '*') {
|
|
106
|
+
if (pattern[index + 1] === '*') {
|
|
107
|
+
if (pattern[index + 2] === '/') {
|
|
108
|
+
source += '(?:.*/)?';
|
|
109
|
+
index += 2;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
source += '.*';
|
|
113
|
+
index += 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
source += '[^/]*';
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
source += escapeRegExpChar(char);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return new RegExp(`${source}$`);
|
|
125
|
+
}
|
|
126
|
+
function escapeRegExpChar(char) {
|
|
127
|
+
if (!char) {
|
|
128
|
+
return '';
|
|
129
|
+
}
|
|
130
|
+
return /[\\^$+?.()|[\]{}]/.test(char) ? `\\${char}` : char;
|
|
131
|
+
}
|
|
132
|
+
function isReleaseIgnoredBuildInputPath(path) {
|
|
133
|
+
return (path === 'package.json' ||
|
|
134
|
+
path === 'tsconfig.test.json' ||
|
|
135
|
+
path.includes('/__tests__/') ||
|
|
136
|
+
path.endsWith('.test.ts') ||
|
|
137
|
+
path.endsWith('.test.tsx') ||
|
|
138
|
+
path.endsWith('.spec.ts') ||
|
|
139
|
+
path.endsWith('.spec.tsx'));
|
|
140
|
+
}
|
|
141
|
+
function isPackageMetadataPath(path) {
|
|
142
|
+
return /^(README|LICENSE|CHANGELOG)(\.|$)/.test(path);
|
|
143
|
+
}
|
|
144
|
+
function isManifestFilesPath(path, manifest) {
|
|
145
|
+
const files = manifest?.files;
|
|
146
|
+
if (!Array.isArray(files)) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
for (const entry of files) {
|
|
150
|
+
if (typeof entry !== 'string' || entry.length === 0 || entry.startsWith('!')) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (matchesManifestFilesEntry(path, entry)) {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
function matchesManifestFilesEntry(path, entry) {
|
|
160
|
+
const normalized = entry.replace(/^\.\//, '').replace(/\/$/, '');
|
|
161
|
+
if (!normalized || normalized.includes('*')) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
return path === normalized || path.startsWith(`${normalized}/`);
|
|
165
|
+
}
|
|
166
|
+
function stableJsonEqual(left, right) {
|
|
167
|
+
return JSON.stringify(stableJson(left)) === JSON.stringify(stableJson(right));
|
|
168
|
+
}
|
|
169
|
+
function stableJson(value) {
|
|
170
|
+
if (Array.isArray(value)) {
|
|
171
|
+
return value.map(stableJson);
|
|
172
|
+
}
|
|
173
|
+
if (isRecord(value)) {
|
|
174
|
+
const normalized = {};
|
|
175
|
+
for (const key of Object.keys(value).sort()) {
|
|
176
|
+
normalized[key] = stableJson(value[key]);
|
|
177
|
+
}
|
|
178
|
+
return normalized;
|
|
179
|
+
}
|
|
180
|
+
return value;
|
|
181
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface ReleasePackageInfo {
|
|
2
|
+
name: string;
|
|
3
|
+
projectName: string;
|
|
4
|
+
path: string;
|
|
5
|
+
version: string;
|
|
6
|
+
}
|
|
7
|
+
export interface GitReleaseTagInfo {
|
|
8
|
+
name: string;
|
|
9
|
+
sha: string;
|
|
10
|
+
timestamp: number;
|
|
11
|
+
}
|
|
12
|
+
export interface MatchedReleaseTag<Package extends ReleasePackageInfo = ReleasePackageInfo> {
|
|
13
|
+
tag: string;
|
|
14
|
+
sha: string;
|
|
15
|
+
timestamp: number;
|
|
16
|
+
pkg: Package;
|
|
17
|
+
}
|
|
18
|
+
export interface ReleaseTagRecord<Package extends ReleasePackageInfo = ReleasePackageInfo> extends MatchedReleaseTag<Package> {
|
|
19
|
+
needsNpmPublish: boolean;
|
|
20
|
+
needsGithubRelease: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface ReleaseTarget<Package extends ReleasePackageInfo = ReleasePackageInfo> {
|
|
23
|
+
sha: string;
|
|
24
|
+
timestamp: number;
|
|
25
|
+
packages: Package[];
|
|
26
|
+
npmPackages: Package[];
|
|
27
|
+
githubPackages: Package[];
|
|
28
|
+
}
|
|
29
|
+
export interface DurableTagState {
|
|
30
|
+
npmPublished: boolean;
|
|
31
|
+
githubReleaseExists: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface ReleasePlanningShell {
|
|
34
|
+
listReleaseTagsByCreatorDate(): Promise<GitReleaseTagInfo[]>;
|
|
35
|
+
isAncestor(ancestor: string, descendant: string): Promise<boolean>;
|
|
36
|
+
packageVersionAtRef(packagePath: string, ref: string): Promise<string | null>;
|
|
37
|
+
durableTagState(pkg: ReleasePackageInfo, tag: string): Promise<DurableTagState>;
|
|
38
|
+
}
|
|
39
|
+
export declare function releaseTag(pkg: Pick<ReleasePackageInfo, 'name' | 'version'>): string;
|
|
40
|
+
export declare function npmDistTagForVersion(version: string): string;
|
|
41
|
+
export declare function releasePackageForTag<Package extends Omit<ReleasePackageInfo, 'version'>>(packages: Package[], tag: string): {
|
|
42
|
+
pkg: Package;
|
|
43
|
+
version: string;
|
|
44
|
+
} | null;
|
|
45
|
+
export declare function classifyReleaseTag<Package extends ReleasePackageInfo>(tag: MatchedReleaseTag<Package>, state: DurableTagState): ReleaseTagRecord<Package>;
|
|
46
|
+
export declare function collectOwnedReleaseTagRecords<Package extends Omit<ReleasePackageInfo, 'version'>>(packages: Package[], ref: string, shell: ReleasePlanningShell): Promise<Array<ReleaseTagRecord<Package & {
|
|
47
|
+
version: string;
|
|
48
|
+
}>>>;
|
|
49
|
+
export declare function groupReleaseTargets<Package extends ReleasePackageInfo>(records: ReleaseTagRecord<Package>[]): ReleaseTarget<Package>[];
|
|
50
|
+
export declare function pendingReleaseTargets<Package extends ReleasePackageInfo>(records: ReleaseTagRecord<Package>[], headSha: string): ReleaseTarget<Package>[];
|
|
51
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/release/core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export function releaseTag(pkg) {
|
|
2
|
+
return `${pkg.name}@${pkg.version}`;
|
|
3
|
+
}
|
|
4
|
+
export function npmDistTagForVersion(version) {
|
|
5
|
+
return version.includes('-') ? 'next' : 'latest';
|
|
6
|
+
}
|
|
7
|
+
export function releasePackageForTag(packages, tag) {
|
|
8
|
+
for (const pkg of packages) {
|
|
9
|
+
const prefix = `${pkg.name}@`;
|
|
10
|
+
if (tag.startsWith(prefix)) {
|
|
11
|
+
const version = tag.slice(prefix.length);
|
|
12
|
+
if (!version) {
|
|
13
|
+
throw new Error(`Release tag ${tag} does not include a version.`);
|
|
14
|
+
}
|
|
15
|
+
return { pkg, version };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
export function classifyReleaseTag(tag, state) {
|
|
21
|
+
return {
|
|
22
|
+
...tag,
|
|
23
|
+
needsNpmPublish: !state.npmPublished,
|
|
24
|
+
needsGithubRelease: !state.githubReleaseExists,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export async function collectOwnedReleaseTagRecords(packages, ref, shell) {
|
|
28
|
+
const records = [];
|
|
29
|
+
const completedPackages = new Set();
|
|
30
|
+
for (const tag of await shell.listReleaseTagsByCreatorDate()) {
|
|
31
|
+
const match = releasePackageForTag(packages, tag.name);
|
|
32
|
+
if (match && completedPackages.has(match.pkg.name)) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (!match || !(await shell.isAncestor(tag.sha, ref))) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const versionAtTag = await shell.packageVersionAtRef(match.pkg.path, tag.sha);
|
|
39
|
+
if (versionAtTag !== match.version) {
|
|
40
|
+
throw new Error(`Release tag ${tag.name} points at ${tag.sha.slice(0, 12)}, but ${match.pkg.path}/package.json has version ${versionAtTag ?? 'missing'}.`);
|
|
41
|
+
}
|
|
42
|
+
const pkg = { ...match.pkg, version: match.version };
|
|
43
|
+
const state = await shell.durableTagState(pkg, tag.name);
|
|
44
|
+
records.push(classifyReleaseTag({ tag: tag.name, sha: tag.sha, timestamp: tag.timestamp, pkg }, state));
|
|
45
|
+
if (state.npmPublished && state.githubReleaseExists) {
|
|
46
|
+
completedPackages.add(pkg.name);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return records;
|
|
50
|
+
}
|
|
51
|
+
export function groupReleaseTargets(records) {
|
|
52
|
+
const targets = new Map();
|
|
53
|
+
const packageNamesByTarget = new Map();
|
|
54
|
+
for (const record of records) {
|
|
55
|
+
let target = targets.get(record.sha);
|
|
56
|
+
let packageNames = packageNamesByTarget.get(record.sha);
|
|
57
|
+
if (!target) {
|
|
58
|
+
target = { sha: record.sha, timestamp: record.timestamp, packages: [], npmPackages: [], githubPackages: [] };
|
|
59
|
+
targets.set(record.sha, target);
|
|
60
|
+
packageNames = new Set();
|
|
61
|
+
packageNamesByTarget.set(record.sha, packageNames);
|
|
62
|
+
}
|
|
63
|
+
else if (record.timestamp > target.timestamp) {
|
|
64
|
+
target.timestamp = record.timestamp;
|
|
65
|
+
}
|
|
66
|
+
if (!packageNames) {
|
|
67
|
+
throw new Error(`Release target ${record.sha.slice(0, 12)} lost package tracking state.`);
|
|
68
|
+
}
|
|
69
|
+
if (packageNames.has(record.pkg.name)) {
|
|
70
|
+
throw new Error(`Release target ${record.sha.slice(0, 12)} has more than one release tag for ${record.pkg.name}.`);
|
|
71
|
+
}
|
|
72
|
+
packageNames.add(record.pkg.name);
|
|
73
|
+
if (record.needsNpmPublish || record.needsGithubRelease) {
|
|
74
|
+
target.packages.push(record.pkg);
|
|
75
|
+
}
|
|
76
|
+
if (record.needsNpmPublish) {
|
|
77
|
+
target.npmPackages.push(record.pkg);
|
|
78
|
+
}
|
|
79
|
+
if (record.needsGithubRelease) {
|
|
80
|
+
target.githubPackages.push(record.pkg);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return [...targets.values()].sort((left, right) => right.timestamp - left.timestamp || right.sha.localeCompare(left.sha));
|
|
84
|
+
}
|
|
85
|
+
export function pendingReleaseTargets(records, headSha) {
|
|
86
|
+
const pending = [];
|
|
87
|
+
for (const target of groupReleaseTargets(records)) {
|
|
88
|
+
if (target.sha === headSha) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (target.npmPackages.length === 0 && target.githubPackages.length === 0) {
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
pending.push(target);
|
|
95
|
+
}
|
|
96
|
+
return pending.reverse();
|
|
97
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type ReleasePackageInfo } from './core.js';
|
|
2
|
+
interface ProjectChangelogLookupResult {
|
|
3
|
+
projectChangelogs?: Record<string, {
|
|
4
|
+
contents: string;
|
|
5
|
+
}>;
|
|
6
|
+
}
|
|
7
|
+
export interface RenderNxProjectChangelogInput<Package extends ReleasePackageInfo = ReleasePackageInfo> {
|
|
8
|
+
root: string;
|
|
9
|
+
pkg: Package;
|
|
10
|
+
previousTag: string | null;
|
|
11
|
+
dryRun: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface GithubReleaseWriteShell {
|
|
14
|
+
githubReleaseExists(tag: string): Promise<boolean>;
|
|
15
|
+
runGhRelease(args: string[]): Promise<void>;
|
|
16
|
+
log(message: string): void;
|
|
17
|
+
}
|
|
18
|
+
export declare function renderNxProjectChangelogContents(input: RenderNxProjectChangelogInput): Promise<string>;
|
|
19
|
+
export declare function createOrUpdateGithubRelease(pkg: ReleasePackageInfo, contents: string, shell: GithubReleaseWriteShell): Promise<void>;
|
|
20
|
+
export declare function nxProjectChangelogArgs(pkg: ReleasePackageInfo, previousTag: string | null, dryRun: boolean): {
|
|
21
|
+
from: string;
|
|
22
|
+
version: string;
|
|
23
|
+
projects: string[];
|
|
24
|
+
gitCommit: false;
|
|
25
|
+
gitTag: false;
|
|
26
|
+
gitPush: false;
|
|
27
|
+
stageChanges: false;
|
|
28
|
+
createRelease: false;
|
|
29
|
+
deleteVersionPlans: false;
|
|
30
|
+
dryRun: boolean;
|
|
31
|
+
} | {
|
|
32
|
+
firstRelease: boolean;
|
|
33
|
+
version: string;
|
|
34
|
+
projects: string[];
|
|
35
|
+
gitCommit: false;
|
|
36
|
+
gitTag: false;
|
|
37
|
+
gitPush: false;
|
|
38
|
+
stageChanges: false;
|
|
39
|
+
createRelease: false;
|
|
40
|
+
deleteVersionPlans: false;
|
|
41
|
+
dryRun: boolean;
|
|
42
|
+
};
|
|
43
|
+
export declare function projectChangelogContents(result: ProjectChangelogLookupResult, projectName: string): string;
|
|
44
|
+
export declare function githubReleaseCommandArgs(tag: string, notesFile: string, releaseExists: boolean, version: string): string[];
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=github-release.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-release.d.ts","sourceRoot":"","sources":["../../src/release/github-release.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,kBAAkB,EAAc,MAAM,WAAW,CAAC;AAYhE,UAAU,4BAA4B;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,6BAA6B,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IACpG,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,gCAAgC,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CAS5G;AAED,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;EAa1G;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,4BAA4B,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAM1G;AAED,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,OAAO,EACtB,OAAO,EAAE,MAAM,GACd,MAAM,EAAE,CAgBV"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { releaseTag } from './core.js';
|
|
5
|
+
const nxRenderOnlyReleaseConfig = {
|
|
6
|
+
changelog: {
|
|
7
|
+
workspaceChangelog: false,
|
|
8
|
+
projectChangelogs: {
|
|
9
|
+
createRelease: false,
|
|
10
|
+
file: false,
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export async function renderNxProjectChangelogContents(input) {
|
|
15
|
+
return withNxWorkspaceRoot(input.root, async () => {
|
|
16
|
+
const { createAPI } = await import('nx/src/command-line/release/changelog.js');
|
|
17
|
+
const result = await createAPI(nxRenderOnlyReleaseConfig, false)(nxProjectChangelogArgs(input.pkg, input.previousTag, input.dryRun));
|
|
18
|
+
return projectChangelogContents(result, input.pkg.projectName);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export async function createOrUpdateGithubRelease(pkg, contents, shell) {
|
|
22
|
+
const tag = releaseTag(pkg);
|
|
23
|
+
const releaseExists = await shell.githubReleaseExists(tag);
|
|
24
|
+
shell.log(`${pkg.name}@${pkg.version}: ${releaseExists ? 'updating' : 'creating'} GitHub Release for ${tag}.`);
|
|
25
|
+
const tempDir = await mkdtemp(join(tmpdir(), 'smoo-github-release-'));
|
|
26
|
+
const notesFile = join(tempDir, 'notes.md');
|
|
27
|
+
try {
|
|
28
|
+
await writeFile(notesFile, contents);
|
|
29
|
+
await shell.runGhRelease(githubReleaseCommandArgs(tag, notesFile, releaseExists, pkg.version));
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export function nxProjectChangelogArgs(pkg, previousTag, dryRun) {
|
|
36
|
+
const base = {
|
|
37
|
+
version: pkg.version,
|
|
38
|
+
projects: [pkg.projectName],
|
|
39
|
+
gitCommit: false,
|
|
40
|
+
gitTag: false,
|
|
41
|
+
gitPush: false,
|
|
42
|
+
stageChanges: false,
|
|
43
|
+
createRelease: false,
|
|
44
|
+
deleteVersionPlans: false,
|
|
45
|
+
dryRun,
|
|
46
|
+
};
|
|
47
|
+
return previousTag ? { ...base, from: previousTag } : { ...base, firstRelease: true };
|
|
48
|
+
}
|
|
49
|
+
export function projectChangelogContents(result, projectName) {
|
|
50
|
+
const changelog = result.projectChangelogs?.[projectName];
|
|
51
|
+
if (!changelog) {
|
|
52
|
+
throw new Error(`Nx did not generate a project changelog for ${projectName}.`);
|
|
53
|
+
}
|
|
54
|
+
return changelog.contents;
|
|
55
|
+
}
|
|
56
|
+
export function githubReleaseCommandArgs(tag, notesFile, releaseExists, version) {
|
|
57
|
+
const args = [
|
|
58
|
+
'release',
|
|
59
|
+
releaseExists ? 'edit' : 'create',
|
|
60
|
+
tag,
|
|
61
|
+
'--title',
|
|
62
|
+
tag,
|
|
63
|
+
'--notes-file',
|
|
64
|
+
notesFile,
|
|
65
|
+
'--verify-tag',
|
|
66
|
+
`--latest=${isPrereleaseVersion(version) ? 'false' : 'true'}`,
|
|
67
|
+
];
|
|
68
|
+
if (isPrereleaseVersion(version)) {
|
|
69
|
+
args.push('--prerelease');
|
|
70
|
+
}
|
|
71
|
+
return args;
|
|
72
|
+
}
|
|
73
|
+
function isPrereleaseVersion(version) {
|
|
74
|
+
return version.includes('-');
|
|
75
|
+
}
|
|
76
|
+
async function withNxWorkspaceRoot(root, run) {
|
|
77
|
+
const workspaceRootModule = await import('nx/src/utils/workspace-root.js');
|
|
78
|
+
const previousWorkspaceRoot = workspaceRootModule.workspaceRoot;
|
|
79
|
+
const previousEnvWorkspaceRoot = process.env.NX_WORKSPACE_ROOT_PATH;
|
|
80
|
+
const previousCwd = process.cwd();
|
|
81
|
+
process.env.NX_WORKSPACE_ROOT_PATH = root;
|
|
82
|
+
process.chdir(root);
|
|
83
|
+
workspaceRootModule.setWorkspaceRoot(root);
|
|
84
|
+
try {
|
|
85
|
+
return await run();
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
workspaceRootModule.setWorkspaceRoot(previousWorkspaceRoot);
|
|
89
|
+
if (previousEnvWorkspaceRoot === undefined) {
|
|
90
|
+
delete process.env.NX_WORKSPACE_ROOT_PATH;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
process.env.NX_WORKSPACE_ROOT_PATH = previousEnvWorkspaceRoot;
|
|
94
|
+
}
|
|
95
|
+
process.chdir(previousCwd);
|
|
96
|
+
}
|
|
97
|
+
}
|
package/dist/release/index.d.ts
CHANGED
|
@@ -1,24 +1,58 @@
|
|
|
1
|
+
import { type BootstrapNpmPackagesOptions } from './bootstrap-npm-packages.js';
|
|
2
|
+
import { type ReleasePackageInfo } from './core.js';
|
|
1
3
|
export interface ReleaseVersionOptions {
|
|
2
4
|
bump: string;
|
|
3
5
|
dryRun?: boolean;
|
|
6
|
+
githubOutput?: string;
|
|
4
7
|
}
|
|
5
8
|
export interface ReleasePublishOptions {
|
|
6
9
|
bump: string;
|
|
7
|
-
tag?: string;
|
|
8
|
-
npmTag?: string;
|
|
9
10
|
dryRun?: boolean;
|
|
10
11
|
}
|
|
11
|
-
export interface
|
|
12
|
-
|
|
12
|
+
export interface ReleaseRepairPendingOptions {
|
|
13
|
+
dryRun?: boolean;
|
|
13
14
|
}
|
|
14
15
|
export interface ReleaseTrustPublisherOptions {
|
|
15
16
|
dryRun?: boolean;
|
|
17
|
+
bootstrap?: boolean;
|
|
16
18
|
otp?: string;
|
|
19
|
+
bootstrapOtp?: string;
|
|
20
|
+
skipLogin?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface ReleaseBootstrapNpmPackagesOptions {
|
|
23
|
+
dryRun?: boolean;
|
|
17
24
|
skipLogin?: boolean;
|
|
25
|
+
otp?: string;
|
|
26
|
+
packages?: string[];
|
|
27
|
+
}
|
|
28
|
+
export interface ReleaseRetagUnpublishedOptions {
|
|
29
|
+
tags: string[];
|
|
30
|
+
to?: string;
|
|
31
|
+
push?: boolean;
|
|
32
|
+
dispatch?: boolean;
|
|
33
|
+
dryRun?: boolean;
|
|
34
|
+
remote?: string;
|
|
35
|
+
branch?: string;
|
|
18
36
|
}
|
|
19
37
|
export declare function releaseVersion(root: string, options: ReleaseVersionOptions): Promise<void>;
|
|
20
38
|
export declare function releasePublish(root: string, options: ReleasePublishOptions): Promise<void>;
|
|
21
|
-
export declare function
|
|
39
|
+
export declare function releaseRepairPending(root: string, options: ReleaseRepairPendingOptions): Promise<void>;
|
|
22
40
|
export declare function releaseTrustPublisher(root: string, options: ReleaseTrustPublisherOptions): Promise<void>;
|
|
41
|
+
export interface TrustPublisherShell<Package extends ReleasePackageInfo = ReleasePackageInfo> {
|
|
42
|
+
repository: string;
|
|
43
|
+
workflow: string;
|
|
44
|
+
listReleasePackages(): Package[];
|
|
45
|
+
packageExists(name: string): Promise<boolean>;
|
|
46
|
+
bootstrapNpmPackages(options: BootstrapNpmPackagesOptions): Promise<Package[]>;
|
|
47
|
+
login(): Promise<void>;
|
|
48
|
+
trustPublisher(pkg: Package, dryRun: boolean, env?: Record<string, string>): Promise<TrustPublisherResult>;
|
|
49
|
+
promptOtp(packageName: string): Promise<string>;
|
|
50
|
+
log(message: string): void;
|
|
51
|
+
error(message: string): void;
|
|
52
|
+
}
|
|
53
|
+
export type TrustPublisherResult = 'configured' | 'already-configured';
|
|
54
|
+
export declare function configureTrustedPublishers<Package extends ReleasePackageInfo>(shell: TrustPublisherShell<Package>, options: ReleaseTrustPublisherOptions): Promise<void>;
|
|
55
|
+
export declare function releaseBootstrapNpmPackages(root: string, options: ReleaseBootstrapNpmPackagesOptions): Promise<void>;
|
|
56
|
+
export declare function releaseRetagUnpublished(root: string, options: ReleaseRetagUnpublishedOptions): Promise<void>;
|
|
23
57
|
export declare function printReleaseState(root: string): Promise<void>;
|
|
24
58
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/release/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/release/index.ts"],"names":[],"mappings":"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"}
|