@codedrifters/configulator 0.0.422 → 0.0.424

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.mjs CHANGED
@@ -37596,6 +37596,7 @@ var CdkCli = class _CdkCli extends Component11 {
37596
37596
  this.diffDefaults = options.diffDefaults ?? {};
37597
37597
  this.bootstrapDefaults = options.bootstrapDefaults ?? {};
37598
37598
  this.accountOverrides = options.accountOverrides ?? {};
37599
+ this.cliVersion = options.cliVersion ?? project.cdkDeps.cdkCliVersion;
37599
37600
  }
37600
37601
  /**
37601
37602
  * Resolve the `cdk deploy` options to use against a given target.
@@ -41930,7 +41931,25 @@ import { Component as Component22 } from "projen";
41930
41931
  import { BuildWorkflow } from "projen/lib/build";
41931
41932
  import { GitHub as GitHub5, WorkflowSteps as WorkflowSteps2 } from "projen/lib/github";
41932
41933
  import { JobPermission as JobPermission5 } from "projen/lib/github/workflows-model";
41934
+
41935
+ // src/workflows/home-repository.ts
41936
+ var HOME_REPOSITORY_PATTERN = /^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/;
41937
+ var renderHomeRepositoryCondition = (homeRepository, componentName) => {
41938
+ if (homeRepository === void 0) {
41939
+ return void 0;
41940
+ }
41941
+ if (!HOME_REPOSITORY_PATTERN.test(homeRepository)) {
41942
+ throw new Error(
41943
+ `${componentName} requires \`homeRepository\` to be an \`owner/repo\` slug, got "${homeRepository}"`
41944
+ );
41945
+ }
41946
+ return `github.repository == '${homeRepository}'`;
41947
+ };
41948
+
41949
+ // src/workflows/aws-deploy-workflow.ts
41933
41950
  var PROD_DEPLOY_NAME = "prod-deploy";
41951
+ var DIFF_OUTPUT_FILE = "cdk-diff.txt";
41952
+ var DIFF_SUMMARY_BYTE_LIMIT = 9e5;
41934
41953
  var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component22 {
41935
41954
  constructor(project, options = {}) {
41936
41955
  super(project);
@@ -41983,6 +42002,39 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component22 {
41983
42002
  target.region
41984
42003
  ].join("-");
41985
42004
  };
42005
+ /**
42006
+ * Build the deterministic GitHub Actions job name for a target's `cdk diff`
42007
+ * job. Mirrors {@link buildJobName} with a `diff` verb so the diff and deploy
42008
+ * jobs for one target sort next to each other in the run view.
42009
+ */
42010
+ this.buildDiffJobName = (target) => {
42011
+ return [
42012
+ target.awsStageType,
42013
+ target.deploymentTargetRole,
42014
+ "diff",
42015
+ target.project.name,
42016
+ target.account,
42017
+ target.region
42018
+ ].join("-");
42019
+ };
42020
+ /**
42021
+ * Build the CI artifact name for a target's captured diff.
42022
+ *
42023
+ * Carries every component that makes a target unique — including
42024
+ * `deploymentTargetRole`, which two otherwise-identical targets can differ
42025
+ * on. `actions/upload-artifact` v4+ treats artifacts as immutable and rejects
42026
+ * a duplicate name within a run, so parallel diff jobs cannot share one.
42027
+ */
42028
+ this.buildDiffArtifactName = (target) => {
42029
+ return [
42030
+ "cdk-diff",
42031
+ target.awsStageType,
42032
+ target.deploymentTargetRole,
42033
+ target.project.name,
42034
+ target.account,
42035
+ target.region
42036
+ ].join("-");
42037
+ };
41986
42038
  /**
41987
42039
  * Builds a GitHub Actions condition string that checks if the current branch
41988
42040
  * matches any of the provided branch patterns.
@@ -42021,17 +42073,18 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component22 {
42021
42073
  awsDeploymentConfig
42022
42074
  } = target;
42023
42075
  const { roleArn, stackPattern } = ciDeploymentConfig ?? {};
42024
- const { rootCdkOut } = awsDeploymentConfig;
42076
+ const { rootCdkOut, cdkCli } = awsDeploymentConfig;
42025
42077
  const deployJobName = this.buildJobName(target);
42026
42078
  return [
42027
42079
  ...this.setupPnpm(),
42028
42080
  ...this.setupNode(),
42029
42081
  /**
42030
- * Install CDK
42082
+ * Install CDK, pinned to the same version that synthesized the cloud
42083
+ * assembly being deployed. See {@link CdkCli.cliVersion}.
42031
42084
  */
