@codedrifters/configulator 0.0.428 → 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(
@@ -43575,7 +43733,7 @@ var AwsCdkProject = class extends import_projen28.awscdk.AwsCdkTypeScriptApp {
43575
43733
  };
43576
43734
 
43577
43735
  // src/projects/react-vite-site-project.ts
43578
- var import_projen29 = require("projen");
43736
+ var import_projen31 = require("projen");
43579
43737
  var import_ts_deepmerge5 = require("ts-deepmerge");
43580
43738
  var ReactViteSiteProject = class extends TypeScriptProject {
43581
43739
  constructor(userOptions) {
@@ -43614,7 +43772,7 @@ var ReactViteSiteProject = class extends TypeScriptProject {
43614
43772
  };
43615
43773
  super(options);
43616
43774
  this.package.addField("type", "module");
43617
- new import_projen29.TextFile(this, ".nvmrc", { lines: ["v24.11.0"] });
43775
+ new import_projen31.TextFile(this, ".nvmrc", { lines: ["v24.11.0"] });
43618
43776
  this.tsconfig?.file.addOverride("compilerOptions.target", "ES2020");
43619
43777
  this.tsconfig?.file.addOverride("compilerOptions.lib", [
43620
43778
  "ES2020",
@@ -43649,7 +43807,7 @@ var ReactViteSiteProject = class extends TypeScriptProject {
43649
43807
  "vitest/globals",
43650
43808
  "vite/client"
43651
43809
  ]);
43652
- new import_projen29.SampleFile(this, "vite.config.ts", {
43810
+ new import_projen31.SampleFile(this, "vite.config.ts", {
43653
43811
  contents: `import { defineConfig } from 'vite';
43654
43812
  import react from '@vitejs/plugin-react';
43655
43813
  import tailwindcss from '@tailwindcss/vite';
@@ -43661,7 +43819,7 @@ export default defineConfig({
43661
43819
  });
43662
43820
  `
43663
43821
  });
43664
- new import_projen29.SampleFile(this, "src/vite-env.d.ts", {
43822
+ new import_projen31.SampleFile(this, "src/vite-env.d.ts", {
43665
43823
  contents: `/// <reference types="vite/client" />
43666
43824
 
43667
43825
  interface ImportMetaEnv {
@@ -43676,7 +43834,7 @@ interface ImportMeta {
43676
43834
  });
43677
43835
  if (options.testRunner !== TestRunner.JEST) {
43678
43836
  this.tryRemoveFile("vitest.config.ts");
43679
- new import_projen29.SampleFile(this, "vitest.config.ts", {
43837
+ new import_projen31.SampleFile(this, "vitest.config.ts", {
43680
43838
  contents: `import { defineConfig, mergeConfig } from 'vitest/config';
43681
43839
  import react from '@vitejs/plugin-react';
43682
43840
  import viteConfig from './vite.config';
@@ -43820,7 +43978,7 @@ export default mergeConfig(
43820
43978
  }
43821
43979
  if (userOptions.sampleCode === true) {
43822
43980
  const siteName = options.name;
43823
- new import_projen29.SampleFile(this, "index.html", {
43981
+ new import_projen31.SampleFile(this, "index.html", {
43824
43982
  contents: `<!doctype html>
43825
43983
  <html>
43826
43984
  <head>
@@ -43835,7 +43993,7 @@ export default mergeConfig(
43835
43993
  </html>
43836
43994
  `
43837
43995
  });
43838
- new import_projen29.SampleFile(this, "src/routes.tsx", {
43996
+ new import_projen31.SampleFile(this, "src/routes.tsx", {
43839
43997
  contents: `import { createBrowserRouter } from 'react-router-dom';
43840
43998
  import App from './App';
43841
43999
 
@@ -43844,7 +44002,7 @@ export const router = createBrowserRouter([
43844
44002
  ]);
43845
44003
  `
43846
44004
  });
43847
- new import_projen29.SampleFile(this, "src/main.tsx", {
44005
+ new import_projen31.SampleFile(this, "src/main.tsx", {
43848
44006
  contents: `import React from 'react';
43849
44007
  import ReactDOM from 'react-dom/client';
43850
44008
  import { RouterProvider } from 'react-router-dom';
@@ -43858,7 +44016,7 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
43858
44016
  );
43859
44017
  `
43860
44018
  });
43861
- new import_projen29.SampleFile(this, "src/App.tsx", {
44019
+ new import_projen31.SampleFile(this, "src/App.tsx", {
43862
44020
  contents: `export default function App() {
43863
44021
  return (
43864
44022
  <main className="p-4">
@@ -43868,11 +44026,11 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
43868
44026
  }
43869
44027
  `
43870
44028
  });
43871
- new import_projen29.SampleFile(this, "src/index.css", {
44029
+ new import_projen31.SampleFile(this, "src/index.css", {
43872
44030
  contents: `@import "tailwindcss";
43873
44031
  `
43874
44032
  });
43875
- new import_projen29.SampleFile(this, "src/setupTests.ts", {
44033
+ new import_projen31.SampleFile(this, "src/setupTests.ts", {
43876
44034
  contents: `import '@testing-library/jest-dom';
43877
44035
  `
43878
44036
  });
@@ -43881,7 +44039,7 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
43881
44039
  };
43882
44040
 
43883
44041
  // src/projects/starlight-project.ts
43884
- var import_projen30 = require("projen");
44042
+ var import_projen32 = require("projen");
43885
44043
  var STARLIGHT_ROLE = {
43886
44044
  DOCS: "docs",
43887
44045
  SITE: "site"
@@ -43923,10 +44081,10 @@ var StarlightProject = class extends AstroProject {
43923
44081
  turbo.compileTask.inputs.push("src/content/**");
43924
44082
  }
43925
44083
  if (userOptions.sampleContent === true) {
43926
- new import_projen30.SampleFile(this, "src/content/docs/index.mdx", {
44084
+ new import_projen32.SampleFile(this, "src/content/docs/index.mdx", {
43927
44085
  contents: DEFAULT_INDEX_MDX
43928
44086
  });
43929
- new import_projen30.SampleFile(this, "src/content.config.ts", {
44087
+ new import_projen32.SampleFile(this, "src/content.config.ts", {
43930
44088
  contents: DEFAULT_CONTENT_CONFIG_TS
43931
44089
  });
43932
44090
  }
@@ -44009,6 +44167,7 @@ export const collections = {
44009
44167
  AUDIT_CATEGORY_ORDER,
44010
44168
  AgentConfig,
44011
44169
  ApiExtractor,
44170
+ ApplyWorkflow,
44012
44171
  AstroConfig,
44013
44172
  AstroOutput,
44014
44173
  AstroProject,
@@ -44163,6 +44322,7 @@ export const collections = {
44163
44322
  VERSION_NPM_PACKAGES,
44164
44323
  VSCodeConfig,
44165
44324
  Vitest,
44325
+ WorkflowHomeRepository,
44166
44326
  addApproveMergeUpgradeWorkflow,
44167
44327
  addBuildCompleteJob,
44168
44328
  addPlaywright,