env-helper.ts
Source: src/bin/env-helper.ts
Utilities for environment-specific task generation, resource naming, and branch handling. Used in both Projen configuration and at runtime in CDK stacks.
Types and Constants
Environment
type Environment = 'sandbox' | 'development' | 'test' | 'staging' | 'production'
Supported environment names.
SUPPORTED_CDK_ACTIONS
const SUPPORTED_CDK_ACTIONS = ['synth', 'diff', 'deploy', 'deploy:hotswap', 'destroy', 'ls'] as const
CDK actions with task generation support.
EnvironmentConfig
interface EnvironmentConfig {
accountId: string;
enableBranchDeploy: boolean;
}
Environment configuration shape.
Functions
getTaskName
Location: src/bin/env-helper.ts:35-53
getTaskName(
environment: string,
action: typeof SUPPORTED_CDK_ACTIONS[number],
options?: { isBranch?: boolean; taskType?: 'all' | 'stack' }
): string
Generates consistent task names following the convention: <env>[:<branch>]:<action>[:<type>].
Parameters:
| Name | Type | Description |
|---|---|---|
| environment | string | Environment name (test, production, etc.). |
| action | CdkAction | CDK action (synth, deploy, destroy, diff, ls, deploy:hotswap). |
| options.isBranch | boolean (optional) | Whether this is a branch deployment task. |
| options.taskType | 'all' | 'stack' (optional) | Either 'all' (for all stacks) or 'stack' (for specific stacks). |
Returns: string - Task name in the format <env>[:<branch>]:<action>[:<type>].
Examples:
getTaskName('test', 'synth')
// → 'test:synth'
getTaskName('test', 'deploy', { taskType: 'all' })
// → 'test:deploy:all'
getTaskName('test', 'deploy', { isBranch: true, taskType: 'all' })
// → 'test:branch:deploy:all'
getTaskName('test', 'destroy', { isBranch: true, taskType: 'stack' })
// → 'test:branch:destroy:stack'
Usage: Task names are used by GitHub Actions workflows. See How workflows are generated.
addCdkActionTask
Location: src/bin/env-helper.ts:69-116
addCdkActionTask(
cdkProject: AwsCdkTypeScriptApp,
targetAccount: {
CDK_DEFAULT_ACCOUNT: string;
CDK_DEFAULT_REGION: string;
ENVIRONMENT: string;
GITHUB_DEPLOY_ROLE: string;
GIT_BRANCH_REF?: string;
}
): void
Generates npm run tasks for all supported CDK actions with environment-specific variables.
Parameters:
| Name | Type | Description |
|---|---|---|
| cdkProject | AwsCdkTypeScriptApp | Projen CDK project instance. |
| targetAccount | TargetAccount | Environment configuration object. |
TargetAccount Properties:
| Name | Type | Required | Description |
|---|---|---|---|
| CDK_DEFAULT_ACCOUNT | string | Yes | AWS account ID. |
| CDK_DEFAULT_REGION | string | Yes | AWS region. |
| ENVIRONMENT | string | Yes | Environment name. |
| GITHUB_DEPLOY_ROLE | string | Yes | IAM role name for OIDC. |
| GIT_BRANCH_REF | string | No | Branch reference for branch deployments. |
Task Generation Behavior:
| Action | Task Variants | Description |
|---|---|---|
synth, ls | Single task | Operates on all stacks |
deploy, destroy, diff | :all and :stack | :all runs on all stacks with --all flag, :stack accepts stack names via receiveArgs: true |
deploy:hotswap | :all and :stack | Only generated for branch deployments (when GIT_BRANCH_REF is present) |
Example Tasks Generated:
# Regular environment tasks
npm run test:synth # Synth all test stacks
npm run test:deploy:all # Deploy all test stacks
npm run test:deploy:stack MyStack # Deploy specific test stack
npm run test:diff:all # Diff all test stacks
npm run test:destroy:all # Destroy all test stacks
# Branch deployment tasks (when GIT_BRANCH_REF is set)
npm run test:branch:synth
npm run test:branch:deploy:all
npm run test:branch:deploy:hotswap:all
npm run test:branch:destroy:all
Usage in .projenrc.ts:165:
import { addCdkActionTask } from './src/bin/env-helper';
addCdkActionTask(project, {
CDK_DEFAULT_ACCOUNT: '987654321012',
CDK_DEFAULT_REGION: 'us-east-1',
ENVIRONMENT: 'test',
GITHUB_DEPLOY_ROLE: 'GitHubActionsServiceRole',
});
// For branch deployments (line 174)
addCdkActionTask(project, {
CDK_DEFAULT_ACCOUNT: '987654321012',
CDK_DEFAULT_REGION: 'us-east-1',
ENVIRONMENT: 'test',
GITHUB_DEPLOY_ROLE: 'GitHubActionsServiceRole',
GIT_BRANCH_REF: '$(echo ${GIT_BRANCH_REF:-$(git rev-parse --abbrev-ref HEAD)})',
});
Related: Task generation
extractCleanedBranchName
Location: src/bin/env-helper.ts:124-147
extractCleanedBranchName(branchRef: string): string | undefined
Extracts and sanitizes branch names for use in resource naming.
Parameters:
| Name | Type | Description |
|---|---|---|
| branchRef | string | Git branch reference. |
Returns: string | undefined - Sanitized branch name or undefined for excluded branches.
Sanitization Rules:
| Rule | Description |
|---|---|
| Excluded branches | Returns undefined for main, develop, development |
| Version tags | Returns undefined for tags matching v\d+\.\d+\.\d+ |
| Lowercase | Converts to lowercase |
| Extract segment | Extracts last segment after / (e.g., feature/foo-bar → foo-bar) |
| Character filter | Removes all characters except a-z, 0-9, and - |
| Trim hyphens | Trims trailing hyphens |
| Truncate | Truncates to 25 characters |
Examples:
extractCleanedBranchName('feature/user-auth')
// → 'user-auth'
extractCleanedBranchName('bugfix/fix-api-123')
// → 'fix-api-123'
extractCleanedBranchName('main')
// → undefined
extractCleanedBranchName('v1.2.3')
// → undefined
Usage: Used by createEnvResourceName to generate branch-suffixed stack names. See Branch deployment workflow.
createEnvResourceName
Location: src/bin/env-helper.ts:157-181
createEnvResourceName(baseName: string): string
Creates environment or branch-aware resource names with automatic suffixing.
Parameters:
| Name | Type | Description |
|---|---|---|
| baseName | string | Base name for the resource. |
Returns: string - Environment or branch-suffixed resource name (max 64 characters).
Behavior:
| Condition | Format | Example |
|---|---|---|
GIT_BRANCH_REF is set | <baseName>-<cleanedBranchName> | MyStack-user-auth |
| Otherwise | <baseName>-<environment> | MyStack-test |
Error Handling:
- Throws error if
GIT_BRANCH_REFis"main"to prevent accidental branch deploys to production. - Truncates to 64 characters max, removing trailing non-alphanumeric chars.
Examples:
// Regular environment deployment
process.env.ENVIRONMENT = 'test';
createEnvResourceName('MyStack')
// → 'MyStack-test'
// Branch deployment
process.env.GIT_BRANCH_REF = 'feature/user-auth';
createEnvResourceName('MyStack')
// → 'MyStack-user-auth'
// Error case
process.env.GIT_BRANCH_REF = 'main';
createEnvResourceName('MyStack')
// → Throws error
Usage in CDK Stacks:
import { createEnvResourceName } from '../bin/env-helper';
// Stack naming
new Stack(app, createEnvResourceName('StarterStack'), { env });
// Resource naming
new Bucket(this, 'Bucket', {
bucketName: createEnvResourceName('my-app-bucket'),
});
Related: Branch deployment workflow
cicd-helper.ts
Source: src/bin/cicd-helper.ts
Functions for generating GitHub Actions workflows for CDK deployments. See Configuration: CI/CD Workflows.
Functions
createCdkDeploymentWorkflows
Location: src/bin/cicd-helper.ts:113-132
createCdkDeploymentWorkflows(
gh: GitHub,
account: string,
region: string,
env: string,
githubDeployRole: string,
nodeVersion: string,
deployForBranch: boolean,
orderedEnvironments: string[]
): void
Main entry point that orchestrates workflow generation for an environment.
Parameters:
| Name | Type | Description |
|---|---|---|
| gh | GitHub | GitHub instance from Projen. |
| account | string | AWS account ID for deployments. |
| region | string | AWS region for deployments. |
| env | string | Environment name (test, staging, production, etc.). |
| githubDeployRole | string | Name of the IAM role for OIDC authentication. |
| nodeVersion | string | Node.js version for workflows. |
| deployForBranch | boolean | Whether to create branch deployment workflows. |
| orderedEnvironments | string[] | Array of environments in deployment order for workflow chaining. |
Returns: void
Workflows Created:
| Workflow | Filename | Condition |
|---|---|---|
| Regular deployment | cdk-deploy-<env>.yml | Always |
| Branch deployment | cdk-deploy-<env>-branch.yml | If deployForBranch=true |
| Branch destroy | cdk-destroy-<env>-branch.yml | If deployForBranch=true |
Usage in .projenrc.ts:184-193:
import { createCdkDeploymentWorkflows } from './src/bin/cicd-helper';
createCdkDeploymentWorkflows(
project.github,
config.accountId,
awsRegion,
config.name,
githubRole,
nodeVersion,
config.enableBranchDeploy,
orderedEnvironments,
);
Related: Environment deployment workflow
createCdkDeploymentWorkflow
Location: src/bin/cicd-helper.ts:146-217
createCdkDeploymentWorkflow(
gh: GitHub,
account: string,
region: string,
env: string,
githubDeployRole: string,
nodeVersion: string,
isBranchWorkflow: boolean,
orderedEnvironments: string[]
): void
Internal function that creates individual deployment workflows. Handles both regular and branch-based deployments.
Parameters:
| Name | Type | Description |
|---|---|---|
| gh | GitHub | GitHub instance from Projen. |
| account | string | AWS account ID. |
| region | string | AWS region. |
| env | string | Environment name. |
| githubDeployRole | string | IAM role name for OIDC. |
| nodeVersion | string | Node.js version. |
| isBranchWorkflow | boolean | Whether this is a branch deployment workflow. |
| orderedEnvironments | string[] | Ordered list of environments. |
Returns: void
Trigger Behavior:
| Environment | Trigger |
|---|---|
| First env in list | Push to main |
| Subsequent envs | workflow_run when previous env completes successfully |
| Branch workflow | Push to feature branches (excludes main, hotfix/*, github-actions/*, dependabot/**) |
Workflow Configuration:
| Setting | Value | Purpose |
|---|---|---|
| Concurrency | cancel-in-progress: false | Prevents parallel deployments to same environment |
| Permissions | contents: read, id-token: write | For OIDC authentication |
| Environment | Links to GitHub environment | For protection rules |
Steps:
- Checkout repository
- Setup Node.js
- Configure AWS credentials via OIDC
- Install dependencies
- Run
<env>:synth - Run
<env>:deploy:all
Related: Environment deployment workflow and Branch deployment workflow
createCdkDestroyWorkflow
Location: src/bin/cicd-helper.ts:235-303
createCdkDestroyWorkflow(
gh: GitHub,
account: string,
region: string,
env: string,
githubDeployRole: string,
nodeVersion: string
): void
Creates cleanup workflows for branch deployments.
Parameters:
| Name | Type | Description |
|---|---|---|
| gh | GitHub | GitHub instance from Projen. |
| account | string | AWS account ID. |
| region | string | AWS region. |
| env | string | Environment name. |
| githubDeployRole | string | IAM role name for OIDC. |
| nodeVersion | string | Node.js version. |
Returns: void
Trigger Scenarios:
| Trigger | Method | Branch Extraction |
|---|---|---|
| Manual dispatch | workflow_dispatch | Uses current branch ref |
| Branch deletion | delete event | Extracts from GitHub event payload using jq |
| PR closure | pull_request closed | Uses PR head ref from GitHub context |
Safety Features:
- Job-level
ifcondition prevents accidental destruction of main branch stacks - Branch name validation ensures only feature branches are destroyed
- Manual override via
workflow_dispatchfor cleanup operations
Related: Branch destroy workflow
createCdkDiffPrWorkflow
Location: src/bin/cicd-helper.ts:29-94
createCdkDiffPrWorkflow(
gh: GitHub,
account: string,
region: string,
githubDeployRole: string,
nodeVersion: string,
orderedEnvironments: string[]
): void
Creates a workflow that generates CDK diff output and posts it as a PR comment for early visibility into infrastructure changes.
Parameters:
| Name | Type | Description |
|---|---|---|
| gh | GitHub | GitHub instance from Projen. |
| account | string | AWS account ID (usually production). |
| region | string | AWS region. |
| githubDeployRole | string | IAM role name for OIDC. |
| nodeVersion | string | Node.js version. |
| orderedEnvironments | string[] | Ordered list of environments. |
Returns: void
Configuration:
| Setting | Value | Purpose |
|---|---|---|
| Trigger | pull_request_target on PRs to main | Secure access to secrets |
| Comparison | PR branch vs highest environment | Usually production |
| Checkout | PR branch SHA | github.event.pull_request.head.sha |
| Diff output | cdk-diff-output.txt | Captured with || true to prevent workflow failures |
| Comment action | towardsthecloud/aws-cdk-diff-pr-commenter@v1 | Posts diff as PR comment |
| Permissions | contents: read, id-token: write, pull-requests: write | For checkout, OIDC, and commenting |
Usage in .projenrc.ts:197-204:
import { createCdkDiffPrWorkflow } from './src/bin/cicd-helper';
createCdkDiffPrWorkflow(
project.github,
environmentConfigs[environmentConfigs.length - 1].accountId, // Production account
awsRegion,
githubRole,
nodeVersion,
orderedEnvironments,
);
Related: CDK diff PR comment workflow
getCommonWorkflowSteps
Location: src/bin/cicd-helper.ts:362-378
getCommonWorkflowSteps(
nodeVersion: string,
region: string,
githubDeployRole: string,
account: string,
ref?: string
): WorkflowStep[]
Generates standard workflow steps shared across all deployment workflows.
Parameters:
| Name | Type | Description |
|---|---|---|
| nodeVersion | string | Node.js version. |
| region | string | AWS region. |
| githubDeployRole | string | IAM role name. |
| account | string | AWS account ID. |
| ref | string (optional) | Git ref to checkout. |
Returns: WorkflowStep[] - Array of workflow steps.
Steps Generated:
| Step | Action | Purpose |
|---|---|---|
| 1. Checkout repository | actions/checkout@v5 | Clone repo with optional ref |
| 2. Setup Node.js | actions/setup-node@v6 | Install Node.js with version and npm caching |
| 3. Configure AWS credentials | aws-actions/configure-aws-credentials@v4 | OIDC authentication |
| 4. Install dependencies | npm ci | Reproducible installs |
Related: Common workflow steps
git-helper.ts
Source: src/bin/git-helper.ts
Functions
getGitRepositoryDetails
getGitRepositoryDetails(): { gitOwner: string; gitRepoName: string }
Parses the Git remote URL from git config --get remote.origin.url to extract owner and repo.
Returns: Object with gitOwner and gitRepoName.
Usage:
Used by the FoundationStack to scope the GitHub OIDC sub claim to repo:<owner>/<repo>:environment:<env>.
import { getGitRepositoryDetails } from '../bin/git-helper';
const { gitOwner, gitRepoName } = getGitRepositoryDetails();