├── .eslintrc.json ├── .gitattributes ├── .github ├── pull_request_template.md └── workflows │ ├── auto-approve.yml │ ├── build.yml │ ├── pull-request-lint.yml │ ├── release.yml │ ├── upgrade-cdklabs-projen-project-types-main.yml │ ├── upgrade-dev-deps-main.yml │ └── upgrade-main.yml ├── .gitignore ├── .mergify.yml ├── .npmignore ├── .projen ├── deps.json ├── files.json └── tasks.json ├── .projenrc.ts ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md ├── bin └── awscdk-v1-stack-finder ├── package.json ├── src ├── cli.ts └── index.ts ├── tsconfig.dev.json ├── tsconfig.json └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | // ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | { 3 | "env": { 4 | "jest": true, 5 | "node": true 6 | }, 7 | "root": true, 8 | "plugins": [ 9 | "@typescript-eslint", 10 | "import", 11 | "@stylistic" 12 | ], 13 | "parser": "@typescript-eslint/parser", 14 | "parserOptions": { 15 | "ecmaVersion": 2018, 16 | "sourceType": "module", 17 | "project": "./tsconfig.dev.json" 18 | }, 19 | "extends": [ 20 | "plugin:import/typescript" 21 | ], 22 | "settings": { 23 | "import/parsers": { 24 | "@typescript-eslint/parser": [ 25 | ".ts", 26 | ".tsx" 27 | ] 28 | }, 29 | "import/resolver": { 30 | "node": {}, 31 | "typescript": { 32 | "project": "./tsconfig.dev.json", 33 | "alwaysTryTypes": true 34 | } 35 | } 36 | }, 37 | "ignorePatterns": [ 38 | "*.js", 39 | "*.d.ts", 40 | "node_modules/", 41 | "*.generated.ts", 42 | "coverage", 43 | "!.projenrc.ts", 44 | "!projenrc/**/*.ts" 45 | ], 46 | "rules": { 47 | "@stylistic/indent": [ 48 | "error", 49 | 2 50 | ], 51 | "@stylistic/quotes": [ 52 | "error", 53 | "single", 54 | { 55 | "avoidEscape": true 56 | } 57 | ], 58 | "@stylistic/comma-dangle": [ 59 | "error", 60 | "always-multiline" 61 | ], 62 | "@stylistic/comma-spacing": [ 63 | "error", 64 | { 65 | "before": false, 66 | "after": true 67 | } 68 | ], 69 | "@stylistic/no-multi-spaces": [ 70 | "error", 71 | { 72 | "ignoreEOLComments": false 73 | } 74 | ], 75 | "@stylistic/array-bracket-spacing": [ 76 | "error", 77 | "never" 78 | ], 79 | "@stylistic/array-bracket-newline": [ 80 | "error", 81 | "consistent" 82 | ], 83 | "@stylistic/object-curly-spacing": [ 84 | "error", 85 | "always" 86 | ], 87 | "@stylistic/object-curly-newline": [ 88 | "error", 89 | { 90 | "multiline": true, 91 | "consistent": true 92 | } 93 | ], 94 | "@stylistic/object-property-newline": [ 95 | "error", 96 | { 97 | "allowAllPropertiesOnSameLine": true 98 | } 99 | ], 100 | "@stylistic/keyword-spacing": [ 101 | "error" 102 | ], 103 | "@stylistic/brace-style": [ 104 | "error", 105 | "1tbs", 106 | { 107 | "allowSingleLine": true 108 | } 109 | ], 110 | "@stylistic/space-before-blocks": [ 111 | "error" 112 | ], 113 | "@stylistic/member-delimiter-style": [ 114 | "error" 115 | ], 116 | "@stylistic/semi": [ 117 | "error", 118 | "always" 119 | ], 120 | "@stylistic/max-len": [ 121 | "error", 122 | { 123 | "code": 150, 124 | "ignoreUrls": true, 125 | "ignoreStrings": true, 126 | "ignoreTemplateLiterals": true, 127 | "ignoreComments": true, 128 | "ignoreRegExpLiterals": true 129 | } 130 | ], 131 | "@stylistic/quote-props": [ 132 | "error", 133 | "consistent-as-needed" 134 | ], 135 | "@stylistic/key-spacing": [ 136 | "error" 137 | ], 138 | "@stylistic/no-multiple-empty-lines": [ 139 | "error" 140 | ], 141 | "@stylistic/no-trailing-spaces": [ 142 | "error" 143 | ], 144 | "curly": [ 145 | "error", 146 | "multi-line", 147 | "consistent" 148 | ], 149 | "@typescript-eslint/no-require-imports": "error", 150 | "import/no-extraneous-dependencies": [ 151 | "error", 152 | { 153 | "devDependencies": [ 154 | "**/test/**", 155 | "**/build-tools/**", 156 | ".projenrc.ts", 157 | "projenrc/**/*.ts" 158 | ], 159 | "optionalDependencies": false, 160 | "peerDependencies": true 161 | } 162 | ], 163 | "import/no-unresolved": [ 164 | "error" 165 | ], 166 | "import/order": [ 167 | "warn", 168 | { 169 | "groups": [ 170 | "builtin", 171 | "external" 172 | ], 173 | "alphabetize": { 174 | "order": "asc", 175 | "caseInsensitive": true 176 | } 177 | } 178 | ], 179 | "import/no-duplicates": [ 180 | "error" 181 | ], 182 | "no-shadow": [ 183 | "off" 184 | ], 185 | "@typescript-eslint/no-shadow": "error", 186 | "@typescript-eslint/no-floating-promises": "error", 187 | "no-return-await": [ 188 | "off" 189 | ], 190 | "@typescript-eslint/return-await": "error", 191 | "dot-notation": [ 192 | "error" 193 | ], 194 | "no-bitwise": [ 195 | "error" 196 | ], 197 | "@typescript-eslint/member-ordering": [ 198 | "error", 199 | { 200 | "default": [ 201 | "public-static-field", 202 | "public-static-method", 203 | "protected-static-field", 204 | "protected-static-method", 205 | "private-static-field", 206 | "private-static-method", 207 | "field", 208 | "constructor", 209 | "method" 210 | ] 211 | } 212 | ] 213 | }, 214 | "overrides": [ 215 | { 216 | "files": [ 217 | ".projenrc.ts" 218 | ], 219 | "rules": { 220 | "@typescript-eslint/no-require-imports": "off", 221 | "import/no-extraneous-dependencies": "off" 222 | } 223 | } 224 | ] 225 | } 226 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | * text=auto eol=lf 4 | *.snap linguist-generated 5 | /.eslintrc.json linguist-generated 6 | /.gitattributes linguist-generated 7 | /.github/pull_request_template.md linguist-generated 8 | /.github/workflows/auto-approve.yml linguist-generated 9 | /.github/workflows/build.yml linguist-generated 10 | /.github/workflows/pull-request-lint.yml linguist-generated 11 | /.github/workflows/release.yml linguist-generated 12 | /.github/workflows/upgrade-cdklabs-projen-project-types-main.yml linguist-generated 13 | /.github/workflows/upgrade-dev-deps-main.yml linguist-generated 14 | /.github/workflows/upgrade-main.yml linguist-generated 15 | /.gitignore linguist-generated 16 | /.mergify.yml linguist-generated 17 | /.npmignore linguist-generated 18 | /.projen/** linguist-generated 19 | /.projen/deps.json linguist-generated 20 | /.projen/files.json linguist-generated 21 | /.projen/tasks.json linguist-generated 22 | /LICENSE linguist-generated 23 | /package.json linguist-generated 24 | /tsconfig.dev.json linguist-generated 25 | /tsconfig.json linguist-generated 26 | /yarn.lock linguist-generated -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Fixes # -------------------------------------------------------------------------------- /.github/workflows/auto-approve.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: auto-approve 4 | on: 5 | pull_request_target: 6 | types: 7 | - labeled 8 | - opened 9 | - synchronize 10 | - reopened 11 | - ready_for_review 12 | jobs: 13 | approve: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | pull-requests: write 17 | if: contains(github.event.pull_request.labels.*.name, 'auto-approve') && (github.event.pull_request.user.login == 'cdklabs-automation' || github.event.pull_request.user.login == 'dependabot[bot]') 18 | steps: 19 | - uses: hmarr/auto-approve-action@v2.2.1 20 | with: 21 | github-token: ${{ secrets.GITHUB_TOKEN }} 22 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: build 4 | on: 5 | pull_request: {} 6 | workflow_dispatch: {} 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | contents: write 12 | outputs: 13 | self_mutation_happened: ${{ steps.self_mutation.outputs.self_mutation_happened }} 14 | env: 15 | CI: "true" 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4 19 | with: 20 | ref: ${{ github.event.pull_request.head.ref }} 21 | repository: ${{ github.event.pull_request.head.repo.full_name }} 22 | - name: Setup Node.js 23 | uses: actions/setup-node@v4 24 | with: 25 | node-version: lts/* 26 | - name: Install dependencies 27 | run: yarn install --check-files 28 | - name: build 29 | run: npx projen build 30 | - name: Find mutations 31 | id: self_mutation 32 | run: |- 33 | git add . 34 | git diff --staged --patch --exit-code > repo.patch || echo "self_mutation_happened=true" >> $GITHUB_OUTPUT 35 | working-directory: ./ 36 | - name: Upload patch 37 | if: steps.self_mutation.outputs.self_mutation_happened 38 | uses: actions/upload-artifact@v4.4.0 39 | with: 40 | name: repo.patch 41 | path: repo.patch 42 | overwrite: true 43 | - name: Fail build on mutation 44 | if: steps.self_mutation.outputs.self_mutation_happened 45 | run: |- 46 | echo "::error::Files were changed during build (see build log). If this was triggered from a fork, you will need to update your branch." 47 | cat repo.patch 48 | exit 1 49 | self-mutation: 50 | needs: build 51 | runs-on: ubuntu-latest 52 | permissions: 53 | contents: write 54 | if: always() && needs.build.outputs.self_mutation_happened && !(github.event.pull_request.head.repo.full_name != github.repository) 55 | steps: 56 | - name: Checkout 57 | uses: actions/checkout@v4 58 | with: 59 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }} 60 | ref: ${{ github.event.pull_request.head.ref }} 61 | repository: ${{ github.event.pull_request.head.repo.full_name }} 62 | - name: Download patch 63 | uses: actions/download-artifact@v4 64 | with: 65 | name: repo.patch 66 | path: ${{ runner.temp }} 67 | - name: Apply patch 68 | run: '[ -s ${{ runner.temp }}/repo.patch ] && git apply ${{ runner.temp }}/repo.patch || echo "Empty patch. Skipping."' 69 | - name: Set git identity 70 | run: |- 71 | git config user.name "github-actions" 72 | git config user.email "github-actions@github.com" 73 | - name: Push changes 74 | env: 75 | PULL_REQUEST_REF: ${{ github.event.pull_request.head.ref }} 76 | run: |- 77 | git add . 78 | git commit -s -m "chore: self mutation" 79 | git push origin HEAD:$PULL_REQUEST_REF 80 | -------------------------------------------------------------------------------- /.github/workflows/pull-request-lint.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: pull-request-lint 4 | on: 5 | pull_request_target: 6 | types: 7 | - labeled 8 | - opened 9 | - synchronize 10 | - reopened 11 | - ready_for_review 12 | - edited 13 | merge_group: {} 14 | jobs: 15 | validate: 16 | name: Validate PR title 17 | runs-on: ubuntu-latest 18 | permissions: 19 | pull-requests: write 20 | if: (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') 21 | steps: 22 | - uses: amannn/action-semantic-pull-request@v5.4.0 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | with: 26 | types: |- 27 | feat 28 | fix 29 | chore 30 | requireScope: false 31 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: release 4 | on: 5 | push: 6 | branches: 7 | - main 8 | workflow_dispatch: {} 9 | concurrency: 10 | group: ${{ github.workflow }} 11 | cancel-in-progress: false 12 | jobs: 13 | release: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | contents: write 17 | outputs: 18 | latest_commit: ${{ steps.git_remote.outputs.latest_commit }} 19 | tag_exists: ${{ steps.check_tag_exists.outputs.exists }} 20 | env: 21 | CI: "true" 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v4 25 | with: 26 | fetch-depth: 0 27 | - name: Set git identity 28 | run: |- 29 | git config user.name "github-actions" 30 | git config user.email "github-actions@github.com" 31 | - name: Setup Node.js 32 | uses: actions/setup-node@v4 33 | with: 34 | node-version: lts/* 35 | - name: Install dependencies 36 | run: yarn install --check-files --frozen-lockfile 37 | - name: release 38 | run: npx projen release 39 | - name: Check if version has already been tagged 40 | id: check_tag_exists 41 | run: |- 42 | TAG=$(cat dist/releasetag.txt) 43 | ([ ! -z "$TAG" ] && git ls-remote -q --exit-code --tags origin $TAG && (echo "exists=true" >> $GITHUB_OUTPUT)) || (echo "exists=false" >> $GITHUB_OUTPUT) 44 | cat $GITHUB_OUTPUT 45 | - name: Check for new commits 46 | id: git_remote 47 | run: |- 48 | echo "latest_commit=$(git ls-remote origin -h ${{ github.ref }} | cut -f1)" >> $GITHUB_OUTPUT 49 | cat $GITHUB_OUTPUT 50 | - name: Backup artifact permissions 51 | if: ${{ steps.git_remote.outputs.latest_commit == github.sha }} 52 | run: cd dist && getfacl -R . > permissions-backup.acl 53 | continue-on-error: true 54 | - name: Upload artifact 55 | if: ${{ steps.git_remote.outputs.latest_commit == github.sha }} 56 | uses: actions/upload-artifact@v4.4.0 57 | with: 58 | name: build-artifact 59 | path: dist 60 | overwrite: true 61 | release_github: 62 | name: Publish to GitHub Releases 63 | needs: 64 | - release 65 | - release_npm 66 | runs-on: ubuntu-latest 67 | permissions: 68 | contents: write 69 | if: needs.release.outputs.tag_exists != 'true' && needs.release.outputs.latest_commit == github.sha 70 | steps: 71 | - uses: actions/setup-node@v4 72 | with: 73 | node-version: lts/* 74 | - name: Download build artifacts 75 | uses: actions/download-artifact@v4 76 | with: 77 | name: build-artifact 78 | path: dist 79 | - name: Restore build artifact permissions 80 | run: cd dist && setfacl --restore=permissions-backup.acl 81 | continue-on-error: true 82 | - name: Release 83 | env: 84 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 85 | run: errout=$(mktemp); gh release create $(cat dist/releasetag.txt) -R $GITHUB_REPOSITORY -F dist/changelog.md -t $(cat dist/releasetag.txt) --target $GITHUB_SHA 2> $errout && true; exitcode=$?; if [ $exitcode -ne 0 ] && ! grep -q "Release.tag_name already exists" $errout; then cat $errout; exit $exitcode; fi 86 | release_npm: 87 | name: Publish to npm 88 | needs: release 89 | runs-on: ubuntu-latest 90 | permissions: 91 | id-token: write 92 | contents: read 93 | if: needs.release.outputs.tag_exists != 'true' && needs.release.outputs.latest_commit == github.sha 94 | steps: 95 | - uses: actions/setup-node@v4 96 | with: 97 | node-version: lts/* 98 | - name: Download build artifacts 99 | uses: actions/download-artifact@v4 100 | with: 101 | name: build-artifact 102 | path: dist 103 | - name: Restore build artifact permissions 104 | run: cd dist && setfacl --restore=permissions-backup.acl 105 | continue-on-error: true 106 | - name: Release 107 | env: 108 | NPM_DIST_TAG: latest 109 | NPM_REGISTRY: registry.npmjs.org 110 | NPM_CONFIG_PROVENANCE: "true" 111 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 112 | run: npx -p publib@latest publib-npm 113 | -------------------------------------------------------------------------------- /.github/workflows/upgrade-cdklabs-projen-project-types-main.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: upgrade-cdklabs-projen-project-types-main 4 | on: 5 | workflow_dispatch: {} 6 | jobs: 7 | upgrade: 8 | name: Upgrade 9 | runs-on: ubuntu-latest 10 | permissions: 11 | contents: read 12 | outputs: 13 | patch_created: ${{ steps.create_patch.outputs.patch_created }} 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | with: 18 | ref: main 19 | - name: Setup Node.js 20 | uses: actions/setup-node@v4 21 | - name: Install dependencies 22 | run: yarn install --check-files --frozen-lockfile 23 | - name: Upgrade dependencies 24 | run: npx projen upgrade-cdklabs-projen-project-types 25 | - name: Find mutations 26 | id: create_patch 27 | run: |- 28 | git add . 29 | git diff --staged --patch --exit-code > repo.patch || echo "patch_created=true" >> $GITHUB_OUTPUT 30 | working-directory: ./ 31 | - name: Upload patch 32 | if: steps.create_patch.outputs.patch_created 33 | uses: actions/upload-artifact@v4.4.0 34 | with: 35 | name: repo.patch 36 | path: repo.patch 37 | overwrite: true 38 | pr: 39 | name: Create Pull Request 40 | needs: upgrade 41 | runs-on: ubuntu-latest 42 | permissions: 43 | contents: read 44 | if: ${{ needs.upgrade.outputs.patch_created }} 45 | steps: 46 | - name: Checkout 47 | uses: actions/checkout@v4 48 | with: 49 | ref: main 50 | - name: Download patch 51 | uses: actions/download-artifact@v4 52 | with: 53 | name: repo.patch 54 | path: ${{ runner.temp }} 55 | - name: Apply patch 56 | run: '[ -s ${{ runner.temp }}/repo.patch ] && git apply ${{ runner.temp }}/repo.patch || echo "Empty patch. Skipping."' 57 | - name: Set git identity 58 | run: |- 59 | git config user.name "github-actions" 60 | git config user.email "github-actions@github.com" 61 | - name: Create Pull Request 62 | id: create-pr 63 | uses: peter-evans/create-pull-request@v6 64 | with: 65 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }} 66 | commit-message: |- 67 | chore(deps): upgrade cdklabs-projen-project-types 68 | 69 | Upgrades project dependencies. See details in [workflow run]. 70 | 71 | [Workflow Run]: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 72 | 73 | ------ 74 | 75 | *Automatically created by projen via the "upgrade-cdklabs-projen-project-types-main" workflow* 76 | branch: github-actions/upgrade-cdklabs-projen-project-types-main 77 | title: "chore(deps): upgrade cdklabs-projen-project-types" 78 | labels: auto-approve 79 | body: |- 80 | Upgrades project dependencies. See details in [workflow run]. 81 | 82 | [Workflow Run]: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 83 | 84 | ------ 85 | 86 | *Automatically created by projen via the "upgrade-cdklabs-projen-project-types-main" workflow* 87 | author: github-actions 88 | committer: github-actions 89 | signoff: true 90 | -------------------------------------------------------------------------------- /.github/workflows/upgrade-dev-deps-main.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: upgrade-dev-deps-main 4 | on: 5 | workflow_dispatch: {} 6 | schedule: 7 | - cron: 0 18 * * 1 8 | jobs: 9 | upgrade: 10 | name: Upgrade 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: read 14 | outputs: 15 | patch_created: ${{ steps.create_patch.outputs.patch_created }} 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4 19 | with: 20 | ref: main 21 | - name: Setup Node.js 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: lts/* 25 | - name: Install dependencies 26 | run: yarn install --check-files --frozen-lockfile 27 | - name: Upgrade dependencies 28 | run: npx projen upgrade-dev-deps 29 | - name: Find mutations 30 | id: create_patch 31 | run: |- 32 | git add . 33 | git diff --staged --patch --exit-code > repo.patch || echo "patch_created=true" >> $GITHUB_OUTPUT 34 | working-directory: ./ 35 | - name: Upload patch 36 | if: steps.create_patch.outputs.patch_created 37 | uses: actions/upload-artifact@v4.4.0 38 | with: 39 | name: repo.patch 40 | path: repo.patch 41 | overwrite: true 42 | pr: 43 | name: Create Pull Request 44 | needs: upgrade 45 | runs-on: ubuntu-latest 46 | permissions: 47 | contents: read 48 | if: ${{ needs.upgrade.outputs.patch_created }} 49 | steps: 50 | - name: Checkout 51 | uses: actions/checkout@v4 52 | with: 53 | ref: main 54 | - name: Download patch 55 | uses: actions/download-artifact@v4 56 | with: 57 | name: repo.patch 58 | path: ${{ runner.temp }} 59 | - name: Apply patch 60 | run: '[ -s ${{ runner.temp }}/repo.patch ] && git apply ${{ runner.temp }}/repo.patch || echo "Empty patch. Skipping."' 61 | - name: Set git identity 62 | run: |- 63 | git config user.name "github-actions" 64 | git config user.email "github-actions@github.com" 65 | - name: Create Pull Request 66 | id: create-pr 67 | uses: peter-evans/create-pull-request@v6 68 | with: 69 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }} 70 | commit-message: |- 71 | chore(deps): upgrade dev dependencies 72 | 73 | Upgrades project dependencies. See details in [workflow run]. 74 | 75 | [Workflow Run]: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 76 | 77 | ------ 78 | 79 | *Automatically created by projen via the "upgrade-dev-deps-main" workflow* 80 | branch: github-actions/upgrade-dev-deps-main 81 | title: "chore(deps): upgrade dev dependencies" 82 | labels: auto-approve 83 | body: |- 84 | Upgrades project dependencies. See details in [workflow run]. 85 | 86 | [Workflow Run]: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 87 | 88 | ------ 89 | 90 | *Automatically created by projen via the "upgrade-dev-deps-main" workflow* 91 | author: github-actions 92 | committer: github-actions 93 | signoff: true 94 | -------------------------------------------------------------------------------- /.github/workflows/upgrade-main.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: upgrade-main 4 | on: 5 | workflow_dispatch: {} 6 | schedule: 7 | - cron: 0 18 * * 1 8 | jobs: 9 | upgrade: 10 | name: Upgrade 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: read 14 | outputs: 15 | patch_created: ${{ steps.create_patch.outputs.patch_created }} 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4 19 | with: 20 | ref: main 21 | - name: Setup Node.js 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: lts/* 25 | - name: Install dependencies 26 | run: yarn install --check-files --frozen-lockfile 27 | - name: Upgrade dependencies 28 | run: npx projen upgrade 29 | - name: Find mutations 30 | id: create_patch 31 | run: |- 32 | git add . 33 | git diff --staged --patch --exit-code > repo.patch || echo "patch_created=true" >> $GITHUB_OUTPUT 34 | working-directory: ./ 35 | - name: Upload patch 36 | if: steps.create_patch.outputs.patch_created 37 | uses: actions/upload-artifact@v4.4.0 38 | with: 39 | name: repo.patch 40 | path: repo.patch 41 | overwrite: true 42 | pr: 43 | name: Create Pull Request 44 | needs: upgrade 45 | runs-on: ubuntu-latest 46 | permissions: 47 | contents: read 48 | if: ${{ needs.upgrade.outputs.patch_created }} 49 | steps: 50 | - name: Checkout 51 | uses: actions/checkout@v4 52 | with: 53 | ref: main 54 | - name: Download patch 55 | uses: actions/download-artifact@v4 56 | with: 57 | name: repo.patch 58 | path: ${{ runner.temp }} 59 | - name: Apply patch 60 | run: '[ -s ${{ runner.temp }}/repo.patch ] && git apply ${{ runner.temp }}/repo.patch || echo "Empty patch. Skipping."' 61 | - name: Set git identity 62 | run: |- 63 | git config user.name "github-actions" 64 | git config user.email "github-actions@github.com" 65 | - name: Create Pull Request 66 | id: create-pr 67 | uses: peter-evans/create-pull-request@v6 68 | with: 69 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }} 70 | commit-message: |- 71 | fix(deps): upgrade dependencies 72 | 73 | Upgrades project dependencies. See details in [workflow run]. 74 | 75 | [Workflow Run]: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 76 | 77 | ------ 78 | 79 | *Automatically created by projen via the "upgrade-main" workflow* 80 | branch: github-actions/upgrade-main 81 | title: "fix(deps): upgrade dependencies" 82 | labels: auto-approve 83 | body: |- 84 | Upgrades project dependencies. See details in [workflow run]. 85 | 86 | [Workflow Run]: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 87 | 88 | ------ 89 | 90 | *Automatically created by projen via the "upgrade-main" workflow* 91 | author: github-actions 92 | committer: github-actions 93 | signoff: true 94 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | !/.gitattributes 3 | !/.projen/tasks.json 4 | !/.projen/deps.json 5 | !/.projen/files.json 6 | !/.github/workflows/pull-request-lint.yml 7 | !/.github/workflows/auto-approve.yml 8 | !/package.json 9 | !/LICENSE 10 | !/.npmignore 11 | logs 12 | *.log 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | lerna-debug.log* 17 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | lib-cov 23 | coverage 24 | *.lcov 25 | .nyc_output 26 | build/Release 27 | node_modules/ 28 | jspm_packages/ 29 | *.tsbuildinfo 30 | .eslintcache 31 | *.tgz 32 | .yarn-integrity 33 | .cache 34 | /test-reports/ 35 | junit.xml 36 | /coverage/ 37 | !/.github/workflows/build.yml 38 | /dist/changelog.md 39 | /dist/version.txt 40 | !/.github/workflows/release.yml 41 | !/.mergify.yml 42 | !/.github/pull_request_template.md 43 | !/test/ 44 | !/tsconfig.json 45 | !/tsconfig.dev.json 46 | !/src/ 47 | /lib 48 | /dist/ 49 | !/.eslintrc.json 50 | !/.github/workflows/upgrade-cdklabs-projen-project-types-main.yml 51 | !/.github/workflows/upgrade-main.yml 52 | !/.github/workflows/upgrade-dev-deps-main.yml 53 | !/.projenrc.ts 54 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | queue_rules: 4 | - name: default 5 | update_method: merge 6 | conditions: 7 | - "#approved-reviews-by>=1" 8 | - -label~=(do-not-merge) 9 | - status-success=build 10 | merge_method: squash 11 | commit_message_template: |- 12 | {{ title }} (#{{ number }}) 13 | 14 | {{ body }} 15 | pull_request_rules: 16 | - name: Automatic merge on approval and successful build 17 | actions: 18 | delete_head_branch: {} 19 | queue: 20 | name: default 21 | conditions: 22 | - "#approved-reviews-by>=1" 23 | - -label~=(do-not-merge) 24 | - status-success=build 25 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | /.projen/ 3 | /test-reports/ 4 | junit.xml 5 | /coverage/ 6 | permissions-backup.acl 7 | /dist/changelog.md 8 | /dist/version.txt 9 | /.mergify.yml 10 | /test/ 11 | /tsconfig.dev.json 12 | /src/ 13 | !/lib/ 14 | !/lib/**/*.js 15 | !/lib/**/*.d.ts 16 | dist 17 | /tsconfig.json 18 | /.github/ 19 | /.vscode/ 20 | /.idea/ 21 | /.projenrc.js 22 | tsconfig.tsbuildinfo 23 | /.eslintrc.json 24 | /.gitattributes 25 | /.projenrc.ts 26 | /projenrc 27 | -------------------------------------------------------------------------------- /.projen/deps.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | { 4 | "name": "@stylistic/eslint-plugin", 5 | "version": "^2", 6 | "type": "build" 7 | }, 8 | { 9 | "name": "@types/jest", 10 | "type": "build" 11 | }, 12 | { 13 | "name": "@types/node", 14 | "version": "^18", 15 | "type": "build" 16 | }, 17 | { 18 | "name": "@typescript-eslint/eslint-plugin", 19 | "version": "^8", 20 | "type": "build" 21 | }, 22 | { 23 | "name": "@typescript-eslint/parser", 24 | "version": "^8", 25 | "type": "build" 26 | }, 27 | { 28 | "name": "cdklabs-projen-project-types", 29 | "type": "build" 30 | }, 31 | { 32 | "name": "commit-and-tag-version", 33 | "version": "^12", 34 | "type": "build" 35 | }, 36 | { 37 | "name": "constructs", 38 | "version": "^10.0.0", 39 | "type": "build" 40 | }, 41 | { 42 | "name": "eslint-import-resolver-typescript", 43 | "type": "build" 44 | }, 45 | { 46 | "name": "eslint-plugin-import", 47 | "type": "build" 48 | }, 49 | { 50 | "name": "eslint", 51 | "version": "^9", 52 | "type": "build" 53 | }, 54 | { 55 | "name": "jest", 56 | "type": "build" 57 | }, 58 | { 59 | "name": "jest-junit", 60 | "version": "^16", 61 | "type": "build" 62 | }, 63 | { 64 | "name": "projen", 65 | "type": "build" 66 | }, 67 | { 68 | "name": "ts-jest", 69 | "type": "build" 70 | }, 71 | { 72 | "name": "ts-node", 73 | "type": "build" 74 | }, 75 | { 76 | "name": "typescript", 77 | "type": "build" 78 | }, 79 | { 80 | "name": "aws-sdk", 81 | "type": "runtime" 82 | }, 83 | { 84 | "name": "yaml", 85 | "type": "runtime" 86 | } 87 | ], 88 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 89 | } 90 | -------------------------------------------------------------------------------- /.projen/files.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | ".eslintrc.json", 4 | ".gitattributes", 5 | ".github/pull_request_template.md", 6 | ".github/workflows/auto-approve.yml", 7 | ".github/workflows/build.yml", 8 | ".github/workflows/pull-request-lint.yml", 9 | ".github/workflows/release.yml", 10 | ".github/workflows/upgrade-cdklabs-projen-project-types-main.yml", 11 | ".github/workflows/upgrade-dev-deps-main.yml", 12 | ".github/workflows/upgrade-main.yml", 13 | ".gitignore", 14 | ".mergify.yml", 15 | ".npmignore", 16 | ".projen/deps.json", 17 | ".projen/files.json", 18 | ".projen/tasks.json", 19 | "LICENSE", 20 | "tsconfig.dev.json", 21 | "tsconfig.json" 22 | ], 23 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 24 | } 25 | -------------------------------------------------------------------------------- /.projen/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "tasks": { 3 | "build": { 4 | "name": "build", 5 | "description": "Full release build", 6 | "steps": [ 7 | { 8 | "spawn": "default" 9 | }, 10 | { 11 | "spawn": "pre-compile" 12 | }, 13 | { 14 | "spawn": "compile" 15 | }, 16 | { 17 | "spawn": "post-compile" 18 | }, 19 | { 20 | "spawn": "test" 21 | }, 22 | { 23 | "spawn": "package" 24 | } 25 | ] 26 | }, 27 | "bump": { 28 | "name": "bump", 29 | "description": "Bumps version based on latest git tag and generates a changelog entry", 30 | "env": { 31 | "OUTFILE": "package.json", 32 | "CHANGELOG": "dist/changelog.md", 33 | "BUMPFILE": "dist/version.txt", 34 | "RELEASETAG": "dist/releasetag.txt", 35 | "RELEASE_TAG_PREFIX": "", 36 | "BUMP_PACKAGE": "commit-and-tag-version@^12", 37 | "RELEASABLE_COMMITS": "git log --no-merges --oneline $LATEST_TAG..HEAD -E --grep \"^(feat|fix){1}(\\([^()[:space:]]+\\))?(!)?:[[:blank:]]+.+\"" 38 | }, 39 | "steps": [ 40 | { 41 | "builtin": "release/bump-version" 42 | } 43 | ], 44 | "condition": "git log --oneline -1 | grep -qv \"chore(release):\"" 45 | }, 46 | "clobber": { 47 | "name": "clobber", 48 | "description": "hard resets to HEAD of origin and cleans the local repo", 49 | "env": { 50 | "BRANCH": "$(git branch --show-current)" 51 | }, 52 | "steps": [ 53 | { 54 | "exec": "git checkout -b scratch", 55 | "name": "save current HEAD in \"scratch\" branch" 56 | }, 57 | { 58 | "exec": "git checkout $BRANCH" 59 | }, 60 | { 61 | "exec": "git fetch origin", 62 | "name": "fetch latest changes from origin" 63 | }, 64 | { 65 | "exec": "git reset --hard origin/$BRANCH", 66 | "name": "hard reset to origin commit" 67 | }, 68 | { 69 | "exec": "git clean -fdx", 70 | "name": "clean all untracked files" 71 | }, 72 | { 73 | "say": "ready to rock! (unpushed commits are under the \"scratch\" branch)" 74 | } 75 | ], 76 | "condition": "git diff --exit-code > /dev/null" 77 | }, 78 | "compile": { 79 | "name": "compile", 80 | "description": "Only compile", 81 | "steps": [ 82 | { 83 | "exec": "tsc --build" 84 | } 85 | ] 86 | }, 87 | "default": { 88 | "name": "default", 89 | "description": "Synthesize project files", 90 | "steps": [ 91 | { 92 | "exec": "ts-node --project tsconfig.dev.json .projenrc.ts" 93 | } 94 | ] 95 | }, 96 | "eject": { 97 | "name": "eject", 98 | "description": "Remove projen from the project", 99 | "env": { 100 | "PROJEN_EJECTING": "true" 101 | }, 102 | "steps": [ 103 | { 104 | "spawn": "default" 105 | } 106 | ] 107 | }, 108 | "eslint": { 109 | "name": "eslint", 110 | "description": "Runs eslint against the codebase", 111 | "env": { 112 | "ESLINT_USE_FLAT_CONFIG": "false" 113 | }, 114 | "steps": [ 115 | { 116 | "exec": "eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern $@ src test build-tools projenrc .projenrc.ts", 117 | "receiveArgs": true 118 | } 119 | ] 120 | }, 121 | "install": { 122 | "name": "install", 123 | "description": "Install project dependencies and update lockfile (non-frozen)", 124 | "steps": [ 125 | { 126 | "exec": "yarn install --check-files" 127 | } 128 | ] 129 | }, 130 | "install:ci": { 131 | "name": "install:ci", 132 | "description": "Install project dependencies using frozen lockfile", 133 | "steps": [ 134 | { 135 | "exec": "yarn install --check-files --frozen-lockfile" 136 | } 137 | ] 138 | }, 139 | "package": { 140 | "name": "package", 141 | "description": "Creates the distribution package", 142 | "steps": [ 143 | { 144 | "exec": "mkdir -p dist/js" 145 | }, 146 | { 147 | "exec": "npm pack --pack-destination dist/js" 148 | } 149 | ] 150 | }, 151 | "post-compile": { 152 | "name": "post-compile", 153 | "description": "Runs after successful compilation" 154 | }, 155 | "post-upgrade": { 156 | "name": "post-upgrade", 157 | "description": "Runs after upgrading dependencies" 158 | }, 159 | "pre-compile": { 160 | "name": "pre-compile", 161 | "description": "Prepare the project for compilation" 162 | }, 163 | "release": { 164 | "name": "release", 165 | "description": "Prepare a release from \"main\" branch", 166 | "env": { 167 | "RELEASE": "true", 168 | "MAJOR": "1" 169 | }, 170 | "steps": [ 171 | { 172 | "exec": "rm -fr dist" 173 | }, 174 | { 175 | "spawn": "bump" 176 | }, 177 | { 178 | "spawn": "build" 179 | }, 180 | { 181 | "spawn": "unbump" 182 | }, 183 | { 184 | "exec": "git diff --ignore-space-at-eol --exit-code" 185 | } 186 | ] 187 | }, 188 | "test": { 189 | "name": "test", 190 | "description": "Run tests", 191 | "steps": [ 192 | { 193 | "exec": "jest --passWithNoTests --updateSnapshot", 194 | "receiveArgs": true 195 | }, 196 | { 197 | "spawn": "eslint" 198 | } 199 | ] 200 | }, 201 | "test:watch": { 202 | "name": "test:watch", 203 | "description": "Run jest in watch mode", 204 | "steps": [ 205 | { 206 | "exec": "jest --watch" 207 | } 208 | ] 209 | }, 210 | "unbump": { 211 | "name": "unbump", 212 | "description": "Restores version to 0.0.0", 213 | "env": { 214 | "OUTFILE": "package.json", 215 | "CHANGELOG": "dist/changelog.md", 216 | "BUMPFILE": "dist/version.txt", 217 | "RELEASETAG": "dist/releasetag.txt", 218 | "RELEASE_TAG_PREFIX": "", 219 | "BUMP_PACKAGE": "commit-and-tag-version@^12", 220 | "RELEASABLE_COMMITS": "git log --no-merges --oneline $LATEST_TAG..HEAD -E --grep \"^(feat|fix){1}(\\([^()[:space:]]+\\))?(!)?:[[:blank:]]+.+\"" 221 | }, 222 | "steps": [ 223 | { 224 | "builtin": "release/reset-version" 225 | } 226 | ] 227 | }, 228 | "upgrade": { 229 | "name": "upgrade", 230 | "description": "upgrade dependencies", 231 | "env": { 232 | "CI": "0" 233 | }, 234 | "steps": [ 235 | { 236 | "exec": "npx npm-check-updates@16 --upgrade --target=minor --peer --no-deprecated --dep=prod --filter=aws-sdk,yaml" 237 | }, 238 | { 239 | "exec": "yarn install --check-files" 240 | }, 241 | { 242 | "exec": "yarn upgrade aws-sdk yaml" 243 | }, 244 | { 245 | "exec": "npx projen" 246 | }, 247 | { 248 | "spawn": "post-upgrade" 249 | } 250 | ] 251 | }, 252 | "upgrade-cdklabs-projen-project-types": { 253 | "name": "upgrade-cdklabs-projen-project-types", 254 | "description": "upgrade cdklabs-projen-project-types", 255 | "env": { 256 | "CI": "0" 257 | }, 258 | "steps": [ 259 | { 260 | "exec": "npx npm-check-updates@16 --upgrade --target=latest --peer --no-deprecated --dep=dev,peer,prod,optional --filter=cdklabs-projen-project-types,projen" 261 | }, 262 | { 263 | "exec": "yarn install --check-files" 264 | }, 265 | { 266 | "exec": "yarn upgrade cdklabs-projen-project-types projen" 267 | }, 268 | { 269 | "exec": "npx projen" 270 | }, 271 | { 272 | "spawn": "post-upgrade" 273 | } 274 | ] 275 | }, 276 | "upgrade-dev-deps": { 277 | "name": "upgrade-dev-deps", 278 | "description": "upgrade dev dependencies", 279 | "env": { 280 | "CI": "0" 281 | }, 282 | "steps": [ 283 | { 284 | "exec": "npx npm-check-updates@16 --upgrade --target=minor --peer --no-deprecated --dep=dev --filter=@types/jest,eslint-import-resolver-typescript,eslint-plugin-import,jest,ts-jest,ts-node,typescript" 285 | }, 286 | { 287 | "exec": "yarn install --check-files" 288 | }, 289 | { 290 | "exec": "yarn upgrade @stylistic/eslint-plugin @types/jest @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser commit-and-tag-version constructs eslint-import-resolver-typescript eslint-plugin-import eslint jest jest-junit ts-jest ts-node typescript" 291 | }, 292 | { 293 | "exec": "npx projen" 294 | }, 295 | { 296 | "spawn": "post-upgrade" 297 | } 298 | ] 299 | }, 300 | "watch": { 301 | "name": "watch", 302 | "description": "Watch & compile in the background", 303 | "steps": [ 304 | { 305 | "exec": "tsc --build -w" 306 | } 307 | ] 308 | } 309 | }, 310 | "env": { 311 | "PATH": "$(npx -c \"node --print process.env.PATH\")" 312 | }, 313 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 314 | } 315 | -------------------------------------------------------------------------------- /.projenrc.ts: -------------------------------------------------------------------------------- 1 | import { CdklabsTypeScriptProject } from 'cdklabs-projen-project-types'; 2 | 3 | const project = new CdklabsTypeScriptProject({ 4 | setNodeEngineVersion: false, 5 | stability: 'stable', 6 | private: false, 7 | defaultReleaseBranch: 'main', 8 | name: 'awscdk-v1-stack-finder', 9 | projenrcTs: true, 10 | majorVersion: 1, 11 | 12 | bin: { 13 | 'awscdk-v1-stack-finder': 'bin/awscdk-v1-stack-finder', 14 | }, 15 | 16 | releaseToNpm: true, 17 | sampleCode: false, 18 | deps: [ 19 | 'aws-sdk', 20 | 'yaml', 21 | ], 22 | // description: undefined, /* The description is just a string that helps people understand the purpose of the package. */ 23 | // devDeps: [], /* Build dependencies for this module. */ 24 | // packageName: undefined, /* The "name" in package.json. */ 25 | }); 26 | project.synth(); -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## AWS CDK V1 Stack Finder 2 | 3 | Command line tool to identify stacks that were deployed with AWS CDK V1 (as opposed to V2). 4 | You can use this to help with the migration process from V1 to V2. 5 | 6 | ## Usage 7 | 8 | Configure you AWS credentials as normal, and run: 9 | 10 | ```console 11 | npx awscdk-v1-stack-finder 12 | ``` 13 | 14 | To use a profile, run: 15 | 16 | ```console 17 | AWS_SDK_LOAD_CONFIG=1 AWS_PROFILE= npx awscdk-v1-stack-finder 18 | ``` 19 | 20 | By default, this will scan all regions in your account (apart from `us-iso-east-1` and `us-iso-west-1`) 21 | and print the stacks that were deployed with AWS CDK V1: 22 | 23 | ```console 24 | ❯ npx awscdk-v1-stack-finder 25 | us-east-1: fetching stacks 26 | us-east-1: complete 27 | eu-west-1: fetching stacks 28 | eu-west-1: complete 29 | us-west-1: fetching stacks 30 | us-west-1: complete 31 | ap-southeast-1: fetching stacks 32 | ap-southeast-1: complete 33 | ap-northeast-1: fetching stacks 34 | ap-northeast-1: complete 35 | ... 36 | ... 37 | ... 38 | 39 | Found 12 AWS CDK V1 stacks: 40 | 41 | name: us-east-1-v1-CdkStack-5 | id: arn:aws:cloudformation:us-east-1:123456789999:stack/us-east-1-v1-CdkStack-5/8dba4af0-ec83-11ec-b731-12920c137c03 42 | name: us-east-1-v1-CdkStack-4 | id: arn:aws:cloudformation:us-east-1:123456789999:stack/us-east-1-v1-CdkStack-4/543baa30-ec83-11ec-8b26-0e62bae32ce5 43 | name: us-east-1-v1-CdkStack-3 | id: arn:aws:cloudformation:us-east-1:123456789999:stack/us-east-1-v1-CdkStack-3/1df2e010-ec83-11ec-abb7-0ed4b803f023 44 | name: us-east-1-v1-CdkStack-2 | id: arn:aws:cloudformation:us-east-1:123456789999:stack/us-east-1-v1-CdkStack-2/e7706850-ec82-11ec-ab94-0a18c92d7bc5 45 | name: us-east-1-v1-CdkStack-1 | id: arn:aws:cloudformation:us-east-1:123456789999:stack/us-east-1-v1-CdkStack-1/adec4950-ec82-11ec-8704-0a59224ca017 46 | name: us-east-1-v1-CdkStack-0 | id: arn:aws:cloudformation:us-east-1:123456789999:stack/us-east-1-v1-CdkStack-0/7421ab70-ec82-11ec-8f7a-0ad10107c705 47 | name: us-east-2-v1-CdkStack-5 | id: arn:aws:cloudformation:us-east-2:123456789999:stack/us-east-2-v1-CdkStack-5/da55d860-ec84-11ec-b1a9-06f24f6851ca 48 | name: us-east-2-v1-CdkStack-4 | id: arn:aws:cloudformation:us-east-2:123456789999:stack/us-east-2-v1-CdkStack-4/a36adad0-ec84-11ec-b55d-0a7b3c2a4574 49 | name: us-east-2-v1-CdkStack-3 | id: arn:aws:cloudformation:us-east-2:123456789999:stack/us-east-2-v1-CdkStack-3/693f0a20-ec84-11ec-a89c-0a27eef80a54 50 | name: us-east-2-v1-CdkStack-2 | id: arn:aws:cloudformation:us-east-2:123456789999:stack/us-east-2-v1-CdkStack-2/32393190-ec84-11ec-ad0b-0a46add5eab0 51 | name: us-east-2-v1-CdkStack-1 | id: arn:aws:cloudformation:us-east-2:123456789999:stack/us-east-2-v1-CdkStack-1/fb30c0f0-ec83-11ec-94ea-02306812ac04 52 | name: us-east-2-v1-CdkStack-0 | id: arn:aws:cloudformation:us-east-2:123456789999:stack/us-east-2-v1-CdkStack-0/c41febe0-ec83-11ec-8d9d-020bb84204d2 53 | ``` 54 | 55 | You can also pass explicit regions using the `AWS_REGIONS` environment variable: 56 | 57 | ```console 58 | ❯ AWS_REGIONS=us-east-1,us-east-2 npx awscdk-v1-stack-finder 59 | us-east-1: fetching stacks 60 | us-east-1: complete 61 | us-east-2: fetching stacks 62 | us-east-2: complete 63 | 64 | Found 12 AWS CDK V1 stacks: 65 | 66 | name: us-east-1-v1-CdkStack-5 | id: arn:aws:cloudformation:us-east-1:123456789999:stack/us-east-1-v1-CdkStack-5/8dba4af0-ec83-11ec-b731-12920c137c03 67 | name: us-east-1-v1-CdkStack-4 | id: arn:aws:cloudformation:us-east-1:123456789999:stack/us-east-1-v1-CdkStack-4/543baa30-ec83-11ec-8b26-0e62bae32ce5 68 | name: us-east-1-v1-CdkStack-3 | id: arn:aws:cloudformation:us-east-1:123456789999:stack/us-east-1-v1-CdkStack-3/1df2e010-ec83-11ec-abb7-0ed4b803f023 69 | name: us-east-1-v1-CdkStack-2 | id: arn:aws:cloudformation:us-east-1:123456789999:stack/us-east-1-v1-CdkStack-2/e7706850-ec82-11ec-ab94-0a18c92d7bc5 70 | name: us-east-1-v1-CdkStack-1 | id: arn:aws:cloudformation:us-east-1:123456789999:stack/us-east-1-v1-CdkStack-1/adec4950-ec82-11ec-8704-0a59224ca017 71 | name: us-east-1-v1-CdkStack-0 | id: arn:aws:cloudformation:us-east-1:123456789999:stack/us-east-1-v1-CdkStack-0/7421ab70-ec82-11ec-8f7a-0ad10107c705 72 | name: us-east-2-v1-CdkStack-5 | id: arn:aws:cloudformation:us-east-2:123456789999:stack/us-east-2-v1-CdkStack-5/da55d860-ec84-11ec-b1a9-06f24f6851ca 73 | name: us-east-2-v1-CdkStack-4 | id: arn:aws:cloudformation:us-east-2:123456789999:stack/us-east-2-v1-CdkStack-4/a36adad0-ec84-11ec-b55d-0a7b3c2a4574 74 | name: us-east-2-v1-CdkStack-3 | id: arn:aws:cloudformation:us-east-2:123456789999:stack/us-east-2-v1-CdkStack-3/693f0a20-ec84-11ec-a89c-0a27eef80a54 75 | name: us-east-2-v1-CdkStack-2 | id: arn:aws:cloudformation:us-east-2:123456789999:stack/us-east-2-v1-CdkStack-2/32393190-ec84-11ec-ad0b-0a46add5eab0 76 | name: us-east-2-v1-CdkStack-1 | id: arn:aws:cloudformation:us-east-2:123456789999:stack/us-east-2-v1-CdkStack-1/fb30c0f0-ec83-11ec-94ea-02306812ac04 77 | name: us-east-2-v1-CdkStack-0 | id: arn:aws:cloudformation:us-east-2:123456789999:stack/us-east-2-v1-CdkStack-0/c41febe0-ec83-11ec-8d9d-020bb84204d2 78 | ``` 79 | 80 | ## Security 81 | 82 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 83 | 84 | ## License 85 | 86 | This project is licensed under the Apache-2.0 License. 87 | 88 | -------------------------------------------------------------------------------- /bin/awscdk-v1-stack-finder: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // eslint-disable-next-line @typescript-eslint/no-require-imports 3 | require('../lib/cli.js'); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "awscdk-v1-stack-finder", 3 | "repository": { 4 | "type": "git", 5 | "url": "https://github.com/cdklabs/awscdk-v1-stack-finder.git" 6 | }, 7 | "bin": { 8 | "awscdk-v1-stack-finder": "bin/awscdk-v1-stack-finder" 9 | }, 10 | "scripts": { 11 | "build": "npx projen build", 12 | "bump": "npx projen bump", 13 | "clobber": "npx projen clobber", 14 | "compile": "npx projen compile", 15 | "default": "npx projen default", 16 | "eject": "npx projen eject", 17 | "eslint": "npx projen eslint", 18 | "package": "npx projen package", 19 | "post-compile": "npx projen post-compile", 20 | "post-upgrade": "npx projen post-upgrade", 21 | "pre-compile": "npx projen pre-compile", 22 | "release": "npx projen release", 23 | "test": "npx projen test", 24 | "test:watch": "npx projen test:watch", 25 | "unbump": "npx projen unbump", 26 | "upgrade": "npx projen upgrade", 27 | "upgrade-cdklabs-projen-project-types": "npx projen upgrade-cdklabs-projen-project-types", 28 | "upgrade-dev-deps": "npx projen upgrade-dev-deps", 29 | "watch": "npx projen watch", 30 | "projen": "npx projen" 31 | }, 32 | "author": { 33 | "name": "Amazon Web Services", 34 | "email": "aws-cdk-dev@amazon.com", 35 | "organization": true 36 | }, 37 | "devDependencies": { 38 | "@stylistic/eslint-plugin": "^2", 39 | "@types/jest": "^28.1.8", 40 | "@types/node": "^18", 41 | "@typescript-eslint/eslint-plugin": "^8", 42 | "@typescript-eslint/parser": "^8", 43 | "cdklabs-projen-project-types": "^0.3.1", 44 | "commit-and-tag-version": "^12", 45 | "constructs": "^10.0.0", 46 | "eslint": "^9", 47 | "eslint-import-resolver-typescript": "^2.7.1", 48 | "eslint-plugin-import": "^2.31.0", 49 | "jest": "^27", 50 | "jest-junit": "^16", 51 | "projen": "^0.92.9", 52 | "ts-jest": "^27", 53 | "ts-node": "^10.9.2", 54 | "typescript": "^4.9.5" 55 | }, 56 | "dependencies": { 57 | "aws-sdk": "^2.1692.0", 58 | "yaml": "^2.8.0" 59 | }, 60 | "main": "lib/index.js", 61 | "license": "Apache-2.0", 62 | "publishConfig": { 63 | "access": "public" 64 | }, 65 | "version": "0.0.0", 66 | "jest": { 67 | "coverageProvider": "v8", 68 | "testMatch": [ 69 | "/@(src|test)/**/*(*.)@(spec|test).ts?(x)", 70 | "/@(src|test)/**/__tests__/**/*.ts?(x)", 71 | "/@(projenrc)/**/*(*.)@(spec|test).ts?(x)", 72 | "/@(projenrc)/**/__tests__/**/*.ts?(x)" 73 | ], 74 | "clearMocks": true, 75 | "collectCoverage": true, 76 | "coverageReporters": [ 77 | "json", 78 | "lcov", 79 | "clover", 80 | "cobertura", 81 | "text" 82 | ], 83 | "coverageDirectory": "coverage", 84 | "coveragePathIgnorePatterns": [ 85 | "/node_modules/" 86 | ], 87 | "testPathIgnorePatterns": [ 88 | "/node_modules/" 89 | ], 90 | "watchPathIgnorePatterns": [ 91 | "/node_modules/" 92 | ], 93 | "reporters": [ 94 | "default", 95 | [ 96 | "jest-junit", 97 | { 98 | "outputDirectory": "test-reports" 99 | } 100 | ] 101 | ], 102 | "preset": "ts-jest", 103 | "globals": { 104 | "ts-jest": { 105 | "tsconfig": "tsconfig.dev.json" 106 | } 107 | } 108 | }, 109 | "types": "lib/index.d.ts", 110 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 111 | } 112 | -------------------------------------------------------------------------------- /src/cli.ts: -------------------------------------------------------------------------------- 1 | import { find } from './index'; 2 | 3 | process.env.AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE = '1'; 4 | 5 | find().catch(e => { 6 | console.log(e); 7 | process.exit(1); 8 | }); -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import * as zlib from 'zlib'; 2 | import * as AWS from 'aws-sdk'; 3 | import * as YAML from 'yaml'; 4 | 5 | const ALL_STATUSES_EXCEPT_DELETE_COMPLETE = [ 6 | 'CREATE_IN_PROGRESS', 7 | 'CREATE_FAILED', 8 | 'CREATE_COMPLETE', 9 | 'ROLLBACK_IN_PROGRESS', 10 | 'ROLLBACK_FAILED', 11 | 'ROLLBACK_COMPLETE', 12 | 'DELETE_IN_PROGRESS', 13 | 'DELETE_FAILED', 14 | 'UPDATE_IN_PROGRESS', 15 | 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS', 16 | 'UPDATE_COMPLETE', 17 | 'UPDATE_FAILED', 18 | 'UPDATE_ROLLBACK_IN_PROGRESS', 19 | 'UPDATE_ROLLBACK_FAILED', 20 | 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS', 21 | 'UPDATE_ROLLBACK_COMPLETE', 22 | 'REVIEW_IN_PROGRESS', 23 | 'IMPORT_IN_PROGRESS', 24 | 'IMPORT_COMPLETE', 25 | 'IMPORT_ROLLBACK_IN_PROGRESS', 26 | 'IMPORT_ROLLBACK_FAILED', 27 | 'IMPORT_ROLLBACK_COMPLETE', 28 | ]; 29 | 30 | const DEFAULT_AWS_REGIONS = [ 31 | 'us-east-1', // US East (N. Virginia) 32 | 'eu-west-1', // Europe (Ireland) 33 | 'us-west-1', // US West (N. California) 34 | 'ap-southeast-1', // Asia Pacific (Singapore) 35 | 'ap-northeast-1', // Asia Pacific (Tokyo) 36 | 'us-gov-west-1', // AWS GovCloud (US-West) 37 | 'us-west-2', // US West (Oregon) 38 | 'sa-east-1', // South America (São Paulo) 39 | 'ap-southeast-2', // Asia Pacific (Sydney) 40 | 'cn-north-1', // China (Beijing) 41 | 'eu-central-1', // Europe (Frankfurt) 42 | 'ap-northeast-2', // Asia Pacific (Seoul) 43 | 'ap-south-1', // Asia Pacific (Mumbai) 44 | 'us-east-2', // US East (Ohio) 45 | 'ca-central-1', // Canada (Central) 46 | 'eu-west-2', // Europe (London) 47 | 'us-isob-east-1', // AWS ISO-B 48 | 'cn-northwest-1', // China (Ningxia) 49 | 'eu-west-3', // Europe (Paris) 50 | 'ap-northeast-3', // Asia Pacific (Osaka) 51 | 'us-gov-east-1', // AWS GovCloud (US-East) 52 | 'eu-north-1', // Europe (Stockholm) 53 | 'ap-east-1', // Asia Pacific (Hong Kong) 54 | 'me-south-1', // Middle East (Bahrain) 55 | 'eu-south-1', // Europe (Milan) 56 | 'af-south-1', // Africa (Cape Town) 57 | 'eu-south-2', // Europe (Spain) 58 | 'ap-southeast-3', // Asia Pacific (Jakarta) 29 59 | 'me-central-1', // Middle East (UAE) 60 | 'eu-central-2', // Europe (Zurich) 61 | 'ap-south-2', // Asia Pacific (Hyderabad) 62 | 'ap-southeast-4', // Asia Pacific (Melbourne) 63 | 64 | // these regions never return the listStacks call for some reason 65 | // and block the process forever. 66 | 67 | // 'us-iso-east-1', // AWS ISO 68 | // 'us-iso-west-1', // US ISO West 69 | 70 | ]; 71 | 72 | export async function find() { 73 | 74 | const stacks: string[] = []; 75 | 76 | const regions = process.env.AWS_REGIONS ? (process.env.AWS_REGIONS.split(',')) : DEFAULT_AWS_REGIONS; 77 | 78 | for (const region of regions) { 79 | 80 | const cloudformation = new AWS.CloudFormation({ region: region }); 81 | const response = await listStacks(cloudformation, region); 82 | await processListStacksResponse(response, cloudformation, region, stacks); 83 | console.log(`${region}: complete`); 84 | } 85 | 86 | console.log(''); 87 | 88 | if (stacks.length === 0) { 89 | console.log('No unsupported AWS CDK stacks found'); 90 | } else { 91 | console.log(`Found ${stacks.length} stacks produced by an unsupported AWS CDK version:`); 92 | console.log(''); 93 | for (const stack of stacks) { 94 | console.log(stack); 95 | } 96 | } 97 | 98 | } 99 | 100 | async function listStacks( 101 | cloudformation: AWS.CloudFormation, 102 | region: string, 103 | nextToken?: AWS.CloudFormation.Types.NextToken, 104 | ): Promise { 105 | console.log(`${region}: fetching stacks ${nextToken ? `(token: ${nextToken})` : ''}`); 106 | try { 107 | const response = await cloudformation.listStacks({ 108 | StackStatusFilter: ALL_STATUSES_EXCEPT_DELETE_COMPLETE, 109 | NextToken: nextToken, 110 | }).promise(); 111 | return response; 112 | } catch (error: any) { 113 | console.error(`${region}: Failed to list stacks. Error: ${error.message}`); 114 | return {}; 115 | } 116 | } 117 | 118 | 119 | async function processListStacksResponse( 120 | response: AWS.CloudFormation.ListStacksOutput, 121 | cloudformation: AWS.CloudFormation, 122 | region: string, 123 | stacks: string[]) { 124 | if (!response) { 125 | return; 126 | } 127 | 128 | await findV1Stacks(response, cloudformation, region, stacks); 129 | 130 | if (response.NextToken) { 131 | // Note: This might be unnecessary, since the ListStacks API keeps 132 | // responses up to 1 MB in size all in one page. 133 | await processNextPage(response.NextToken, cloudformation, region, stacks); 134 | } 135 | } 136 | 137 | async function processNextPage(nextToken: string, cloudformation: AWS.CloudFormation, region: string, stacks: string[]) { 138 | console.log(`${region}: fetching stacks (page token ${nextToken})`); 139 | const nextPageResult = await listStacks(cloudformation, region, nextToken); 140 | console.log(`${region}: finished fetching stacks`); 141 | await processListStacksResponse(nextPageResult, cloudformation, region, stacks); 142 | } 143 | 144 | async function findV1Stacks( 145 | response: AWS.CloudFormation.Types.ListStacksOutput, 146 | cloudformation: AWS.CloudFormation, 147 | region: string, 148 | stacks: string[]) { 149 | 150 | for (const stack of response.StackSummaries ?? []) { 151 | try { 152 | const getTemplateResponse = await cloudformation.getTemplate({ 153 | StackName: stack.StackName, 154 | }).promise(); 155 | 156 | if (!getTemplateResponse.TemplateBody) { 157 | throw new Error('No template body found'); 158 | } 159 | 160 | let body: any; 161 | try { 162 | body = YAML.parse(getTemplateResponse.TemplateBody, { 163 | version: '1.1', 164 | // Don't complain about undefined !Ref tags (etc). This will not produce the right output, 165 | // but for the purposes of looking at metadata it doesn't matter. 166 | logLevel: 'silent', 167 | }); 168 | } catch (yamlErr) { 169 | throw new Error(`Template body parse error: ${yamlErr}`); 170 | } 171 | 172 | if (body.Resources.CDKMetadata) { 173 | let stackVersion: undefined | string; 174 | 175 | if (body.Resources.CDKMetadata.Properties?.Analytics) { 176 | const buf = Buffer.from(body.Resources.CDKMetadata.Properties.Analytics.split(':').splice(2)[0], 'base64'); 177 | const analyticsString = zlib.gunzipSync(buf).toString(); 178 | const constructInfo = decodePrefixEncodedString(analyticsString); 179 | // Strings look like `!.` 180 | const stackConstruct = constructInfo.find(x => x.endsWith('@aws-cdk/core.Stack') || x.endsWith('monocdk.Stack') || x.includes('!monocdk.') ); 181 | if (stackConstruct) { 182 | stackVersion = stackConstruct.split('!')[0]; 183 | } 184 | } 185 | 186 | // Before versions 1.93.0 and 2.0.0-alpha.10, the CDKMetadata resource had a different format. 187 | if (body.Resources.CDKMetadata.Properties?.Modules) { 188 | const modules = body.Resources.CDKMetadata.Properties.Modules.split(',') as string[]; 189 | // Strings look like `=` 190 | const coreModule = modules.find(m => m.startsWith('@aws-cdk/core=') || m.startsWith('monocdk=')); 191 | if (coreModule) { 192 | stackVersion = coreModule.split('=')[1]; 193 | } 194 | } 195 | 196 | if (stackVersion && (stackVersion.startsWith('1.') || stackVersion.startsWith('0.')) && stackVersion !== '0.0.0') { 197 | stacks.push(`name: ${stack.StackName} | version: ${stackVersion} | id: ${stack.StackId}`); 198 | } 199 | } 200 | } catch (e: any) { 201 | console.error(`${region}: ${stack.StackName}: ${e.message}`); 202 | continue; 203 | } 204 | } 205 | } 206 | 207 | /** 208 | * Explode the prefix-encoded string 209 | * 210 | * Example: 211 | * '1.90.0!aws-cdk-lib.{Stack,Construct,service.Resource},0.42.1!aws-cdk-lib-experiments.NewStuff' 212 | * 213 | * Becomes: 214 | * [1.90.0!aws-cdk-lib.Stack, 1.90.0!aws-cdk-lib.Construct, 1.90.0!aws-cdk-lib.service.Resource, 0.42.1!aws-cdk-lib-experiments.NewStuff] 215 | */ 216 | function decodePrefixEncodedString(x: string) { 217 | const ret = new Array(); 218 | const prefixes = new Array(); 219 | let current = new StringBuilder(); 220 | let i = 0; 221 | while (i < x.length) { 222 | switch (x[i]) { 223 | case ',': 224 | if (current.hasChars) { 225 | ret.push(prefixes.join('') + current.toString()); 226 | current = new StringBuilder(); 227 | } 228 | break; 229 | case '}': 230 | if (current.hasChars) { 231 | ret.push(prefixes.join('') + current.toString()); 232 | } 233 | current = new StringBuilder(); 234 | prefixes.pop(); 235 | break; 236 | case '{': 237 | prefixes.push(current.toString()); 238 | current = new StringBuilder(); 239 | break; 240 | default: 241 | current.append(x[i]); 242 | break; 243 | } 244 | 245 | i += 1; 246 | } 247 | if (current.hasChars) { 248 | ret.push(prefixes.join('') + current.toString()); 249 | } 250 | 251 | return ret; 252 | } 253 | 254 | class StringBuilder { 255 | private readonly parts = new Array(); 256 | constructor() { 257 | } 258 | 259 | public append(x: string) { 260 | this.parts.push(x); 261 | } 262 | 263 | public get hasChars() { 264 | return this.parts.length > 0; 265 | } 266 | 267 | public toString(): string { 268 | return this.parts.join(''); 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /tsconfig.dev.json: -------------------------------------------------------------------------------- 1 | // ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | { 3 | "compilerOptions": { 4 | "alwaysStrict": true, 5 | "declaration": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "inlineSourceMap": true, 9 | "inlineSources": true, 10 | "lib": [ 11 | "es2020" 12 | ], 13 | "module": "CommonJS", 14 | "noEmitOnError": false, 15 | "noFallthroughCasesInSwitch": true, 16 | "noImplicitAny": true, 17 | "noImplicitReturns": true, 18 | "noImplicitThis": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "resolveJsonModule": true, 22 | "strict": true, 23 | "strictNullChecks": true, 24 | "strictPropertyInitialization": true, 25 | "stripInternal": true, 26 | "target": "ES2020" 27 | }, 28 | "include": [ 29 | "src/**/*.ts", 30 | "test/**/*.ts", 31 | ".projenrc.ts", 32 | "projenrc/**/*.ts" 33 | ], 34 | "exclude": [ 35 | "node_modules" 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | // ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | { 3 | "compilerOptions": { 4 | "rootDir": "src", 5 | "outDir": "lib", 6 | "alwaysStrict": true, 7 | "declaration": true, 8 | "esModuleInterop": true, 9 | "experimentalDecorators": true, 10 | "inlineSourceMap": true, 11 | "inlineSources": true, 12 | "lib": [ 13 | "es2020" 14 | ], 15 | "module": "CommonJS", 16 | "noEmitOnError": false, 17 | "noFallthroughCasesInSwitch": true, 18 | "noImplicitAny": true, 19 | "noImplicitReturns": true, 20 | "noImplicitThis": true, 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | "resolveJsonModule": true, 24 | "strict": true, 25 | "strictNullChecks": true, 26 | "strictPropertyInitialization": true, 27 | "stripInternal": true, 28 | "target": "ES2020" 29 | }, 30 | "include": [ 31 | "src/**/*.ts" 32 | ], 33 | "exclude": [] 34 | } 35 | --------------------------------------------------------------------------------