@codedrifters/configulator 0.0.196 → 0.0.197

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
@@ -186,11 +186,13 @@ __export(index_exports, {
186
186
  AwsDeployWorkflow: () => AwsDeployWorkflow,
187
187
  AwsDeploymentConfig: () => AwsDeploymentConfig,
188
188
  AwsDeploymentTarget: () => AwsDeploymentTarget,
189
+ AwsTeardownWorkflow: () => AwsTeardownWorkflow,
189
190
  BUILT_IN_BUNDLES: () => BUILT_IN_BUNDLES,
190
191
  CLAUDE_RULE_TARGET: () => CLAUDE_RULE_TARGET,
191
192
  COMPLETE_JOB_ID: () => COMPLETE_JOB_ID,
192
193
  DEFAULT_PRIORITY_LABELS: () => DEFAULT_PRIORITY_LABELS,
193
194
  DEFAULT_STATUS_LABELS: () => DEFAULT_STATUS_LABELS,
195
+ DEFAULT_TEARDOWN_BRANCH_PATTERNS: () => DEFAULT_TEARDOWN_BRANCH_PATTERNS,
194
196
  DEFAULT_TYPE_LABELS: () => DEFAULT_TYPE_LABELS,
195
197
  JsiiFaker: () => JsiiFaker,
196
198
  MCP_TRANSPORT: () => MCP_TRANSPORT,
@@ -5914,7 +5916,7 @@ var DEFAULT_FAVICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0
5914
5916
  `;
5915
5917
 
5916
5918
  // src/projects/aws-cdk-project.ts
5917
- var import_projen19 = require("projen");
5919
+ var import_projen20 = require("projen");
5918
5920
  var import_javascript5 = require("projen/lib/javascript");
5919
5921
  var import_release2 = require("projen/lib/release");
5920
5922
  var import_ts_deepmerge3 = require("ts-deepmerge");
@@ -6190,8 +6192,212 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends import_projen18.Compone
6190
6192
  }
6191
6193
  };
6192
6194
 
6195
+ // src/workflows/aws-teardown-workflow.ts
6196
+ var import_projen19 = require("projen");
6197
+ var import_github3 = require("projen/lib/github");
6198
+ var import_workflows_model6 = require("projen/lib/github/workflows-model");
6199
+ var DEFAULT_TEARDOWN_BRANCH_PATTERNS = [
6200
+ "feat/*",
6201
+ "fix/*",
6202
+ "feature/*"
6203
+ ];
6204
+ var resolveBranchPatterns = (explicit, targets) => {
6205
+ if (explicit && explicit.length > 0) {
6206
+ return [...explicit];
6207
+ }
6208
+ const derived = Array.from(
6209
+ new Set(
6210
+ targets.flatMap((target) => target.branches.map((b) => b.branch)).filter((branch) => typeof branch === "string").filter((branch) => branch.includes("*"))
6211
+ )
6212
+ );
6213
+ if (derived.length > 0) {
6214
+ return derived;
6215
+ }
6216
+ return [...DEFAULT_TEARDOWN_BRANCH_PATTERNS];
6217
+ };
6218
+ var AwsTeardownWorkflow = class extends import_projen19.Component {
6219
+ constructor(rootProject, options) {
6220
+ super(rootProject);
6221
+ this.rootProject = rootProject;
6222
+ const {
6223
+ awsDestructionTargets,
6224
+ repoTagName,
6225
+ stageTypeTagName,
6226
+ environmentTypeTagName,
6227
+ branchNameTagName,
6228
+ deleteBranchPatterns
6229
+ } = options;
6230
+ if (!repoTagName) {
6231
+ throw new Error("AwsTeardownWorkflow requires `repoTagName`");
6232
+ }
6233
+ if (!stageTypeTagName) {
6234
+ throw new Error("AwsTeardownWorkflow requires `stageTypeTagName`");
6235
+ }
6236
+ if (!environmentTypeTagName) {
6237
+ throw new Error("AwsTeardownWorkflow requires `environmentTypeTagName`");
6238
+ }
6239
+ if (!branchNameTagName) {
6240
+ throw new Error("AwsTeardownWorkflow requires `branchNameTagName`");
6241
+ }
6242
+ if (!(rootProject instanceof MonorepoProject)) {
6243
+ throw new Error(
6244
+ "AwsTeardownWorkflow requires the root project to be a MonorepoProject"
6245
+ );
6246
+ }
6247
+ const github = import_github3.GitHub.of(this.rootProject);
6248
+ if (!github) {
6249
+ throw new Error(
6250
+ "AwsTeardownWorkflow requires a GitHub component in the root project"
6251
+ );
6252
+ }
6253
+ const branchPatterns = resolveBranchPatterns(
6254
+ deleteBranchPatterns,
6255
+ awsDestructionTargets
6256
+ );
6257
+ const workflow = new import_github3.GithubWorkflow(github, "teardown-dev");
6258
+ workflow.on({
6259
+ workflowDispatch: {},
6260
+ schedule: [
6261
+ {
6262
+ cron: "32 6 * * *"
6263
+ }
6264
+ ],
6265
+ delete: {
6266
+ branches: branchPatterns
6267
+ }
6268
+ });
6269
+ awsDestructionTargets.forEach((target) => {
6270
+ const {
6271
+ awsStageType,
6272
+ deploymentTargetRole,
6273
+ account,
6274
+ region,
6275
+ ciDeploymentConfig
6276
+ } = target;
6277
+ const { roleArn } = ciDeploymentConfig ?? {};
6278
+ workflow.addJob(
6279
+ `teardown-${awsStageType}-${deploymentTargetRole}-${account}-${region}`.toLowerCase(),
6280
+ {
6281
+ name: `Teardown Stacks in ${awsStageType}/${deploymentTargetRole}/${account}/${region}`,
6282
+ runsOn: ["ubuntu-latest"],
6283
+ permissions: {
6284
+ contents: import_workflows_model6.JobPermission.READ,
6285
+ idToken: import_workflows_model6.JobPermission.WRITE
6286
+ },
6287
+ env: {
6288
+ REPO: "${{ github.repository }}",
6289
+ REGIONS: [region].join(" ")
6290
+ },
6291
+ steps: [
6292
+ {
6293
+ name: `AWS Creds ${account}/${region}`,
6294
+ uses: "aws-actions/configure-aws-credentials@v6",
6295
+ with: {
6296
+ "role-to-assume": roleArn,
6297
+ "aws-region": region,
6298
+ "role-duration-seconds": 900
6299
+ }
6300
+ },
6301
+ {
6302
+ name: "Fetch All Branches",
6303
+ id: "fetch_branches",
6304
+ uses: "actions/github-script@v9",
6305
+ with: {
6306
+ script: [
6307
+ "const all = await github.paginate(github.rest.repos.listBranches, {",
6308
+ " owner: context.repo.owner,",
6309
+ " repo: context.repo.repo,",
6310
+ " per_page: 100",
6311
+ "});",
6312
+ "const names = all.map(b => b.name);",
6313
+ "console.log(`Found branches: ${names}`);",
6314
+ 'core.setOutput("json", JSON.stringify(names));'
6315
+ ].join("\n")
6316
+ }
6317
+ },
6318
+ {
6319
+ name: "Save Branches to File",
6320
+ run: [
6321
+ 'echo "Saving branches to file"',
6322
+ "echo '${{ steps.fetch_branches.outputs.json }}' | jq -r '.[]' | sort -u > branches.txt",
6323
+ 'echo "Branches:"',
6324
+ "cat branches.txt"
6325
+ ].join("\n")
6326
+ },
6327
+ {
6328
+ name: "Find Stacks by Tag",
6329
+ id: "find_stacks",
6330
+ run: [
6331
+ "set -euo pipefail",
6332
+ ": > candidates.txt # columns: arn region branchTag",
6333
+ "# Build tag filters",
6334
+ `TAG_FILTERS=( "Key=${repoTagName},Values=$REPO" )`,
6335
+ `TAG_FILTERS+=( "Key=${stageTypeTagName},Values=${awsStageType}" )`,
6336
+ `TAG_FILTERS+=( "Key=${environmentTypeTagName},Values=${deploymentTargetRole}" )`,
6337
+ "for r in $REGIONS; do",
6338
+ ` echo "Scanning region: $r"`,
6339
+ " aws resourcegroupstaggingapi get-resources \\",
6340
+ ' --region "$r" \\',
6341
+ ' --resource-type-filters "cloudformation:stack" \\',
6342
+ ' --tag-filters "${TAG_FILTERS[@]}" \\',
6343
+ ` | jq -r --arg r "$r" '`,
6344
+ " .ResourceTagMappingList[]",
6345
+ " | . as $res",
6346
+ ` | ($res.Tags[] | select(.Key=="${branchNameTagName}") | .Value) as $branch`,
6347
+ ' | [$res.ResourceARN, $r, ($branch // "")]',
6348
+ " | @tsv",
6349
+ " ' >> candidates.txt",
6350
+ "done",
6351
+ "echo 'Tagged stacks:'",
6352
+ `(echo -e "ARN\\tREGION\\tBRANCH"; cat candidates.txt) | column -t -s $'\\t'`
6353
+ ].join("\n")
6354
+ },
6355
+ {
6356
+ name: "Determine Orphan Stacks (No Matching Branch)",
6357
+ run: [
6358
+ "set -euo pipefail",
6359
+ ": > orphans.txt # arn region branch",
6360
+ "while IFS=$'\\t' read -r arn region branch; do",
6361
+ ' [ -z "$arn" ] && continue',
6362
+ ' if [ -z "$branch" ]; then',
6363
+ " # If no Branch tag, treat as not-a-preview; skip",
6364
+ " continue",
6365
+ " fi",
6366
+ ' if ! grep -Fxq "$branch" branches.txt; then',
6367
+ ' echo -e "$arn\\t$region\\t$branch" >> orphans.txt',
6368
+ " fi",
6369
+ "done < candidates.txt",
6370
+ "",
6371
+ "if [ -s orphans.txt ]; then",
6372
+ ' echo "Orphan stacks (no matching branch):"',
6373
+ ` (echo -e "ARN\\tREGION\\tBRANCH"; cat orphans.txt) | column -t -s $'\\t'`,
6374
+ "else",
6375
+ ' echo "No orphan stacks found."',
6376
+ "fi"
6377
+ ].join("\n")
6378
+ },
6379
+ {
6380
+ name: "Delete Orphan Stacks",
6381
+ if: "hashFiles('orphans.txt') != ''",
6382
+ run: [
6383
+ "set -euo pipefail",
6384
+ "while IFS=$'\\t' read -r arn region branch; do",
6385
+ ' [ -z "$arn" ] && continue',
6386
+ ` stack_name=$(cut -d'/' -f2 <<<"$arn")`,
6387
+ ' echo "Deleting $stack_name (branch=$branch) in $region"',
6388
+ ' aws cloudformation delete-stack --region "$region" --stack-name "$stack_name" || true',
6389
+ "done < orphans.txt"
6390
+ ].join("\n")
6391
+ }
6392
+ ]
6393
+ }
6394
+ );
6395
+ });
6396
+ }
6397
+ };
6398
+
6193
6399
  // src/projects/aws-cdk-project.ts
