(planInput: MigrationInput)
| 488 | }; |
| 489 | |
| 490 | const writeDryRun = (planInput: MigrationInput): void => { |
| 491 | const plan = planMigration({ |
| 492 | ...planInput, |
| 493 | collectPolicyErrors: true, |
| 494 | orphanPolicyMode: "retarget_all", |
| 495 | }); |
| 496 | const neverWiden = verifyPolicyRewriteNeverWidens(plan, planInput); |
| 497 | const r2Copies = plan.orgs |
| 498 | .filter((org) => !org.completed && org.hardErrors.length === 0) |
| 499 | .flatMap((org) => |
| 500 | org.blobCopies |
| 501 | .filter((copy) => copy.backend === "external") |
| 502 | .map((copy) => ({ |
| 503 | tenantHash: org.tenantHash, |
| 504 | tenant: org.tenant, |
| 505 | sourceKey: copy.sourceObjectName, |
| 506 | destKey: copy.targetObjectName, |
| 507 | })), |
| 508 | ); |
| 509 | mkdirSync(outputDir, { recursive: true }); |
| 510 | for (const org of plan.orgs) { |
| 511 | writeFileSync(`${outputDir}/org-${org.tenantHash}.md`, renderOrgDiff(org)); |
| 512 | } |
| 513 | writeFileSync(`${outputDir}/r2-copy-manifest.json`, `${JSON.stringify(r2Copies, null, 2)}\n`); |
| 514 | writeFileSync( |
| 515 | `${outputDir}/summary.md`, |
| 516 | `${renderSummary(plan)}\npolicy_never_widen=${neverWiden.ok}\npolicy_never_widen_checked=${neverWiden.checkedPolicies}\nr2_copy_manifest=${outputDir}/r2-copy-manifest.json\nr2_copy_count=${r2Copies.length}\nr2_copy_command=wrangler r2 object get <bucket>/<sourceKey> | wrangler r2 object put <bucket>/<destKey> --pipe\n`, |
| 517 | ); |
| 518 | console.log(renderSummary(plan)); |
| 519 | console.log(`policy_never_widen=${neverWiden.ok}`); |
| 520 | console.log(`policy_never_widen_checked=${neverWiden.checkedPolicies}`); |
| 521 | console.log(`r2_copy_manifest=${outputDir}/r2-copy-manifest.json`); |
| 522 | console.log(`r2_copy_count=${r2Copies.length}`); |
| 523 | console.log( |
| 524 | "r2_copy_command=wrangler r2 object get <bucket>/<sourceKey> | wrangler r2 object put <bucket>/<destKey> --pipe", |
| 525 | ); |
| 526 | console.log(`diff_dir=${outputDir}`); |
| 527 | if (!neverWiden.ok) { |
| 528 | throw new Error( |
| 529 | `Policy rewrite failed coverage checks: widened=${neverWiden.widened.length}, narrowed=${neverWiden.narrowed.length}`, |
| 530 | ); |
| 531 | } |
| 532 | if ( |
| 533 | plan.summary.integrationsMissingSpecBlob > 0 || |
| 534 | plan.summary.integrationsMissingDefsBlob > 0 |
| 535 | ) { |
| 536 | throw new Error( |
| 537 | `Serving blob check failed: missing spec=${plan.summary.integrationsMissingSpecBlob}, missing defs=${plan.summary.integrationsMissingDefsBlob}`, |
| 538 | ); |
| 539 | } |
| 540 | const zeroOperationIntegrations = plan.orgs |
| 541 | .filter((org) => !org.completed && org.hardErrors.length === 0) |
| 542 | .flatMap((org) => org.integrations) |
| 543 | .filter( |
| 544 | (integration) => |
| 545 | integration.servingState.operationsToBuild === 0 && |
| 546 | !integration.servingState.expectedZeroOperations, |
| 547 | ); |
no test coverage detected