@codedrifters/configulator 0.0.430 → 0.0.432
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 +105 -1
- package/lib/index.d.ts +105 -1
- package/lib/index.js +137 -12
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +136 -12
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/lib/index.mjs
CHANGED
|
@@ -42230,6 +42230,7 @@ var DIFF_REPORT_JOB_ID = "diff-report";
|
|
|
42230
42230
|
var DIFF_OUTPUT_DIRECTORY = "cdk-diff";
|
|
42231
42231
|
var DIFF_PART_ARTIFACT_PREFIX = "cdk-diff-part";
|
|
42232
42232
|
var DIFF_ARTIFACT_NAME = "cdk-diff";
|
|
42233
|
+
var DIFF_NEW_STACK_MARKER = "NEW STACK";
|
|
42233
42234
|
var DIFF_PART_RETENTION_DAYS = 1;
|
|
42234
42235
|
var DIFF_SUMMARY_BYTE_LIMIT = 9e5;
|
|
42235
42236
|
var RUN_URL = "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}";
|
|
@@ -42305,6 +42306,11 @@ var DiffReportJob = class _DiffReportJob extends Component23 {
|
|
|
42305
42306
|
* captured anything from one that simply had no changes — the latter has a
|
|
42306
42307
|
* file, carrying the CDK CLI's own no-differences wording, rather than being
|
|
42307
42308
|
* detected by matching on it.
|
|
42309
|
+
*
|
|
42310
|
+
* A capture carrying {@link DIFF_NEW_STACK_MARKER} lines has its banners
|
|
42311
|
+
* lifted out of the `<details>` block and quoted under the heading, so a
|
|
42312
|
+
* target that will be created from scratch reads as such without expanding
|
|
42313
|
+
* anything.
|
|
42308
42314
|
*/
|
|
42309
42315
|
this.renderSummaryStep = () => {
|
|
42310
42316
|
if (!this.summary || this.targets.length === 0) {
|
|
@@ -42329,6 +42335,10 @@ var DiffReportJob = class _DiffReportJob extends Component23 {
|
|
|
42329
42335
|
' echo ""',
|
|
42330
42336
|
" continue",
|
|
42331
42337
|
" fi",
|
|
42338
|
+
` if grep -q '^${DIFF_NEW_STACK_MARKER}' "$file"; then`,
|
|
42339
|
+
` grep '^${DIFF_NEW_STACK_MARKER}' "$file" | sed 's/^/> **/; s/$/**/'`,
|
|
42340
|
+
' echo ""',
|
|
42341
|
+
" fi",
|
|
42332
42342
|
" echo '<details><summary>cdk diff output</summary>'",
|
|
42333
42343
|
' echo ""',
|
|
42334
42344
|
" echo '```'",
|
|
@@ -42548,6 +42558,7 @@ var renderSetupPnpm = (pnpmVersion) => {
|
|
|
42548
42558
|
|
|
42549
42559
|
// src/workflows/aws-deploy-workflow.ts
|
|
42550
42560
|
var PROD_DEPLOY_NAME = "prod-deploy";
|
|
42561
|
+
var BRANCH_NAME_EXPRESSION = "${{ github.head_ref || github.ref_name }}";
|
|
42551
42562
|
var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component25 {
|
|
42552
42563
|
constructor(project, options = {}) {
|
|
42553
42564
|
super(project);
|
|
@@ -42578,6 +42589,28 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component25 {
|
|
|
42578
42589
|
target.region
|
|
42579
42590
|
].join("-");
|
|
42580
42591
|
};
|
|
42592
|
+
/**
|
|
42593
|
+
* Build a deploy job's `concurrency` setting from its job name.
|
|
42594
|
+
*
|
|
42595
|
+
* Two shapes, deliberately:
|
|
42596
|
+
*
|
|
42597
|
+
* - Unscoped (the default) stays the bare string the job has always carried,
|
|
42598
|
+
* so an existing consumer's workflow is byte-identical.
|
|
42599
|
+
* - Branch-scoped spells out `cancel-in-progress: false` rather than leaning
|
|
42600
|
+
* on GitHub's default, the same way the apply job does. A group keyed on
|
|
42601
|
+
* the branch reads like a "cancel superseded pushes" group, and that is the
|
|
42602
|
+
* one thing it must not be — cancelling a half-finished `cdk deploy`
|
|
42603
|
+
* strands a CloudFormation stack mid-update.
|
|
42604
|
+
*/
|
|
42605
|
+
this.buildDeployConcurrency = (deployJobName) => {
|
|
42606
|
+
if (!this.branchScopedConcurrency) {
|
|
42607
|
+
return deployJobName;
|
|
42608
|
+
}
|
|
42609
|
+
return {
|
|
42610
|
+
group: `${deployJobName}-${BRANCH_NAME_EXPRESSION}`,
|
|
42611
|
+
"cancel-in-progress": false
|
|
42612
|
+
};
|
|
42613
|
+
};
|
|
42581
42614
|
/**
|
|
42582
42615
|
* Build the deterministic GitHub Actions job name for a target's apply job.
|
|
42583
42616
|
* Mirrors {@link buildJobName} with an `apply` verb.
|
|
@@ -42707,6 +42740,13 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component25 {
|
|
|
42707
42740
|
* same-target deploy. `cancel-in-progress` is spelled out rather than
|
|
42708
42741
|
* left to GitHub's default: cancelling a half-finished `cdk deploy`
|
|
42709
42742
|
* strands a CloudFormation stack mid-update.
|
|
42743
|
+
*
|
|
42744
|
+
* `branchScopedConcurrency` deliberately does not reach here. An apply is
|
|
42745
|
+
* dispatched from whatever ref the operator happens to be on — unrelated
|
|
42746
|
+
* to the branch the nominated plan ran against, which is the only branch
|
|
42747
|
+
* that describes what is about to be deployed. Keying on the dispatch ref
|
|
42748
|
+
* would hand out separate locks to applies of the same target, so the
|
|
42749
|
+
* unsuffixed group stays.
|
|
42710
42750
|
*/
|
|
42711
42751
|
concurrency: {
|
|
42712
42752
|
group: this.buildJobName(target),
|
|
@@ -42876,6 +42916,11 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component25 {
|
|
|
42876
42916
|
* `app` and `stackPatterns` target the built cloud assembly, and `ci` /
|
|
42877
42917
|
* `noColor` force the human-readable diff onto stdout without ANSI escapes
|
|
42878
42918
|
* (without `--ci` the CLI interleaves it into stderr alongside logs).
|
|
42919
|
+
*
|
|
42920
|
+
* `method` is the one resolved flag not baked into the rendered command. A
|
|
42921
|
+
* from-scratch target has to be classified before it can be diffed — see
|
|
42922
|
+
* {@link diffProbeLines} — so the command reads the effective method from
|
|
42923
|
+
* `$method`.
|
|
42879
42924
|
*/
|
|
42880
42925
|
this.diffSteps = (target) => {
|
|
42881
42926
|
const {
|
|
@@ -42890,6 +42935,20 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component25 {
|
|
|
42890
42935
|
const { rootCdkOut, cdkCli } = awsDeploymentConfig;
|
|
42891
42936
|
const label = `${awsStageType}/${deploymentTargetRole}/${account}/${region}`;
|
|
42892
42937
|
const outputFile = this.buildDiffOutputFile(target);
|
|
42938
|
+
const stackPatterns = stackPattern ? [stackPattern] : void 0;
|
|
42939
|
+
const diffCommand = [
|
|
42940
|
+
`pnpm dlx "aws-cdk@${cdkCli.cliVersion}"`,
|
|
42941
|
+
renderCdkDiff({
|
|
42942
|
+
...cdkCli.diffOptionsFor(target),
|
|
42943
|
+
app: rootCdkOut,
|
|
42944
|
+
ci: true,
|
|
42945
|
+
noColor: true,
|
|
42946
|
+
method: void 0,
|
|
42947
|
+
stackPatterns: void 0
|
|
42948
|
+
}),
|
|
42949
|
+
'--method="$method"',
|
|
42950
|
+
...(stackPatterns ?? []).map((pattern) => `"${pattern}"`)
|
|
42951
|
+
].join(" ");
|
|
42893
42952
|
return [
|
|
42894
42953
|
...this.setupPnpm(),
|
|
42895
42954
|
...this.setupNode(),
|
|
@@ -42907,11 +42966,14 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component25 {
|
|
|
42907
42966
|
}
|
|
42908
42967
|
},
|
|
42909
42968
|
/**
|
|
42910
|
-
*
|
|
42911
|
-
* log. `pipefail` keeps the CLI's
|
|
42969
|
+
* Classify the target's stacks, then run CDK Diff, capturing the output
|
|
42970
|
+
* while leaving it visible in the job log. `pipefail` keeps the CLI's
|
|
42971
|
+
* exit code from being masked by `tee`.
|
|
42912
42972
|
*
|
|
42913
42973
|
* The capture lands under the same path the report job will merge it
|
|
42914
|
-
* back to, so a target's file name is identical in both places.
|
|
42974
|
+
* back to, so a target's file name is identical in both places. It is
|
|
42975
|
+
* truncated first and appended to from there, so a re-run never reads a
|
|
42976
|
+
* previous attempt's banners.
|
|
42915
42977
|
*/
|
|
42916
42978
|
{
|
|
42917
42979
|
name: `Diff ${label}`,
|
|
@@ -42919,13 +42981,9 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component25 {
|
|
|
42919
42981
|
run: [
|
|
42920
42982
|
"set -o pipefail",
|
|
42921
42983
|
`mkdir -p ${DIFF_OUTPUT_DIRECTORY}`,
|
|
42922
|
-
|
|
42923
|
-
|
|
42924
|
-
|
|
42925
|
-
ci: true,
|
|
42926
|
-
noColor: true,
|
|
42927
|
-
stackPatterns: stackPattern ? [stackPattern] : void 0
|
|
42928
|
-
})} 2>&1 | tee ${outputFile}`
|
|
42984
|
+
`: > ${outputFile}`,
|
|
42985
|
+
...this.diffProbeLines(target, outputFile),
|
|
42986
|
+
`${diffCommand} 2>&1 | tee -a ${outputFile}`
|
|
42929
42987
|
].join("\n")
|
|
42930
42988
|
},
|
|
42931
42989
|
/**
|
|
@@ -42941,6 +42999,70 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component25 {
|
|
|
42941
42999
|
})
|
|
42942
43000
|
];
|
|
42943
43001
|
};
|
|
43002
|
+
/**
|
|
43003
|
+
* Lines that classify every stack a target's pattern matches before the diff
|
|
43004
|
+
* runs, so a stack that will be created from scratch is reported as such
|
|
43005
|
+
* instead of failing the job.
|
|
43006
|
+
*
|
|
43007
|
+
* `cdk diff --method=change-set` asks CloudFormation for an `UPDATE` change
|
|
43008
|
+
* set whenever the stack exists — and a `ROLLBACK_COMPLETE` /
|
|
43009
|
+
* `ROLLBACK_FAILED` tombstone left by a failed first create does exist, so
|
|
43010
|
+
* CloudFormation rejects the request and the job goes red. `cdk deploy`
|
|
43011
|
+
* consults `stackStatus.isCreationFailure`, deletes the tombstone and
|
|
43012
|
+
* recreates the stack, so the apply succeeds on exactly the stack the diff
|
|
43013
|
+
* refuses to look at. Under the `plan-apply` gate that asymmetry is a hard
|
|
43014
|
+
* blocker rather than a cosmetic one: the apply requires a successful plan
|
|
43015
|
+
* run, so one from-scratch target blocks applying any plan for the stage.
|
|
43016
|
+
*
|
|
43017
|
+
* `cdk list --long --json` resolves the pattern to CloudFormation stack names
|
|
43018
|
+
* out of the built assembly's manifest — no synth, no cloud call — and each
|
|
43019
|
+
* name costs one `describe-stacks`, which needs only
|
|
43020
|
+
* `cloudformation:DescribeStacks`. Any role that can run a change-set diff
|
|
43021
|
+
* already carries it. A `cdk list` that fails contributes no names, leaving
|
|
43022
|
+
* the diff to run exactly as it does today.
|
|
43023
|
+
*
|
|
43024
|
+
* A genuinely absent stack keeps the configured method — CDK gives it a
|
|
43025
|
+
* `CREATE` change set and diffs it fine. Only a tombstone moves the method,
|
|
43026
|
+
* and only to `template`, never to `auto`: `auto` would swallow a real
|
|
43027
|
+
* permission failure and present a degraded diff as authoritative, which is
|
|
43028
|
+
* what an explicit `change-set` pin exists to prevent. `template`
|
|
43029
|
+
* over-reporting replacements is vacuous here, because every resource in a
|
|
43030
|
+
* stack built from scratch is an add.
|
|
43031
|
+
*
|
|
43032
|
+
* The method is per invocation, not per stack — `cdk diff` diffs everything
|
|
43033
|
+
* its pattern matches in one pass. A pattern matching several stacks where
|
|
43034
|
+
* only one is a tombstone therefore diffs all of them with `template`, and
|
|
43035
|
+
* the banner names the stack that caused it.
|
|
43036
|
+
*/
|
|
43037
|
+
this.diffProbeLines = (target, outputFile) => {
|
|
43038
|
+
const { ciDeploymentConfig, awsDeploymentConfig } = target;
|
|
43039
|
+
const { stackPattern } = ciDeploymentConfig ?? {};
|
|
43040
|
+
const { rootCdkOut, cdkCli } = awsDeploymentConfig;
|
|
43041
|
+
const configuredMethod = cdkCli.diffOptionsFor(target).method ?? CDK_DIFF_METHOD.ChangeSet;
|
|
43042
|
+
const listCommand = `pnpm dlx "aws-cdk@${cdkCli.cliVersion}" ${renderCdkList(
|
|
43043
|
+
{
|
|
43044
|
+
app: rootCdkOut,
|
|
43045
|
+
json: true,
|
|
43046
|
+
long: true,
|
|
43047
|
+
stackPatterns: stackPattern ? [stackPattern] : void 0
|
|
43048
|
+
}
|
|
43049
|
+
)}`;
|
|
43050
|
+
return [
|
|
43051
|
+
`method=${configuredMethod}`,
|
|
43052
|
+
"while read -r stack; do",
|
|
43053
|
+
' status=$(aws cloudformation describe-stacks --stack-name "$stack" --query "Stacks[0].StackStatus" --output text 2>/dev/null || echo NOT_FOUND)',
|
|
43054
|
+
' case "$status" in',
|
|
43055
|
+
" NOT_FOUND|REVIEW_IN_PROGRESS)",
|
|
43056
|
+
` echo "${DIFF_NEW_STACK_MARKER} \u2014 $stack does not exist yet, so this target will be created from scratch." | tee -a ${outputFile}`,
|
|
43057
|
+
" ;;",
|
|
43058
|
+
" ROLLBACK_COMPLETE|ROLLBACK_FAILED)",
|
|
43059
|
+
` method=${CDK_DIFF_METHOD.Template}`,
|
|
43060
|
+
` echo "${DIFF_NEW_STACK_MARKER} \u2014 $stack exists only as a failed-create tombstone ($status), so this target will be created from scratch. Diffing it with --method=${CDK_DIFF_METHOD.Template}." | tee -a ${outputFile}`,
|
|
43061
|
+
" ;;",
|
|
43062
|
+
" esac",
|
|
43063
|
+
`done < <(${listCommand} 2>/dev/null | jq -r '.[].name' 2>/dev/null)`
|
|
43064
|
+
];
|
|
43065
|
+
};
|
|
42944
43066
|
if (!(project.root instanceof MonorepoProject)) {
|
|
42945
43067
|
throw new Error(
|
|
42946
43068
|
"AwsDeployWorkflow requires the root project to be a MonorepoProject"
|
|
@@ -42972,6 +43094,7 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component25 {
|
|
|
42972
43094
|
artifact: options.diff?.artifact ?? true,
|
|
42973
43095
|
summary: options.diff?.summary ?? true
|
|
42974
43096
|
};
|
|
43097
|
+
this.branchScopedConcurrency = options.branchScopedConcurrency ?? false;
|
|
42975
43098
|
this.environmentName = resolveEnvironmentGate(
|
|
42976
43099
|
options.gate,
|
|
42977
43100
|
options.environmentName,
|
|
@@ -43035,7 +43158,7 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component25 {
|
|
|
43035
43158
|
* Set GIT_BRANCH_NAME so Turborepo remote cache hashes match between local and CI.
|
|
43036
43159
|
*/
|
|
43037
43160
|
env: {
|
|
43038
|
-
GIT_BRANCH_NAME:
|
|
43161
|
+
GIT_BRANCH_NAME: BRANCH_NAME_EXPRESSION,
|
|
43039
43162
|
...options.buildWorkflowOptions?.env,
|
|
43040
43163
|
...buildWorkflowOptions?.env
|
|
43041
43164
|
},
|
|
@@ -43125,7 +43248,7 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component25 {
|
|
|
43125
43248
|
pullRequests: JobPermission7.WRITE
|
|
43126
43249
|
},
|
|
43127
43250
|
...this.environmentName ? { environment: this.environmentName } : void 0,
|
|
43128
|
-
concurrency: deployJobName,
|
|
43251
|
+
concurrency: this.buildDeployConcurrency(deployJobName),
|
|
43129
43252
|
if: jobCondition,
|
|
43130
43253
|
steps: [...this.deploySteps(target)]
|
|
43131
43254
|
});
|
|
@@ -44144,6 +44267,7 @@ export {
|
|
|
44144
44267
|
DEFAULT_UPSTREAM_CONFIGULATOR_ENABLED,
|
|
44145
44268
|
DEPLOY_GATE,
|
|
44146
44269
|
DIFF_ARTIFACT_NAME,
|
|
44270
|
+
DIFF_NEW_STACK_MARKER,
|
|
44147
44271
|
DIFF_OUTPUT_DIRECTORY,
|
|
44148
44272
|
DIFF_PART_ARTIFACT_PREFIX,
|
|
44149
44273
|
DIFF_REPORT_JOB_ID,
|