@bensandee/tooling 0.27.1 → 0.28.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/dist/bin.mjs CHANGED
@@ -113,6 +113,7 @@ const LEGACY_PATTERNS = {
113
113
  /** Detect existing project state in the target directory. */
114
114
  function detectProject(targetDir) {
115
115
  const exists = (rel) => existsSync(path.join(targetDir, rel));
116
+ const rootPkg = readPackageJson(targetDir);
116
117
  return {
117
118
  hasPackageJson: exists("package.json"),
118
119
  hasTsconfig: exists("tsconfig.json"),
@@ -127,7 +128,8 @@ function detectProject(targetDir) {
127
128
  hasReleaseItConfig: exists(".release-it.json") || exists(".release-it.yaml") || exists(".release-it.toml"),
128
129
  hasSimpleReleaseConfig: exists(".versionrc") || exists(".versionrc.json") || exists(".versionrc.js"),
129
130
  hasChangesetsConfig: exists(".changeset/config.json"),
130
- hasRepositoryField: !!readPackageJson(targetDir)?.repository,
131
+ hasRepositoryField: !!rootPkg?.repository,
132
+ hasCommitAndTagVersion: !!rootPkg?.devDependencies?.["commit-and-tag-version"],
131
133
  legacyConfigs: detectLegacyConfigs(targetDir)
132
134
  };
133
135
  }
@@ -801,7 +803,7 @@ function ensureWorkflowConcurrency(existing, concurrency) {
801
803
  }
802
804
  }
803
805
  //#endregion
804
- //#region src/generators/deploy-ci.ts
806
+ //#region src/generators/publish-ci.ts
805
807
  /** Build a GitHub Actions expression like `${{ expr }}` without triggering no-template-curly-in-string. */
806
808
  function actionsExpr$2(expr) {
807
809
  return `\${{ ${expr} }}`;
@@ -810,14 +812,14 @@ function hasEnginesNode$2(ctx) {
810
812
  return typeof ctx.packageJson?.["engines"]?.["node"] === "string";
811
813
  }
812
814
  function deployWorkflow(ci, nodeVersionYaml) {
813
- return `${workflowSchemaComment(ci)}name: Deploy
815
+ return `${workflowSchemaComment(ci)}name: Publish
814
816
  on:
815
817
  push:
816
818
  tags:
817
819
  - "v[0-9]+.[0-9]+.[0-9]+"
818
820
 
819
821
  jobs:
820
- deploy:
822
+ publish:
821
823
  runs-on: ubuntu-latest
822
824
  steps:
823
825
  - uses: actions/checkout@v4
@@ -911,16 +913,16 @@ async function generateDeployCi(ctx) {
911
913
  return {
912
914
  filePath: workflowPath,
913
915
  action: "updated",
914
- description: "Migrated tooling binary name in deploy workflow"
916
+ description: "Migrated tooling binary name in publish workflow"
915
917
  };
916
918
  }
917
919
  return {
918
920
  filePath: workflowPath,
919
921
  action: "skipped",
920
- description: "Deploy workflow already up to date"
922
+ description: "Publish workflow already up to date"
921
923
  };
922
924
  }
923
- const merged = mergeWorkflowSteps(existing, "deploy", requiredDeploySteps());
925
+ const merged = mergeWorkflowSteps(existing, "publish", requiredDeploySteps());
924
926
  const withComment = ensureSchemaComment(merged.content, ctx.config.ci);
925
927
  if (!merged.changed) {
926
928
  if (withComment !== raw) {
@@ -928,33 +930,33 @@ async function generateDeployCi(ctx) {
928
930
  return {
929
931
  filePath: workflowPath,
930
932
  action: "updated",
931
- description: existing !== raw ? "Migrated tooling binary name in deploy workflow" : "Added schema comment to deploy workflow"
933
+ description: existing !== raw ? "Migrated tooling binary name in publish workflow" : "Added schema comment to publish workflow"
932
934
  };
933
935
  }
934
936
  return {
935
937
  filePath: workflowPath,
936
938
  action: "skipped",
937
- description: "Existing deploy workflow preserved"
939
+ description: "Existing publish workflow preserved"
938
940
  };
939
941
  }
940
942
  ctx.write(workflowPath, withComment);
941
943
  return {
942
944
  filePath: workflowPath,
943
945
  action: "updated",
944
- description: "Added missing steps to deploy workflow"
946
+ description: "Added missing steps to publish workflow"
945
947
  };
946
948
  }
947
949
  return {
948
950
  filePath: workflowPath,
949
951
  action: "skipped",
950
- description: "Deploy workflow already up to date"
952
+ description: "Publish workflow already up to date"
951
953
  };
952
954
  }
953
955
  ctx.write(workflowPath, content);
954
956
  return {
955
957
  filePath: workflowPath,
956
958
  action: "created",
957
- description: `Generated ${isGitHub ? "GitHub" : "Forgejo"} Actions deploy workflow`
959
+ description: `Generated ${isGitHub ? "GitHub" : "Forgejo"} Actions publish workflow`
958
960
  };
959
961
  }
