@bensandee/tooling 0.55.0 → 0.55.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.
Files changed (2) hide show
  1. package/dist/bin.mjs +59 -9
  2. package/package.json +1 -1
package/dist/bin.mjs CHANGED
@@ -1457,6 +1457,7 @@ function hasReleaseAssets(ctx) {
1457
1457
  return false;
1458
1458
  }
1459
1459
  }
1460
+ const ARCHIVE_DIR$1 = ".tooling-archived";
1460
1461
  async function generateDeployCi(ctx) {
1461
1462
  const filePath = "deploy-ci";
1462
1463
  if (!ctx.config.publishDocker || ctx.config.ci === "none") return {
@@ -1466,6 +1467,23 @@ async function generateDeployCi(ctx) {
1466
1467
  };
1467
1468
  const isGitHub = ctx.config.ci === "github";
1468
1469
  const workflowPath = isGitHub ? ".github/workflows/publish.yml" : ".forgejo/workflows/publish.yml";
1470
+ if (ctx.config.releaseStrategy === "simple") {
1471
+ const existing = ctx.read(workflowPath);
1472
+ if (existing !== void 0) {
1473
+ ctx.write(`${ARCHIVE_DIR$1}/${workflowPath}`, existing);
1474
+ ctx.remove(workflowPath);
1475
+ return {
1476
+ filePath: workflowPath,
1477
+ action: "archived",
1478
+ description: `Moved to ${ARCHIVE_DIR$1}/${workflowPath} (docker publish runs in release.yml for simple strategy)`
1479
+ };
1480
+ }
1481
+ return {
1482
+ filePath,
1483
+ action: "skipped",
1484
+ description: "Publish workflow not generated for simple release strategy"
1485
+ };
1486
+ }
1469
1487
  const steps = publishSteps(computeNodeVersionYaml(ctx), hasRepositoryUrl(ctx));
1470
1488
  const content = buildWorkflowYaml({
1471
1489
  ci: ctx.config.ci,
@@ -1773,7 +1791,7 @@ async function generatePackageJson(ctx) {
1773
1791
  const devDeps = { ...ROOT_DEV_DEPS };
1774
1792
  if (!isMonorepo) Object.assign(devDeps, PER_PACKAGE_DEV_DEPS);
1775
1793
  devDeps["@bensandee/config"] = isWorkspacePackage(ctx, "@bensandee/config") ? "workspace:*" : "0.10.2";
1776
- devDeps["@bensandee/tooling"] = isWorkspacePackage(ctx, "@bensandee/tooling") ? "workspace:*" : "0.55.0";
1794
+ devDeps["@bensandee/tooling"] = isWorkspacePackage(ctx, "@bensandee/tooling") ? "workspace:*" : "0.55.1";
1777
1795
  if (ctx.config.useEslintPlugin) devDeps["@bensandee/eslint-plugin"] = isWorkspacePackage(ctx, "@bensandee/eslint-plugin") ? "workspace:*" : "0.12.0";
1778
1796
  if (ctx.config.formatter === "oxfmt") devDeps["oxfmt"] = {
1779
1797
  "@changesets/cli": "2.30.0",
@@ -2844,11 +2862,29 @@ async function runReleaseAssets(executor, config) {
2844
2862
  log.info("No tags pointing to HEAD, skipping upload");
2845
2863
  return;
2846
2864
  }
2865
+ let uploaded = 0;
2847
2866
  for (const tag of tags) {
2867
+ if (!await releaseExists(executor, config, tag)) {
2868
+ log.info(`No release found for ${tag}, skipping (likely a sliding tag)`);
2869
+ continue;
2870
+ }
2848
2871
  log.info(`Uploading assets to release ${tag}`);
2849
2872
  for (const target of targets) for (const asset of target.files) if (config.platform.type === "github") uploadToGitHub(executor, config, tag, asset);
2850
2873
  else await uploadToForgejo(executor, config.platform.conn, tag, asset);
2874
+ uploaded++;
2851
2875
  }
2876
+ if (uploaded === 0) log.info("No releases found for any tag pointing to HEAD, skipping upload");
2877
+ }
2878
+ async function releaseExists(executor, config, tag) {
2879
+ if (!config.platform) return false;
2880
+ if (config.platform.type === "forgejo") return findRelease(executor, config.platform.conn, tag);
2881
+ const result = executor.exec("gh", [
2882
+ "release",
2883
+ "view",
2884
+ tag
2885
+ ], { cwd: config.cwd });
2886
+ debugExec(config, `gh release view ${tag}`, result);
2887
+ return result.exitCode === 0;
2852
2888
  }
2853
2889
  //#endregion
2854
2890
  //#region src/generators/gitignore.ts
@@ -2866,10 +2902,19 @@ const REQUIRED_ENTRIES = [
2866
2902
  const OPTIONAL_ENTRIES = [
2867
2903
  ".tooling-migrate.md",
2868
2904
  ".tooling-archived/",
2869
- ".claude/hooks/bst-hook.audit.local.jsonl*",
2870
- `${CONVENTION_OUTPUT_DIR}/`
2905
+ ".claude/hooks/bst-hook.audit.local.jsonl*"
2871
2906
  ];
2872
- const ALL_ENTRIES = [...REQUIRED_ENTRIES, ...OPTIONAL_ENTRIES];
2907
+ /**
2908
+ * Optional entries added only when a feature is actually configured.
2909
+ * Patterns are written without a leading slash so they match at any depth —
2910
+ * a single `release-assets/` entry in the root .gitignore covers monorepo
2911
+ * subpackage output like `packages/app/release-assets/` too.
2912
+ */
2913
+ function conditionalEntries(ctx) {
2914
+ const entries = [];
2915
+ if (hasReleaseAssets(ctx)) entries.push(`${CONVENTION_OUTPUT_DIR}/`);
2916
+ return entries;
2917
+ }
2873
2918
  /** Normalize a gitignore entry for comparison: strip leading `/` and trailing `/`. */
2874
2919
  function normalizeEntry(entry) {
2875
2920
  let s = entry.trim();
@@ -2879,10 +2924,15 @@ function normalizeEntry(entry) {
2879
2924
  }
2880
2925
  async function generateGitignore(ctx) {
2881
2926
  const filePath = ".gitignore";
2927
+ const allEntries = [
2928
+ ...REQUIRED_ENTRIES,
2929
+ ...OPTIONAL_ENTRIES,
2930
+ ...conditionalEntries(ctx)
2931
+ ];
2882
2932
  const existing = ctx.read(filePath);
2883
2933
  if (existing) {
2884
2934
  const existingNormalized = new Set(existing.split("\n").map(normalizeEntry).filter((line) => line.length > 0));
2885
- const missing = ALL_ENTRIES.filter((entry) => !existingNormalized.has(normalizeEntry(entry)));
2935
+ const missing = allEntries.filter((entry) => !existingNormalized.has(normalizeEntry(entry)));
2886
2936
  if (missing.length === 0) return {
2887
2937
  filePath,
2888
2938
  action: "skipped",
@@ -2902,7 +2952,7 @@ async function generateGitignore(ctx) {
2902
2952
  description: `Appended ${String(missing.length)} missing entries`
2903
2953
  };
2904
2954
  }
2905
- ctx.write(filePath, ALL_ENTRIES.join("\n") + "\n");
2955
+ ctx.write(filePath, allEntries.join("\n") + "\n");
2906
2956
  return {
2907
2957
  filePath,
2908
2958
  action: "created",
@@ -4091,7 +4141,7 @@ async function runGenerators(ctx) {
4091
4141
  function generateMigratePrompt(results, config, detected) {
4092
4142
  const sections = [];
4093
4143
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
4094
- sections.push(`# Migration Prompt\n\n_Generated by \`@bensandee/tooling@0.55.0 repo:sync\` on ${timestamp}_\n`);
4144
+ sections.push(`# Migration Prompt\n\n_Generated by \`@bensandee/tooling@0.55.1 repo:sync\` on ${timestamp}_\n`);
4095
4145
  const changed = results.filter((r) => r.action === "created" || r.action === "updated" || r.action === "archived");
4096
4146
  if (changed.length > 0) {
4097
4147
  const items = changed.map((r) => {
@@ -7065,7 +7115,7 @@ async function sendWebhookWithLogging(url, secret, payload) {
7065
7115
  const main = defineCommand({
7066
7116
  meta: {
7067
7117
  name: "bst",
7068
- version: "0.55.0",
7118
+ version: "0.55.1",
7069
7119
  description: "Bootstrap and maintain standardized TypeScript project tooling"
7070
7120
  },
7071
7121
  subCommands: {
@@ -7134,7 +7184,7 @@ const main = defineCommand({
7134
7184
  })
7135
7185
  }
7136
7186
  });
7137
- console.log(`@bensandee/tooling v0.55.0`);
7187
+ console.log(`@bensandee/tooling v0.55.1`);
7138
7188
  async function run() {
7139
7189
  await runMain(main);
7140
7190
  process.exit(process.exitCode ?? 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bensandee/tooling",
3
- "version": "0.55.0",
3
+ "version": "0.55.1",
4
4
  "description": "CLI tool to bootstrap and maintain standardized TypeScript project tooling",
5
5
  "license": "MIT",
6
6
  "repository": {