@biffo/cli 0.41.11 → 0.41.13

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/core.version CHANGED
@@ -1 +1 @@
1
- 0.41.11
1
+ 0.41.13
package/dist/index.js CHANGED
@@ -1542,6 +1542,12 @@ function materializeTemplateAtTag(repo, version, git = defaultGit) {
1542
1542
  return { dir, cleanup: () => rmSync3(dir, { recursive: true, force: true }) };
1543
1543
  }
1544
1544
 
1545
+ // src/lib/global-workflows.ts
1546
+ var GLOBAL_DISPATCH_REF = "main";
1547
+ var GLOBAL_DISPATCH_WORKFLOW_PATHS = [
1548
+ ".github/workflows/deploy-global.yml"
1549
+ ];
1550
+
1545
1551
  // src/commands/core-upgrade.ts
1546
1552
  var MISSING_TEMPLATE_ROOT_GUIDANCE2 = "Pass --template-repo <path> to a biffo-template git checkout, e.g. `biffo core upgrade --template-repo /path/to/biffo-template`.";
1547
1553
  var coreUpgradeCommand = new Command3("upgrade").description("Three-way-merge template-owned files for a core upgrade; preview it or open a PR").option("--cwd <path>", "Instance repo root to upgrade (defaults to the current directory)").option(
@@ -1718,7 +1724,7 @@ async function applyAndOpenPr(options, deps, plan, migrations, fromVersion, toVe
1718
1724
  head: branch,
1719
1725
  base,
1720
1726
  title: `Upgrade Biffo core ${fromVersion} \u2192 ${toVersion}`,
1721
- body: buildPrBody(fromVersion, toVersion, plan, migrations)
1727
+ body: buildPrBody(fromVersion, toVersion, plan, migrations, base)
1722
1728
  });
1723
1729
  if (plan.conflicts.length > 0) {
1724
1730
  log.warn(`PR opened with ${plan.conflicts.length} conflict(s) to resolve: ${pr.url}`);
@@ -1726,7 +1732,7 @@ async function applyAndOpenPr(options, deps, plan, migrations, fromVersion, toVe
1726
1732
  log.success(`Opened PR #${pr.number}: ${pr.url}`);
1727
1733
  }
1728
1734
  }
