@codedrifters/configulator 0.0.427 → 0.0.429

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/lib/index.js CHANGED
@@ -184,6 +184,7 @@ __export(index_exports, {
184
184
  AUDIT_CATEGORY_ORDER: () => AUDIT_CATEGORY_ORDER,
185
185
  AgentConfig: () => AgentConfig,
186
186
  ApiExtractor: () => ApiExtractor,
187
+ ApplyWorkflow: () => ApplyWorkflow,
187
188
  AstroConfig: () => AstroConfig,
188
189
  AstroOutput: () => AstroOutput,
189
190
  AstroProject: () => AstroProject,
@@ -338,6 +339,7 @@ __export(index_exports, {
338
339
  VERSION_NPM_PACKAGES: () => VERSION_NPM_PACKAGES,
339
340
  VSCodeConfig: () => VSCodeConfig,
340
341
  Vitest: () => Vitest,
342
+ WorkflowHomeRepository: () => WorkflowHomeRepository,
341
343
  addApproveMergeUpgradeWorkflow: () => addApproveMergeUpgradeWorkflow,
342
344
  addBuildCompleteJob: () => addBuildCompleteJob,
343
345
  addPlaywright: () => addPlaywright,
@@ -42290,69 +42292,23 @@ var DEFAULT_FAVICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0
42290
42292
  `;
42291
42293
 
42292
42294
  // src/projects/aws-cdk-project.ts
42293
- var import_projen28 = require("projen");
42295
+ var import_projen30 = require("projen");
42294
42296
  var import_javascript5 = require("projen/lib/javascript");
42295
42297
  var import_release2 = require("projen/lib/release");
42296
42298
  var import_ts_deepmerge4 = require("ts-deepmerge");
42297
42299
 
42298
42300
  // src/workflows/aws-deploy-workflow.ts
42299
42301
  var import_utils11 = __toESM(require_lib());
42300
- var import_projen26 = require("projen");
42302
+ var import_projen28 = require("projen");
42301
42303
  var import_build = require("projen/lib/build");
42304
+ var import_github7 = require("projen/lib/github");
42305
+ var import_workflows_model6 = require("projen/lib/github/workflows-model");
42306
+
42307
+ // src/workflows/apply-workflow.ts
42308
+ var import_projen26 = require("projen");
42302
42309
  var import_github6 = require("projen/lib/github");
42303
42310
  var import_workflows_model5 = require("projen/lib/github/workflows-model");
42304
42311
 
42305
- // src/workflows/deploy-gate.ts
42306
- var DEPLOY_GATE = {
42307
- /**
42308
- * Hold each deploy job behind a GitHub environment so its protection rules —
42309
- * required reviewers, wait timers, deployment branch policies — apply before
42310
- * the job is sent to a runner.
42311
- */
42312
- ENVIRONMENT: "environment",
42313
- /**
42314
- * Split the workflow in two. A **plan** workflow builds and diffs but never
42315
- * deploys; a dispatch-only **apply** workflow deploys the exact cloud
42316
- * assembly a nominated plan run produced.
42317
- *
42318
- * Needs no protection rule, so unlike {@link DEPLOY_GATE.ENVIRONMENT} it
42319
- * works on every GitHub plan. `environmentName` is optional here and layers
42320
- * an environment onto the apply jobs.
42321
- */
42322
- PLAN_APPLY: "plan-apply"
42323
- };
42324
- var resolveEnvironmentGate = (gate, environmentName, componentName) => {
42325
- const trimmed = environmentName?.trim();
42326
- if (gate === void 0) {
42327
- if (trimmed) {
42328
- throw new Error(
42329
- `${componentName} requires \`gate\` to be set when \`environmentName\` is supplied, got "${environmentName}" with no gate`
42330
- );
42331
- }
42332
- return void 0;
42333
- }
42334
- if (gate === DEPLOY_GATE.ENVIRONMENT && !trimmed) {
42335
- throw new Error(
42336
- `${componentName} requires a non-empty \`environmentName\` when \`gate\` is "${gate}"`
42337
- );
42338
- }
42339
- return trimmed;
42340
- };
42341
-
42342
- // src/workflows/home-repository.ts
42343
- var HOME_REPOSITORY_PATTERN = /^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/;
42344
- var renderHomeRepositoryCondition = (homeRepository, componentName) => {
42345
- if (homeRepository === void 0) {
42346
- return void 0;
42347
- }
42348
- if (!HOME_REPOSITORY_PATTERN.test(homeRepository)) {
42349
- throw new Error(
42350
- `${componentName} requires \`homeRepository\` to be an \`owner/repo\` slug, got "${homeRepository}"`
42351
- );
42352
- }
42353
- return `github.repository == '${homeRepository}'`;
42354
- };
42355
-
42356
42312
  // src/workflows/plan-apply.ts
42357
42313
  var VALIDATE_PLAN_JOB_ID = "validate-plan";
42358
42314
  var PLAN_RUN_ID_INPUT = "plan_run_id";
