@codedrifters/configulator 0.0.425 → 0.0.426
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 +192 -13
- package/lib/index.d.ts +193 -14
- package/lib/index.js +355 -33
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +353 -36
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -195,6 +195,7 @@ __export(index_exports, {
|
|
|
195
195
|
AwsDeploymentConfig: () => AwsDeploymentConfig,
|
|
196
196
|
AwsDeploymentTarget: () => AwsDeploymentTarget,
|
|
197
197
|
AwsTeardownWorkflow: () => AwsTeardownWorkflow,
|
|
198
|
+
BUILD_ARTIFACT_NAME: () => BUILD_ARTIFACT_NAME,
|
|
198
199
|
BUILT_IN_BUNDLES: () => BUILT_IN_BUNDLES,
|
|
199
200
|
BUNDLE_OWNERSHIP: () => BUNDLE_OWNERSHIP,
|
|
200
201
|
CDK_BOOTSTRAP_DEFAULTS_BY_STAGE: () => CDK_BOOTSTRAP_DEFAULTS_BY_STAGE,
|
|
@@ -293,7 +294,9 @@ __export(index_exports, {
|
|
|
293
294
|
MONOREPO_LAYOUT: () => MONOREPO_LAYOUT,
|
|
294
295
|
MonorepoProject: () => MonorepoProject,
|
|
295
296
|
Nvmrc: () => Nvmrc,
|
|
297
|
+
PERMISSION_BACKUP_FILE: () => PERMISSION_BACKUP_FILE,
|
|
296
298
|
PHASE_LABEL_TYPE_MAP: () => PHASE_LABEL_TYPE_MAP,
|
|
299
|
+
PLAN_RUN_ID_INPUT: () => PLAN_RUN_ID_INPUT,
|
|
297
300
|
PROD_DEPLOY_NAME: () => PROD_DEPLOY_NAME,
|
|
298
301
|
PROGRESS_FILES_FORMAT_VALUES: () => PROGRESS_FILES_FORMAT_VALUES,
|
|
299
302
|
PnpmWorkspace: () => PnpmWorkspace,
|
|
@@ -327,6 +330,7 @@ __export(index_exports, {
|
|
|
327
330
|
TypeScriptConfig: () => TypeScriptConfig,
|
|
328
331
|
TypeScriptProject: () => TypeScriptProject,
|
|
329
332
|
UNKNOWN_TYPE_FALLBACK_TIER: () => UNKNOWN_TYPE_FALLBACK_TIER,
|
|
333
|
+
VALIDATE_PLAN_JOB_ID: () => VALIDATE_PLAN_JOB_ID,
|
|
330
334
|
VALID_PRIORITY_VALUES: () => VALID_PRIORITY_VALUES,
|
|
331
335
|
VALID_STATUS_VALUES: () => VALID_STATUS_VALUES,
|
|
332
336
|
VERSION: () => VERSION,
|
|
@@ -471,6 +475,7 @@ __export(index_exports, {
|
|
|
471
475
|
renderNextRequirementIdProcedure: () => renderNextRequirementIdProcedure,
|
|
472
476
|
renderPhaseTypeInvariantSection: () => renderPhaseTypeInvariantSection,
|
|
473
477
|
renderPhaseTypeInvariantShellHelpers: () => renderPhaseTypeInvariantShellHelpers,
|
|
478
|
+
renderPlanValidationScript: () => renderPlanValidationScript,
|
|
474
479
|
renderPriorityRulesSection: () => renderPriorityRulesSection,
|
|
475
480
|
renderProgressFileName: () => renderProgressFileName,
|
|
476
481
|
renderProgressFilePath: () => renderProgressFilePath,
|
|
@@ -42304,7 +42309,17 @@ var DEPLOY_GATE = {
|
|
|
42304
42309
|
* required reviewers, wait timers, deployment branch policies — apply before
|
|
42305
42310
|
* the job is sent to a runner.
|
|
42306
42311
|
*/
|
|
42307
|
-
ENVIRONMENT: "environment"
|
|
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"
|
|
42308
42323
|
};
|
|
42309
42324
|
var resolveEnvironmentGate = (gate, environmentName, componentName) => {
|
|
42310
42325
|
const trimmed = environmentName?.trim();
|
|
@@ -42316,7 +42331,7 @@ var resolveEnvironmentGate = (gate, environmentName, componentName) => {
|
|
|
42316
42331
|
}
|
|
42317
42332
|
return void 0;
|
|
42318
42333
|
}
|
|
42319
|
-
if (!trimmed) {
|
|
42334
|
+
if (gate === DEPLOY_GATE.ENVIRONMENT && !trimmed) {
|
|
42320
42335
|
throw new Error(
|
|
42321
42336
|
`${componentName} requires a non-empty \`environmentName\` when \`gate\` is "${gate}"`
|
|
42322
42337
|
);
|
|
@@ -42338,6 +42353,105 @@ var renderHomeRepositoryCondition = (homeRepository, componentName) => {
|
|
|
42338
42353
|
return `github.repository == '${homeRepository}'`;
|
|
42339
42354
|
};
|
|
42340
42355
|
|
|
42356
|
+
// src/workflows/plan-apply.ts
|
|
42357
|
+
var VALIDATE_PLAN_JOB_ID = "validate-plan";
|
|
42358
|
+
var PLAN_RUN_ID_INPUT = "plan_run_id";
|
|
42359
|
+
var BUILD_ARTIFACT_NAME = "build-artifact";
|
|
42360
|
+
var PERMISSION_BACKUP_FILE = "permissions-backup.acl";
|
|
42361
|
+
var renderPlanValidationScript = (options) => {
|
|
42362
|
+
const {
|
|
42363
|
+
planWorkflowPath,
|
|
42364
|
+
allowedBranches,
|
|
42365
|
+
requireCurrentHead,
|
|
42366
|
+
verifyArtifactDigest
|
|
42367
|
+
} = options;
|
|
42368
|
+
return [
|
|
42369
|
+
"const raw = (process.env.PLAN_RUN_ID ?? '').trim();",
|
|
42370
|
+
"const runId = Number(raw);",
|
|
42371
|
+
"if (!/^[0-9]+$/.test(raw) || !Number.isSafeInteger(runId) || runId <= 0) {",
|
|
42372
|
+
' core.setFailed(`plan_run_id must be a positive run id, got "${raw}"`);',
|
|
42373
|
+
" return;",
|
|
42374
|
+
"}",
|
|
42375
|
+
"",
|
|
42376
|
+
"const { owner, repo } = context.repo;",
|
|
42377
|
+
"const { data: run } = await github.rest.actions.getWorkflowRun({",
|
|
42378
|
+
" owner,",
|
|
42379
|
+
" repo,",
|
|
42380
|
+
" run_id: runId,",
|
|
42381
|
+
"});",
|
|
42382
|
+
"",
|
|
42383
|
+
`const expectedPath = ${JSON.stringify(planWorkflowPath)};`,
|
|
42384
|
+
"if (run.path !== expectedPath) {",
|
|
42385
|
+
' core.setFailed(`Run ${runId} belongs to workflow "${run.path}", expected "${expectedPath}".`);',
|
|
42386
|
+
" return;",
|
|
42387
|
+
"}",
|
|
42388
|
+
"",
|
|
42389
|
+
'if (run.status !== "completed" || run.conclusion !== "success") {',
|
|
42390
|
+
' core.setFailed(`Run ${runId} is status "${run.status}" / conclusion "${run.conclusion}", expected a completed successful plan run.`);',
|
|
42391
|
+
" return;",
|
|
42392
|
+
"}",
|
|
42393
|
+
"",
|
|
42394
|
+
`const allowedBranches = ${JSON.stringify(allowedBranches)};`,
|
|
42395
|
+
'const branch = run.head_branch ?? "";',
|
|
42396
|
+
"const branchAllowed = allowedBranches.some((pattern) =>",
|
|
42397
|
+
' pattern.includes("*")',
|
|
42398
|
+
' ? branch.startsWith(pattern.slice(0, pattern.indexOf("*")))',
|
|
42399
|
+
" : branch === pattern,",
|
|
42400
|
+
");",
|
|
42401
|
+
"if (!branchAllowed) {",
|
|
42402
|
+
' core.setFailed(`Run ${runId} ran on branch "${branch}", which no deployment target in this workflow accepts (allowed: ${allowedBranches.join(", ")}).`);',
|
|
42403
|
+
" return;",
|
|
42404
|
+
"}",
|
|
42405
|
+
...requireCurrentHead ? [
|
|
42406
|
+
"",
|
|
42407
|
+
"const { data: liveBranch } = await github.rest.repos.getBranch({",
|
|
42408
|
+
" owner,",
|
|
42409
|
+
" repo,",
|
|
42410
|
+
" branch,",
|
|
42411
|
+
"});",
|
|
42412
|
+
"if (liveBranch.commit.sha !== run.head_sha) {",
|
|
42413
|
+
' core.setFailed(`Run ${runId} planned ${run.head_sha} but "${branch}" now points at ${liveBranch.commit.sha}. Re-run the plan workflow against the current head.`);',
|
|
42414
|
+
" return;",
|
|
42415
|
+
"}"
|
|
42416
|
+
] : [],
|
|
42417
|
+
"",
|
|
42418
|
+
"const artifacts = await github.paginate(",
|
|
42419
|
+
" github.rest.actions.listWorkflowRunArtifacts,",
|
|
42420
|
+
" { owner, repo, run_id: runId, per_page: 100 },",
|
|
42421
|
+
");",
|
|
42422
|
+
`const artifactName = ${JSON.stringify(BUILD_ARTIFACT_NAME)};`,
|
|
42423
|
+
"const artifact = artifacts.find((a) => a.name === artifactName);",
|
|
42424
|
+
"if (!artifact) {",
|
|
42425
|
+
' core.setFailed(`Run ${runId} published no "${artifactName}" artifact. Only a plan run whose build job completed can be applied.`);',
|
|
42426
|
+
" return;",
|
|
42427
|
+
"}",
|
|
42428
|
+
"if (artifact.expired) {",
|
|
42429
|
+
' core.setFailed(`The "${artifactName}" artifact on run ${runId} expired at ${artifact.expires_at}. Artifact retention is this gate\'s approval window \u2014 re-run the plan workflow.`);',
|
|
42430
|
+
" return;",
|
|
42431
|
+
"}",
|
|
42432
|
+
...verifyArtifactDigest ? [
|
|
42433
|
+
"if (!artifact.digest) {",
|
|
42434
|
+
' core.setFailed(`The "${artifactName}" artifact on run ${runId} reports no digest, so it cannot be verified. Disable planApply.verifyArtifactDigest or re-run the plan workflow.`);',
|
|
42435
|
+
" return;",
|
|
42436
|
+
"}",
|
|
42437
|
+
'core.setOutput("artifact_digest", artifact.digest);'
|
|
42438
|
+
] : [],
|
|
42439
|
+
"",
|
|
42440
|
+
'core.setOutput("head_sha", run.head_sha);',
|
|
42441
|
+
'core.setOutput("head_branch", branch);',
|
|
42442
|
+
"await core.summary",
|
|
42443
|
+
" .addHeading(`Applying plan run ${runId}`, 2)",
|
|
42444
|
+
" .addTable([",
|
|
42445
|
+
' [{ data: "Field", header: true }, { data: "Value", header: true }],',
|
|
42446
|
+
' ["Plan run", `<a href="${run.html_url}">${runId}</a>`],',
|
|
42447
|
+
' ["Branch", branch],',
|
|
42448
|
+
' ["Commit", run.head_sha],',
|
|
42449
|
+
' ["Artifact expires", artifact.expires_at ?? "unknown"],',
|
|
42450
|
+
" ])",
|
|
42451
|
+
" .write();"
|
|
42452
|
+
].join("\n");
|
|
42453
|
+
};
|
|
42454
|
+
|
|
42341
42455
|
// src/workflows/aws-deploy-workflow.ts
|
|
42342
42456
|
var PROD_DEPLOY_NAME = "prod-deploy";
|
|
42343
42457
|
var DIFF_OUTPUT_FILE = "cdk-diff.txt";
|
|
@@ -42409,6 +42523,20 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
|
|
|
42409
42523
|
target.region
|
|
42410
42524
|
].join("-");
|
|
42411
42525
|
};
|
|
42526
|
+
/**
|
|
42527
|
+
* Build the deterministic GitHub Actions job name for a target's apply job.
|
|
42528
|
+
* Mirrors {@link buildJobName} with an `apply` verb.
|
|
42529
|
+
*/
|
|
42530
|
+
this.buildApplyJobName = (target) => {
|
|
42531
|
+
return [
|
|
42532
|
+
target.awsStageType,
|
|
42533
|
+
target.deploymentTargetRole,
|
|
42534
|
+
"apply",
|
|
42535
|
+
target.project.name,
|
|
42536
|
+
target.account,
|
|
42537
|
+
target.region
|
|
42538
|
+
].join("-");
|
|
42539
|
+
};
|
|
42412
42540
|
/**
|
|
42413
42541
|
* Build the CI artifact name for a target's captured diff.
|
|
42414
42542
|
*
|
|
@@ -42427,6 +42555,163 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
|
|
|
42427
42555
|
target.region
|
|
42428
42556
|
].join("-");
|
|
42429
42557
|
};
|
|
42558
|
+
/**
|
|
42559
|
+
* Create the dispatch-only apply workflow and its validation job.
|
|
42560
|
+
*
|
|
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`.
|
|
42566
|
+
*/
|
|
42567
|
+
this.createApplyWorkflow = (github, homeRepositoryCondition) => {
|
|
42568
|
+
const { applyWorkflowName, requireCurrentHead, verifyArtifactDigest } = this.planApplyOptions;
|
|
42569
|
+
if (github.tryFindWorkflow(applyWorkflowName)) {
|
|
42570
|
+
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.`
|
|
42572
|
+
);
|
|
42573
|
+
}
|
|
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
|
+
]
|
|
42634
|
+
});
|
|
42635
|
+
return workflow;
|
|
42636
|
+
};
|
|
42637
|
+
/**
|
|
42638
|
+
* Register one target's apply job on the apply workflow.
|
|
42639
|
+
*
|
|
42640
|
+
* Differences from the `single`-gate deploy job, all of them forced by the
|
|
42641
|
+
* apply run having no build job of its own:
|
|
42642
|
+
*
|
|
42643
|
+
* - `needs` starts at the validation job rather than `build`, so a plan run
|
|
42644
|
+
* that fails any check skips every apply job instead of deploying.
|
|
42645
|
+
* - `actions: read` is added, which is what lets `actions/download-artifact`
|
|
42646
|
+
* reach across runs.
|
|
42647
|
+
* - No `pull-requests: write`, and no sticky PR comment step: an apply is
|
|
42648
|
+
* always a `workflow_dispatch`, so the comment could never fire.
|
|
42649
|
+
* - No branch filter on `github.ref`. The ref an operator happens to
|
|
42650
|
+
* dispatch from is unrelated to what was planned; the branch that matters
|
|
42651
|
+
* is the plan run's, and the validation job checks that one.
|
|
42652
|
+
*
|
|
42653
|
+
* When `environmentName` is also supplied, it lands here rather than on the
|
|
42654
|
+
* plan's jobs — a second approver on top of whoever dispatched the apply.
|
|
42655
|
+
* `validate-plan` stays ungated so its verdict is available to read *before*
|
|
42656
|
+
* the approval is given.
|
|
42657
|
+
*/
|
|
42658
|
+
this.addApplyJob = (workflow, target, homeRepositoryCondition) => {
|
|
42659
|
+
const applyJobName = this.buildApplyJobName(target);
|
|
42660
|
+
const { verifyArtifactDigest } = this.planApplyOptions;
|
|
42661
|
+
const artifactsDirectory = this.rootProject.artifactsDirectory;
|
|
42662
|
+
workflow.addJob(applyJobName, {
|
|
42663
|
+
name: `Apply ${this.project.name} ${target.awsStageType}/${target.deploymentTargetRole}/${target.account}/${target.region}`,
|
|
42664
|
+
needs: [
|
|
42665
|
+
VALIDATE_PLAN_JOB_ID,
|
|
42666
|
+
...this.deployAfterTargets.map((p) => this.buildApplyJobName(p))
|
|
42667
|
+
],
|
|
42668
|
+
runsOn: ["ubuntu-latest"],
|
|
42669
|
+
permissions: {
|
|
42670
|
+
actions: import_workflows_model5.JobPermission.READ,
|
|
42671
|
+
contents: import_workflows_model5.JobPermission.READ,
|
|
42672
|
+
idToken: import_workflows_model5.JobPermission.WRITE
|
|
42673
|
+
},
|
|
42674
|
+
...this.environmentName ? { environment: this.environmentName } : void 0,
|
|
42675
|
+
/**
|
|
42676
|
+
* Shares the deploy job's group name so an apply can never overlap a
|
|
42677
|
+
* same-target deploy. `cancel-in-progress` is spelled out rather than
|
|
42678
|
+
* left to GitHub's default: cancelling a half-finished `cdk deploy`
|
|
42679
|
+
* strands a CloudFormation stack mid-update.
|
|
42680
|
+
*/
|
|
42681
|
+
concurrency: {
|
|
42682
|
+
group: this.buildJobName(target),
|
|
42683
|
+
"cancel-in-progress": false
|
|
42684
|
+
},
|
|
42685
|
+
...homeRepositoryCondition ? { if: `\${{ ${homeRepositoryCondition} }}` } : {},
|
|
42686
|
+
steps: [
|
|
42687
|
+
/**
|
|
42688
|
+
* Cross-run download of the plan's assembly. `run-id` plus an explicit
|
|
42689
|
+
* `github-token` is what makes `actions/download-artifact` look outside
|
|
42690
|
+
* the current run; without both it silently searches this run and finds
|
|
42691
|
+
* nothing.
|
|
42692
|
+
*/
|
|
42693
|
+
{
|
|
42694
|
+
name: "Download plan build artifacts",
|
|
42695
|
+
uses: "actions/download-artifact@v8",
|
|
42696
|
+
with: {
|
|
42697
|
+
name: BUILD_ARTIFACT_NAME,
|
|
42698
|
+
path: artifactsDirectory,
|
|
42699
|
+
"run-id": `\${{ inputs.${PLAN_RUN_ID_INPUT} }}`,
|
|
42700
|
+
"github-token": "${{ secrets.GITHUB_TOKEN }}",
|
|
42701
|
+
...verifyArtifactDigest ? {
|
|
42702
|
+
"artifact-digest": `\${{ needs.${VALIDATE_PLAN_JOB_ID}.outputs.artifact_digest }}`
|
|
42703
|
+
} : {}
|
|
42704
|
+
}
|
|
42705
|
+
},
|
|
42706
|
+
{
|
|
42707
|
+
name: "Restore build artifact permissions",
|
|
42708
|
+
continueOnError: true,
|
|
42709
|
+
run: `cd ${artifactsDirectory} && setfacl --restore=${PERMISSION_BACKUP_FILE}`
|
|
42710
|
+
},
|
|
42711
|
+
...this.deploySteps(target, { stickyPrComment: false })
|
|
42712
|
+
]
|
|
42713
|
+
});
|
|
42714
|
+
};
|
|
42430
42715
|
/**
|
|
42431
42716
|
* Builds a GitHub Actions condition string that checks if the current branch
|
|
42432
42717
|
* matches any of the provided branch patterns.
|
|
@@ -42455,7 +42740,15 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
|
|
|
42455
42740
|
}
|
|
42456
42741
|
return conditions.join(" || ");
|
|
42457
42742
|
};
|
|
42458
|
-
|
|
42743
|
+
/**
|
|
42744
|
+
* Steps for a target's deploy job.
|
|
42745
|
+
*
|
|
42746
|
+
* `stickyPrComment` drops the sticky-PR-comment step when false. Apply jobs
|
|
42747
|
+
* pass false: they only ever run on `workflow_dispatch` and so could never
|
|
42748
|
+
* satisfy that step's own `pull_request` guard.
|
|
42749
|
+
*/
|
|
42750
|
+
this.deploySteps = (target, options = {}) => {
|
|
42751
|
+
const { stickyPrComment = true } = options;
|
|
42459
42752
|
const {
|
|
42460
42753
|
awsStageType,
|
|
42461
42754
|
deploymentTargetRole,
|
|
@@ -42534,15 +42827,17 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
|
|
|
42534
42827
|
* comment is keyed by the deploy job name so dev/stage/prod comments
|
|
42535
42828
|
* don't collide on the same PR.
|
|
42536
42829
|
*/
|
|
42537
|
-
|
|
42538
|
-
|
|
42539
|
-
|
|
42540
|
-
|
|
42541
|
-
|
|
42542
|
-
|
|
42543
|
-
|
|
42830
|
+
...stickyPrComment ? [
|
|
42831
|
+
{
|
|
42832
|
+
name: "Sticky PR comment with deploy endpoints",
|
|
42833
|
+
if: "github.event_name == 'pull_request' && hashFiles('deploy-urls.md') != ''",
|
|
42834
|
+
uses: "marocchino/sticky-pull-request-comment@v3",
|
|
42835
|
+
with: {
|
|
42836
|
+
header: deployJobName,
|
|
42837
|
+
path: "deploy-urls.md"
|
|
42838
|
+
}
|
|
42544
42839
|
}
|
|
42545
|
-
|
|
42840
|
+
] : []
|
|
42546
42841
|
];
|
|
42547
42842
|
};
|
|
42548
42843
|
/**
|
|
@@ -42686,8 +42981,15 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
|
|
|
42686
42981
|
(target) => target.awsStageType === this.awsStageType && target.ciDeployment
|
|
42687
42982
|
) ?? [];
|
|
42688
42983
|
this.deployAfterTargets = options.deployAfterTargets ?? [];
|
|
42984
|
+
this.gate = options.gate;
|
|
42985
|
+
const isPlanApply = this.gate === DEPLOY_GATE.PLAN_APPLY;
|
|
42986
|
+
if (isPlanApply && options.diff?.enabled === false) {
|
|
42987
|
+
throw new Error(
|
|
42988
|
+
"AwsDeployWorkflow cannot disable `diff` under the `plan-apply` gate: the diff jobs are what keep the plan workflow publishing the build artifact the apply workflow deploys."
|
|
42989
|
+
);
|
|
42990
|
+
}
|
|
42689
42991
|
this.diffOptions = {
|
|
42690
|
-
enabled: options.diff?.enabled ??
|
|
42992
|
+
enabled: options.diff?.enabled ?? isPlanApply,
|
|
42691
42993
|
artifact: options.diff?.artifact ?? true,
|
|
42692
42994
|
summary: options.diff?.summary ?? true
|
|
42693
42995
|
};
|
|
@@ -42773,6 +43075,17 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
|
|
|
42773
43075
|
...buildWorkflowOptions?.preBuildSteps ?? []
|
|
42774
43076
|
]
|
|
42775
43077
|
});
|
|
43078
|
+
this.planApplyOptions = {
|
|
43079
|
+
applyWorkflowName: options.planApply?.applyWorkflowName ?? `${this.buildWorkflow.name}-apply`,
|
|
43080
|
+
requireCurrentHead: options.planApply?.requireCurrentHead ?? false,
|
|
43081
|
+
verifyArtifactDigest: options.planApply?.verifyArtifactDigest ?? false
|
|
43082
|
+
};
|
|
43083
|
+
if (isPlanApply) {
|
|
43084
|
+
this.applyWorkflow = this.createApplyWorkflow(
|
|
43085
|
+
github,
|
|
43086
|
+
homeRepositoryCondition
|
|
43087
|
+
);
|
|
43088
|
+
}
|
|
42776
43089
|
this.awsDeploymentTargets.forEach((target) => {
|
|
42777
43090
|
const deployJobName = this.buildJobName(target);
|
|
42778
43091
|
const branchFilterCondition = this.buildBranchFilterCondition(
|
|
@@ -42783,27 +43096,31 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen26.Compone
|
|
|
42783
43096
|
...homeRepositoryCondition ? [homeRepositoryCondition] : [],
|
|
42784
43097
|
...branchFilterCondition ? [`(${branchFilterCondition})`] : []
|
|
42785
43098
|
].join(" && ") + " }}";
|
|
42786
|
-
|
|
42787
|
-
|
|
42788
|
-
|
|
42789
|
-
|
|
42790
|
-
|
|
42791
|
-
|
|
42792
|
-
|
|
42793
|
-
|
|
42794
|
-
|
|
42795
|
-
|
|
42796
|
-
|
|
42797
|
-
|
|
42798
|
-
|
|
42799
|
-
|
|
42800
|
-
|
|
42801
|
-
|
|
42802
|
-
|
|
42803
|
-
|
|
42804
|
-
|
|
42805
|
-
|
|
42806
|
-
|
|
43099
|
+
if (this.applyWorkflow) {
|
|
43100
|
+
this.addApplyJob(this.applyWorkflow, target, homeRepositoryCondition);
|
|
43101
|
+
} else {
|
|
43102
|
+
const gatedOnDiff = !!this.environmentName && this.diffOptions.enabled;
|
|
43103
|
+
this.buildWorkflow.addPostBuildJob(deployJobName, {
|
|
43104
|
+
name: `Deploy ${this.project.name} ${target.awsStageType}/${target.deploymentTargetRole}/${target.account}/${target.region}`,
|
|
43105
|
+
needs: [
|
|
43106
|
+
"build",
|
|
43107
|
+
...gatedOnDiff ? [this.buildDiffJobName(target)] : [],
|
|
43108
|
+
...this.deployAfterTargets.map((p) => {
|
|
43109
|
+
return this.buildJobName(p);
|
|
43110
|
+
})
|
|
43111
|
+
],
|
|
43112
|
+
runsOn: ["ubuntu-latest"],
|
|
43113
|
+
permissions: {
|
|
43114
|
+
contents: import_workflows_model5.JobPermission.READ,
|
|
43115
|
+
idToken: import_workflows_model5.JobPermission.WRITE,
|
|
43116
|
+
pullRequests: import_workflows_model5.JobPermission.WRITE
|
|
43117
|
+
},
|
|
43118
|
+
...this.environmentName ? { environment: this.environmentName } : void 0,
|
|
43119
|
+
concurrency: deployJobName,
|
|
43120
|
+
if: jobCondition,
|
|
43121
|
+
steps: [...this.deploySteps(target)]
|
|
43122
|
+
});
|
|
43123
|
+
}
|
|
42807
43124
|
if (this.diffOptions.enabled) {
|
|
42808
43125
|
const diffJobName = this.buildDiffJobName(target);
|
|
42809
43126
|
this.buildWorkflow.addPostBuildJob(diffJobName, {
|
|
@@ -43713,6 +44030,7 @@ export const collections = {
|
|
|
43713
44030
|
AwsDeploymentConfig,
|
|
43714
44031
|
AwsDeploymentTarget,
|
|
43715
44032
|
AwsTeardownWorkflow,
|
|
44033
|
+
BUILD_ARTIFACT_NAME,
|
|
43716
44034
|
BUILT_IN_BUNDLES,
|
|
43717
44035
|
BUNDLE_OWNERSHIP,
|
|
43718
44036
|
CDK_BOOTSTRAP_DEFAULTS_BY_STAGE,
|
|
@@ -43811,7 +44129,9 @@ export const collections = {
|
|
|
43811
44129
|
MONOREPO_LAYOUT,
|
|
43812
44130
|
MonorepoProject,
|
|
43813
44131
|
Nvmrc,
|
|
44132
|
+
PERMISSION_BACKUP_FILE,
|
|
43814
44133
|
PHASE_LABEL_TYPE_MAP,
|
|
44134
|
+
PLAN_RUN_ID_INPUT,
|
|
43815
44135
|
PROD_DEPLOY_NAME,
|
|
43816
44136
|
PROGRESS_FILES_FORMAT_VALUES,
|
|
43817
44137
|
PnpmWorkspace,
|
|
@@ -43845,6 +44165,7 @@ export const collections = {
|
|
|
43845
44165
|
TypeScriptConfig,
|
|
43846
44166
|
TypeScriptProject,
|
|
43847
44167
|
UNKNOWN_TYPE_FALLBACK_TIER,
|
|
44168
|
+
VALIDATE_PLAN_JOB_ID,
|
|
43848
44169
|
VALID_PRIORITY_VALUES,
|
|
43849
44170
|
VALID_STATUS_VALUES,
|
|
43850
44171
|
VERSION,
|
|
@@ -43989,6 +44310,7 @@ export const collections = {
|
|
|
43989
44310
|
renderNextRequirementIdProcedure,
|
|
43990
44311
|
renderPhaseTypeInvariantSection,
|
|
43991
44312
|
renderPhaseTypeInvariantShellHelpers,
|
|
44313
|
+
renderPlanValidationScript,
|
|
43992
44314
|
renderPriorityRulesSection,
|
|
43993
44315
|
renderProgressFileName,
|
|
43994
44316
|
renderProgressFilePath,
|