42032
42085
  {
42033
42086
  name: "Install CDK",
42034
- run: "pnpm add aws-cdk"
42087
+ run: `pnpm add "aws-cdk@${cdkCli.cliVersion}"`
42035
42088
  },
42036
42089
  /**
42037
42090
  * Configure AWS creds.
@@ -42051,8 +42104,8 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component22 {
42051
42104
  */
42052
42105
  {
42053
42106
  name: `Deploy ${awsStageType}/${deploymentTargetRole}/${account}/${region}`,
42054
- run: `pnpm dlx aws-cdk ${renderCdkDeploy({
42055
- ...awsDeploymentConfig.cdkCli.deployOptionsFor(target),
42107
+ run: `pnpm dlx "aws-cdk@${cdkCli.cliVersion}" ${renderCdkDeploy({
42108
+ ...cdkCli.deployOptionsFor(target),
42056
42109
  app: rootCdkOut,
42057
42110
  stackPatterns: stackPattern ? [stackPattern] : void 0
42058
42111
  })} --outputs-file cdk-outputs.json`
@@ -42100,6 +42153,128 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component22 {
42100
42153
  }
42101
42154
  ];
42102
42155
  };
42156
+ /**
42157
+ * Steps for a target's optional `cdk diff` job.
42158
+ *
42159
+ * Mirrors {@link deploySteps}' toolchain and credential setup — same pnpm /
42160
+ * Node setup, same version-pinned `aws-cdk` install, same OIDC role — so a
42161
+ * diff is computed by the same CLI that will run the deploy.
42162
+ *
42163
+ * The `cdk diff` flags come from the {@link CdkCli} precedence chain via
42164
+ * `diffOptionsFor(target)`, so `method`, `securityOnly`, `fail`, and the rest
42165
+ * are consumer-controlled per stage, per account, or per target. Four options
42166
+ * are pinned at the call site because the capture mechanism depends on them:
42167
+ * `app` and `stackPatterns` target the built cloud assembly, and `ci` /
42168
+ * `noColor` force the human-readable diff onto stdout without ANSI escapes
42169
+ * (without `--ci` the CLI interleaves it into stderr alongside logs).
42170
+ */
42171
+ this.diffSteps = (target) => {
42172
+ const {
42173
+ awsStageType,
42174
+ deploymentTargetRole,
42175
+ account,
42176
+ region,
42177
+ ciDeploymentConfig,
42178
+ awsDeploymentConfig
42179
+ } = target;
42180
+ const { roleArn, stackPattern } = ciDeploymentConfig ?? {};
42181
+ const { rootCdkOut, cdkCli } = awsDeploymentConfig;
42182
+ const label = `${awsStageType}/${deploymentTargetRole}/${account}/${region}`;
42183
+ const artifactName = this.buildDiffArtifactName(target);
42184
+ const capturedFileGuard = `always() && hashFiles('${DIFF_OUTPUT_FILE}') != ''`;
42185
+ const runUrl = "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}";
42186
+ return [
42187
+ ...this.setupPnpm(),
42188
+ ...this.setupNode(),
42189
+ /**
42190
+ * Install CDK, pinned to the same version that synthesized the cloud
42191
+ * assembly being diffed. See {@link CdkCli.cliVersion}.
42192
+ */
42193
+ {
42194
+ name: "Install CDK",
42195
+ run: `pnpm add "aws-cdk@${cdkCli.cliVersion}"`
42196
+ },
42197
+ /**
42198
+ * Configure AWS creds.
42199
+ */
42200
+ {
42201
+ name: `AWS Creds ${label}`,
42202
+ uses: "aws-actions/configure-aws-credentials@v6",
42203
+ with: {
42204
+ "role-to-assume": roleArn,
42205
+ "aws-region": region,
42206
+ "role-duration-seconds": 900
42207
+ // 15 minutes
42208
+ }
42209
+ },
42210
+ /**
42211
+ * Run CDK Diff, capturing the output while leaving it visible in the job
42212
+ * log. `pipefail` keeps the CLI's exit code from being masked by `tee`.
42213
+ */
42214
+ {
42215
+ name: `Diff ${label}`,
42216
+ shell: "bash",
42217
+ run: [
42218
+ "set -o pipefail",
42219
+ `pnpm dlx "aws-cdk@${cdkCli.cliVersion}" ${renderCdkDiff({
42220
+ ...cdkCli.diffOptionsFor(target),
42221
+ app: rootCdkOut,
42222
+ ci: true,
42223
+ noColor: true,
42224
+ stackPatterns: stackPattern ? [stackPattern] : void 0
42225
+ })} 2>&1 | tee ${DIFF_OUTPUT_FILE}`
42226
+ ].join("\n")
42227
+ },
42228
+ /**
42229
+ * Render the captured diff into the job summary inside a collapsed
42230
+ * `<details>` block, truncated below GitHub's 1 MiB per-step cap — a
42231
+ * summary that exceeds the cap is dropped in full rather than clipped.
42232
+ */
42233
+ ...this.diffOptions.summary ? [
42234
+ {
42235
+ name: `Render diff summary ${label}`,
42236
+ if: capturedFileGuard,
42237
+ shell: "bash",
42238
+ run: [
42239
+ `size=$(wc -c < ${DIFF_OUTPUT_FILE})`,
42240
+ "{",
42241
+ ` echo '## cdk diff \u2014 ${label}'`,
42242
+ ' echo ""',
42243
+ " echo '<details><summary>cdk diff output</summary>'",
42244
+ ' echo ""',
42245
+ " echo '```'",
42246
+ ` if [ "$size" -gt ${DIFF_SUMMARY_BYTE_LIMIT} ]; then`,
42247
+ ` head -c ${DIFF_SUMMARY_BYTE_LIMIT} ${DIFF_OUTPUT_FILE}`,
42248
+ ` printf '\\n... truncated at ${DIFF_SUMMARY_BYTE_LIMIT} bytes ...\\n'`,
42249
+ " else",
42250
+ ` cat ${DIFF_OUTPUT_FILE}`,
42251
+ " fi",
42252
+ " echo '```'",
42253
+ ' echo ""',
42254
+ " echo '</details>'",
42255
+ ...this.diffOptions.artifact ? [
42256
+ ' echo ""',
42257
+ ` echo 'Full diff: the \`${artifactName}\` artifact on [this run](${runUrl}).'`
42258
+ ] : [],
42259
+ '} >> "$GITHUB_STEP_SUMMARY"'
42260
+ ].join("\n")
42261
+ }
42262
+ ] : [],
42263
+ /**
42264
+ * Upload the untruncated diff as a per-run artifact.
42265
+ */
42266
+ ...this.diffOptions.artifact ? [
42267
+ WorkflowSteps2.uploadArtifact({
42268
+ name: `Upload diff ${label}`,
42269
+ if: capturedFileGuard,
42270
+ with: {
42271
+ name: artifactName,
42272
+ path: DIFF_OUTPUT_FILE
42273
+ }
42274
+ })
42275
+ ] : []
42276
+ ];
42277
+ };
42103
42278
  if (!(project.root instanceof MonorepoProject)) {
42104
42279
  throw new Error(
42105
42280
  "AwsDeployWorkflow requires the root project to be a MonorepoProject"
@@ -42119,6 +42294,16 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component22 {
42119
42294
  (target) => target.awsStageType === this.awsStageType && target.ciDeployment
42120
42295
  ) ?? [];
42121
42296
  this.deployAfterTargets = options.deployAfterTargets ?? [];
42297
+ this.diffOptions = {
42298
+ enabled: options.diff?.enabled ?? false,
42299
+ artifact: options.diff?.artifact ?? true,
42300
+ summary: options.diff?.summary ?? true
42301
+ };
42302
+ this.homeRepository = options.homeRepository;
42303
+ const homeRepositoryCondition = renderHomeRepositoryCondition(
42304
+ this.homeRepository,
42305
+ "AwsDeployWorkflow"
42306
+ );
42122
42307
  if (options.buildWorkflow && options.buildWorkflowOptions) {
42123
42308
  throw new Error(
42124
42309
  "Cannot provide both buildWorkflow and buildWorkflowOptions"
@@ -42196,10 +42381,11 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component22 {
42196
42381
  const branchFilterCondition = this.buildBranchFilterCondition(
42197
42382
  target.branches
42198
42383
  );
42199
- const jobCondition = branchFilterCondition ? "${{ " + [
42384
+ const jobCondition = "${{ " + [
42200
42385
  "!needs.build.outputs.self_mutation_happened",
42201
- `(${branchFilterCondition})`
42202
- ].join(" && ") + " }}" : "${{ !needs.build.outputs.self_mutation_happened }}";
42386
+ ...homeRepositoryCondition ? [homeRepositoryCondition] : [],
42387
+ ...branchFilterCondition ? [`(${branchFilterCondition})`] : []
42388
+ ].join(" && ") + " }}";
42203
42389
  this.buildWorkflow.addPostBuildJob(deployJobName, {
42204
42390
  name: `Deploy ${this.project.name} ${target.awsStageType}/${target.deploymentTargetRole}/${target.account}/${target.region}`,
42205
42391
  needs: [
@@ -42218,6 +42404,20 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component22 {
42218
42404
  if: jobCondition,
42219
42405
  steps: [...this.deploySteps(target)]
42220
42406
  });
42407
+ if (this.diffOptions.enabled) {
42408
+ const diffJobName = this.buildDiffJobName(target);
42409
+ this.buildWorkflow.addPostBuildJob(diffJobName, {
42410
+ name: `Diff ${this.project.name} ${target.awsStageType}/${target.deploymentTargetRole}/${target.account}/${target.region}`,
42411
+ needs: ["build"],
42412
+ runsOn: ["ubuntu-latest"],
42413
+ permissions: {
42414
+ contents: JobPermission5.READ,
42415
+ idToken: JobPermission5.WRITE
42416
+ },
42417
+ if: jobCondition,
42418
+ steps: [...this.diffSteps(target)]
42419
+ });
42420
+ }
42221
42421
  });
42222
42422
  addBuildCompleteJob(this.buildWorkflow);
42223
42423
  }
@@ -42280,7 +42480,8 @@ var AwsTeardownWorkflow = class extends Component23 {
42280
42480
  stageTypeTagName,
42281
42481
  environmentTypeTagName,
42282
42482
  branchNameTagName,
42283
- deleteBranchPatterns
42483
+ deleteBranchPatterns,
42484
+ homeRepository
42284
42485
  } = options;
42285
42486
  if (!repoTagName) {
42286
42487
  throw new Error("AwsTeardownWorkflow requires `repoTagName`");
@@ -42309,6 +42510,10 @@ var AwsTeardownWorkflow = class extends Component23 {
42309
42510
  deleteBranchPatterns,
42310
42511
  awsDestructionTargets
42311
42512
  );
42513
+ const homeRepositoryCondition = renderHomeRepositoryCondition(
42514
+ homeRepository,
42515
+ "AwsTeardownWorkflow"
42516
+ );
42312
42517
  const workflow = new GithubWorkflow(github, "teardown-dev");
42313
42518
  workflow.on({
42314
42519
  workflowDispatch: {},
@@ -42335,6 +42540,7 @@ var AwsTeardownWorkflow = class extends Component23 {
42335
42540
  {
42336
42541
  name: `Teardown Stacks in ${awsStageType}/${deploymentTargetRole}/${account}/${region}`,
42337
42542
  runsOn: ["ubuntu-latest"],
42543
+ ...homeRepositoryCondition ? { if: `\${{ ${homeRepositoryCondition} }}` } : {},
42338
42544
  permissions: {
42339
42545
  contents: JobPermission6.READ,
42340
42546
  idToken: JobPermission6.WRITE
@@ -43368,6 +43574,7 @@ export {
43368
43574
  renderFocusSection,
43369
43575
  renderGithubIssueTypeSection,
43370
43576
  renderGithubIssueTypeSectionLines,
43577
+ renderHomeRepositoryCondition,
43371
43578
  renderIssueTemplateLabelsCheckerScript,
43372
43579
  renderIssueTemplatesBundleHook,
43373
43580
  renderIssueTemplatesCheckerScript,