@@ -42452,11 +42408,244 @@ var renderPlanValidationScript = (options) => {
42452
42408
  ].join("\n");
42453
42409
  };
42454
42410
 
42411
+ // src/workflows/apply-workflow.ts
42412
+ var ApplyWorkflow = class _ApplyWorkflow extends import_projen26.Component {
42413
+ constructor(project, github, options) {
42414
+ super(project);
42415
+ /**
42416
+ * Every attached component's targets, in attach order. Held as targets rather
42417
+ * than branches because `AwsDeploymentTarget.branches` is mutable — the
42418
+ * branch union is read at `preSynthesize`, once every component has attached.
42419
+ */
42420
+ this.attachedTargets = [];
42421
+ /**
42422
+ * Attach another component's apply jobs to this workflow.
42423
+ *
42424
+ * Every setting the shared `validate-plan` job bakes in must match what the
42425
+ * workflow was created with — there is one validation job for the whole file,
42426
+ * so a disagreement cannot be honoured and is rejected rather than resolved
42427
+ * in favour of whichever component happened to be constructed first.
42428
+ */
42429
+ this.attach = (options) => {
42430
+ const { componentName } = options;
42431
+ const name = this.workflow.name;
42432
+ if (options.planWorkflowName !== this.contract.planWorkflowName) {
42433
+ throw new Error(
42434
+ `${componentName} cannot attach to the apply workflow "${name}": it plans from build workflow "${options.planWorkflowName}", but that apply workflow only accepts runs of "${this.contract.planWorkflowName}". Every component sharing an apply workflow must share one build workflow.`
42435
+ );
42436
+ }
42437
+ this.requireAgreement(
42438
+ componentName,
42439
+ "requireCurrentHead",
42440
+ options.requireCurrentHead,
42441
+ this.contract.requireCurrentHead
42442
+ );
42443
+ this.requireAgreement(
42444
+ componentName,
42445
+ "verifyArtifactDigest",
42446
+ options.verifyArtifactDigest,
42447
+ this.contract.verifyArtifactDigest
42448
+ );
42449
+ this.attachedTargets.push(...options.awsDeploymentTargets);
42450
+ };
42451
+ /**
42452
+ * Reject a boolean `planApply` setting that differs from the one this
42453
+ * workflow was created with.
42454
+ */
42455
+ this.requireAgreement = (componentName, option, supplied, expected) => {
42456
+ if (supplied === expected) {
42457
+ return;
42458
+ }
42459
+ throw new Error(
42460
+ `${componentName} cannot attach to the apply workflow "${this.workflow.name}": \`planApply.${option}\` is ${supplied} here and ${expected} on the components already attached. The setting is baked into the one shared \`${VALIDATE_PLAN_JOB_ID}\` job, so every component sharing an apply workflow must agree on it.`
42461
+ );
42462
+ };
42463
+ /**
42464
+ * Render the validation job every apply job depends on.
42465
+ *
42466
+ * `allowedBranches` is the union of every attached target's branches, deduped
42467
+ * and left in attach order. The apply run's own `github.ref` says nothing
42468
+ * about what was planned, so the list is checked against the *plan run's*
42469
+ * `head_branch` rather than against a workflow-level branch filter.
42470
+ */
42471
+ this.renderValidateJob = () => {
42472
+ const { planWorkflowName, requireCurrentHead, verifyArtifactDigest } = this.contract;
42473
+ const allowedBranches = Array.from(
42474
+ new Set(
42475
+ this.attachedTargets.flatMap(
42476
+ (target) => target.branches.map((b) => b.branch)
42477
+ )
42478
+ )
42479
+ );
42480
+ return {
42481
+ name: "Validate plan run",
42482
+ runsOn: ["ubuntu-latest"],
42483
+ permissions: {
42484
+ actions: import_workflows_model5.JobPermission.READ,
42485
+ contents: import_workflows_model5.JobPermission.READ
42486
+ },
42487
+ ...this.homeRepositoryCondition ? { if: `\${{ ${this.homeRepositoryCondition} }}` } : {},
42488
+ outputs: {
42489
+ head_sha: { stepId: "validate_plan_run", outputName: "head_sha" },
42490
+ head_branch: { stepId: "validate_plan_run", outputName: "head_branch" },
42491
+ ...verifyArtifactDigest ? {
42492
+ artifact_digest: {
42493
+ stepId: "validate_plan_run",
42494
+ outputName: "artifact_digest"
42495
+ }
42496
+ } : {}
42497
+ },
42498
+ steps: [
42499
+ {
42500
+ name: "Validate plan run",
42501
+ id: "validate_plan_run",
42502
+ uses: "actions/github-script@v9",
42503
+ /**
42504
+ * The dispatch input reaches the script through the environment
42505
+ * rather than a `${{ }}` interpolation, so a crafted run id cannot
42506
+ * inject JavaScript into the validation itself.
42507
+ */
42508
+ env: {
42509
+ PLAN_RUN_ID: `\${{ inputs.${PLAN_RUN_ID_INPUT} }}`
42510
+ },
42511
+ with: {
42512
+ script: renderPlanValidationScript({
42513
+ planWorkflowPath: `.github/workflows/${planWorkflowName}.yml`,
42514
+ allowedBranches,
42515
+ requireCurrentHead,
42516
+ verifyArtifactDigest
42517
+ })
42518
+ }
42519
+ }
42520
+ ]
42521
+ };
42522
+ };
42523
+ const { applyWorkflowName } = options;
42524
+ if (github.tryFindWorkflow(applyWorkflowName)) {
42525
+ throw new Error(
42526
+ `${options.componentName} cannot create the apply workflow "${applyWorkflowName}" because a workflow with that name already exists. Set \`planApply.applyWorkflow\` to share the existing one, or \`planApply.applyWorkflowName\` to something unique.`
42527
+ );
42528
+ }
42529
+ this.contract = {
42530
+ planWorkflowName: options.planWorkflowName,
42531
+ requireCurrentHead: options.requireCurrentHead,
42532
+ verifyArtifactDigest: options.verifyArtifactDigest
42533
+ };
42534
+ this.homeRepositoryCondition = options.homeRepositoryCondition;
42535
+ this.attachedTargets.push(...options.awsDeploymentTargets);
42536
+ this.workflow = new import_github6.GithubWorkflow(github, applyWorkflowName);
42537
+ this.workflow.on({
42538
+ workflowDispatch: {
42539
+ inputs: {
42540
+ [PLAN_RUN_ID_INPUT]: {
42541
+ description: "Run id of the plan workflow run to apply. Its build artifact is deployed verbatim.",
42542
+ required: true,
42543
+ type: "string"
42544
+ }
42545
+ }
42546
+ }
42547
+ });
42548
+ this.workflow.addJob(VALIDATE_PLAN_JOB_ID, this.renderValidateJob());
42549
+ }
42550
+ static of(project, workflow) {
42551
+ const isDefined = (c) => c instanceof _ApplyWorkflow && c.workflow === workflow;
42552
+ return project.components.find(isDefined);
42553
+ }
42554
+ preSynthesize() {
42555
+ this.workflow.updateJob(VALIDATE_PLAN_JOB_ID, this.renderValidateJob());
42556
+ super.preSynthesize();
42557
+ }
42558
+ };
42559
+
42560
+ // src/workflows/deploy-gate.ts
42561
+ var DEPLOY_GATE = {
42562
+ /**
42563
+ * Hold each deploy job behind a GitHub environment so its protection rules —
42564
+ * required reviewers, wait timers, deployment branch policies — apply before
42565
+ * the job is sent to a runner.
42566
+ */
42567
+ ENVIRONMENT: "environment",
42568
+ /**
42569
+ * Split the workflow in two. A **plan** workflow builds and diffs but never
42570
+ * deploys; a dispatch-only **apply** workflow deploys the exact cloud
42571
+ * assembly a nominated plan run produced.
42572
+ *
42573
+ * Needs no protection rule, so unlike {@link DEPLOY_GATE.ENVIRONMENT} it
42574
+ * works on every GitHub plan. `environmentName` is optional here and layers
42575
+ * an environment onto the apply jobs.
42576
+ */
42577
+ PLAN_APPLY: "plan-apply"
42578
+ };
42579
+ var resolveEnvironmentGate = (gate, environmentName, componentName) => {
42580
+ const trimmed = environmentName?.trim();
42581
+ if (gate === void 0) {
42582
+ if (trimmed) {
42583
+ throw new Error(
42584
+ `${componentName} requires \`gate\` to be set when \`environmentName\` is supplied, got "${environmentName}" with no gate`
42585
+ );
42586
+ }
42587
+ return void 0;
42588
+ }
42589
+ if (gate === DEPLOY_GATE.ENVIRONMENT && !trimmed) {
42590
+ throw new Error(
42591
+ `${componentName} requires a non-empty \`environmentName\` when \`gate\` is "${gate}"`
42592
+ );
42593
+ }
42594
+ return trimmed;
42595
+ };
42596
+
42597
+ // src/workflows/home-repository.ts
42598
+ var import_projen27 = require("projen");
42599
+ var HOME_REPOSITORY_PATTERN = /^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/;
42600
+ var renderHomeRepositoryCondition = (homeRepository, componentName) => {
42601
+ if (homeRepository === void 0) {
42602
+ return void 0;
42603
+ }
42604
+ if (!HOME_REPOSITORY_PATTERN.test(homeRepository)) {
42605
+ throw new Error(
42606
+ `${componentName} requires \`homeRepository\` to be an \`owner/repo\` slug, got "${homeRepository}"`
42607
+ );
42608
+ }
42609
+ return `github.repository == '${homeRepository}'`;
42610
+ };
42611
+ var describePin = (homeRepository) => homeRepository === void 0 ? "unset" : `"${homeRepository}"`;
42612
+ var WorkflowHomeRepository = class _WorkflowHomeRepository extends import_projen27.Component {
42613
+ static of(project, workflow) {
42614
+ const isDefined = (c) => c instanceof _WorkflowHomeRepository && c.workflow === workflow;
42615
+ return project.components.find(isDefined);
42616
+ }
42617
+ /**
42618
+ * Record a pin against a workflow, throwing when it disagrees with what an
42619
+ * earlier component declared for the same one.
42620
+ *
42621
+ * @param project - Project the record is attached to. Use the root project,
42622
+ * so components on sibling sub-projects find each other.
42623
+ */
42624
+ static require(project, options) {
42625
+ const { workflow, workflowName, homeRepository, componentName } = options;
42626
+ const existing = _WorkflowHomeRepository.of(project, workflow);
42627
+ if (!existing) {
42628
+ return new _WorkflowHomeRepository(project, options);
42629
+ }
42630
+ if (existing.homeRepository !== homeRepository) {
42631
+ throw new Error(
42632
+ `${componentName} requires every component sharing the workflow "${workflowName}" to declare the same \`homeRepository\`, got ${describePin(homeRepository)} here and ${describePin(existing.homeRepository)} already declared. The pin guards every job in one workflow file, so it cannot differ between them.`
42633
+ );
42634
+ }
42635
+ return existing;
42636
+ }
42637
+ constructor(project, options) {
42638
+ super(project);
42639
+ this.workflow = options.workflow;
42640
+ this.homeRepository = options.homeRepository;
42641
+ }
42642
+ };
42643
+
42455
42644
  // src/workflows/aws-deploy-workflow.ts
