@codedrifters/configulator 0.0.430 → 0.0.431

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.d.mts CHANGED
@@ -12573,6 +12573,35 @@ interface DeployWorkflowOptions {
12573
12573
  * @default discovers all targets using stageType
12574
12574
  */
12575
12575
  readonly awsDeploymentTargets?: Array<AwsDeploymentTarget>;
12576
+ /**
12577
+ * Key each deploy job's concurrency group on the branch as well as the
12578
+ * deployment target.
12579
+ *
12580
+ * A deploy job's group is otherwise the target coordinates alone
12581
+ * (`<stage>-<role>-deploy-<project>-<account>-<region>`), and GitHub scopes
12582
+ * concurrency groups to the *repository* — so one group serializes every run
12583
+ * of every workflow carrying that job, on every branch. That is what you want
12584
+ * when each branch deploys the same stacks.
12585
+ *
12586
+ * It is not what you want when the CDK app derives its stack names from the
12587
+ * branch: two branches then update entirely separate stacks while queueing
12588
+ * behind one lock. Setting this appends the branch, so branches deploy in
12589
+ * parallel and same-branch runs still serialize.
12590
+ *
12591
+ * Enabling this lets per-branch deploys run concurrently into the *same* AWS
12592
+ * account, so anything they share outside their own stacks — a parent hosted
12593
+ * zone, an account-level singleton — has to tolerate concurrent mutation.
12594
+ *
12595
+ * Applies to the deploy job only. The `plan-apply` gate's apply job keeps the
12596
+ * unsuffixed group: an apply is dispatched from whatever ref the operator
12597
+ * happens to be on, which says nothing about the branch that was planned, so
12598
+ * a branch key there would weaken the mutual exclusion rather than sharpen
12599
+ * it.
12600
+ *
12601
+ * @see `docs/packages/@codedrifters/configulator/workflows/aws-deploy-workflow.md`
12602
+ * @default false - the group is the deployment target alone
12603
+ */
12604
+ readonly branchScopedConcurrency?: boolean;
12576
12605
  /**
12577
12606
  * Existing workflow, useful if we're tacking deployments onto an existing
12578
12607
  * build workflow
@@ -12700,6 +12729,10 @@ declare class AwsDeployWorkflow extends Component {
12700
12729
  * never have to re-apply the defaults.
12701
12730
  */
12702
12731
  readonly diffOptions: Required<DeployDiffOptions>;
12732
+ /**
12733
+ * Whether each deploy job's concurrency group carries the branch.
12734
+ */
12735
+ readonly branchScopedConcurrency: boolean;
12703
12736
  /**
12704
12737
  * Repository this workflow's cloud-touching jobs are pinned to, if any.
12705
12738
  */
@@ -12738,6 +12771,20 @@ declare class AwsDeployWorkflow extends Component {
12738
12771
  * header so dev/stage/prod comments don't collide on the same PR.
12739
12772
  */
12740
12773
  private buildJobName;
12774
+ /**
12775
+ * Build a deploy job's `concurrency` setting from its job name.
12776
+ *
12777
+ * Two shapes, deliberately:
12778
+ *
12779
+ * - Unscoped (the default) stays the bare string the job has always carried,
12780
+ * so an existing consumer's workflow is byte-identical.
12781
+ * - Branch-scoped spells out `cancel-in-progress: false` rather than leaning
12782
+ * on GitHub's default, the same way the apply job does. A group keyed on
12783
+ * the branch reads like a "cancel superseded pushes" group, and that is the
12784
+ * one thing it must not be — cancelling a half-finished `cdk deploy`
12785
+ * strands a CloudFormation stack mid-update.
12786
+ */
12787
+ private buildDeployConcurrency;
12741
12788
  /**
12742
12789
  * Build the deterministic GitHub Actions job name for a target's apply job.
12743
12790
  * Mirrors {@link buildJobName} with an `apply` verb.
package/lib/index.d.ts CHANGED
@@ -12622,6 +12622,35 @@ interface DeployWorkflowOptions {
12622
12622
  * @default discovers all targets using stageType
12623
12623
  */
12624
12624
  readonly awsDeploymentTargets?: Array<AwsDeploymentTarget>;
12625
+ /**
12626
+ * Key each deploy job's concurrency group on the branch as well as the
12627
+ * deployment target.
12628
+ *
12629
+ * A deploy job's group is otherwise the target coordinates alone
12630
+ * (`<stage>-<role>-deploy-<project>-<account>-<region>`), and GitHub scopes
12631
+ * concurrency groups to the *repository* — so one group serializes every run
12632
+ * of every workflow carrying that job, on every branch. That is what you want
12633
+ * when each branch deploys the same stacks.
12634
+ *
12635
+ * It is not what you want when the CDK app derives its stack names from the
12636
+ * branch: two branches then update entirely separate stacks while queueing
12637
+ * behind one lock. Setting this appends the branch, so branches deploy in
12638
+ * parallel and same-branch runs still serialize.
12639
+ *
12640
+ * Enabling this lets per-branch deploys run concurrently into the *same* AWS
12641
+ * account, so anything they share outside their own stacks — a parent hosted
12642
+ * zone, an account-level singleton — has to tolerate concurrent mutation.
12643
+ *
12644
+ * Applies to the deploy job only. The `plan-apply` gate's apply job keeps the
12645
+ * unsuffixed group: an apply is dispatched from whatever ref the operator
12646
+ * happens to be on, which says nothing about the branch that was planned, so
12647
+ * a branch key there would weaken the mutual exclusion rather than sharpen
12648
+ * it.
12649
+ *
12650
+ * @see `docs/packages/@codedrifters/configulator/workflows/aws-deploy-workflow.md`
12651
+ * @default false - the group is the deployment target alone
12652
+ */
12653
+ readonly branchScopedConcurrency?: boolean;
12625
12654
  /**
12626
12655
  * Existing workflow, useful if we're tacking deployments onto an existing
12627
12656
  * build workflow
@@ -12749,6 +12778,10 @@ declare class AwsDeployWorkflow extends Component {
12749
12778
  * never have to re-apply the defaults.
12750
12779
  */
12751
12780
  readonly diffOptions: Required<DeployDiffOptions>;
12781
+ /**
12782
+ * Whether each deploy job's concurrency group carries the branch.
12783
+ */
12784
+ readonly branchScopedConcurrency: boolean;
12752
12785
  /**
12753
12786
  * Repository this workflow's cloud-touching jobs are pinned to, if any.
12754
12787
  */
@@ -12787,6 +12820,20 @@ declare class AwsDeployWorkflow extends Component {
12787
12820
  * header so dev/stage/prod comments don't collide on the same PR.
12788
12821
  */
12789
12822
  private buildJobName;
12823
+ /**
12824
+ * Build a deploy job's `concurrency` setting from its job name.
12825
+ *
12826
+ * Two shapes, deliberately:
12827
+ *
12828
+ * - Unscoped (the default) stays the bare string the job has always carried,
12829
+ * so an existing consumer's workflow is byte-identical.
12830
+ * - Branch-scoped spells out `cancel-in-progress: false` rather than leaning
12831
+ * on GitHub's default, the same way the apply job does. A group keyed on
12832
+ * the branch reads like a "cancel superseded pushes" group, and that is the
12833
+ * one thing it must not be — cancelling a half-finished `cdk deploy`
12834
+ * strands a CloudFormation stack mid-update.
12835
+ */
12836
+ private buildDeployConcurrency;
12790
12837
  /**
12791
12838
  * Build the deterministic GitHub Actions job name for a target's apply job.
12792
12839
  * Mirrors {@link buildJobName} with an `apply` verb.
package/lib/index.js CHANGED
@@ -42928,6 +42928,7 @@ var renderSetupPnpm = (pnpmVersion) => {
42928
42928
 
42929
42929
  // src/workflows/aws-deploy-workflow.ts
42930
42930
  var PROD_DEPLOY_NAME = "prod-deploy";
42931
+ var BRANCH_NAME_EXPRESSION = "${{ github.head_ref || github.ref_name }}";
42931
42932
  var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen29.Component {
42932
42933
  constructor(project, options = {}) {
42933
42934
  super(project);
@@ -42958,6 +42959,28 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen29.Compone
42958
42959
  target.region
42959
42960
  ].join("-");
42960
42961
  };
42962
+ /**
42963
+ * Build a deploy job's `concurrency` setting from its job name.
42964
+ *
42965
+ * Two shapes, deliberately:
42966
+ *
42967
+ * - Unscoped (the default) stays the bare string the job has always carried,
42968
+ * so an existing consumer's workflow is byte-identical.
42969
+ * - Branch-scoped spells out `cancel-in-progress: false` rather than leaning
42970
+ * on GitHub's default, the same way the apply job does. A group keyed on
42971
+ * the branch reads like a "cancel superseded pushes" group, and that is the
42972
+ * one thing it must not be — cancelling a half-finished `cdk deploy`
42973
+ * strands a CloudFormation stack mid-update.
42974
+ */
42975
+ this.buildDeployConcurrency = (deployJobName) => {
42976
+ if (!this.branchScopedConcurrency) {
42977
+ return deployJobName;
42978
+ }
42979
+ return {
42980
+ group: `${deployJobName}-${BRANCH_NAME_EXPRESSION}`,
42981
+ "cancel-in-progress": false
42982
+ };
42983
+ };
42961
42984
  /**
42962
42985
  * Build the deterministic GitHub Actions job name for a target's apply job.
42963
42986
  * Mirrors {@link buildJobName} with an `apply` verb.
@@ -43087,6 +43110,13 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen29.Compone
43087
43110
  * same-target deploy. `cancel-in-progress` is spelled out rather than
43088
43111
  * left to GitHub's default: cancelling a half-finished `cdk deploy`
43089
43112
  * strands a CloudFormation stack mid-update.
43113
+ *
43114
+ * `branchScopedConcurrency` deliberately does not reach here. An apply is
43115
+ * dispatched from whatever ref the operator happens to be on — unrelated
43116
+ * to the branch the nominated plan ran against, which is the only branch
43117
+ * that describes what is about to be deployed. Keying on the dispatch ref
43118
+ * would hand out separate locks to applies of the same target, so the
43119
+ * unsuffixed group stays.
43090
43120
  */
43091
43121
  concurrency: {
43092
43122
  group: this.buildJobName(target),
@@ -43352,6 +43382,7 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen29.Compone
43352
43382
  artifact: options.diff?.artifact ?? true,
43353
43383
  summary: options.diff?.summary ?? true
43354
43384
  };
43385
+ this.branchScopedConcurrency = options.branchScopedConcurrency ?? false;
43355
43386
  this.environmentName = resolveEnvironmentGate(
43356
43387
  options.gate,
43357
43388
  options.environmentName,
@@ -43415,7 +43446,7 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen29.Compone
43415
43446
  * Set GIT_BRANCH_NAME so Turborepo remote cache hashes match between local and CI.
43416
43447
  */
43417
43448
  env: {
43418
- GIT_BRANCH_NAME: "${{ github.head_ref || github.ref_name }}",
43449
+ GIT_BRANCH_NAME: BRANCH_NAME_EXPRESSION,
43419
43450
  ...options.buildWorkflowOptions?.env,
43420
43451
  ...buildWorkflowOptions?.env
43421
43452
  },
@@ -43505,7 +43536,7 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen29.Compone
43505
43536
  pullRequests: import_workflows_model7.JobPermission.WRITE
43506
43537
  },
43507
43538
  ...this.environmentName ? { environment: this.environmentName } : void 0,
43508
- concurrency: deployJobName,
43539
+ concurrency: this.buildDeployConcurrency(deployJobName),
43509
43540
  if: jobCondition,
43510
43541
  steps: [...this.deploySteps(target)]
43511
43542
  });