@releasekit/publish 0.2.0-next.9 → 0.3.0-next.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/LICENSE +21 -0
- package/README.md +13 -1
- package/dist/{chunk-Y7Y6GQ6R.js → chunk-GOBII36Q.js} +297 -112
- package/dist/cli.cjs +317 -134
- package/dist/cli.js +1 -1
- package/dist/index.cjs +311 -128
- package/dist/index.d.cts +13 -2
- package/dist/index.d.ts +13 -2
- package/dist/index.js +1 -1
- package/package.json +38 -28
package/dist/index.cjs
CHANGED
|
@@ -75,14 +75,16 @@ function getDefaultConfig() {
|
|
|
75
75
|
push: true,
|
|
76
76
|
pushMethod: "auto",
|
|
77
77
|
remote: "origin",
|
|
78
|
-
branch: "main"
|
|
78
|
+
branch: "main",
|
|
79
|
+
httpsTokenEnv: void 0,
|
|
80
|
+
skipHooks: false
|
|
79
81
|
},
|
|
80
82
|
githubRelease: {
|
|
81
83
|
enabled: true,
|
|
82
84
|
draft: true,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
perPackage: true,
|
|
86
|
+
prerelease: "auto",
|
|
87
|
+
releaseNotes: "auto"
|
|
86
88
|
},
|
|
87
89
|
verify: {
|
|
88
90
|
npm: {
|
|
@@ -123,15 +125,16 @@ function toPublishConfig(config) {
|
|
|
123
125
|
push: config.git.push ?? defaults.git.push,
|
|
124
126
|
pushMethod: config.git.pushMethod ?? defaults.git.pushMethod,
|
|
125
127
|
remote: config.git.remote ?? defaults.git.remote,
|
|
126
|
-
branch: config.git.branch ?? defaults.git.branch
|
|
128
|
+
branch: config.git.branch ?? defaults.git.branch,
|
|
129
|
+
httpsTokenEnv: config.git.httpsTokenEnv ?? defaults.git.httpsTokenEnv,
|
|
130
|
+
skipHooks: config.git.skipHooks ?? defaults.git.skipHooks
|
|
127
131
|
} : defaults.git,
|
|
128
132
|
githubRelease: {
|
|
129
133
|
enabled: config.githubRelease?.enabled ?? defaults.githubRelease.enabled,
|
|
130
134
|
draft: config.githubRelease?.draft ?? defaults.githubRelease.draft,
|
|
131
|
-
generateNotes: config.githubRelease?.generateNotes ?? defaults.githubRelease.generateNotes,
|
|
132
135
|
perPackage: config.githubRelease?.perPackage ?? defaults.githubRelease.perPackage,
|
|
133
136
|
prerelease: config.githubRelease?.prerelease ?? defaults.githubRelease.prerelease,
|
|
134
|
-
|
|
137
|
+
releaseNotes: config.githubRelease?.releaseNotes ?? defaults.githubRelease.releaseNotes
|
|
135
138
|
},
|
|
136
139
|
verify: {
|
|
137
140
|
npm: {
|
|
@@ -305,8 +308,20 @@ var import_core3 = require("@releasekit/core");
|
|
|
305
308
|
// src/utils/exec.ts
|
|
306
309
|
var import_node_child_process = require("child_process");
|
|
307
310
|
var import_core2 = require("@releasekit/core");
|
|
311
|
+
function redactArg(arg) {
|
|
312
|
+
try {
|
|
313
|
+
const url = new URL(arg);
|
|
314
|
+
if (url.username || url.password) {
|
|
315
|
+
url.username = url.username ? "***" : "";
|
|
316
|
+
url.password = url.password ? "***" : "";
|
|
317
|
+
return url.toString();
|
|
318
|
+
}
|
|
319
|
+
} catch {
|
|
320
|
+
}
|
|
321
|
+
return arg;
|
|
322
|
+
}
|
|
308
323
|
async function execCommand(file, args, options = {}) {
|
|
309
|
-
const displayCommand = options.label ?? [file, ...args].join(" ");
|
|
324
|
+
const displayCommand = options.label ?? [file, ...args.map(redactArg)].join(" ");
|
|
310
325
|
if (options.dryRun) {
|
|
311
326
|
(0, import_core2.info)(`[DRY RUN] Would execute: ${displayCommand}`);
|
|
312
327
|
return { stdout: "", stderr: "", exitCode: 0 };
|
|
@@ -362,7 +377,7 @@ function detectNpmAuth() {
|
|
|
362
377
|
if (process.env.ACTIONS_ID_TOKEN_REQUEST_URL) {
|
|
363
378
|
return "oidc";
|
|
364
379
|
}
|
|
365
|
-
if (process.env.NPM_TOKEN) {
|
|
380
|
+
if (process.env.NPM_TOKEN || process.env.NODE_AUTH_TOKEN) {
|
|
366
381
|
return "token";
|
|
367
382
|
}
|
|
368
383
|
return null;
|
|
@@ -571,13 +586,17 @@ function topologicalSort(crates) {
|
|
|
571
586
|
var path2 = __toESM(require("path"), 1);
|
|
572
587
|
var import_core4 = require("@releasekit/core");
|
|
573
588
|
async function runGitCommitStage(ctx) {
|
|
574
|
-
const { input, cliOptions, cwd } = ctx;
|
|
589
|
+
const { input, config, cliOptions, cwd } = ctx;
|
|
575
590
|
const dryRun = cliOptions.dryRun;
|
|
591
|
+
const skipHooks = config.git.skipHooks ?? false;
|
|
576
592
|
if (!input.commitMessage) {
|
|
577
593
|
(0, import_core4.info)("No commit message provided, skipping git commit");
|
|
578
594
|
return;
|
|
579
595
|
}
|
|
580
596
|
const filePaths = input.updates.map((u) => path2.resolve(cwd, u.filePath));
|
|
597
|
+
if (ctx.additionalFiles) {
|
|
598
|
+
filePaths.push(...ctx.additionalFiles.map((f) => path2.resolve(cwd, f)));
|
|
599
|
+
}
|
|
581
600
|
if (filePaths.length === 0) {
|
|
582
601
|
(0, import_core4.info)("No files to commit");
|
|
583
602
|
return;
|
|
@@ -594,8 +613,13 @@ async function runGitCommitStage(ctx) {
|
|
|
594
613
|
`git add failed: ${error instanceof Error ? error.message : String(error)}`
|
|
595
614
|
);
|
|
596
615
|
}
|
|
616
|
+
const commitArgs = ["commit"];
|
|
617
|
+
if (skipHooks) {
|
|
618
|
+
commitArgs.push("--no-verify");
|
|
619
|
+
}
|
|
620
|
+
commitArgs.push("-m", input.commitMessage);
|
|
597
621
|
try {
|
|
598
|
-
await execCommand("git",
|
|
622
|
+
await execCommand("git", commitArgs, {
|
|
599
623
|
cwd,
|
|
600
624
|
dryRun,
|
|
601
625
|
label: `git commit -m "${input.commitMessage}"`
|
|
@@ -633,6 +657,18 @@ async function runGitCommitStage(ctx) {
|
|
|
633
657
|
|
|
634
658
|
// src/stages/git-push.ts
|
|
635
659
|
var import_core5 = require("@releasekit/core");
|
|
660
|
+
function toGithubAuthedUrl(remoteUrl, token) {
|
|
661
|
+
try {
|
|
662
|
+
const url = new URL(remoteUrl);
|
|
663
|
+
if (url.protocol !== "https:") return void 0;
|
|
664
|
+
if (url.host !== "github.com") return void 0;
|
|
665
|
+
url.username = "x-access-token";
|
|
666
|
+
url.password = token;
|
|
667
|
+
return url.toString();
|
|
668
|
+
} catch {
|
|
669
|
+
return void 0;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
636
672
|
async function runGitPushStage(ctx) {
|
|
637
673
|
const { config, cliOptions, cwd, output } = ctx;
|
|
638
674
|
const dryRun = cliOptions.dryRun;
|
|
@@ -653,16 +689,26 @@ async function runGitPushStage(ctx) {
|
|
|
653
689
|
pushMethod = "https";
|
|
654
690
|
}
|
|
655
691
|
}
|
|
692
|
+
const httpsTokenEnv = config.git.httpsTokenEnv;
|
|
693
|
+
const httpsToken = httpsTokenEnv ? process.env[httpsTokenEnv] : void 0;
|
|
656
694
|
try {
|
|
695
|
+
let pushRemote = remote;
|
|
696
|
+
if (pushMethod === "https" && httpsToken) {
|
|
697
|
+
const remoteUrlResult = await execCommand("git", ["remote", "get-url", remote], { cwd, dryRun: false });
|
|
698
|
+
const authed = toGithubAuthedUrl(remoteUrlResult.stdout.trim(), httpsToken);
|
|
699
|
+
if (authed) {
|
|
700
|
+
pushRemote = authed;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
657
703
|
if (output.git.committed) {
|
|
658
|
-
await execCommand("git", ["push",
|
|
704
|
+
await execCommand("git", ["push", pushRemote, branch], {
|
|
659
705
|
cwd,
|
|
660
706
|
dryRun,
|
|
661
707
|
label: `git push ${remote} ${branch}`
|
|
662
708
|
});
|
|
663
709
|
}
|
|
664
710
|
if (output.git.tags.length > 0) {
|
|
665
|
-
await execCommand("git", ["push",
|
|
711
|
+
await execCommand("git", ["push", pushRemote, "--tags"], {
|
|
666
712
|
cwd,
|
|
667
713
|
dryRun,
|
|
668
714
|
label: `git push ${remote} --tags`
|
|
@@ -699,6 +745,62 @@ function getDistTag(version, defaultTag = "latest") {
|
|
|
699
745
|
}
|
|
700
746
|
|
|
701
747
|
// src/stages/github-release.ts
|
|
748
|
+
function resolveNotes(notesSetting, tag, changelogs, pipelineNotes) {
|
|
749
|
+
if (notesSetting === "none") {
|
|
750
|
+
return { useGithubNotes: false };
|
|
751
|
+
}
|
|
752
|
+
if (notesSetting === "github") {
|
|
753
|
+
return { useGithubNotes: true };
|
|
754
|
+
}
|
|
755
|
+
if (notesSetting !== "auto") {
|
|
756
|
+
const body = readFileIfExists(notesSetting);
|
|
757
|
+
if (body) return { body, useGithubNotes: false };
|
|
758
|
+
(0, import_core6.debug)(`Notes file not found: ${notesSetting}, falling back to GitHub auto-notes`);
|
|
759
|
+
return { useGithubNotes: true };
|
|
760
|
+
}
|
|
761
|
+
if (pipelineNotes) {
|
|
762
|
+
const body = findNotesForTag(tag, pipelineNotes);
|
|
763
|
+
if (body) return { body, useGithubNotes: false };
|
|
764
|
+
}
|
|
765
|
+
const packageBody = formatChangelogForTag(tag, changelogs);
|
|
766
|
+
if (packageBody) {
|
|
767
|
+
return { body: packageBody, useGithubNotes: false };
|
|
768
|
+
}
|
|
769
|
+
return { useGithubNotes: true };
|
|
770
|
+
}
|
|
771
|
+
function isVersionOnlyTag(tag) {
|
|
772
|
+
return /^v?\d+\.\d+\.\d+/.test(tag);
|
|
773
|
+
}
|
|
774
|
+
function findNotesForTag(tag, notes) {
|
|
775
|
+
for (const [packageName, body] of Object.entries(notes)) {
|
|
776
|
+
if (tag.startsWith(`${packageName}@`) && body.trim()) {
|
|
777
|
+
return body;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
const entries = Object.values(notes).filter((b) => b.trim());
|
|
781
|
+
if (entries.length === 1 && isVersionOnlyTag(tag)) return entries[0];
|
|
782
|
+
return void 0;
|
|
783
|
+
}
|
|
784
|
+
function readFileIfExists(filePath) {
|
|
785
|
+
try {
|
|
786
|
+
const content = fs3.readFileSync(filePath, "utf-8").trim();
|
|
787
|
+
return content || void 0;
|
|
788
|
+
} catch {
|
|
789
|
+
return void 0;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
function formatChangelogForTag(tag, changelogs) {
|
|
793
|
+
if (changelogs.length === 0) return void 0;
|
|
794
|
+
const changelog = changelogs.find((c) => tag.startsWith(`${c.packageName}@`));
|
|
795
|
+
const target = changelog ?? (changelogs.length === 1 && isVersionOnlyTag(tag) ? changelogs[0] : void 0);
|
|
796
|
+
if (!target || target.entries.length === 0) return void 0;
|
|
797
|
+
const lines = [];
|
|
798
|
+
for (const entry of target.entries) {
|
|
799
|
+
const scope = entry.scope ? `**${entry.scope}:** ` : "";
|
|
800
|
+
lines.push(`- ${scope}${entry.description}`);
|
|
801
|
+
}
|
|
802
|
+
return lines.join("\n");
|
|
803
|
+
}
|
|
702
804
|
async function runGithubReleaseStage(ctx) {
|
|
703
805
|
const { config, cliOptions, output } = ctx;
|
|
704
806
|
const dryRun = cliOptions.dryRun;
|
|
@@ -711,19 +813,13 @@ async function runGithubReleaseStage(ctx) {
|
|
|
711
813
|
(0, import_core6.info)("No tags available for GitHub release");
|
|
712
814
|
return;
|
|
713
815
|
}
|
|
714
|
-
let notesBody;
|
|
715
|
-
if (config.githubRelease.notesFile) {
|
|
716
|
-
try {
|
|
717
|
-
notesBody = fs3.readFileSync(config.githubRelease.notesFile, "utf-8");
|
|
718
|
-
} catch {
|
|
719
|
-
(0, import_core6.debug)(`Could not read notes file: ${config.githubRelease.notesFile}`);
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
816
|
const firstTag = tags[0];
|
|
723
817
|
if (!firstTag) return;
|
|
724
818
|
const tagsToRelease = config.githubRelease.perPackage ? tags : [firstTag];
|
|
725
819
|
for (const tag of tagsToRelease) {
|
|
726
|
-
const
|
|
820
|
+
const MAX_TAG_LENGTH = 1e3;
|
|
821
|
+
const truncatedTag = tag.length > MAX_TAG_LENGTH ? tag.slice(0, MAX_TAG_LENGTH) : tag;
|
|
822
|
+
const versionMatch = truncatedTag.match(/(\d{1,20}\.\d{1,20}\.\d{1,20}(?:[-+.]?[a-zA-Z0-9.-]{0,100})?)$/);
|
|
727
823
|
const version = versionMatch?.[1] ?? "";
|
|
728
824
|
const isPreRel = config.githubRelease.prerelease === "auto" ? version ? isPrerelease(version) : false : config.githubRelease.prerelease;
|
|
729
825
|
const result = {
|
|
@@ -739,9 +835,15 @@ async function runGithubReleaseStage(ctx) {
|
|
|
739
835
|
if (isPreRel) {
|
|
740
836
|
ghArgs.push("--prerelease");
|
|
741
837
|
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
838
|
+
const { body, useGithubNotes } = resolveNotes(
|
|
839
|
+
config.githubRelease.releaseNotes,
|
|
840
|
+
tag,
|
|
841
|
+
ctx.input.changelogs,
|
|
842
|
+
ctx.releaseNotes
|
|
843
|
+
);
|
|
844
|
+
if (body) {
|
|
845
|
+
ghArgs.push("--notes", body);
|
|
846
|
+
} else if (useGithubNotes) {
|
|
745
847
|
ghArgs.push("--generate-notes");
|
|
746
848
|
}
|
|
747
849
|
try {
|
|
@@ -765,16 +867,82 @@ async function runGithubReleaseStage(ctx) {
|
|
|
765
867
|
}
|
|
766
868
|
|
|
767
869
|
// src/stages/npm-publish.ts
|
|
768
|
-
var
|
|
769
|
-
var
|
|
770
|
-
var
|
|
870
|
+
var fs6 = __toESM(require("fs"), 1);
|
|
871
|
+
var path5 = __toESM(require("path"), 1);
|
|
872
|
+
var import_core8 = require("@releasekit/core");
|
|
771
873
|
|
|
772
|
-
// src/utils/
|
|
874
|
+
// src/utils/npm-env.ts
|
|
773
875
|
var fs4 = __toESM(require("fs"), 1);
|
|
876
|
+
var os = __toESM(require("os"), 1);
|
|
774
877
|
var path3 = __toESM(require("path"), 1);
|
|
878
|
+
var import_core7 = require("@releasekit/core");
|
|
879
|
+
function writeTempNpmrc(contents) {
|
|
880
|
+
const dir = fs4.mkdtempSync(path3.join(os.tmpdir(), "releasekit-npmrc-"));
|
|
881
|
+
const npmrcPath = path3.join(dir, ".npmrc");
|
|
882
|
+
fs4.writeFileSync(npmrcPath, contents, "utf-8");
|
|
883
|
+
return {
|
|
884
|
+
npmrcPath,
|
|
885
|
+
cleanup: () => {
|
|
886
|
+
try {
|
|
887
|
+
fs4.rmSync(dir, { recursive: true, force: true });
|
|
888
|
+
} catch {
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
function createNpmSubprocessIsolation(options) {
|
|
894
|
+
const { authMethod, registryUrl } = options;
|
|
895
|
+
const baseEnv = {};
|
|
896
|
+
if (!authMethod) return { env: baseEnv, cleanup: () => {
|
|
897
|
+
} };
|
|
898
|
+
const token = process.env.NPM_TOKEN ?? process.env.NODE_AUTH_TOKEN;
|
|
899
|
+
const registryHost = (() => {
|
|
900
|
+
try {
|
|
901
|
+
return new URL(registryUrl).host;
|
|
902
|
+
} catch {
|
|
903
|
+
return "registry.npmjs.org";
|
|
904
|
+
}
|
|
905
|
+
})();
|
|
906
|
+
const lines = [`registry=${registryUrl}`];
|
|
907
|
+
if (authMethod === "oidc") {
|
|
908
|
+
lines.push("always-auth=false");
|
|
909
|
+
}
|
|
910
|
+
if (authMethod === "token" && token) {
|
|
911
|
+
lines.push(`//${registryHost}/:_authToken=${token}`);
|
|
912
|
+
}
|
|
913
|
+
lines.push("");
|
|
914
|
+
const { npmrcPath, cleanup } = writeTempNpmrc(lines.join("\n"));
|
|
915
|
+
(0, import_core7.debug)(`Using isolated npm userconfig: ${npmrcPath}`);
|
|
916
|
+
const isOidc = authMethod === "oidc";
|
|
917
|
+
return {
|
|
918
|
+
env: {
|
|
919
|
+
...baseEnv,
|
|
920
|
+
// Ensure npm and tools that read npm_config_* pick up our temp file
|
|
921
|
+
NPM_CONFIG_USERCONFIG: npmrcPath,
|
|
922
|
+
npm_config_userconfig: npmrcPath,
|
|
923
|
+
// Auth-specific hardening
|
|
924
|
+
...isOidc ? {
|
|
925
|
+
// Prevent setup-node's always-auth from forcing token lookups
|
|
926
|
+
NPM_CONFIG_ALWAYS_AUTH: "false",
|
|
927
|
+
npm_config_always_auth: "false",
|
|
928
|
+
// Explicitly prevent token-based publishing from being selected implicitly
|
|
929
|
+
NODE_AUTH_TOKEN: void 0,
|
|
930
|
+
NPM_TOKEN: void 0
|
|
931
|
+
} : {
|
|
932
|
+
// Ensure CLIs that expect NODE_AUTH_TOKEN can still work
|
|
933
|
+
NODE_AUTH_TOKEN: token
|
|
934
|
+
}
|
|
935
|
+
},
|
|
936
|
+
cleanup
|
|
937
|
+
};
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
// src/utils/package-manager.ts
|
|
941
|
+
var fs5 = __toESM(require("fs"), 1);
|
|
942
|
+
var path4 = __toESM(require("path"), 1);
|
|
775
943
|
function detectPackageManager(cwd) {
|
|
776
|
-
if (
|
|
777
|
-
if (
|
|
944
|
+
if (fs5.existsSync(path4.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
945
|
+
if (fs5.existsSync(path4.join(cwd, "yarn.lock"))) return "yarn";
|
|
778
946
|
return "npm";
|
|
779
947
|
}
|
|
780
948
|
function buildPublishCommand(pm, packageName, _packageDir, options) {
|
|
@@ -803,7 +971,7 @@ async function runNpmPublishStage(ctx) {
|
|
|
803
971
|
const { input, config, cliOptions, cwd } = ctx;
|
|
804
972
|
const dryRun = cliOptions.dryRun;
|
|
805
973
|
if (!config.npm.enabled) {
|
|
806
|
-
(0,
|
|
974
|
+
(0, import_core8.info)("NPM publishing disabled in config");
|
|
807
975
|
return;
|
|
808
976
|
}
|
|
809
977
|
const authMethod = config.npm.auth === "auto" ? detectNpmAuth() : config.npm.auth;
|
|
@@ -811,107 +979,117 @@ async function runNpmPublishStage(ctx) {
|
|
|
811
979
|
throw createPublishError("NPM_AUTH_ERROR" /* NPM_AUTH_ERROR */, "No NPM authentication method detected");
|
|
812
980
|
}
|
|
813
981
|
const useProvenance = config.npm.provenance && authMethod === "oidc";
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
(
|
|
832
|
-
|
|
982
|
+
const npmIsolation = createNpmSubprocessIsolation({
|
|
983
|
+
authMethod,
|
|
984
|
+
registryUrl: config.npm.registry
|
|
985
|
+
});
|
|
986
|
+
try {
|
|
987
|
+
for (const update of input.updates) {
|
|
988
|
+
const result = {
|
|
989
|
+
packageName: update.packageName,
|
|
990
|
+
version: update.newVersion,
|
|
991
|
+
registry: "npm",
|
|
992
|
+
success: false,
|
|
993
|
+
skipped: false
|
|
994
|
+
};
|
|
995
|
+
const pkgJsonPath = path5.resolve(cwd, update.filePath);
|
|
996
|
+
try {
|
|
997
|
+
const pkgContent = fs6.readFileSync(pkgJsonPath, "utf-8");
|
|
998
|
+
const pkgJson = JSON.parse(pkgContent);
|
|
999
|
+
if (pkgJson.private) {
|
|
1000
|
+
result.skipped = true;
|
|
1001
|
+
result.success = true;
|
|
1002
|
+
result.reason = "Package is private";
|
|
1003
|
+
ctx.output.npm.push(result);
|
|
1004
|
+
(0, import_core8.debug)(`Skipping private package: ${update.packageName}`);
|
|
1005
|
+
continue;
|
|
1006
|
+
}
|
|
1007
|
+
} catch {
|
|
1008
|
+
if (update.filePath.endsWith("Cargo.toml")) {
|
|
1009
|
+
result.skipped = true;
|
|
1010
|
+
result.success = true;
|
|
1011
|
+
result.reason = "Not an npm package";
|
|
1012
|
+
ctx.output.npm.push(result);
|
|
1013
|
+
continue;
|
|
1014
|
+
}
|
|
833
1015
|
}
|
|
834
|
-
|
|
835
|
-
|
|
1016
|
+
const { file: viewFile, args: viewArgs } = buildViewCommand(
|
|
1017
|
+
ctx.packageManager,
|
|
1018
|
+
update.packageName,
|
|
1019
|
+
update.newVersion
|
|
1020
|
+
);
|
|
1021
|
+
const viewResult = await execCommandSafe(viewFile, viewArgs, {
|
|
1022
|
+
cwd,
|
|
1023
|
+
dryRun: false,
|
|
1024
|
+
// Always check, even in dry-run
|
|
1025
|
+
env: npmIsolation.env
|
|
1026
|
+
});
|
|
1027
|
+
if (viewResult.exitCode === 0 && viewResult.stdout.trim()) {
|
|
1028
|
+
result.alreadyPublished = true;
|
|
836
1029
|
result.skipped = true;
|
|
837
1030
|
result.success = true;
|
|
838
|
-
result.reason = "
|
|
1031
|
+
result.reason = "Already published";
|
|
839
1032
|
ctx.output.npm.push(result);
|
|
1033
|
+
(0, import_core8.warn)(`${update.packageName}@${update.newVersion} is already published, skipping`);
|
|
840
1034
|
continue;
|
|
841
1035
|
}
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
ctx.packageManager,
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
cwd,
|
|
850
|
-
dryRun: false
|
|
851
|
-
// Always check, even in dry-run
|
|
852
|
-
});
|
|
853
|
-
if (viewResult.exitCode === 0 && viewResult.stdout.trim()) {
|
|
854
|
-
result.alreadyPublished = true;
|
|
855
|
-
result.skipped = true;
|
|
856
|
-
result.success = true;
|
|
857
|
-
result.reason = "Already published";
|
|
858
|
-
ctx.output.npm.push(result);
|
|
859
|
-
(0, import_core7.warn)(`${update.packageName}@${update.newVersion} is already published, skipping`);
|
|
860
|
-
continue;
|
|
861
|
-
}
|
|
862
|
-
const distTag = getDistTag(update.newVersion, config.npm.tag);
|
|
863
|
-
const pkgDir = path4.dirname(path4.resolve(cwd, update.filePath));
|
|
864
|
-
const { file: pubFile, args: pubArgs } = buildPublishCommand(ctx.packageManager, update.packageName, pkgDir, {
|
|
865
|
-
access: config.npm.access,
|
|
866
|
-
tag: distTag,
|
|
867
|
-
provenance: useProvenance,
|
|
868
|
-
noGitChecks: true
|
|
869
|
-
});
|
|
870
|
-
try {
|
|
871
|
-
await execCommand(pubFile, pubArgs, {
|
|
872
|
-
cwd,
|
|
873
|
-
dryRun,
|
|
874
|
-
label: `npm publish ${update.packageName}@${update.newVersion}`
|
|
1036
|
+
const distTag = getDistTag(update.newVersion, config.npm.tag);
|
|
1037
|
+
const pkgDir = path5.dirname(path5.resolve(cwd, update.filePath));
|
|
1038
|
+
const { file: pubFile, args: pubArgs } = buildPublishCommand(ctx.packageManager, update.packageName, pkgDir, {
|
|
1039
|
+
access: config.npm.access,
|
|
1040
|
+
tag: distTag,
|
|
1041
|
+
provenance: useProvenance,
|
|
1042
|
+
noGitChecks: true
|
|
875
1043
|
});
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
1044
|
+
try {
|
|
1045
|
+
await execCommand(pubFile, pubArgs, {
|
|
1046
|
+
cwd,
|
|
1047
|
+
dryRun,
|
|
1048
|
+
label: `npm publish ${update.packageName}@${update.newVersion}`,
|
|
1049
|
+
env: npmIsolation.env
|
|
1050
|
+
});
|
|
1051
|
+
result.success = true;
|
|
1052
|
+
if (!dryRun) {
|
|
1053
|
+
(0, import_core8.success)(`Published ${update.packageName}@${update.newVersion} to npm`);
|
|
1054
|
+
}
|
|
1055
|
+
} catch (error) {
|
|
1056
|
+
result.reason = error instanceof Error ? error.message : String(error);
|
|
1057
|
+
(0, import_core8.warn)(`Failed to publish ${update.packageName}: ${result.reason}`);
|
|
879
1058
|
}
|
|
880
|
-
|
|
881
|
-
result.reason = error instanceof Error ? error.message : String(error);
|
|
882
|
-
(0, import_core7.warn)(`Failed to publish ${update.packageName}: ${result.reason}`);
|
|
1059
|
+
ctx.output.npm.push(result);
|
|
883
1060
|
}
|
|
884
|
-
|
|
1061
|
+
} finally {
|
|
1062
|
+
npmIsolation.cleanup();
|
|
885
1063
|
}
|
|
886
1064
|
}
|
|
887
1065
|
|
|
888
1066
|
// src/stages/prepare.ts
|
|
889
|
-
var
|
|
890
|
-
var
|
|
891
|
-
var
|
|
1067
|
+
var fs7 = __toESM(require("fs"), 1);
|
|
1068
|
+
var path6 = __toESM(require("path"), 1);
|
|
1069
|
+
var import_core9 = require("@releasekit/core");
|
|
892
1070
|
async function runPrepareStage(ctx) {
|
|
893
1071
|
const { input, config, cliOptions, cwd } = ctx;
|
|
894
1072
|
if (config.npm.enabled && config.npm.copyFiles.length > 0) {
|
|
895
1073
|
for (const update of input.updates) {
|
|
896
|
-
const pkgDir =
|
|
1074
|
+
const pkgDir = path6.dirname(path6.resolve(cwd, update.filePath));
|
|
897
1075
|
for (const file of config.npm.copyFiles) {
|
|
898
|
-
const src =
|
|
899
|
-
const dest =
|
|
900
|
-
if (!
|
|
901
|
-
(0,
|
|
1076
|
+
const src = path6.resolve(cwd, file);
|
|
1077
|
+
const dest = path6.join(pkgDir, file);
|
|
1078
|
+
if (!fs7.existsSync(src)) {
|
|
1079
|
+
(0, import_core9.debug)(`Source file not found, skipping copy: ${src}`);
|
|
902
1080
|
continue;
|
|
903
1081
|
}
|
|
904
|
-
if (
|
|
905
|
-
(0,
|
|
1082
|
+
if (path6.resolve(path6.dirname(src)) === path6.resolve(pkgDir)) {
|
|
1083
|
+
(0, import_core9.debug)(`Skipping copy of ${file} - same directory as source`);
|
|
906
1084
|
continue;
|
|
907
1085
|
}
|
|
908
1086
|
if (cliOptions.dryRun) {
|
|
909
|
-
(0,
|
|
1087
|
+
(0, import_core9.info)(`[DRY RUN] Would copy ${src} \u2192 ${dest}`);
|
|
910
1088
|
continue;
|
|
911
1089
|
}
|
|
912
1090
|
try {
|
|
913
|
-
|
|
914
|
-
(0,
|
|
1091
|
+
fs7.copyFileSync(src, dest);
|
|
1092
|
+
(0, import_core9.debug)(`Copied ${file} \u2192 ${pkgDir}`);
|
|
915
1093
|
} catch (error) {
|
|
916
1094
|
throw createPublishError(
|
|
917
1095
|
"FILE_COPY_ERROR" /* FILE_COPY_ERROR */,
|
|
@@ -923,26 +1101,26 @@ async function runPrepareStage(ctx) {
|
|
|
923
1101
|
}
|
|
924
1102
|
if (config.cargo.enabled) {
|
|
925
1103
|
for (const update of input.updates) {
|
|
926
|
-
const pkgDir =
|
|
927
|
-
const cargoPath =
|
|
928
|
-
if (!
|
|
1104
|
+
const pkgDir = path6.dirname(path6.resolve(cwd, update.filePath));
|
|
1105
|
+
const cargoPath = path6.join(pkgDir, "Cargo.toml");
|
|
1106
|
+
if (!fs7.existsSync(cargoPath)) {
|
|
929
1107
|
continue;
|
|
930
1108
|
}
|
|
931
1109
|
if (cliOptions.dryRun) {
|
|
932
|
-
(0,
|
|
1110
|
+
(0, import_core9.info)(`[DRY RUN] Would update ${cargoPath} to version ${update.newVersion}`);
|
|
933
1111
|
continue;
|
|
934
1112
|
}
|
|
935
1113
|
updateCargoVersion(cargoPath, update.newVersion);
|
|
936
|
-
(0,
|
|
1114
|
+
(0, import_core9.debug)(`Updated ${cargoPath} to version ${update.newVersion}`);
|
|
937
1115
|
}
|
|
938
1116
|
}
|
|
939
1117
|
}
|
|
940
1118
|
|
|
941
1119
|
// src/stages/verify.ts
|
|
942
|
-
var
|
|
1120
|
+
var import_core11 = require("@releasekit/core");
|
|
943
1121
|
|
|
944
1122
|
// src/utils/retry.ts
|
|
945
|
-
var
|
|
1123
|
+
var import_core10 = require("@releasekit/core");
|
|
946
1124
|
async function withRetry(fn, options, shouldRetry) {
|
|
947
1125
|
let lastError;
|
|
948
1126
|
let delay = options.initialDelay;
|
|
@@ -955,7 +1133,7 @@ async function withRetry(fn, options, shouldRetry) {
|
|
|
955
1133
|
throw error;
|
|
956
1134
|
}
|
|
957
1135
|
if (attempt < options.maxAttempts) {
|
|
958
|
-
(0,
|
|
1136
|
+
(0, import_core10.debug)(`Attempt ${attempt}/${options.maxAttempts} failed, retrying in ${delay}ms...`);
|
|
959
1137
|
await sleep(delay);
|
|
960
1138
|
delay = Math.floor(delay * options.backoffMultiplier);
|
|
961
1139
|
}
|
|
@@ -981,7 +1159,7 @@ async function runVerifyStage(ctx) {
|
|
|
981
1159
|
attempts: 0
|
|
982
1160
|
};
|
|
983
1161
|
if (cliOptions.dryRun) {
|
|
984
|
-
(0,
|
|
1162
|
+
(0, import_core11.info)(`[DRY RUN] Would verify ${pkg.packageName}@${pkg.version} on npm`);
|
|
985
1163
|
result.verified = true;
|
|
986
1164
|
ctx.output.verification.push(result);
|
|
987
1165
|
continue;
|
|
@@ -997,12 +1175,12 @@ async function runVerifyStage(ctx) {
|
|
|
997
1175
|
if (viewResult.exitCode !== 0 || !viewResult.stdout.trim()) {
|
|
998
1176
|
throw new Error(`${pkg.packageName}@${pkg.version} not yet available on npm`);
|
|
999
1177
|
}
|
|
1000
|
-
(0,
|
|
1178
|
+
(0, import_core11.debug)(`Verified ${pkg.packageName}@${pkg.version} on npm`);
|
|
1001
1179
|
}, config.verify.npm);
|
|
1002
1180
|
result.verified = true;
|
|
1003
|
-
(0,
|
|
1181
|
+
(0, import_core11.success)(`Verified ${pkg.packageName}@${pkg.version} on npm`);
|
|
1004
1182
|
} catch {
|
|
1005
|
-
(0,
|
|
1183
|
+
(0, import_core11.warn)(`Failed to verify ${pkg.packageName}@${pkg.version} on npm after ${result.attempts} attempts`);
|
|
1006
1184
|
}
|
|
1007
1185
|
ctx.output.verification.push(result);
|
|
1008
1186
|
}
|
|
@@ -1018,7 +1196,7 @@ async function runVerifyStage(ctx) {
|
|
|
1018
1196
|
attempts: 0
|
|
1019
1197
|
};
|
|
1020
1198
|
if (cliOptions.dryRun) {
|
|
1021
|
-
(0,
|
|
1199
|
+
(0, import_core11.info)(`[DRY RUN] Would verify ${crate.packageName}@${crate.version} on crates.io`);
|
|
1022
1200
|
result.verified = true;
|
|
1023
1201
|
ctx.output.verification.push(result);
|
|
1024
1202
|
continue;
|
|
@@ -1030,12 +1208,12 @@ async function runVerifyStage(ctx) {
|
|
|
1030
1208
|
if (!response.ok) {
|
|
1031
1209
|
throw new Error(`${crate.packageName}@${crate.version} not yet available on crates.io`);
|
|
1032
1210
|
}
|
|
1033
|
-
(0,
|
|
1211
|
+
(0, import_core11.debug)(`Verified ${crate.packageName}@${crate.version} on crates.io`);
|
|
1034
1212
|
}, config.verify.cargo);
|
|
1035
1213
|
result.verified = true;
|
|
1036
|
-
(0,
|
|
1214
|
+
(0, import_core11.success)(`Verified ${crate.packageName}@${crate.version} on crates.io`);
|
|
1037
1215
|
} catch {
|
|
1038
|
-
(0,
|
|
1216
|
+
(0, import_core11.warn)(`Failed to verify ${crate.packageName}@${crate.version} on crates.io after ${result.attempts} attempts`);
|
|
1039
1217
|
}
|
|
1040
1218
|
ctx.output.verification.push(result);
|
|
1041
1219
|
}
|
|
@@ -1070,6 +1248,8 @@ async function runPipeline(input, config, options) {
|
|
|
1070
1248
|
cliOptions: options,
|
|
1071
1249
|
packageManager: detectPackageManager(cwd),
|
|
1072
1250
|
cwd,
|
|
1251
|
+
releaseNotes: options.releaseNotes,
|
|
1252
|
+
additionalFiles: options.additionalFiles,
|
|
1073
1253
|
output: {
|
|
1074
1254
|
dryRun: options.dryRun,
|
|
1075
1255
|
git: { committed: false, tags: [], pushed: false },
|
|
@@ -1081,7 +1261,10 @@ async function runPipeline(input, config, options) {
|
|
|
1081
1261
|
};
|
|
1082
1262
|
try {
|
|
1083
1263
|
await runPrepareStage(ctx);
|
|
1084
|
-
if (!options.skipGit) {
|
|
1264
|
+
if (options.skipGitCommit && !options.skipGit) {
|
|
1265
|
+
ctx.output.git.committed = !!input.commitMessage;
|
|
1266
|
+
ctx.output.git.tags = [...input.tags];
|
|
1267
|
+
} else if (!options.skipGit) {
|
|
1085
1268
|
await runGitCommitStage(ctx);
|
|
1086
1269
|
}
|
|
1087
1270
|
if (!options.skipPublish) {
|
|
@@ -1110,8 +1293,8 @@ async function runPipeline(input, config, options) {
|
|
|
1110
1293
|
}
|
|
1111
1294
|
|
|
1112
1295
|
// src/stages/input.ts
|
|
1113
|
-
var
|
|
1114
|
-
var
|
|
1296
|
+
var fs8 = __toESM(require("fs"), 1);
|
|
1297
|
+
var import_core12 = require("@releasekit/core");
|
|
1115
1298
|
var import_zod = require("zod");
|
|
1116
1299
|
var VersionChangelogEntrySchema = import_zod.z.object({
|
|
1117
1300
|
type: import_zod.z.string(),
|
|
@@ -1144,7 +1327,7 @@ async function parseInput(inputPath) {
|
|
|
1144
1327
|
let raw;
|
|
1145
1328
|
if (inputPath) {
|
|
1146
1329
|
try {
|
|
1147
|
-
raw =
|
|
1330
|
+
raw = fs8.readFileSync(inputPath, "utf-8");
|
|
1148
1331
|
} catch {
|
|
1149
1332
|
throw createPublishError("INPUT_PARSE_ERROR" /* INPUT_PARSE_ERROR */, `Could not read file: ${inputPath}`);
|
|
1150
1333
|
}
|
|
@@ -1164,7 +1347,7 @@ async function parseInput(inputPath) {
|
|
|
1164
1347
|
${issues}`);
|
|
1165
1348
|
}
|
|
1166
1349
|
if (result.data.updates.length === 0) {
|
|
1167
|
-
(0,
|
|
1350
|
+
(0, import_core12.info)("No package updates in version output \u2014 pipeline will be a no-op");
|
|
1168
1351
|
}
|
|
1169
1352
|
return result.data;
|
|
1170
1353
|
}
|