42456
42645
  var PROD_DEPLOY_NAME = "prod-deploy";
42457
42646
  var DIFF_OUTPUT_FILE = "cdk-diff.txt";
42458
42647
  var DIFF_SUMMARY_BYTE_LIMIT = 9e5;
42459
- var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Component {
42648
+ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen28.Component {
42460
42649
  constructor(project, options = {}) {
42461
42650
  super(project);
42462
42651
  this.project = project;
@@ -42556,83 +42745,28 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
42556
42745
  ].join("-");
42557
42746
  };
42558
42747
  /**
42559
- * Create the dispatch-only apply workflow and its validation job.
42748
+ * Join an apply workflow another `AwsDeployWorkflow` already created, so this
42749
+ * component's apply jobs land in that file rather than a second one.
42560
42750
  *
42561
- * The workflow file name defaults to the plan workflow's name suffixed with
42562
- * `-apply`. A name already in use throws rather than silently colliding on
42563
- * the underlying `.github/workflows/<name>.yml` file the usual cause is two
42564
- * `AwsDeployWorkflow`s sharing one build workflow, and the fix is an explicit
42565
- * `planApply.applyWorkflowName`.
42751
+ * Rejects a `GithubWorkflow` that is not an apply workflow: attaching to an
42752
+ * arbitrary one would add apply jobs depending on a `validate-plan` job that
42753
+ * does not exist there, which GitHub rejects only at run time.
42566
42754
  */
42567
- this.createApplyWorkflow = (github, homeRepositoryCondition) => {
42568
- const { applyWorkflowName, requireCurrentHead, verifyArtifactDigest } = this.planApplyOptions;
42569
- if (github.tryFindWorkflow(applyWorkflowName)) {
42755
+ this.attachApplyWorkflow = (workflow) => {
42756
+ const shared = ApplyWorkflow.of(this.rootProject, workflow);
42757
+ if (!shared) {
42570
42758
  throw new Error(
42571
- `AwsDeployWorkflow cannot create the apply workflow "${applyWorkflowName}" because a workflow with that name already exists. Set \`planApply.applyWorkflowName\` to something unique.`
42759
+ `AwsDeployWorkflow cannot attach to the workflow "${workflow.name}" because it is not an apply workflow. Pass the \`applyWorkflow\` of an AwsDeployWorkflow built with the \`plan-apply\` gate.`
42572
42760
  );
42573
42761
  }
42574
- const workflow = new import_github6.GithubWorkflow(github, applyWorkflowName);
42575
- workflow.on({
42576
- workflowDispatch: {
42577
- inputs: {
42578
- [PLAN_RUN_ID_INPUT]: {
42579
- description: "Run id of the plan workflow run to apply. Its build artifact is deployed verbatim.",
42580
- required: true,
42581
- type: "string"
42582
- }
42583
- }
42584
- }
42585
- });
42586
- const allowedBranches = Array.from(
42587
- new Set(
42588
- this.awsDeploymentTargets.flatMap(
42589
- (target) => target.branches.map((b) => b.branch)
42590
- )
42591
- )
42592
- );
42593
- workflow.addJob(VALIDATE_PLAN_JOB_ID, {
42594
- name: "Validate plan run",
42595
- runsOn: ["ubuntu-latest"],
42596
- permissions: {
42597
- actions: import_workflows_model5.JobPermission.READ,
42598
- contents: import_workflows_model5.JobPermission.READ
42599
- },
42600
- ...homeRepositoryCondition ? { if: `\${{ ${homeRepositoryCondition} }}` } : {},
42601
- outputs: {
42602
- head_sha: { stepId: "validate_plan_run", outputName: "head_sha" },
42603
- head_branch: { stepId: "validate_plan_run", outputName: "head_branch" },
42604
- ...verifyArtifactDigest ? {
42605
- artifact_digest: {
42606
- stepId: "validate_plan_run",
42607
- outputName: "artifact_digest"
42608
- }
42609
- } : {}
42610
- },
42611
- steps: [
42612
- {
42613
- name: "Validate plan run",
42614
- id: "validate_plan_run",
42615
- uses: "actions/github-script@v9",
42616
- /**
42617
- * The dispatch input reaches the script through the environment
42618
- * rather than a `${{ }}` interpolation, so a crafted run id cannot
42619
- * inject JavaScript into the validation itself.
42620
- */
42621
- env: {
42622
- PLAN_RUN_ID: `\${{ inputs.${PLAN_RUN_ID_INPUT} }}`
42623
- },
42624
- with: {
42625
- script: renderPlanValidationScript({
42626
- planWorkflowPath: `.github/workflows/${this.buildWorkflow.name}.yml`,
42627
- allowedBranches,
42628
- requireCurrentHead,
42629
- verifyArtifactDigest
42630
- })
42631
- }
42632
- }
42633
- ]
42762
+ shared.attach({
42763
+ planWorkflowName: this.buildWorkflow.name,
42764
+ requireCurrentHead: this.planApplyOptions.requireCurrentHead,
42765
+ verifyArtifactDigest: this.planApplyOptions.verifyArtifactDigest,
42766
+ awsDeploymentTargets: this.awsDeploymentTargets,
42767
+ componentName: "AwsDeployWorkflow"
42634
42768
  });
42635
- return workflow;
42769
+ return shared;
42636
42770
  };
42637
42771
  /**
42638
42772
  * Register one target's apply job on the apply workflow.
@@ -42667,9 +42801,9 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
42667
42801
  ],
42668
42802
  runsOn: ["ubuntu-latest"],
42669
42803
  permissions: {
42670
- actions: import_workflows_model5.JobPermission.READ,
42671
- contents: import_workflows_model5.JobPermission.READ,
42672
- idToken: import_workflows_model5.JobPermission.WRITE
42804
+ actions: import_workflows_model6.JobPermission.READ,
42805
+ contents: import_workflows_model6.JobPermission.READ,
42806
+ idToken: import_workflows_model6.JobPermission.WRITE
42673
42807
  },
42674
42808
  ...this.environmentName ? { environment: this.environmentName } : void 0,
42675
42809
  /**
@@ -42935,7 +43069,7 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
42935
43069
  * Upload the untruncated diff as a per-run artifact.
42936
43070
  */
42937
43071
  ...this.diffOptions.artifact ? [
42938
- import_github6.WorkflowSteps.uploadArtifact({
43072
+ import_github7.WorkflowSteps.uploadArtifact({
42939
43073
  name: `Upload diff ${label}`,
42940
43074
  if: capturedFileGuard,
42941
43075
  with: {
@@ -42952,7 +43086,7 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
42952
43086
  );
42953
43087
  }
42954
43088
  this.rootProject = project.root;
42955
- const github = import_github6.GitHub.of(this.rootProject);
43089
+ const github = import_github7.GitHub.of(this.rootProject);
42956
43090
  if (!github) {
42957
43091
  throw new Error(
42958
43092
  "AwsDeployWorkflow requires a GitHub component in the root project"
@@ -43059,16 +43193,40 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
43059
43193
  ...buildWorkflowOptions?.preBuildSteps ?? []
43060
43194
  ]
43061
43195
  });
43196
+ WorkflowHomeRepository.require(this.rootProject, {
43197
+ workflow: this.buildWorkflow,
43198
+ workflowName: this.buildWorkflow.name,
43199
+ homeRepository: this.homeRepository,
43200
+ componentName: "AwsDeployWorkflow"
43201
+ });
43202
+ const sharedApplyWorkflow = options.planApply?.applyWorkflow;
43203
+ if (sharedApplyWorkflow && options.planApply?.applyWorkflowName) {
43204
+ throw new Error(
43205
+ "Cannot provide both planApply.applyWorkflow and planApply.applyWorkflowName: the workflow being joined already has a name."
43206
+ );
43207
+ }
43062
43208
  this.planApplyOptions = {
43063
- applyWorkflowName: options.planApply?.applyWorkflowName ?? `${this.buildWorkflow.name}-apply`,
43209
+ applyWorkflowName: sharedApplyWorkflow?.name ?? options.planApply?.applyWorkflowName ?? `${this.buildWorkflow.name}-apply`,
43064
43210
  requireCurrentHead: options.planApply?.requireCurrentHead ?? false,
43065
43211
  verifyArtifactDigest: options.planApply?.verifyArtifactDigest ?? false
43066
43212
  };
43067
43213
  if (isPlanApply) {
43068
- this.applyWorkflow = this.createApplyWorkflow(
43069
- github,
43070
- homeRepositoryCondition
43071
- );
43214
+ const applyWorkflow = sharedApplyWorkflow ? this.attachApplyWorkflow(sharedApplyWorkflow) : new ApplyWorkflow(this.rootProject, github, {
43215
+ applyWorkflowName: this.planApplyOptions.applyWorkflowName,
43216
+ planWorkflowName: this.buildWorkflow.name,
43217
+ requireCurrentHead: this.planApplyOptions.requireCurrentHead,
43218
+ verifyArtifactDigest: this.planApplyOptions.verifyArtifactDigest,
43219
+ homeRepositoryCondition,
43220
+ awsDeploymentTargets: this.awsDeploymentTargets,
43221
+ componentName: "AwsDeployWorkflow"
43222
+ });
43223
+ this.applyWorkflow = applyWorkflow.workflow;
43224
+ WorkflowHomeRepository.require(this.rootProject, {
43225
+ workflow: applyWorkflow.workflow,
43226
+ workflowName: this.planApplyOptions.applyWorkflowName,
43227
+ homeRepository: this.homeRepository,
43228
+ componentName: "AwsDeployWorkflow"
43229
+ });
43072
43230
  }
43073
43231
  this.awsDeploymentTargets.forEach((target) => {
43074
43232
  const deployJobName = this.buildJobName(target);
@@ -43095,9 +43253,9 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
43095
43253
  ],
43096
43254
  runsOn: ["ubuntu-latest"],
43097
43255
  permissions: {
43098
- contents: import_workflows_model5.JobPermission.READ,
43099
- idToken: import_workflows_model5.JobPermission.WRITE,
43100
- pullRequests: import_workflows_model5.JobPermission.WRITE
43256
+ contents: import_workflows_model6.JobPermission.READ,
43257
+ idToken: import_workflows_model6.JobPermission.WRITE,
43258
+ pullRequests: import_workflows_model6.JobPermission.WRITE
43101
43259
  },
43102
43260
  ...this.environmentName ? { environment: this.environmentName } : void 0,
43103
43261
  concurrency: deployJobName,
@@ -43112,8 +43270,8 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
43112
43270
  needs: ["build"],
43113
43271
  runsOn: ["ubuntu-latest"],
43114
43272
  permissions: {
43115
- contents: import_workflows_model5.JobPermission.READ,
43116
- idToken: import_workflows_model5.JobPermission.WRITE
43273
+ contents: import_workflows_model6.JobPermission.READ,
43274
+ idToken: import_workflows_model6.JobPermission.WRITE
43117
43275
  },
43118
43276
  if: jobCondition,
43119
43277
  steps: [...this.diffSteps(target)]
@@ -43133,7 +43291,7 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
43133
43291
  name: "Build Sub Projects",
43134
43292
  run: `pnpm exec projen ${ROOT_CI_TASK_NAME}`
43135
43293
  },
43136
- import_github6.WorkflowSteps.uploadArtifact({
43294
+ import_github7.WorkflowSteps.uploadArtifact({
43137
43295
  name: "Upload Turbo runs",
43138
43296
  if: "always()",
43139
43297
  continueOnError: true,
@@ -43149,9 +43307,9 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
43149
43307
  };
43150
43308
 
43151
43309
  // src/workflows/aws-teardown-workflow.ts
43152
- var import_projen27 = require("projen");
43153
- var import_github7 = require("projen/lib/github");
43154
- var import_workflows_model6 = require("projen/lib/github/workflows-model");
43310
+ var import_projen29 = require("projen");
43311
+ var import_github8 = require("projen/lib/github");
43312
+ var import_workflows_model7 = require("projen/lib/github/workflows-model");
43155
43313
  var DEFAULT_TEARDOWN_BRANCH_PATTERNS = [
43156
43314
  "feat/*",
43157
43315
  "fix/*",
@@ -43171,7 +43329,7 @@ var resolveBranchPatterns = (explicit, targets) => {
43171
43329
  }
43172
43330
  return [...DEFAULT_TEARDOWN_BRANCH_PATTERNS];
43173
43331
  };
43174
- var AwsTeardownWorkflow = class extends import_projen27.Component {
43332
+ var AwsTeardownWorkflow = class extends import_projen29.Component {
43175
43333
  constructor(rootProject, options) {
43176
43334
  super(rootProject);
43177
43335
  this.rootProject = rootProject;
@@ -43201,7 +43359,7 @@ var AwsTeardownWorkflow = class extends import_projen27.Component {
43201
43359
  "AwsTeardownWorkflow requires the root project to be a MonorepoProject"
43202
43360
  );
43203
43361
  }
43204
- const github = import_github7.GitHub.of(this.rootProject);
43362
+ const github = import_github8.GitHub.of(this.rootProject);
43205
43363
  if (!github) {
43206
43364
  throw new Error(
43207
43365
  "AwsTeardownWorkflow requires a GitHub component in the root project"
@@ -43215,7 +43373,7 @@ var AwsTeardownWorkflow = class extends import_projen27.Component {
43215
43373
  homeRepository,
43216
43374
  "AwsTeardownWorkflow"
43217
43375
  );
43218
- const workflow = new import_github7.GithubWorkflow(github, "teardown-dev");
43376
+ const workflow = new import_github8.GithubWorkflow(github, "teardown-dev");
43219
43377
  workflow.on({
43220
43378
  workflowDispatch: {},
43221
43379
  schedule: [
@@ -43243,8 +43401,8 @@ var AwsTeardownWorkflow = class extends import_projen27.Component {
43243
43401
  runsOn: ["ubuntu-latest"],
43244
43402
  ...homeRepositoryCondition ? { if: `\${{ ${homeRepositoryCondition} }}` } : {},
43245
43403
  permissions: {
43246
- contents: import_workflows_model6.JobPermission.READ,
43247
- idToken: import_workflows_model6.JobPermission.WRITE
43404
+ contents: import_workflows_model7.JobPermission.READ,
43405
+ idToken: import_workflows_model7.JobPermission.WRITE
43248
43406
  },
43249
43407
  env: {
43250
43408
  REPO: "${{ github.repository }}",
@@ -43359,7 +43517,7 @@ var AwsTeardownWorkflow = class extends import_projen27.Component {
43359
43517
  };
43360
43518
 
43361
43519
  // src/projects/aws-cdk-project.ts
43362
- var AwsCdkProject = class extends import_projen28.awscdk.AwsCdkTypeScriptApp {
43520
+ var AwsCdkProject = class extends import_projen30.awscdk.AwsCdkTypeScriptApp {
43363
43521
  constructor(userOptions) {
43364
43522
  if (!(userOptions.parent instanceof MonorepoProject)) {
43365
43523
  throw new Error(
@@ -43495,12 +43653,18 @@ var AwsCdkProject = class extends import_projen28.awscdk.AwsCdkTypeScriptApp {
43495
43653
  const targetsForAutoDerive = AwsDeploymentConfig.of(this)?.awsDeploymentTargets ?? [];
43496
43654
  const deployWorkflows = options.deployWorkflows ?? Array.from(new Set(targetsForAutoDerive.map((t) => t.awsStageType))).map(
43497
43655
  (awsStageType) => {
43656
+ const diff = options.diff ? { diff: options.diff } : {};
43498
43657
  if (options.sharedBuildWorkflow) {
43499
- return { awsStageType, buildWorkflow: options.sharedBuildWorkflow };
43658
+ return {
43659
+ awsStageType,
43660
+ buildWorkflow: options.sharedBuildWorkflow,
43661
+ ...diff
43662
+ };
43500
43663
  }
43501
43664
  return {
43502
43665
  awsStageType,
43503
- ...options.buildWorkflowOptions ? { buildWorkflowOptions: options.buildWorkflowOptions } : {}
43666
+ ...options.buildWorkflowOptions ? { buildWorkflowOptions: options.buildWorkflowOptions } : {},
43667
+ ...diff
43504
43668
  };
43505
43669
  }
43506
43670
  );
@@ -43569,7 +43733,7 @@ var AwsCdkProject = class extends import_projen28.awscdk.AwsCdkTypeScriptApp {
43569
43733
  };
43570
43734
 
43571
43735
  // src/projects/react-vite-site-project.ts
43572
- var import_projen29 = require("projen");
43736
+ var import_projen31 = require("projen");
43573
43737
  var import_ts_deepmerge5 = require("ts-deepmerge");
43574
43738
  var ReactViteSiteProject = class extends TypeScriptProject {
43575
43739
  constructor(userOptions) {
@@ -43608,7 +43772,7 @@ var ReactViteSiteProject = class extends TypeScriptProject {
43608
43772
  };
43609
43773
  super(options);
43610
43774
  this.package.addField("type", "module");
43611
- new import_projen29.TextFile(this, ".nvmrc", { lines: ["v24.11.0"] });
43775
+ new import_projen31.TextFile(this, ".nvmrc", { lines: ["v24.11.0"] });
43612
43776
  this.tsconfig?.file.addOverride("compilerOptions.target", "ES2020");
43613
43777
  this.tsconfig?.file.addOverride("compilerOptions.lib", [
43614
43778
  "ES2020",
@@ -43643,7 +43807,7 @@ var ReactViteSiteProject = class extends TypeScriptProject {
43643
43807
  "vitest/globals",
43644
43808
  "vite/client"
43645
43809
  ]);
43646
- new import_projen29.SampleFile(this, "vite.config.ts", {
43810
+ new import_projen31.SampleFile(this, "vite.config.ts", {
43647
43811
  contents: `import { defineConfig } from 'vite';
43648
43812
  import react from '@vitejs/plugin-react';
43649
43813
  import tailwindcss from '@tailwindcss/vite';
@@ -43655,7 +43819,7 @@ export default defineConfig({
43655
43819
  });
43656
43820
  `
43657
43821
  });
43658
- new import_projen29.SampleFile(this, "src/vite-env.d.ts", {
43822
+ new import_projen31.SampleFile(this, "src/vite-env.d.ts", {
43659
43823
  contents: `/// <reference types="vite/client" />
43660
43824
 
43661
43825
  interface ImportMetaEnv {
@@ -43670,7 +43834,7 @@ interface ImportMeta {
43670
43834
  });
43671
43835
  if (options.testRunner !== TestRunner.JEST) {
43672
43836
  this.tryRemoveFile("vitest.config.ts");
43673
- new import_projen29.SampleFile(this, "vitest.config.ts", {
43837
+ new import_projen31.SampleFile(this, "vitest.config.ts", {
43674
43838
  contents: `import { defineConfig, mergeConfig } from 'vitest/config';
43675
43839
  import react from '@vitejs/plugin-react';
43676
43840
  import viteConfig from './vite.config';
@@ -43814,7 +43978,7 @@ export default mergeConfig(
43814
43978
  }
43815
43979
  if (userOptions.sampleCode === true) {
43816
43980
  const siteName = options.name;
43817
- new import_projen29.SampleFile(this, "index.html", {
43981
+ new import_projen31.SampleFile(this, "index.html", {
43818
43982
  contents: `<!doctype html>
43819
43983
  <html>
43820
43984
  <head>
@@ -43829,7 +43993,7 @@ export default mergeConfig(
43829
43993
  </html>
43830
43994
  `
43831
43995
  });
43832
- new import_projen29.SampleFile(this, "src/routes.tsx", {
43996
+ new import_projen31.SampleFile(this, "src/routes.tsx", {
43833
43997
  contents: `import { createBrowserRouter } from 'react-router-dom';
43834
43998
  import App from './App';
43835
43999
 
@@ -43838,7 +44002,7 @@ export const router = createBrowserRouter([
43838
44002
  ]);
43839
44003
  `
43840
44004
  });
43841
- new import_projen29.SampleFile(this, "src/main.tsx", {
44005
+ new import_projen31.SampleFile(this, "src/main.tsx", {
43842
44006
  contents: `import React from 'react';
43843
44007
  import ReactDOM from 'react-dom/client';
43844
44008
  import { RouterProvider } from 'react-router-dom';
@@ -43852,7 +44016,7 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
43852
44016
  );
43853
44017
  `
43854
44018
  });
43855
- new import_projen29.SampleFile(this, "src/App.tsx", {
44019
+ new import_projen31.SampleFile(this, "src/App.tsx", {
43856
44020
  contents: `export default function App() {
43857
44021
  return (
43858
44022
  <main className="p-4">
@@ -43862,11 +44026,11 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
43862
44026
  }
43863
44027
  `
43864
44028
  });
43865
- new import_projen29.SampleFile(this, "src/index.css", {
44029
+ new import_projen31.SampleFile(this, "src/index.css", {
43866
44030
  contents: `@import "tailwindcss";
43867
44031
  `
43868
44032
  });
43869
- new import_projen29.SampleFile(this, "src/setupTests.ts", {
44033
+ new import_projen31.SampleFile(this, "src/setupTests.ts", {
43870
44034
  contents: `import '@testing-library/jest-dom';
43871
44035
  `
43872
44036
  });
@@ -43875,7 +44039,7 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
43875
44039
  };
43876
44040
 
43877
44041
  // src/projects/starlight-project.ts
43878
- var import_projen30 = require("projen");
44042
+ var import_projen32 = require("projen");
43879
44043
  var STARLIGHT_ROLE = {
43880
44044
  DOCS: "docs",
43881
44045
  SITE: "site"
@@ -43917,10 +44081,10 @@ var StarlightProject = class extends AstroProject {
43917
44081
  turbo.compileTask.inputs.push("src/content/**");
43918
44082
  }
43919
44083
  if (userOptions.sampleContent === true) {
43920
- new import_projen30.SampleFile(this, "src/content/docs/index.mdx", {
44084
+ new import_projen32.SampleFile(this, "src/content/docs/index.mdx", {
43921
44085
  contents: DEFAULT_INDEX_MDX
43922
44086
  });
43923
- new import_projen30.SampleFile(this, "src/content.config.ts", {
44087
+ new import_projen32.SampleFile(this, "src/content.config.ts", {
43924
44088
  contents: DEFAULT_CONTENT_CONFIG_TS
43925
44089
  });
43926
44090
  }
@@ -44003,6 +44167,7 @@ export const collections = {
44003
44167
  AUDIT_CATEGORY_ORDER,
44004
44168
  AgentConfig,
44005
44169
  ApiExtractor,
44170
+ ApplyWorkflow,
44006
44171
  AstroConfig,
44007
44172
  AstroOutput,
44008
44173
  AstroProject,
@@ -44157,6 +44322,7 @@ export const collections = {
44157
44322
  VERSION_NPM_PACKAGES,
44158
44323
  VSCodeConfig,
44159
44324
  Vitest,
44325
+ WorkflowHomeRepository,
44160
44326
  addApproveMergeUpgradeWorkflow,
44161
44327
  addBuildCompleteJob,
44162
44328
  addPlaywright,