@releasekit/publish 0.2.0-next.8 → 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Sam Maister
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -82,13 +82,21 @@ releasekit-publish --input version-output.json
82
82
  ### In CI (GitHub Actions)
83
83
 
84
84
  ```yaml
85
+ - name: Configure permissions (OIDC + git pushes)
86
+ # at job level:
87
+ # permissions:
88
+ # id-token: write
89
+ # contents: write
90
+
85
91
  - name: Version
86
92
  run: releasekit-version --json > version-output.json
87
93
 
88
94
  - name: Publish
89
95
  run: releasekit-publish --input version-output.json
96
+ # For OIDC trusted publishing: no npm token needed (recommended).
97
+ # For token-based publishing: set NPM_TOKEN (or NODE_AUTH_TOKEN).
90
98
  env:
91
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
99
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
92
100
  ```
93
101
 
94
102
  ## Configuration
@@ -105,6 +113,10 @@ Configure via `releasekit.config.json`:
105
113
  "access": "public",
106
114
  "copyFiles": ["LICENSE"]
107
115
  },
116
+ "git": {
117
+ "pushMethod": "auto",
118
+ "httpsTokenEnv": "GITHUB_TOKEN"
119
+ },
108
120
  "cargo": {
109
121
  "enabled": false,
110
122
  "noVerify": false
@@ -23,7 +23,9 @@ function getDefaultConfig() {
23
23
  push: true,
24
24
  pushMethod: "auto",
25
25
  remote: "origin",
26
- branch: "main"
26
+ branch: "main",
27
+ httpsTokenEnv: void 0,
28
+ skipHooks: false
27
29
  },
28
30
  githubRelease: {
29
31
  enabled: true,
@@ -71,7 +73,9 @@ function toPublishConfig(config) {
71
73
  push: config.git.push ?? defaults.git.push,
72
74
  pushMethod: config.git.pushMethod ?? defaults.git.pushMethod,
73
75
  remote: config.git.remote ?? defaults.git.remote,
74
- branch: config.git.branch ?? defaults.git.branch
76
+ branch: config.git.branch ?? defaults.git.branch,
77
+ httpsTokenEnv: config.git.httpsTokenEnv ?? defaults.git.httpsTokenEnv,
78
+ skipHooks: config.git.skipHooks ?? defaults.git.skipHooks
75
79
  } : defaults.git,
76
80
  githubRelease: {
77
81
  enabled: config.githubRelease?.enabled ?? defaults.githubRelease.enabled,
@@ -248,8 +252,20 @@ function createPublishError(code, details) {
248
252
  // src/utils/exec.ts
249
253
  import { execFile } from "child_process";
250
254
  import { debug, info } from "@releasekit/core";
255
+ function redactArg(arg) {
256
+ try {
257
+ const url = new URL(arg);
258
+ if (url.username || url.password) {
259
+ url.username = url.username ? "***" : "";
260
+ url.password = url.password ? "***" : "";
261
+ return url.toString();
262
+ }
263
+ } catch {
264
+ }
265
+ return arg;
266
+ }
251
267
  async function execCommand(file, args, options = {}) {
252
- const displayCommand = options.label ?? [file, ...args].join(" ");
268
+ const displayCommand = options.label ?? [file, ...args.map(redactArg)].join(" ");
253
269
  if (options.dryRun) {
254
270
  info(`[DRY RUN] Would execute: ${displayCommand}`);
255
271
  return { stdout: "", stderr: "", exitCode: 0 };
@@ -305,7 +321,7 @@ function detectNpmAuth() {
305
321
  if (process.env.ACTIONS_ID_TOKEN_REQUEST_URL) {
306
322
  return "oidc";
307
323
  }
308
- if (process.env.NPM_TOKEN) {
324
+ if (process.env.NPM_TOKEN || process.env.NODE_AUTH_TOKEN) {
309
325
  return "token";
310
326
  }
311
327
  return null;
@@ -560,8 +576,9 @@ function topologicalSort(crates) {
560
576
  import * as path3 from "path";
561
577
  import { info as info2, success as success2 } from "@releasekit/core";
562
578
  async function runGitCommitStage(ctx) {
563
- const { input, cliOptions, cwd } = ctx;
579
+ const { input, config, cliOptions, cwd } = ctx;
564
580
  const dryRun = cliOptions.dryRun;
581
+ const skipHooks = config.git.skipHooks ?? false;
565
582
  if (!input.commitMessage) {
566
583
  info2("No commit message provided, skipping git commit");
567
584
  return;
@@ -583,8 +600,13 @@ async function runGitCommitStage(ctx) {
583
600
  `git add failed: ${error instanceof Error ? error.message : String(error)}`
584
601
  );
585
602
  }
603
+ const commitArgs = ["commit"];
604
+ if (skipHooks) {
605
+ commitArgs.push("--no-verify");
606
+ }
607
+ commitArgs.push("-m", input.commitMessage);
586
608
  try {
587
- await execCommand("git", ["commit", "-m", input.commitMessage], {
609
+ await execCommand("git", commitArgs, {
588
610
  cwd,
589
611
  dryRun,
590
612
  label: `git commit -m "${input.commitMessage}"`
@@ -622,6 +644,18 @@ async function runGitCommitStage(ctx) {
622
644
 
623
645
  // src/stages/git-push.ts
624
646
  import { info as info3, success as success3 } from "@releasekit/core";
647
+ function toGithubAuthedUrl(remoteUrl, token) {
648
+ try {
649
+ const url = new URL(remoteUrl);
650
+ if (url.protocol !== "https:") return void 0;
651
+ if (url.host !== "github.com") return void 0;
652
+ url.username = "x-access-token";
653
+ url.password = token;
654
+ return url.toString();
655
+ } catch {
656
+ return void 0;
657
+ }
658
+ }
625
659
  async function runGitPushStage(ctx) {
626
660
  const { config, cliOptions, cwd, output } = ctx;
627
661
  const dryRun = cliOptions.dryRun;
@@ -642,16 +676,26 @@ async function runGitPushStage(ctx) {
642
676
  pushMethod = "https";
643
677
  }
644
678
  }
679
+ const httpsTokenEnv = config.git.httpsTokenEnv;
680
+ const httpsToken = httpsTokenEnv ? process.env[httpsTokenEnv] : void 0;
645
681
  try {
682
+ let pushRemote = remote;
683
+ if (pushMethod === "https" && httpsToken) {
684
+ const remoteUrlResult = await execCommand("git", ["remote", "get-url", remote], { cwd, dryRun: false });
685
+ const authed = toGithubAuthedUrl(remoteUrlResult.stdout.trim(), httpsToken);
686
+ if (authed) {
687
+ pushRemote = authed;
688
+ }
689
+ }
646
690
  if (output.git.committed) {
647
- await execCommand("git", ["push", remote, branch], {
691
+ await execCommand("git", ["push", pushRemote, branch], {
648
692
  cwd,
649
693
  dryRun,
650
694
  label: `git push ${remote} ${branch}`
651
695
  });
652
696
  }
653
697
  if (output.git.tags.length > 0) {
654
- await execCommand("git", ["push", remote, "--tags"], {
698
+ await execCommand("git", ["push", pushRemote, "--tags"], {
655
699
  cwd,
656
700
  dryRun,
657
701
  label: `git push ${remote} --tags`
@@ -696,7 +740,9 @@ async function runGithubReleaseStage(ctx) {
696
740
  if (!firstTag) return;
697
741
  const tagsToRelease = config.githubRelease.perPackage ? tags : [firstTag];
698
742
  for (const tag of tagsToRelease) {
699
- const versionMatch = tag.match(/(\d+\.\d+\.\d+.*)$/);
743
+ const MAX_TAG_LENGTH = 1e3;
744
+ const truncatedTag = tag.length > MAX_TAG_LENGTH ? tag.slice(0, MAX_TAG_LENGTH) : tag;
745
+ const versionMatch = truncatedTag.match(/(\d{1,20}\.\d{1,20}\.\d{1,20}(?:[-+.]?[a-zA-Z0-9.-]{0,100})?)$/);
700
746
  const version = versionMatch?.[1] ?? "";
701
747
  const isPreRel = config.githubRelease.prerelease === "auto" ? version ? isPrerelease(version) : false : config.githubRelease.prerelease;
702
748
  const result = {
@@ -738,9 +784,77 @@ async function runGithubReleaseStage(ctx) {
738
784
  }
739
785
 
740
786
  // src/stages/npm-publish.ts
787
+ import * as fs6 from "fs";
788
+ import * as path5 from "path";
789
+ import { debug as debug5, info as info5, success as success5, warn as warn3 } from "@releasekit/core";
790
+
791
+ // src/utils/npm-env.ts
741
792
  import * as fs5 from "fs";
793
+ import * as os from "os";
742
794
  import * as path4 from "path";
743
- import { debug as debug4, info as info5, success as success5, warn as warn3 } from "@releasekit/core";
795
+ import { debug as debug4 } from "@releasekit/core";
796
+ function writeTempNpmrc(contents) {
797
+ const dir = fs5.mkdtempSync(path4.join(os.tmpdir(), "releasekit-npmrc-"));
798
+ const npmrcPath = path4.join(dir, ".npmrc");
799
+ fs5.writeFileSync(npmrcPath, contents, "utf-8");
800
+ return {
801
+ npmrcPath,
802
+ cleanup: () => {
803
+ try {
804
+ fs5.rmSync(dir, { recursive: true, force: true });
805
+ } catch {
806
+ }
807
+ }
808
+ };
809
+ }
810
+ function createNpmSubprocessIsolation(options) {
811
+ const { authMethod, registryUrl } = options;
812
+ const baseEnv = {};
813
+ if (!authMethod) return { env: baseEnv, cleanup: () => {
814
+ } };
815
+ const token = process.env.NPM_TOKEN ?? process.env.NODE_AUTH_TOKEN;
816
+ const registryHost = (() => {
817
+ try {
818
+ return new URL(registryUrl).host;
819
+ } catch {
820
+ return "registry.npmjs.org";
821
+ }
822
+ })();
823
+ const lines = [`registry=${registryUrl}`];
824
+ if (authMethod === "oidc") {
825
+ lines.push("always-auth=false");
826
+ }
827
+ if (authMethod === "token" && token) {
828
+ lines.push(`//${registryHost}/:_authToken=${token}`);
829
+ }
830
+ lines.push("");
831
+ const { npmrcPath, cleanup } = writeTempNpmrc(lines.join("\n"));
832
+ debug4(`Using isolated npm userconfig: ${npmrcPath}`);
833
+ const isOidc = authMethod === "oidc";
834
+ return {
835
+ env: {
836
+ ...baseEnv,
837
+ // Ensure npm and tools that read npm_config_* pick up our temp file
838
+ NPM_CONFIG_USERCONFIG: npmrcPath,
839
+ npm_config_userconfig: npmrcPath,
840
+ // Auth-specific hardening
841
+ ...isOidc ? {
842
+ // Prevent setup-node's always-auth from forcing token lookups
843
+ NPM_CONFIG_ALWAYS_AUTH: "false",
844
+ npm_config_always_auth: "false",
845
+ // Explicitly prevent token-based publishing from being selected implicitly
846
+ NODE_AUTH_TOKEN: void 0,
847
+ NPM_TOKEN: void 0
848
+ } : {
849
+ // Ensure CLIs that expect NODE_AUTH_TOKEN can still work
850
+ NODE_AUTH_TOKEN: token
851
+ }
852
+ },
853
+ cleanup
854
+ };
855
+ }
856
+
857
+ // src/stages/npm-publish.ts
744
858
  async function runNpmPublishStage(ctx) {
745
859
  const { input, config, cliOptions, cwd } = ctx;
746
860
  const dryRun = cliOptions.dryRun;
@@ -753,98 +867,108 @@ async function runNpmPublishStage(ctx) {
753
867
  throw createPublishError("NPM_AUTH_ERROR" /* NPM_AUTH_ERROR */, "No NPM authentication method detected");
754
868
  }
755
869
  const useProvenance = config.npm.provenance && authMethod === "oidc";
756
- for (const update of input.updates) {
757
- const result = {
758
- packageName: update.packageName,
759
- version: update.newVersion,
760
- registry: "npm",
761
- success: false,
762
- skipped: false
763
- };
764
- const pkgJsonPath = path4.resolve(cwd, update.filePath);
765
- try {
766
- const pkgContent = fs5.readFileSync(pkgJsonPath, "utf-8");
767
- const pkgJson = JSON.parse(pkgContent);
768
- if (pkgJson.private) {
769
- result.skipped = true;
770
- result.success = true;
771
- result.reason = "Package is private";
772
- ctx.output.npm.push(result);
773
- debug4(`Skipping private package: ${update.packageName}`);
774
- continue;
870
+ const npmIsolation = createNpmSubprocessIsolation({
871
+ authMethod,
872
+ registryUrl: config.npm.registry
873
+ });
874
+ try {
875
+ for (const update of input.updates) {
876
+ const result = {
877
+ packageName: update.packageName,
878
+ version: update.newVersion,
879
+ registry: "npm",
880
+ success: false,
881
+ skipped: false
882
+ };
883
+ const pkgJsonPath = path5.resolve(cwd, update.filePath);
884
+ try {
885
+ const pkgContent = fs6.readFileSync(pkgJsonPath, "utf-8");
886
+ const pkgJson = JSON.parse(pkgContent);
887
+ if (pkgJson.private) {
888
+ result.skipped = true;
889
+ result.success = true;
890
+ result.reason = "Package is private";
891
+ ctx.output.npm.push(result);
892
+ debug5(`Skipping private package: ${update.packageName}`);
893
+ continue;
894
+ }
895
+ } catch {
896
+ if (update.filePath.endsWith("Cargo.toml")) {
897
+ result.skipped = true;
898
+ result.success = true;
899
+ result.reason = "Not an npm package";
900
+ ctx.output.npm.push(result);
901
+ continue;
902
+ }
775
903
  }
776
- } catch {
777
- if (update.filePath.endsWith("Cargo.toml")) {
904
+ const { file: viewFile, args: viewArgs } = buildViewCommand(
905
+ ctx.packageManager,
906
+ update.packageName,
907
+ update.newVersion
908
+ );
909
+ const viewResult = await execCommandSafe(viewFile, viewArgs, {
910
+ cwd,
911
+ dryRun: false,
912
+ // Always check, even in dry-run
913
+ env: npmIsolation.env
914
+ });
915
+ if (viewResult.exitCode === 0 && viewResult.stdout.trim()) {
916
+ result.alreadyPublished = true;
778
917
  result.skipped = true;
779
918
  result.success = true;
780
- result.reason = "Not an npm package";
919
+ result.reason = "Already published";
781
920
  ctx.output.npm.push(result);
921
+ warn3(`${update.packageName}@${update.newVersion} is already published, skipping`);
782
922
  continue;
783
923
  }
784
- }
785
- const { file: viewFile, args: viewArgs } = buildViewCommand(
786
- ctx.packageManager,
787
- update.packageName,
788
- update.newVersion
789
- );
790
- const viewResult = await execCommandSafe(viewFile, viewArgs, {
791
- cwd,
792
- dryRun: false
793
- // Always check, even in dry-run
794
- });
795
- if (viewResult.exitCode === 0 && viewResult.stdout.trim()) {
796
- result.alreadyPublished = true;
797
- result.skipped = true;
798
- result.success = true;
799
- result.reason = "Already published";
800
- ctx.output.npm.push(result);
801
- warn3(`${update.packageName}@${update.newVersion} is already published, skipping`);
802
- continue;
803
- }
804
- const distTag = getDistTag(update.newVersion, config.npm.tag);
805
- const pkgDir = path4.dirname(path4.resolve(cwd, update.filePath));
806
- const { file: pubFile, args: pubArgs } = buildPublishCommand(ctx.packageManager, update.packageName, pkgDir, {
807
- access: config.npm.access,
808
- tag: distTag,
809
- provenance: useProvenance,
810
- noGitChecks: true
811
- });
812
- try {
813
- await execCommand(pubFile, pubArgs, {
814
- cwd,
815
- dryRun,
816
- label: `npm publish ${update.packageName}@${update.newVersion}`
924
+ const distTag = getDistTag(update.newVersion, config.npm.tag);
925
+ const pkgDir = path5.dirname(path5.resolve(cwd, update.filePath));
926
+ const { file: pubFile, args: pubArgs } = buildPublishCommand(ctx.packageManager, update.packageName, pkgDir, {
927
+ access: config.npm.access,
928
+ tag: distTag,
929
+ provenance: useProvenance,
930
+ noGitChecks: true
817
931
  });
818
- result.success = true;
819
- if (!dryRun) {
820
- success5(`Published ${update.packageName}@${update.newVersion} to npm`);
932
+ try {
933
+ await execCommand(pubFile, pubArgs, {
934
+ cwd,
935
+ dryRun,
936
+ label: `npm publish ${update.packageName}@${update.newVersion}`,
937
+ env: npmIsolation.env
938
+ });
939
+ result.success = true;
940
+ if (!dryRun) {
941
+ success5(`Published ${update.packageName}@${update.newVersion} to npm`);
942
+ }
943
+ } catch (error) {
944
+ result.reason = error instanceof Error ? error.message : String(error);
945
+ warn3(`Failed to publish ${update.packageName}: ${result.reason}`);
821
946
  }
822
- } catch (error) {
823
- result.reason = error instanceof Error ? error.message : String(error);
824
- warn3(`Failed to publish ${update.packageName}: ${result.reason}`);
947
+ ctx.output.npm.push(result);
825
948
  }
826
- ctx.output.npm.push(result);
949
+ } finally {
950
+ npmIsolation.cleanup();
827
951
  }
828
952
  }
829
953
 
830
954
  // src/stages/prepare.ts
831
- import * as fs6 from "fs";
832
- import * as path5 from "path";
833
- import { debug as debug5, info as info6 } from "@releasekit/core";
955
+ import * as fs7 from "fs";
956
+ import * as path6 from "path";
957
+ import { debug as debug6, info as info6 } from "@releasekit/core";
834
958
  async function runPrepareStage(ctx) {
835
959
  const { input, config, cliOptions, cwd } = ctx;
836
960
  if (config.npm.enabled && config.npm.copyFiles.length > 0) {
837
961
  for (const update of input.updates) {
838
- const pkgDir = path5.dirname(path5.resolve(cwd, update.filePath));
962
+ const pkgDir = path6.dirname(path6.resolve(cwd, update.filePath));
839
963
  for (const file of config.npm.copyFiles) {
840
- const src = path5.resolve(cwd, file);
841
- const dest = path5.join(pkgDir, file);
842
- if (!fs6.existsSync(src)) {
843
- debug5(`Source file not found, skipping copy: ${src}`);
964
+ const src = path6.resolve(cwd, file);
965
+ const dest = path6.join(pkgDir, file);
966
+ if (!fs7.existsSync(src)) {
967
+ debug6(`Source file not found, skipping copy: ${src}`);
844
968
  continue;
845
969
  }
846
- if (path5.resolve(path5.dirname(src)) === path5.resolve(pkgDir)) {
847
- debug5(`Skipping copy of ${file} - same directory as source`);
970
+ if (path6.resolve(path6.dirname(src)) === path6.resolve(pkgDir)) {
971
+ debug6(`Skipping copy of ${file} - same directory as source`);
848
972
  continue;
849
973
  }
850
974
  if (cliOptions.dryRun) {
@@ -852,8 +976,8 @@ async function runPrepareStage(ctx) {
852
976
  continue;
853
977
  }
854
978
  try {
855
- fs6.copyFileSync(src, dest);
856
- debug5(`Copied ${file} \u2192 ${pkgDir}`);
979
+ fs7.copyFileSync(src, dest);
980
+ debug6(`Copied ${file} \u2192 ${pkgDir}`);
857
981
  } catch (error) {
858
982
  throw createPublishError(
859
983
  "FILE_COPY_ERROR" /* FILE_COPY_ERROR */,
@@ -865,9 +989,9 @@ async function runPrepareStage(ctx) {
865
989
  }
866
990
  if (config.cargo.enabled) {
867
991
  for (const update of input.updates) {
868
- const pkgDir = path5.dirname(path5.resolve(cwd, update.filePath));
869
- const cargoPath = path5.join(pkgDir, "Cargo.toml");
870
- if (!fs6.existsSync(cargoPath)) {
992
+ const pkgDir = path6.dirname(path6.resolve(cwd, update.filePath));
993
+ const cargoPath = path6.join(pkgDir, "Cargo.toml");
994
+ if (!fs7.existsSync(cargoPath)) {
871
995
  continue;
872
996
  }
873
997
  if (cliOptions.dryRun) {
@@ -875,16 +999,16 @@ async function runPrepareStage(ctx) {
875
999
  continue;
876
1000
  }
877
1001
  updateCargoVersion(cargoPath, update.newVersion);
878
- debug5(`Updated ${cargoPath} to version ${update.newVersion}`);
1002
+ debug6(`Updated ${cargoPath} to version ${update.newVersion}`);
879
1003
  }
880
1004
  }
881
1005
  }
882
1006
 
883
1007
  // src/stages/verify.ts
884
- import { debug as debug7, info as info7, success as success6, warn as warn4 } from "@releasekit/core";
1008
+ import { debug as debug8, info as info7, success as success6, warn as warn4 } from "@releasekit/core";
885
1009
 
886
1010
  // src/utils/retry.ts
887
- import { debug as debug6 } from "@releasekit/core";
1011
+ import { debug as debug7 } from "@releasekit/core";
888
1012
  async function withRetry(fn, options, shouldRetry) {
889
1013
  let lastError;
890
1014
  let delay = options.initialDelay;
@@ -897,7 +1021,7 @@ async function withRetry(fn, options, shouldRetry) {
897
1021
  throw error;
898
1022
  }
899
1023
  if (attempt < options.maxAttempts) {
900
- debug6(`Attempt ${attempt}/${options.maxAttempts} failed, retrying in ${delay}ms...`);
1024
+ debug7(`Attempt ${attempt}/${options.maxAttempts} failed, retrying in ${delay}ms...`);
901
1025
  await sleep(delay);
902
1026
  delay = Math.floor(delay * options.backoffMultiplier);
903
1027
  }
@@ -939,7 +1063,7 @@ async function runVerifyStage(ctx) {
939
1063
  if (viewResult.exitCode !== 0 || !viewResult.stdout.trim()) {
940
1064
  throw new Error(`${pkg.packageName}@${pkg.version} not yet available on npm`);
941
1065
  }
942
- debug7(`Verified ${pkg.packageName}@${pkg.version} on npm`);
1066
+ debug8(`Verified ${pkg.packageName}@${pkg.version} on npm`);
943
1067
  }, config.verify.npm);
944
1068
  result.verified = true;
945
1069
  success6(`Verified ${pkg.packageName}@${pkg.version} on npm`);
@@ -972,7 +1096,7 @@ async function runVerifyStage(ctx) {
972
1096
  if (!response.ok) {
973
1097
  throw new Error(`${crate.packageName}@${crate.version} not yet available on crates.io`);
974
1098
  }
975
- debug7(`Verified ${crate.packageName}@${crate.version} on crates.io`);
1099
+ debug8(`Verified ${crate.packageName}@${crate.version} on crates.io`);
976
1100
  }, config.verify.cargo);
977
1101
  result.verified = true;
978
1102
  success6(`Verified ${crate.packageName}@${crate.version} on crates.io`);
@@ -1023,7 +1147,10 @@ async function runPipeline(input, config, options) {
1023
1147
  };
1024
1148
  try {
1025
1149
  await runPrepareStage(ctx);
1026
- if (!options.skipGit) {
1150
+ if (options.skipGitCommit && !options.skipGit) {
1151
+ ctx.output.git.committed = !!input.commitMessage;
1152
+ ctx.output.git.tags = [...input.tags];
1153
+ } else if (!options.skipGit) {
1027
1154
  await runGitCommitStage(ctx);
1028
1155
  }
1029
1156
  if (!options.skipPublish) {
@@ -1052,7 +1179,7 @@ async function runPipeline(input, config, options) {
1052
1179
  }
1053
1180
 
1054
1181
  // src/stages/input.ts
1055
- import * as fs7 from "fs";
1182
+ import * as fs8 from "fs";
1056
1183
  import { info as info8 } from "@releasekit/core";
1057
1184
  import { z } from "zod";
1058
1185
  var VersionChangelogEntrySchema = z.object({
@@ -1086,7 +1213,7 @@ async function parseInput(inputPath) {
1086
1213
  let raw;
1087
1214
  if (inputPath) {
1088
1215
  try {
1089
- raw = fs7.readFileSync(inputPath, "utf-8");
1216
+ raw = fs8.readFileSync(inputPath, "utf-8");
1090
1217
  } catch {
1091
1218
  throw createPublishError("INPUT_PARSE_ERROR" /* INPUT_PARSE_ERROR */, `Could not read file: ${inputPath}`);
1092
1219
  }