@fern-api/generator-cli 0.10.0 → 0.10.1
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/cli.js +150 -17
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -42211,7 +42211,8 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42211
42211
|
};
|
|
42212
42212
|
}
|
|
42213
42213
|
async finalizeWithBump(params) {
|
|
42214
|
-
const { service, language, mappedMagicVersion, previousVersion
|
|
42214
|
+
const { service, language, mappedMagicVersion, previousVersion } = params;
|
|
42215
|
+
const analysis = this.withChangelogFallback(params.analysis);
|
|
42215
42216
|
const newVersion = incrementVersion(previousVersion, analysis.versionBump);
|
|
42216
42217
|
this.logger.info(`AutoVersionStep: ${analysis.versionBump} bump: ${previousVersion} \u2192 ${newVersion}`);
|
|
42217
42218
|
await service.replaceMagicVersion(this.outputDir, mappedMagicVersion, newVersion);
|
|
@@ -42265,7 +42266,8 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42265
42266
|
* the bumped version but does NOT commit — GithubStep handles the commit.
|
|
42266
42267
|
*/
|
|
42267
42268
|
async finalizeWithBumpNonReplay(params) {
|
|
42268
|
-
const { service, language, mappedMagicVersion, previousVersion
|
|
42269
|
+
const { service, language, mappedMagicVersion, previousVersion } = params;
|
|
42270
|
+
const analysis = this.withChangelogFallback(params.analysis);
|
|
42269
42271
|
const newVersion = incrementVersion(previousVersion, analysis.versionBump);
|
|
42270
42272
|
this.logger.info(
|
|
42271
42273
|
`AutoVersionStep (non-replay): ${analysis.versionBump} bump: ${previousVersion} \u2192 ${newVersion}`
|
|
@@ -42572,6 +42574,26 @@ ${body}` : `${COMMIT_MARKER} ${subject}`;
|
|
|
42572
42574
|
}
|
|
42573
42575
|
await (0, import_promises16.writeFile)(changelogPath, prependChangelogBlock({ existingContent: existing, version: version2, entry }), "utf-8");
|
|
42574
42576
|
}
|
|
42577
|
+
/**
|
|
42578
|
+
* MAJOR/MINOR bumps must ship a changelog entry. FAI occasionally returns a
|
|
42579
|
+
* bump with a populated `pr_description` / `version_bump_reason` but an empty
|
|
42580
|
+
* `changelog_entry`; reuse that text rather than writing a version-only block.
|
|
42581
|
+
*/
|
|
42582
|
+
withChangelogFallback(analysis) {
|
|
42583
|
+
const fallback = resolveChangelogEntryFallbackWithSource(analysis);
|
|
42584
|
+
if (fallback == null) {
|
|
42585
|
+
if (analysis.versionBump !== "PATCH" && !hasText(analysis.changelogEntry)) {
|
|
42586
|
+
this.logger.warn(
|
|
42587
|
+
`AutoVersionStep: FAI returned a ${analysis.versionBump} bump without a changelog entry and no fallback text.`
|
|
42588
|
+
);
|
|
42589
|
+
}
|
|
42590
|
+
return analysis;
|
|
42591
|
+
}
|
|
42592
|
+
this.logger.warn(
|
|
42593
|
+
`AutoVersionStep: FAI returned a ${analysis.versionBump} bump without a changelog entry; using the ${fallback.source} instead.`
|
|
42594
|
+
);
|
|
42595
|
+
return { ...analysis, changelogEntry: fallback.text };
|
|
42596
|
+
}
|
|
42575
42597
|
brandMessage(message) {
|
|
42576
42598
|
if (this.config.isWhitelabel) {
|
|
42577
42599
|
return message;
|
|
@@ -42602,10 +42624,7 @@ ${body}` : `${COMMIT_MARKER} ${subject}`;
|
|
|
42602
42624
|
}
|
|
42603
42625
|
async analyzeChunks(chunks, language, previousVersion) {
|
|
42604
42626
|
const { client, VersionBump: VersionBump4 } = await this.loadBaml();
|
|
42605
|
-
|
|
42606
|
-
let bestMessage = "";
|
|
42607
|
-
let bestVersionBumpReason;
|
|
42608
|
-
const changelogEntries = [];
|
|
42627
|
+
const chunkAnalyses = [];
|
|
42609
42628
|
for (let i2 = 0; i2 < chunks.length; i2++) {
|
|
42610
42629
|
const chunk = chunks[i2];
|
|
42611
42630
|
if (!chunk) {
|
|
@@ -42621,20 +42640,22 @@ ${body}` : `${COMMIT_MARKER} ${subject}`;
|
|
|
42621
42640
|
if (analysis.version_bump === VersionBump4.NO_CHANGE) {
|
|
42622
42641
|
continue;
|
|
42623
42642
|
}
|
|
42624
|
-
|
|
42625
|
-
|
|
42626
|
-
|
|
42627
|
-
|
|
42628
|
-
|
|
42629
|
-
}
|
|
42630
|
-
const entry = analysis.changelog_entry?.trim();
|
|
42631
|
-
if (entry) {
|
|
42632
|
-
changelogEntries.push(entry);
|
|
42633
|
-
}
|
|
42643
|
+
chunkAnalyses.push({
|
|
42644
|
+
versionBump: analysis.version_bump,
|
|
42645
|
+
message: analysis.message,
|
|
42646
|
+
changelogEntry: analysis.changelog_entry,
|
|
42647
|
+
versionBumpReason: analysis.version_bump_reason
|
|
42648
|
+
});
|
|
42634
42649
|
}
|
|
42635
|
-
if (
|
|
42650
|
+
if (chunkAnalyses.length === 0) {
|
|
42636
42651
|
return null;
|
|
42637
42652
|
}
|
|
42653
|
+
const { bestBump, bestMessage, bestVersionBumpReason, changelogEntries, usedBumpReasonAsEntry } = aggregateChunkAnalyses(chunkAnalyses);
|
|
42654
|
+
if (usedBumpReasonAsEntry) {
|
|
42655
|
+
this.logger.warn(
|
|
42656
|
+
`AutoVersionStep: no chunk produced a changelog entry for the ${bestBump} bump; using its version bump reason instead.`
|
|
42657
|
+
);
|
|
42658
|
+
}
|
|
42638
42659
|
if (changelogEntries.length <= 1) {
|
|
42639
42660
|
return {
|
|
42640
42661
|
versionBump: bestBump,
|
|
@@ -42750,6 +42771,57 @@ ${body}` : `${COMMIT_MARKER} ${subject}`;
|
|
|
42750
42771
|
return adapter;
|
|
42751
42772
|
}
|
|
42752
42773
|
};
|
|
42774
|
+
function aggregateChunkAnalyses(chunkAnalyses) {
|
|
42775
|
+
let bestBump = "NO_CHANGE";
|
|
42776
|
+
let bestMessage = "";
|
|
42777
|
+
let bestVersionBumpReason;
|
|
42778
|
+
const entries2 = [];
|
|
42779
|
+
for (const analysis of chunkAnalyses) {
|
|
42780
|
+
const prev = bestBump;
|
|
42781
|
+
bestBump = maxVersionBump(bestBump, analysis.versionBump);
|
|
42782
|
+
if (bestBump !== prev) {
|
|
42783
|
+
bestMessage = analysis.message;
|
|
42784
|
+
bestVersionBumpReason = analysis.versionBumpReason;
|
|
42785
|
+
}
|
|
42786
|
+
const text = analysis.changelogEntry?.trim();
|
|
42787
|
+
if (text) {
|
|
42788
|
+
entries2.push({ bump: analysis.versionBump, text });
|
|
42789
|
+
}
|
|
42790
|
+
}
|
|
42791
|
+
const changelogEntries = entries2.map((entry) => entry.text);
|
|
42792
|
+
const hasEntryAtBestBump = entries2.some((entry) => entry.bump === bestBump);
|
|
42793
|
+
const usedBumpReasonAsEntry = bestBump !== "PATCH" && !hasEntryAtBestBump && hasText(bestVersionBumpReason);
|
|
42794
|
+
if (usedBumpReasonAsEntry && bestVersionBumpReason != null) {
|
|
42795
|
+
changelogEntries.unshift(bestVersionBumpReason.trim());
|
|
42796
|
+
}
|
|
42797
|
+
return { bestBump, bestMessage, bestVersionBumpReason, changelogEntries, usedBumpReasonAsEntry };
|
|
42798
|
+
}
|
|
42799
|
+
function hasText(value) {
|
|
42800
|
+
return value != null && value.trim().length > 0;
|
|
42801
|
+
}
|
|
42802
|
+
function commitMessageBody(message) {
|
|
42803
|
+
const trimmed2 = message.trimEnd();
|
|
42804
|
+
const withoutTrailer = trimmed2.endsWith(FERN_TRAILER) ? trimmed2.slice(0, -FERN_TRAILER.length) : trimmed2;
|
|
42805
|
+
const [, ...rest] = withoutTrailer.split("\n");
|
|
42806
|
+
const body = rest.join("\n").trim();
|
|
42807
|
+
return body.length > 0 ? body : void 0;
|
|
42808
|
+
}
|
|
42809
|
+
function resolveChangelogEntryFallbackWithSource(analysis) {
|
|
42810
|
+
if (hasText(analysis.changelogEntry) || analysis.versionBump === "PATCH") {
|
|
42811
|
+
return void 0;
|
|
42812
|
+
}
|
|
42813
|
+
const candidates = [
|
|
42814
|
+
["PR description", analysis.prDescription],
|
|
42815
|
+
["version bump reason", analysis.versionBumpReason],
|
|
42816
|
+
["commit message body", commitMessageBody(analysis.message)]
|
|
42817
|
+
];
|
|
42818
|
+
for (const [source, text] of candidates) {
|
|
42819
|
+
if (hasText(text)) {
|
|
42820
|
+
return { source, text: text.trim() };
|
|
42821
|
+
}
|
|
42822
|
+
}
|
|
42823
|
+
return void 0;
|
|
42824
|
+
}
|
|
42753
42825
|
var FAI_VERSION_BUMPS = ["MAJOR", "MINOR", "PATCH", "NO_CHANGE"];
|
|
42754
42826
|
function isFaiAnalyzeResponse(value) {
|
|
42755
42827
|
if (typeof value !== "object" || value == null) {
|
|
@@ -43921,6 +43993,66 @@ var ReplayStep = class extends BaseStep {
|
|
|
43921
43993
|
}
|
|
43922
43994
|
};
|
|
43923
43995
|
|
|
43996
|
+
// ../cli/generation/local-generation/docker-utils/lib/dockerHubOatLogin.js
|
|
43997
|
+
var DOCKERHUB_OAT_ENV_VAR = "DOCKERHUB_OAT";
|
|
43998
|
+
var DOCKERHUB_OAT_USERNAME_ENV_VAR = "DOCKERHUB_OAT_USERNAME";
|
|
43999
|
+
var DEFAULT_DOCKERHUB_OAT_USERNAME = "fernenterprise";
|
|
44000
|
+
var DOCKER_HUB_HOSTS = /* @__PURE__ */ new Set([
|
|
44001
|
+
"docker.io",
|
|
44002
|
+
"index.docker.io",
|
|
44003
|
+
"registry-1.docker.io",
|
|
44004
|
+
"registry.hub.docker.com"
|
|
44005
|
+
]);
|
|
44006
|
+
function getDockerHubNamespace(imageName) {
|
|
44007
|
+
const parts = imageName.split("/");
|
|
44008
|
+
const [first2] = parts;
|
|
44009
|
+
if (first2 == null || parts.length < 2) {
|
|
44010
|
+
return void 0;
|
|
44011
|
+
}
|
|
44012
|
+
const host = first2.toLowerCase();
|
|
44013
|
+
const isRegistryHost = host.includes(".") || host.includes(":") || host === "localhost";
|
|
44014
|
+
if (!isRegistryHost) {
|
|
44015
|
+
return first2;
|
|
44016
|
+
}
|
|
44017
|
+
if (!DOCKER_HUB_HOSTS.has(host)) {
|
|
44018
|
+
return void 0;
|
|
44019
|
+
}
|
|
44020
|
+
return parts.length >= 3 ? parts[1] : void 0;
|
|
44021
|
+
}
|
|
44022
|
+
function resolveDockerHubOatLogin(imageName, env3 = process.env) {
|
|
44023
|
+
const token = env3[DOCKERHUB_OAT_ENV_VAR]?.trim();
|
|
44024
|
+
if (token == null || token === "") {
|
|
44025
|
+
return void 0;
|
|
44026
|
+
}
|
|
44027
|
+
const username = env3[DOCKERHUB_OAT_USERNAME_ENV_VAR]?.trim() || DEFAULT_DOCKERHUB_OAT_USERNAME;
|
|
44028
|
+
if (getDockerHubNamespace(imageName) !== username) {
|
|
44029
|
+
return void 0;
|
|
44030
|
+
}
|
|
44031
|
+
return { username, token };
|
|
44032
|
+
}
|
|
44033
|
+
async function ensureDockerHubOatLogin({ imageName, runner, logger, signal, env: env3 = process.env }) {
|
|
44034
|
+
const credentials = resolveDockerHubOatLogin(imageName, env3);
|
|
44035
|
+
if (credentials == null) {
|
|
44036
|
+
return;
|
|
44037
|
+
}
|
|
44038
|
+
logger?.debug(`Logging in to Docker Hub as ${credentials.username} with ${DOCKERHUB_OAT_ENV_VAR} to pull ${imageName}`);
|
|
44039
|
+
const { exitCode, stdout, stderr } = await loggingExeca(logger, runner ?? "docker", ["login", "--username", credentials.username, "--password-stdin"], {
|
|
44040
|
+
input: credentials.token,
|
|
44041
|
+
reject: false,
|
|
44042
|
+
doNotPipeOutput: true,
|
|
44043
|
+
secrets: [credentials.token],
|
|
44044
|
+
signal
|
|
44045
|
+
});
|
|
44046
|
+
if (exitCode !== 0) {
|
|
44047
|
+
if (signal?.aborted === true) {
|
|
44048
|
+
throw new Error(`Docker Hub login as ${credentials.username} was cancelled.`);
|
|
44049
|
+
}
|
|
44050
|
+
throw new Error(`Failed to log in to Docker Hub as ${credentials.username} using ${DOCKERHUB_OAT_ENV_VAR}. Check that the token is a valid organization access token for ${credentials.username} with pull access to ${imageName}.
|
|
44051
|
+
${stdout}
|
|
44052
|
+
${stderr}`);
|
|
44053
|
+
}
|
|
44054
|
+
}
|
|
44055
|
+
|
|
43924
44056
|
// ../cli/generation/local-generation/docker-utils/lib/runDocker.js
|
|
43925
44057
|
var import_promises18 = require("fs/promises");
|
|
43926
44058
|
var import_tmp_promise3 = __toESM(require_tmp_promise(), 1);
|
|
@@ -43955,6 +44087,7 @@ async function pullImage(imageName, runner, signal) {
|
|
|
43955
44087
|
}
|
|
43956
44088
|
async function startContainer({ logger, imageName, runner }) {
|
|
43957
44089
|
const containerRunner = runner ?? "docker";
|
|
44090
|
+
await ensureDockerHubOatLogin({ imageName, runner, logger });
|
|
43958
44091
|
const tryStart = async () => {
|
|
43959
44092
|
const { stdout, exitCode, stderr } = await loggingExeca(logger, containerRunner, ["run", "--user", "root", "-dit", "--entrypoint", "/bin/sh", imageName], {
|
|
43960
44093
|
reject: false,
|