6194
- var AwsCdkProject = class extends import_projen19.awscdk.AwsCdkTypeScriptApp {
6400
+ var AwsCdkProject = class extends import_projen20.awscdk.AwsCdkTypeScriptApp {
6195
6401
  constructor(userOptions) {
6196
6402
  if (!(userOptions.parent instanceof MonorepoProject)) {
6197
6403
  throw new Error(
@@ -6322,6 +6528,9 @@ var AwsCdkProject = class extends import_projen19.awscdk.AwsCdkTypeScriptApp {
6322
6528
  deployWorkflows.forEach(
6323
6529
  (workflowOptions) => new AwsDeployWorkflow(this, workflowOptions)
6324
6530
  );
6531
+ if (options.teardownWorkflow) {
6532
+ new AwsTeardownWorkflow(parent, options.teardownWorkflow);
6533
+ }
6325
6534
  const turboActive = TurboRepo.of(parent) !== void 0;
6326
6535
  if (turboActive) {
6327
6536
  const turbo = new TurboRepo(this);
@@ -6382,9 +6591,9 @@ var AwsCdkProject = class extends import_projen19.awscdk.AwsCdkTypeScriptApp {
6382
6591
 
6383
6592
  // src/typescript/typescript-config.ts
6384
6593
  var import_node_path2 = require("path");
6385
- var import_projen20 = require("projen");
6594
+ var import_projen21 = require("projen");
6386
6595
  var import_path2 = require("projen/lib/util/path");
6387
- var TypeScriptConfig = class extends import_projen20.Component {
6596
+ var TypeScriptConfig = class extends import_projen21.Component {
6388
6597
  constructor(project) {
6389
6598
  super(project);
6390
6599
  let tsPaths = {};
@@ -6422,11 +6631,13 @@ var TypeScriptConfig = class extends import_projen20.Component {
6422
6631
  AwsDeployWorkflow,
6423
6632
  AwsDeploymentConfig,
6424
6633
  AwsDeploymentTarget,
6634
+ AwsTeardownWorkflow,
6425
6635
  BUILT_IN_BUNDLES,
6426
6636
  CLAUDE_RULE_TARGET,
6427
6637
  COMPLETE_JOB_ID,
6428
6638
  DEFAULT_PRIORITY_LABELS,
6429
6639
  DEFAULT_STATUS_LABELS,
6640
+ DEFAULT_TEARDOWN_BRANCH_PATTERNS,
6430
6641
  DEFAULT_TYPE_LABELS,
6431
6642
  JsiiFaker,
6432
6643
  MCP_TRANSPORT,