@fern-api/generator-cli 0.9.14 → 0.9.16
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/dist/api.js +2906 -295
- package/dist/cli.js +112 -41
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -35152,21 +35152,23 @@ function stringifyValidationError(error) {
|
|
|
35152
35152
|
}
|
|
35153
35153
|
|
|
35154
35154
|
// src/configuration/sdk/core/schemas/builders/schema-utils/JsonError.ts
|
|
35155
|
-
var JsonError = class
|
|
35155
|
+
var JsonError = class extends Error {
|
|
35156
35156
|
constructor(errors) {
|
|
35157
35157
|
super(errors.map(stringifyValidationError).join("; "));
|
|
35158
35158
|
this.errors = errors;
|
|
35159
|
-
Object.setPrototypeOf(this,
|
|
35159
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
35160
|
+
this.name = this.constructor.name;
|
|
35160
35161
|
}
|
|
35161
35162
|
errors;
|
|
35162
35163
|
};
|
|
35163
35164
|
|
|
35164
35165
|
// src/configuration/sdk/core/schemas/builders/schema-utils/ParseError.ts
|
|
35165
|
-
var ParseError = class
|
|
35166
|
+
var ParseError = class extends Error {
|
|
35166
35167
|
constructor(errors) {
|
|
35167
35168
|
super(errors.map(stringifyValidationError).join("; "));
|
|
35168
35169
|
this.errors = errors;
|
|
35169
|
-
Object.setPrototypeOf(this,
|
|
35170
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
35171
|
+
this.name = this.constructor.name;
|
|
35170
35172
|
}
|
|
35171
35173
|
errors;
|
|
35172
35174
|
};
|
|
@@ -39176,14 +39178,22 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
39176
39178
|
async handleNormalFlow(params) {
|
|
39177
39179
|
const { prepared, service, language, mappedMagicVersion, previousGenerationSha } = params;
|
|
39178
39180
|
const rawDiff = this.gitDiff(previousGenerationSha, prepared.currentGenerationSha);
|
|
39179
|
-
if (rawDiff.trim().length === 0) {
|
|
39180
|
-
this.logger.info("AutoVersionStep: empty diff between generations; skipping autoversion.");
|
|
39181
|
-
return { executed: true, success: true };
|
|
39182
|
-
}
|
|
39183
39181
|
const previousVersion = await this.resolvePreviousVersion({ service, rawDiff, mappedMagicVersion });
|
|
39184
39182
|
if (previousVersion == null) {
|
|
39185
39183
|
return await this.handleFirstGeneration({ service, language, mappedMagicVersion });
|
|
39186
39184
|
}
|
|
39185
|
+
if (rawDiff.trim().length === 0) {
|
|
39186
|
+
this.logger.info(
|
|
39187
|
+
`AutoVersionStep: empty diff between generations; rewriting placeholder to ${previousVersion}.`
|
|
39188
|
+
);
|
|
39189
|
+
return await this.finalizeNoChange({
|
|
39190
|
+
service,
|
|
39191
|
+
language,
|
|
39192
|
+
mappedMagicVersion,
|
|
39193
|
+
previousVersion,
|
|
39194
|
+
reason: "no diff between generations"
|
|
39195
|
+
});
|
|
39196
|
+
}
|
|
39187
39197
|
const cleanedDiff = service.cleanDiffForAI(rawDiff, mappedMagicVersion);
|
|
39188
39198
|
const rawBytes = Buffer.byteLength(rawDiff, "utf-8");
|
|
39189
39199
|
const cleanedBytes = Buffer.byteLength(cleanedDiff, "utf-8");
|
|
@@ -39191,8 +39201,16 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
39191
39201
|
`AutoVersionStep: raw=${formatSizeKB(rawBytes)}KB (${countFilesInDiff(rawDiff)} files), cleaned=${formatSizeKB(cleanedBytes)}KB (${countFilesInDiff(cleanedDiff)} files)`
|
|
39192
39202
|
);
|
|
39193
39203
|
if (cleanedDiff.trim().length === 0) {
|
|
39194
|
-
this.logger.info(
|
|
39195
|
-
|
|
39204
|
+
this.logger.info(
|
|
39205
|
+
`AutoVersionStep: cleaned diff is empty; no semantic changes \u2014 rewriting placeholder to ${previousVersion}.`
|
|
39206
|
+
);
|
|
39207
|
+
return await this.finalizeNoChange({
|
|
39208
|
+
service,
|
|
39209
|
+
language,
|
|
39210
|
+
mappedMagicVersion,
|
|
39211
|
+
previousVersion,
|
|
39212
|
+
reason: "no semantic changes"
|
|
39213
|
+
});
|
|
39196
39214
|
}
|
|
39197
39215
|
if (cleanedBytes > MAX_RAW_DIFF_BYTES) {
|
|
39198
39216
|
this.logger.warn(
|
|
@@ -39222,13 +39240,14 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
39222
39240
|
analysis = { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") };
|
|
39223
39241
|
}
|
|
39224
39242
|
if (analysis == null) {
|
|
39225
|
-
this.logger.info(
|
|
39226
|
-
return {
|
|
39227
|
-
|
|
39228
|
-
|
|
39243
|
+
this.logger.info(`AutoVersionStep: FAI returned NO_CHANGE; rewriting placeholder to ${previousVersion}.`);
|
|
39244
|
+
return await this.finalizeNoChange({
|
|
39245
|
+
service,
|
|
39246
|
+
language,
|
|
39247
|
+
mappedMagicVersion,
|
|
39229
39248
|
previousVersion,
|
|
39230
|
-
|
|
39231
|
-
};
|
|
39249
|
+
reason: "FAI returned NO_CHANGE"
|
|
39250
|
+
});
|
|
39232
39251
|
}
|
|
39233
39252
|
return await this.finalizeWithBump({
|
|
39234
39253
|
service,
|
|
@@ -39238,6 +39257,38 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
39238
39257
|
analysis
|
|
39239
39258
|
});
|
|
39240
39259
|
}
|
|
39260
|
+
/**
|
|
39261
|
+
* Terminal path for runs that determine no semver bump is needed. The
|
|
39262
|
+
* current working tree still contains `0.0.0-fern-placeholder` from this
|
|
39263
|
+
* run's generator output, so we must rewrite it to `previousVersion`
|
|
39264
|
+
* before exiting — otherwise the SDK ships with the placeholder embedded
|
|
39265
|
+
* in manifests (package.json, pyproject.toml, .fern/metadata.json) and
|
|
39266
|
+
* user-agent strings (e.g. `X-Fern-SDK-Version`). Commits the rewrite as
|
|
39267
|
+
* `[fern-autoversion]` so the replay + github steps see a stable base.
|
|
39268
|
+
*/
|
|
39269
|
+
async finalizeNoChange(params) {
|
|
39270
|
+
const { service, language, mappedMagicVersion, previousVersion, reason } = params;
|
|
39271
|
+
if (!isValidSemver(previousVersion)) {
|
|
39272
|
+
const errorMessage = `AutoVersionStep: resolved previousVersion ${JSON.stringify(previousVersion)} is not a valid semver string. Refusing to rewrite placeholder to avoid shell injection.`;
|
|
39273
|
+
this.logger.error(errorMessage);
|
|
39274
|
+
return { executed: true, success: false, errorMessage };
|
|
39275
|
+
}
|
|
39276
|
+
await service.replaceMagicVersion(this.outputDir, mappedMagicVersion, previousVersion);
|
|
39277
|
+
if (language === "go") {
|
|
39278
|
+
await service.addGoMajorVersionSuffix(this.outputDir, previousVersion);
|
|
39279
|
+
}
|
|
39280
|
+
const commitMessage = this.brandMessage(`SDK regeneration (no semver change: ${reason})`);
|
|
39281
|
+
const commitSha = this.commitAutoversion(commitMessage);
|
|
39282
|
+
return {
|
|
39283
|
+
executed: true,
|
|
39284
|
+
success: true,
|
|
39285
|
+
version: previousVersion,
|
|
39286
|
+
previousVersion,
|
|
39287
|
+
versionBump: "NO_CHANGE",
|
|
39288
|
+
commitMessage,
|
|
39289
|
+
commitSha
|
|
39290
|
+
};
|
|
39291
|
+
}
|
|
39241
39292
|
async finalizeWithBump(params) {
|
|
39242
39293
|
const { service, language, mappedMagicVersion, previousVersion, analysis } = params;
|
|
39243
39294
|
const newVersion = incrementVersion(previousVersion, analysis.versionBump);
|
|
@@ -40159,8 +40210,10 @@ var GithubStep = class extends BaseStep {
|
|
|
40159
40210
|
name = "github";
|
|
40160
40211
|
async execute(context) {
|
|
40161
40212
|
const replayResult = context.previousStepResults.replay;
|
|
40213
|
+
const autoVersionResult = context.previousStepResults.autoVersion;
|
|
40162
40214
|
const skipCommit = this.config.skipCommit ?? this.deriveSkipCommit(replayResult);
|
|
40163
40215
|
const replayConflictInfo = this.config.replayConflictInfo ?? this.deriveReplayConflictInfo(replayResult);
|
|
40216
|
+
const resolvedPrFields = this.resolvePrFields(autoVersionResult);
|
|
40164
40217
|
try {
|
|
40165
40218
|
this.logger.debug("Starting GitHub self-hosted flow in directory: " + this.outputDir);
|
|
40166
40219
|
const repository = ClonedRepository.createAtPath(this.outputDir);
|
|
@@ -40179,10 +40232,11 @@ var GithubStep = class extends BaseStep {
|
|
|
40179
40232
|
newPrBranch,
|
|
40180
40233
|
skipCommit,
|
|
40181
40234
|
replayConflictInfo,
|
|
40182
|
-
replayResult
|
|
40235
|
+
replayResult,
|
|
40236
|
+
resolvedPrFields
|
|
40183
40237
|
);
|
|
40184
40238
|
case "push":
|
|
40185
|
-
return await this.executePushMode(repository);
|
|
40239
|
+
return await this.executePushMode(repository, resolvedPrFields);
|
|
40186
40240
|
default: {
|
|
40187
40241
|
const exhaustive = mode;
|
|
40188
40242
|
throw new Error(`Unexpected GitHub mode: ${String(exhaustive)}`);
|
|
@@ -40198,7 +40252,7 @@ var GithubStep = class extends BaseStep {
|
|
|
40198
40252
|
};
|
|
40199
40253
|
}
|
|
40200
40254
|
}
|
|
40201
|
-
async executePullRequestMode(repository, newPrBranch, skipCommit, replayConflictInfo, replayResult) {
|
|
40255
|
+
async executePullRequestMode(repository, newPrBranch, skipCommit, replayConflictInfo, replayResult, resolved) {
|
|
40202
40256
|
const baseBranch = this.config.branch ?? await repository.getDefaultBranch();
|
|
40203
40257
|
const octokit = new Octokit2({ auth: this.config.token });
|
|
40204
40258
|
const { owner, repo } = parseRepository(this.config.uri);
|
|
@@ -40232,7 +40286,7 @@ var GithubStep = class extends BaseStep {
|
|
|
40232
40286
|
generationBaseSha = await createReplayBranch(
|
|
40233
40287
|
repository,
|
|
40234
40288
|
prBranch,
|
|
40235
|
-
|
|
40289
|
+
resolved.commitMessage,
|
|
40236
40290
|
replayConflictInfo,
|
|
40237
40291
|
this.logger
|
|
40238
40292
|
);
|
|
@@ -40254,8 +40308,7 @@ var GithubStep = class extends BaseStep {
|
|
|
40254
40308
|
if (!skipCommit) {
|
|
40255
40309
|
await this.ensureFernignore();
|
|
40256
40310
|
this.logger.debug("Committing changes...");
|
|
40257
|
-
|
|
40258
|
-
await repository.commitAllChanges(finalCommitMessage2);
|
|
40311
|
+
await repository.commitAllChanges(resolved.commitMessage);
|
|
40259
40312
|
this.logger.debug(`Committed changes to local copy of GitHub repository at ${this.outputDir}`);
|
|
40260
40313
|
}
|
|
40261
40314
|
if (shouldCheckNoDiff(this.config)) {
|
|
@@ -40295,22 +40348,21 @@ var GithubStep = class extends BaseStep {
|
|
|
40295
40348
|
}
|
|
40296
40349
|
}
|
|
40297
40350
|
}
|
|
40298
|
-
const finalCommitMessage = this.config.commitMessage ?? "SDK Generation";
|
|
40299
40351
|
const headSha = await repository.getHeadSha();
|
|
40300
|
-
const changelogUrl =
|
|
40352
|
+
const changelogUrl = resolved.changelogEntry ? `https://github.com/${this.config.uri}/blob/${headSha}/changelog.md` : void 0;
|
|
40301
40353
|
const { prTitle, prBody } = parseCommitMessageForPR(
|
|
40302
|
-
|
|
40303
|
-
|
|
40304
|
-
|
|
40305
|
-
|
|
40306
|
-
|
|
40307
|
-
|
|
40308
|
-
|
|
40354
|
+
resolved.commitMessage,
|
|
40355
|
+
resolved.changelogEntry,
|
|
40356
|
+
resolved.prDescription,
|
|
40357
|
+
resolved.versionBumpReason,
|
|
40358
|
+
resolved.previousVersion,
|
|
40359
|
+
resolved.newVersion,
|
|
40360
|
+
resolved.versionBump,
|
|
40309
40361
|
changelogUrl
|
|
40310
40362
|
);
|
|
40311
40363
|
const replaySection = formatReplayPrBody(replayResult, { branchName: prBranch, repoUri: this.config.uri });
|
|
40312
40364
|
let enrichedBody = replaySection != null ? prBody + "\n\n---\n\n" + replaySection : prBody;
|
|
40313
|
-
enrichedBody = enrichPrBodyForAutomation(enrichedBody, this.config);
|
|
40365
|
+
enrichedBody = enrichPrBodyForAutomation(enrichedBody, this.config, resolved);
|
|
40314
40366
|
if (isUpdatingExistingPR && existingPR != null) {
|
|
40315
40367
|
this.logger.info(`Updated existing pull request: ${existingPR.htmlUrl}`);
|
|
40316
40368
|
result.prUrl = existingPR.htmlUrl;
|
|
@@ -40341,7 +40393,7 @@ var GithubStep = class extends BaseStep {
|
|
|
40341
40393
|
this.logger.info(`Created pull request: ${pullRequest.html_url}`);
|
|
40342
40394
|
result.prUrl = pullRequest.html_url;
|
|
40343
40395
|
result.prNumber = pullRequest.number;
|
|
40344
|
-
if (shouldEnableAutomerge(this.config) && pullRequest.node_id) {
|
|
40396
|
+
if (shouldEnableAutomerge(this.config, resolved) && pullRequest.node_id) {
|
|
40345
40397
|
try {
|
|
40346
40398
|
await octokit.graphql(
|
|
40347
40399
|
`mutation($pullRequestId: ID!) {
|
|
@@ -40369,7 +40421,7 @@ var GithubStep = class extends BaseStep {
|
|
|
40369
40421
|
}
|
|
40370
40422
|
return result;
|
|
40371
40423
|
}
|
|
40372
|
-
async executePushMode(repository) {
|
|
40424
|
+
async executePushMode(repository, resolved) {
|
|
40373
40425
|
const baseBranch = this.config.branch ?? await repository.getDefaultBranch();
|
|
40374
40426
|
if (this.config.branch != null) {
|
|
40375
40427
|
this.logger.debug(`Checking out branch ${this.config.branch}`);
|
|
@@ -40377,8 +40429,7 @@ var GithubStep = class extends BaseStep {
|
|
|
40377
40429
|
}
|
|
40378
40430
|
await this.ensureFernignore();
|
|
40379
40431
|
this.logger.debug("Committing changes...");
|
|
40380
|
-
|
|
40381
|
-
await repository.commitAllChanges(finalCommitMessage);
|
|
40432
|
+
await repository.commitAllChanges(resolved.commitMessage);
|
|
40382
40433
|
this.logger.debug(`Committed changes to local copy of GitHub repository at ${this.outputDir}`);
|
|
40383
40434
|
if (shouldCheckNoDiff(this.config)) {
|
|
40384
40435
|
const noDiff = await repository.treeHashEquals(`origin/${baseBranch}`);
|
|
@@ -40441,14 +40492,33 @@ var GithubStep = class extends BaseStep {
|
|
|
40441
40492
|
}
|
|
40442
40493
|
return void 0;
|
|
40443
40494
|
}
|
|
40495
|
+
resolvePrFields(autoVersion) {
|
|
40496
|
+
return resolvePrFields(this.config, autoVersion);
|
|
40497
|
+
}
|
|
40444
40498
|
};
|
|
40445
|
-
function
|
|
40499
|
+
function resolvePrFields(config, autoVersion) {
|
|
40500
|
+
const autoVersionBreaking = autoVersion?.versionBump === "MAJOR";
|
|
40501
|
+
return {
|
|
40502
|
+
commitMessage: config.commitMessage ?? autoVersion?.commitMessage ?? "SDK Generation",
|
|
40503
|
+
changelogEntry: config.changelogEntry ?? autoVersion?.changelogEntry,
|
|
40504
|
+
prDescription: config.prDescription ?? autoVersion?.prDescription,
|
|
40505
|
+
versionBumpReason: config.versionBumpReason ?? autoVersion?.versionBumpReason,
|
|
40506
|
+
previousVersion: config.previousVersion ?? autoVersion?.previousVersion,
|
|
40507
|
+
newVersion: config.newVersion ?? autoVersion?.version,
|
|
40508
|
+
versionBump: config.versionBump ?? autoVersion?.versionBump,
|
|
40509
|
+
hasBreakingChanges: config.hasBreakingChanges ?? autoVersionBreaking,
|
|
40510
|
+
breakingChangesSummary: config.breakingChangesSummary ?? autoVersion?.prDescription
|
|
40511
|
+
};
|
|
40512
|
+
}
|
|
40513
|
+
function enrichPrBodyForAutomation(body, config, breaking = {}) {
|
|
40446
40514
|
if (!config.automationMode) {
|
|
40447
40515
|
return body;
|
|
40448
40516
|
}
|
|
40517
|
+
const hasBreakingChanges = breaking.hasBreakingChanges ?? config.hasBreakingChanges;
|
|
40518
|
+
const breakingChangesSummary = breaking.breakingChangesSummary ?? config.breakingChangesSummary;
|
|
40449
40519
|
let result = body;
|
|
40450
|
-
if (
|
|
40451
|
-
result += "\n\n---\n\n## \u26A0\uFE0F Breaking Changes\n\nThis release contains breaking changes that require manual review:\n\n" +
|
|
40520
|
+
if (hasBreakingChanges && breakingChangesSummary) {
|
|
40521
|
+
result += "\n\n---\n\n## \u26A0\uFE0F Breaking Changes\n\nThis release contains breaking changes that require manual review:\n\n" + breakingChangesSummary;
|
|
40452
40522
|
}
|
|
40453
40523
|
if (config.runId) {
|
|
40454
40524
|
result += `
|
|
@@ -40459,8 +40529,9 @@ _Fern Run ID: \`${config.runId}\`_`;
|
|
|
40459
40529
|
}
|
|
40460
40530
|
return result;
|
|
40461
40531
|
}
|
|
40462
|
-
function shouldEnableAutomerge(config) {
|
|
40463
|
-
|
|
40532
|
+
function shouldEnableAutomerge(config, breaking = {}) {
|
|
40533
|
+
const hasBreakingChanges = breaking.hasBreakingChanges ?? config.hasBreakingChanges;
|
|
40534
|
+
return config.automationMode === true && config.autoMerge === true && hasBreakingChanges !== true;
|
|
40464
40535
|
}
|
|
40465
40536
|
function shouldCheckNoDiff(config) {
|
|
40466
40537
|
return config.skipIfNoDiff === true;
|