1729
- function buildPrBody(from, to, plan, migrations) {
1735
+ function buildPrBody(from, to, plan, migrations, base = GLOBAL_DISPATCH_REF) {
1730
1736
  const lines = [
1731
1737
  "Automated core upgrade generated by `biffo core upgrade` (ADR-0006).",
1732
1738
  "",
@@ -1753,6 +1759,21 @@ function buildPrBody(from, to, plan, migrations) {
1753
1759
  "Review the DDL before merging: merging this PR runs these migrations against the database on the next deploy."
1754
1760
  );
1755
1761
  }
1762
+ const globalWorkflowChanges = plan.changes.filter(
1763
+ (c) => GLOBAL_DISPATCH_WORKFLOW_PATHS.includes(c.path)
1764
+ );
1765
+ if (base !== GLOBAL_DISPATCH_REF && globalWorkflowChanges.length > 0) {
1766
+ lines.push(
1767
+ "",
1768
+ `## \u26A0 Promotion required \u2014 global workflow change (issue #328)`,
1769
+ "",
1770
+ `This upgrade changes ${globalWorkflowChanges.length} workflow(s) that \`biffo deploy\` dispatches from \`${GLOBAL_DISPATCH_REF}\`, but this PR targets \`${base}\`:`,
1771
+ "",
1772
+ ...globalWorkflowChanges.map((c) => `- \`${c.path}\``),
1773
+ "",
1774
+ `Merging here lands the fix on \`${base}\` \u2014 **but the deploy runs it from \`${GLOBAL_DISPATCH_REF}\`.** Until you promote \`${base}\` \u2192 \`${GLOBAL_DISPATCH_REF}\` (open a PR from \`${base}\` into \`${GLOBAL_DISPATCH_REF}\` and merge it), the old workflow keeps running and this fix will not take effect.`
1775
+ );
1776
+ }
1756
1777
  if (plan.conflicts.length > 0) {
1757
1778
  lines.push(
1758
1779
  "",
@@ -3157,6 +3178,61 @@ async function reportOidcHint(github, org, repo, runId) {
3157
3178
  log.error(" Re-run `biffo init` to rewrite the trust policy with both patterns.");
3158
3179
  log.error("");
3159
3180
  }
3181
+ async function readRemoteCoreVersion(github, org, repo, ref) {
3182
+ const record = await github.getFileContent(org, repo, INSTANCE_CORE_FILE, ref);
3183
+ if (record) {
3184
+ try {
3185
+ const parsed = JSON.parse(record);
3186
+ if (typeof parsed.version === "string") {
3187
+ parseCoreVersion(parsed.version);
3188
+ return parsed.version;
3189
+ }
3190
+ } catch {
3191
+ }
3192
+ }
3193
+ const inherited = await github.getFileContent(org, repo, CORE_VERSION_FILE, ref);
3194
+ if (inherited) {
3195
+ try {
3196
+ const version = inherited.trim();
3197
+ parseCoreVersion(version);
3198
+ return version;
3199
+ } catch {
3200
+ return null;
3201
+ }
3202
+ }
3203
+ return null;
3204
+ }
3205
+ async function warnIfDispatchRefStale(github, org, repo, workflowFile, dispatchRef, deployBranch) {
3206
+ if (dispatchRef === deployBranch) return;
3207
+ let refVersion;
3208
+ let branchVersion;
3209
+ try {
3210
+ ;
3211
+ [refVersion, branchVersion] = await Promise.all([
3212
+ readRemoteCoreVersion(github, org, repo, dispatchRef),
3213
+ readRemoteCoreVersion(github, org, repo, deployBranch)
3214
+ ]);
3215
+ } catch {
3216
+ return;
3217
+ }
3218
+ if (!refVersion || !branchVersion) return;
3219
+ if (compareCoreVersions(refVersion, branchVersion) >= 0) return;
3220
+ log.warn("");
3221
+ log.warn(
3222
+ ` ${workflowFile} is dispatched from '${dispatchRef}', but '${dispatchRef}' is on core ${refVersion} while '${deployBranch}' (deploying now) is on core ${branchVersion}.`
3223
+ );
3224
+ log.warn(
3225
+ ` A core upgrade landed on '${deployBranch}' that has not reached '${dispatchRef}'. This deploy`
3226
+ );
3227
+ log.warn(
3228
+ ` will run the OLDER ${workflowFile} from '${dispatchRef}', so template fixes to it will NOT`
3229
+ );
3230
+ log.warn(
3231
+ ` take effect. Promote '${deployBranch}' \u2192 '${dispatchRef}' (open a PR from '${deployBranch}'`
3232
+ );
3233
+ log.warn(` into '${dispatchRef}' and merge it), then re-run this deploy. (issue #328)`);
3234
+ log.warn("");
3235
+ }
3160
3236
  async function runDeploy(github, aws, config, environment, options = {}) {
3161
3237
  const { org, repo } = config.source_control.config;
3162
3238
  const awsConfig2 = config.cloud.config;
@@ -3198,8 +3274,16 @@ async function runDeploy(github, aws, config, environment, options = {}) {
3198
3274
  if (!skipInfra && hasGlobalInfra) {
3199
3275
  const globalLabel = dns.mode === "external" ? "Requesting SSL certificate for external DNS..." : "Deploying global infrastructure (DNS + SSL certificate)...";
3200
3276
  log.step(2, totalSteps, globalLabel);
3277
+ await warnIfDispatchRefStale(
3278
+ github,
3279
+ org,
3280
+ repo,
3281
+ "deploy-global.yml",
3282
+ GLOBAL_DISPATCH_REF,
3283
+ branch
3284
+ );
3201
3285
  const globalBaselineId = await github.getLatestWorkflowRunId(org, repo, "deploy-global.yml");
3202
- await github.triggerWorkflow(org, repo, "deploy-global.yml", {}, "main");
3286
+ await github.triggerWorkflow(org, repo, "deploy-global.yml", {}, GLOBAL_DISPATCH_REF);
3203
3287
  if (dns.mode === "external") {
3204
3288
  log.info(" DNS will not be changed automatically.");
3205
3289
  log.info(" The workflow summary will list ACM validation CNAMEs to add manually.");
@@ -3214,7 +3298,7 @@ async function runDeploy(github, aws, config, environment, options = {}) {
3214
3298
  globalBaselineId,
3215
3299
  36e5,
3216
3300
  3e4,
3217
- "main"
3301
+ GLOBAL_DISPATCH_REF
3218
3302
  );
3219
3303
  if (globalResult.conclusion !== "success") {
3220
3304
  log.error(`Global infrastructure deploy ${globalResult.conclusion ?? "failed"}.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@biffo/cli",
3
- "version": "0.41.11",
3
+ "version": "0.41.13",
4
4
  "description": "Biffo project scaffolding CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",