960
962
  //#endregion
@@ -1054,7 +1056,7 @@ function getAddedDevDepNames(config) {
1054
1056
  const deps = { ...ROOT_DEV_DEPS };
1055
1057
  if (config.structure !== "monorepo") Object.assign(deps, PER_PACKAGE_DEV_DEPS);
1056
1058
  deps["@bensandee/config"] = "0.9.1";
1057
- deps["@bensandee/tooling"] = "0.27.1";
1059
+ deps["@bensandee/tooling"] = "0.28.0";
1058
1060
  if (config.formatter === "oxfmt") deps["oxfmt"] = "0.35.0";
1059
1061
  if (config.formatter === "prettier") deps["prettier"] = "3.8.1";
1060
1062
  addReleaseDeps(deps, config);
@@ -1079,7 +1081,7 @@ async function generatePackageJson(ctx) {
1079
1081
  const devDeps = { ...ROOT_DEV_DEPS };
1080
1082
  if (!isMonorepo) Object.assign(devDeps, PER_PACKAGE_DEV_DEPS);
1081
1083
  devDeps["@bensandee/config"] = isWorkspacePackage(ctx, "@bensandee/config") ? "workspace:*" : "0.9.1";
1082
- devDeps["@bensandee/tooling"] = isWorkspacePackage(ctx, "@bensandee/tooling") ? "workspace:*" : "0.27.1";
1084
+ devDeps["@bensandee/tooling"] = isWorkspacePackage(ctx, "@bensandee/tooling") ? "workspace:*" : "0.28.0";
1083
1085
  if (ctx.config.useEslintPlugin) devDeps["@bensandee/eslint-plugin"] = isWorkspacePackage(ctx, "@bensandee/eslint-plugin") ? "workspace:*" : "0.9.2";
1084
1086
  if (ctx.config.formatter === "oxfmt") devDeps["oxfmt"] = "0.35.0";
1085
1087
  if (ctx.config.formatter === "prettier") devDeps["prettier"] = "3.8.1";
@@ -2162,7 +2164,7 @@ function actionsExpr(expr) {
2162
2164
  function hasEnginesNode(ctx) {
2163
2165
  return typeof ctx.packageJson?.["engines"]?.["node"] === "string";
2164
2166
  }
2165
- function commonSteps(nodeVersionYaml, publishesNpm) {
2167
+ function commonSteps(nodeVersionYaml, publishesNpm, { build = true } = {}) {
2166
2168
  return ` - uses: actions/checkout@v4
2167
2169
  with:
2168
2170
  fetch-depth: 0
@@ -2171,8 +2173,7 @@ function commonSteps(nodeVersionYaml, publishesNpm) {
2171
2173
  with:
2172
2174
  ${nodeVersionYaml}
2173
2175
  cache: pnpm${publishesNpm ? `\n registry-url: "https://registry.npmjs.org"` : ""}
2174
- - run: pnpm install --frozen-lockfile
2175
- - run: pnpm build`;
2176
+ - run: pnpm install --frozen-lockfile${build ? `\n - run: pnpm build` : ""}`;
2176
2177
  }
2177
2178
  function releaseItWorkflow(ci, nodeVersionYaml, publishesNpm) {
2178
2179
  const isGitHub = ci === "github";
@@ -2226,7 +2227,7 @@ jobs:
2226
2227
  release:
2227
2228
  runs-on: ubuntu-latest
2228
2229
  steps:
2229
- ${commonSteps(nodeVersionYaml, publishesNpm)}${gitConfigStep}${releaseStep}
2230
+ ${commonSteps(nodeVersionYaml, publishesNpm, { build: false })}${gitConfigStep}${releaseStep}
2230
2231
  `;
2231
2232
  }
2232
2233
  /** Build the required release step for the check job (changesets). */
@@ -2290,10 +2291,10 @@ function requiredReleaseSteps(strategy, nodeVersionYaml, publishesNpm) {
2290
2291
  match: { run: "pnpm install" },
2291
2292
  step: { run: "pnpm install --frozen-lockfile" }
2292
2293
  },
2293
- {
2294
+ ...strategy !== "simple" ? [{
2294
2295
  match: { run: "build" },
2295
2296
  step: { run: "pnpm build" }
2296
- }
2297
+ }] : []
2297
2298
  ];
2298
2299
  switch (strategy) {
2299
2300
  case "release-it":
@@ -3003,8 +3004,11 @@ function runDockerPublish(executor, config) {
3003
3004
  */
3004
3005
  function generateMigratePrompt(results, config, detected) {
3005
3006
  const sections = [];
3007
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
3006
3008
  sections.push("# Migration Prompt");
3007
3009
  sections.push("");
3010
+ sections.push(`_Generated by \`@bensandee/tooling@0.28.0 repo:sync\` on ${timestamp}_`);
3011
+ sections.push("");
3008
3012
  sections.push("The following prompt was generated by `@bensandee/tooling repo:sync`. Paste it into Claude Code or another AI assistant to finish migrating this repository.");
3009
3013
  sections.push("");
3010
3014
  sections.push("> **Tip:** Before starting, run `/init` in Claude Code to generate a `CLAUDE.md` that gives the AI a complete picture of your repository's structure, conventions, and build commands.");
@@ -3037,6 +3041,18 @@ function generateMigratePrompt(results, config, detected) {
3037
3041
  }
3038
3042
  sections.push("## Migration tasks");
3039
3043
  sections.push("");
3044
+ if (config.releaseStrategy === "simple" && !detected.hasCommitAndTagVersion) {
3045
+ sections.push("### Add commit-and-tag-version to devDependencies");
3046
+ sections.push("");
3047
+ sections.push("The `simple` release strategy requires `commit-and-tag-version` as a root devDependency so that `pnpm exec commit-and-tag-version` resolves correctly.");
3048
+ sections.push("");
3049
+ sections.push("Run:");
3050
+ sections.push("");
3051
+ sections.push("```sh");
3052
+ sections.push("pnpm add -D -w commit-and-tag-version");
3053
+ sections.push("```");
3054
+ sections.push("");
3055
+ }
3040
3056
  if (config.releaseStrategy !== "none" && !detected.hasRepositoryField) {
3041
3057
  sections.push("### Add repository field to package.json");
3042
3058
  sections.push("");
@@ -4804,7 +4820,7 @@ const dockerCheckCommand = defineCommand({
4804
4820
  const main = defineCommand({
4805
4821
  meta: {
4806
4822
  name: "bst",
4807
- version: "0.27.1",
4823
+ version: "0.28.0",
4808
4824
  description: "Bootstrap and maintain standardized TypeScript project tooling"
4809
4825
  },
4810
4826
  subCommands: {
@@ -4820,7 +4836,7 @@ const main = defineCommand({
4820
4836
  "docker:check": dockerCheckCommand
4821
4837
  }
4822
4838
  });
4823
- console.log(`@bensandee/tooling v0.27.1`);
4839
+ console.log(`@bensandee/tooling v0.28.0`);
4824
4840
  async function run() {
4825
4841
  await runMain(main);
4826
4842
  process.exit(process.exitCode ?? 0);
package/dist/index.d.mts CHANGED
@@ -100,6 +100,8 @@ interface DetectedProjectState {
100
100
  hasChangesetsConfig: boolean;
101
101
  /** Whether package.json has a repository field (needed for release workflows) */
102
102
  hasRepositoryField: boolean;
103
+ /** Whether commit-and-tag-version is in root devDependencies (required for simple release strategy) */
104
+ hasCommitAndTagVersion: boolean;
103
105
  /** Legacy tooling configs found */
104
106
  legacyConfigs: LegacyConfig[];
105
107
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bensandee/tooling",
3
- "version": "0.27.1",
3
+ "version": "0.28.0",
4
4
  "description": "CLI tool to bootstrap and maintain standardized TypeScript project tooling",
5
5
  "bin": {
6
6
  "bst": "./dist/bin.mjs"