@i-santos/create-package-starter 1.5.0-beta.13 → 1.5.0-beta.14
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/lib/run.js +157 -36
- package/package.json +1 -1
package/lib/run.js
CHANGED
|
@@ -1699,7 +1699,7 @@ function getLatestWorkflowRunForBranch(repo, branch, deps) {
|
|
|
1699
1699
|
'--branch',
|
|
1700
1700
|
branch,
|
|
1701
1701
|
'--json',
|
|
1702
|
-
'databaseId,workflowName,status,conclusion,url',
|
|
1702
|
+
'databaseId,workflowName,status,conclusion,url,updatedAt,createdAt,event',
|
|
1703
1703
|
'--limit',
|
|
1704
1704
|
'10'
|
|
1705
1705
|
]);
|
|
@@ -1912,17 +1912,41 @@ function waitForReleasePr(repo, timeoutMinutes, deps, options = {}) {
|
|
|
1912
1912
|
const expectedBase = options.expectedBase || '';
|
|
1913
1913
|
const onProgress = typeof options.onProgress === 'function' ? options.onProgress : null;
|
|
1914
1914
|
const progressIntervalMs = Number.isFinite(options.progressIntervalMs) ? options.progressIntervalMs : 30_000;
|
|
1915
|
+
const allowDirectPublish = Boolean(options.allowDirectPublish);
|
|
1916
|
+
const waitStartedAtMs = nowMs(deps);
|
|
1915
1917
|
let lastProgressAt = 0;
|
|
1916
1918
|
const timeoutAt = nowMs(deps) + timeoutMinutes * 60 * 1000;
|
|
1917
1919
|
while (nowMs(deps) <= timeoutAt) {
|
|
1918
1920
|
const releasePrs = findReleasePrs(repo, deps, { expectedBase });
|
|
1919
1921
|
if (releasePrs.length === 1) {
|
|
1920
|
-
return
|
|
1922
|
+
return {
|
|
1923
|
+
type: 'release_pr',
|
|
1924
|
+
releasePr: releasePrs[0]
|
|
1925
|
+
};
|
|
1921
1926
|
}
|
|
1922
1927
|
if (releasePrs.length > 1) {
|
|
1923
1928
|
throw new Error(`Multiple release PRs detected: ${releasePrs.map((item) => item.url).join(', ')}`);
|
|
1924
1929
|
}
|
|
1925
1930
|
|
|
1931
|
+
if (allowDirectPublish) {
|
|
1932
|
+
const run = getLatestWorkflowRunForBranch(repo, DEFAULT_BETA_BRANCH, deps);
|
|
1933
|
+
if (run) {
|
|
1934
|
+
const updatedAtMs = run.updatedAt ? Date.parse(run.updatedAt) : 0;
|
|
1935
|
+
const recentlyUpdated = Number.isFinite(updatedAtMs) && updatedAtMs >= waitStartedAtMs;
|
|
1936
|
+
const completed = String(run.status || '').toLowerCase() === 'completed';
|
|
1937
|
+
const success = ['success', 'neutral', 'skipped'].includes(String(run.conclusion || '').toLowerCase());
|
|
1938
|
+
const looksLikeReleaseFlow = String(run.workflowName || '').toLowerCase().includes('release')
|
|
1939
|
+
|| String(run.event || '').toLowerCase() === 'push';
|
|
1940
|
+
|
|
1941
|
+
if (recentlyUpdated && completed && success && looksLikeReleaseFlow) {
|
|
1942
|
+
return {
|
|
1943
|
+
type: 'direct_publish',
|
|
1944
|
+
workflowRun: run
|
|
1945
|
+
};
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1926
1950
|
const now = nowMs(deps);
|
|
1927
1951
|
if (onProgress && (lastProgressAt === 0 || now - lastProgressAt >= progressIntervalMs)) {
|
|
1928
1952
|
lastProgressAt = now;
|
|
@@ -2037,7 +2061,91 @@ function listPullRequestFiles(repo, prNumber, deps) {
|
|
|
2037
2061
|
return Array.isArray(files) ? files : [];
|
|
2038
2062
|
}
|
|
2039
2063
|
|
|
2064
|
+
function listRepoContents(repo, ref, dirPath, deps) {
|
|
2065
|
+
const safePath = encodePathForGitHubContent(dirPath || '');
|
|
2066
|
+
const endpoint = safePath
|
|
2067
|
+
? `/repos/${repo}/contents/${safePath}?ref=${encodeURIComponent(ref)}`
|
|
2068
|
+
: `/repos/${repo}/contents?ref=${encodeURIComponent(ref)}`;
|
|
2069
|
+
const content = ghApiJson(deps, 'GET', endpoint);
|
|
2070
|
+
return Array.isArray(content) ? content : [];
|
|
2071
|
+
}
|
|
2072
|
+
|
|
2073
|
+
function findWorkspacePackageJsonPaths(repo, ref, deps) {
|
|
2074
|
+
const root = getRemotePackageVersionFromPath(repo, ref, 'package.json', deps);
|
|
2075
|
+
const rootPackage = parseJsonSafely(
|
|
2076
|
+
Buffer.from(
|
|
2077
|
+
String(
|
|
2078
|
+
ghApiJson(deps, 'GET', `/repos/${repo}/contents/package.json?ref=${encodeURIComponent(ref)}`).content || ''
|
|
2079
|
+
).replace(/\n/g, ''),
|
|
2080
|
+
'base64'
|
|
2081
|
+
).toString('utf8'),
|
|
2082
|
+
{}
|
|
2083
|
+
);
|
|
2084
|
+
const workspaces = Array.isArray(rootPackage.workspaces) ? rootPackage.workspaces : [];
|
|
2085
|
+
const paths = [];
|
|
2086
|
+
for (const workspace of workspaces) {
|
|
2087
|
+
if (!workspace.endsWith('/*')) {
|
|
2088
|
+
continue;
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
const prefix = workspace.slice(0, -2);
|
|
2092
|
+
const entries = listRepoContents(repo, ref, prefix, deps);
|
|
2093
|
+
for (const entry of entries) {
|
|
2094
|
+
if (entry && entry.type === 'dir' && entry.path) {
|
|
2095
|
+
paths.push(`${entry.path}/package.json`);
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
if (paths.length === 0) {
|
|
2101
|
+
return ['package.json'];
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2104
|
+
return [...new Set(paths)];
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
function resolveExpectedNpmPackagesFromRef(repo, targetRef, args, deps) {
|
|
2108
|
+
const explicitPackages = Array.isArray(args.npmPackages) ? args.npmPackages : [];
|
|
2109
|
+
const candidatePaths = findWorkspacePackageJsonPaths(repo, targetRef, deps);
|
|
2110
|
+
const resolved = [];
|
|
2111
|
+
for (const packageJsonPath of candidatePaths) {
|
|
2112
|
+
try {
|
|
2113
|
+
resolved.push(getRemotePackageVersionFromPath(repo, targetRef, packageJsonPath, deps));
|
|
2114
|
+
} catch (error) {
|
|
2115
|
+
// Ignore missing/invalid paths while scanning candidates.
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2119
|
+
const publishable = resolved.filter((pkg) => pkg && pkg.name && pkg.version);
|
|
2120
|
+
const byName = new Map(publishable.map((pkg) => [pkg.name, pkg]));
|
|
2121
|
+
|
|
2122
|
+
if (explicitPackages.length > 0) {
|
|
2123
|
+
const missing = explicitPackages.filter((name) => !byName.has(name));
|
|
2124
|
+
if (missing.length > 0) {
|
|
2125
|
+
throw new Error(
|
|
2126
|
+
[
|
|
2127
|
+
`Could not resolve explicit --npm-package values from ${targetRef}: ${missing.join(', ')}`,
|
|
2128
|
+
`Discovered packages: ${[...byName.keys()].join(', ') || 'none'}`
|
|
2129
|
+
].join('\n')
|
|
2130
|
+
);
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
return explicitPackages.map((name) => byName.get(name));
|
|
2134
|
+
}
|
|
2135
|
+
|
|
2136
|
+
return publishable;
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2040
2139
|
function resolveExpectedNpmPackages(repo, releasePrNumber, targetRef, expectedTag, args, deps) {
|
|
2140
|
+
if (!releasePrNumber) {
|
|
2141
|
+
const resolvedFromRef = resolveExpectedNpmPackagesFromRef(repo, targetRef, args, deps);
|
|
2142
|
+
if (resolvedFromRef.length > 0) {
|
|
2143
|
+
return resolvedFromRef;
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
return [getRemotePackageVersion(repo, targetRef, deps)];
|
|
2147
|
+
}
|
|
2148
|
+
|
|
2041
2149
|
const explicitPackages = Array.isArray(args.npmPackages) ? args.npmPackages : [];
|
|
2042
2150
|
const files = listPullRequestFiles(repo, releasePrNumber, deps);
|
|
2043
2151
|
const packageJsonPaths = [...new Set(
|
|
@@ -3191,8 +3299,9 @@ async function runReleaseCycle(args, dependencies = {}) {
|
|
|
3191
3299
|
summary.releasePr = `dry-run: would wait release PR (${args.releasePrTimeout}m)`;
|
|
3192
3300
|
} else {
|
|
3193
3301
|
reporter.start('release-cycle-wait-release-pr', 'Waiting for release PR (changeset-release/*)...');
|
|
3194
|
-
const
|
|
3302
|
+
const releaseOutcome = waitForReleasePr(gitContext.repo, args.releasePrTimeout, deps, {
|
|
3195
3303
|
expectedBase: releaseBaseBranchForTrack(requestedTrack),
|
|
3304
|
+
allowDirectPublish: true,
|
|
3196
3305
|
onProgress: () => {
|
|
3197
3306
|
const run = getLatestWorkflowRunForBranch(gitContext.repo, DEFAULT_BETA_BRANCH, deps);
|
|
3198
3307
|
if (!run) {
|
|
@@ -3205,40 +3314,52 @@ async function runReleaseCycle(args, dependencies = {}) {
|
|
|
3205
3314
|
);
|
|
3206
3315
|
}
|
|
3207
3316
|
});
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3317
|
+
if (releaseOutcome.type === 'release_pr') {
|
|
3318
|
+
const releasePr = releaseOutcome.releasePr;
|
|
3319
|
+
reporter.ok('release-cycle-wait-release-pr', `Release PR found: #${releasePr.number}`);
|
|
3320
|
+
summary.releasePr = `found (#${releasePr.number})`;
|
|
3321
|
+
summary.actionsPerformed.push(`release pr discovered: #${releasePr.number}`);
|
|
3322
|
+
|
|
3323
|
+
if (args.watchChecks) {
|
|
3324
|
+
reporter.start('release-cycle-watch-release-checks', `Watching release PR checks #${releasePr.number}...`);
|
|
3325
|
+
watchPrChecks(gitContext.repo, releasePr.number, args.checkTimeout, deps);
|
|
3326
|
+
reporter.ok('release-cycle-watch-release-checks', `Release PR checks green (#${releasePr.number}).`);
|
|
3327
|
+
}
|
|
3217
3328
|
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3329
|
+
if (args.mergeReleasePr) {
|
|
3330
|
+
reporter.start('release-cycle-merge-release-ready', `Checking merge readiness for release PR #${releasePr.number}...`);
|
|
3331
|
+
const releaseReadiness = waitForPrMergeReadinessOrThrow(
|
|
3332
|
+
gitContext.repo,
|
|
3333
|
+
releasePr.number,
|
|
3334
|
+
`Release PR #${releasePr.number}`,
|
|
3335
|
+
args.checkTimeout,
|
|
3336
|
+
deps,
|
|
3337
|
+
{ allowBehindTransient: true }
|
|
3338
|
+
);
|
|
3339
|
+
await confirmMergeIfNeeded(args, releaseReadiness, `Release PR #${releasePr.number}`);
|
|
3340
|
+
reporter.ok('release-cycle-merge-release-ready', `Release PR #${releasePr.number} is ready for merge.`);
|
|
3341
|
+
reporter.start('release-cycle-release-auto-merge', `Enabling auto-merge for release PR #${releasePr.number}...`);
|
|
3342
|
+
enablePrAutoMerge(gitContext.repo, releasePr.number, args.mergeMethod, deps);
|
|
3343
|
+
reporter.ok('release-cycle-release-auto-merge', `Auto-merge enabled for release PR #${releasePr.number}.`);
|
|
3344
|
+
reporter.start('release-cycle-release-wait-merge', `Waiting for release PR #${releasePr.number} merge...`);
|
|
3345
|
+
waitForPrMerged(gitContext.repo, releasePr.number, args.releasePrTimeout, deps);
|
|
3346
|
+
reporter.ok('release-cycle-release-wait-merge', `Release PR #${releasePr.number} merged.`);
|
|
3347
|
+
summary.releasePr = `merged (#${releasePr.number})`;
|
|
3348
|
+
summary.actionsPerformed.push(`release pr merged: #${releasePr.number}`);
|
|
3349
|
+
summary.autoMerge = 'enabled (code + release)';
|
|
3350
|
+
mergedReleasePr = releasePr;
|
|
3351
|
+
} else {
|
|
3352
|
+
summary.actionsSkipped.push('merge release pr');
|
|
3353
|
+
}
|
|
3240
3354
|
} else {
|
|
3241
|
-
|
|
3355
|
+
reporter.ok('release-cycle-wait-release-pr', 'No release PR created; detected successful direct publish workflow on release/beta.');
|
|
3356
|
+
summary.releasePr = 'skipped (direct publish)';
|
|
3357
|
+
summary.actionsPerformed.push('direct publish detected: no release PR required');
|
|
3358
|
+
mergedReleasePr = {
|
|
3359
|
+
number: 0,
|
|
3360
|
+
url: '',
|
|
3361
|
+
directPublish: true
|
|
3362
|
+
};
|
|
3242
3363
|
}
|
|
3243
3364
|
}
|
|
3244
3365
|
} else {
|
|
@@ -3253,7 +3374,7 @@ async function runReleaseCycle(args, dependencies = {}) {
|
|
|
3253
3374
|
const expectedTag = requestedTrack === 'stable' ? 'latest' : 'beta';
|
|
3254
3375
|
const targetPackages = resolveExpectedNpmPackages(
|
|
3255
3376
|
gitContext.repo,
|
|
3256
|
-
mergedReleasePr.number,
|
|
3377
|
+
mergedReleasePr && mergedReleasePr.number ? mergedReleasePr.number : 0,
|
|
3257
3378
|
targetRef,
|
|
3258
3379
|
expectedTag,
|
|
3259
3380
|
args,
|
package/package.json
CHANGED