@jjrawlins/cdk-diff-pr-github-action 0.0.1-beta → 0.0.1
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/.jsii +475 -33
- package/.mergify.yml +102 -0
- package/API.md +351 -11
- package/README.md +223 -39
- package/lib/CdkDiffIamTemplate.d.ts +3 -1
- package/lib/CdkDiffIamTemplate.js +10 -5
- package/lib/CdkDiffStackWorkflow.d.ts +2 -2
- package/lib/CdkDiffStackWorkflow.js +19 -20
- package/lib/CdkDriftDetectionWorkflow.d.ts +32 -0
- package/lib/CdkDriftDetectionWorkflow.js +281 -0
- package/lib/CdkDriftIamTemplate.d.ts +10 -0
- package/lib/CdkDriftIamTemplate.js +77 -0
- package/lib/bin/cdk-changeset-script.js +3 -3
- package/lib/bin/cdk-drift-detection-script.d.ts +15 -0
- package/lib/bin/cdk-drift-detection-script.js +196 -0
- package/lib/bin/detect-drift.js +162 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +3 -1
- package/package.json +7 -2
- package/sonar-project.properties +17 -0
- package/.junie/guidelines.md +0 -62
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/.jsii +0 -3917
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/.junie/guidelines.md +0 -62
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/.tool-versions +0 -3
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/API.md +0 -276
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/LICENSE +0 -202
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/README.md +0 -146
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/CdkDiffIamTemplate.d.ts +0 -8
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/CdkDiffIamTemplate.js +0 -96
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/CdkDiffStackWorkflow.d.ts +0 -22
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/CdkDiffStackWorkflow.js +0 -144
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/bin/cdk-changeset-script.d.ts +0 -9
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/bin/cdk-changeset-script.js +0 -256
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/bin/describe-cfn-changeset.js +0 -204
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/index.d.ts +0 -2
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/index.js +0 -19
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/package.json +0 -137
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/yalc.lock +0 -10
- package/.yalc/@jjrawlins/cdk-diff-pr-github-action/yalc.sig +0 -1
- package/lib/bin/describe-cfn-changeset.d.ts +0 -1
- package/lib/bin/describe-cfn-changeset.js +0 -204
- package/yalc.lock +0 -10
- /package/{.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/bin/describe-cfn-changeset.d.ts → lib/bin/detect-drift.d.ts} +0 -0
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
# cdk-diff-pr-github-action
|
|
2
|
-
|
|
3
|
-
A small Projen-based helper library that wires a GitHub workflow to create a CloudFormation Change Set for a CDK stack on every pull request, then comments the formatted diff back on the PR. It also provides a ready‑to‑deploy IAM template you can use to grant the minimal permissions required for the workflow to create and inspect change sets.
|
|
4
|
-
|
|
5
|
-
This package exposes two constructs:
|
|
6
|
-
|
|
7
|
-
- `CdkDiffStackWorkflow` — Generates one GitHub Actions workflow per stack that:
|
|
8
|
-
- Assumes your GitHub OIDC role
|
|
9
|
-
- Optionally chains into a separate CDK deploy role
|
|
10
|
-
- Runs `cdk deploy --no-execute` to create a change set
|
|
11
|
-
- Runs a generated script to render the change set as an HTML table and posts it to the PR and to the GitHub Step Summary
|
|
12
|
-
- Cleans up the change set
|
|
13
|
-
|
|
14
|
-
- `CdkDiffIamTemplate` — Emits a CloudFormation template file (`cdk-diff-workflow-iam-template.yaml`) containing an example IAM role policy with the minimal permissions to create, describe, and delete CloudFormation change sets and read common CDK bootstrap resources. You can launch this in your account and then reference the created role.
|
|
15
|
-
|
|
16
|
-
## Quick start
|
|
17
|
-
|
|
18
|
-
1) Add the constructs to your Projen project (in `.projenrc.ts`).
|
|
19
|
-
2) Synthesize with `npx projen`.
|
|
20
|
-
3) Commit the generated files.
|
|
21
|
-
4) Open a pull request — the workflow will create a change set and comment the diff.
|
|
22
|
-
|
|
23
|
-
## Usage: CdkDiffStackWorkflow
|
|
24
|
-
|
|
25
|
-
`CdkDiffStackWorkflow` renders a workflow per stack named `diff-<StackName>.yml` under `.github/workflows/`. It also generates a helper script at `.github/workflows/scripts/describe-cfn-changeset.ts` that formats the change set output and takes care of posting the PR comment and Step Summary.
|
|
26
|
-
|
|
27
|
-
Example `.projenrc.ts`:
|
|
28
|
-
|
|
29
|
-
```ts
|
|
30
|
-
import { awscdk } from 'projen';
|
|
31
|
-
import { CdkDiffStackWorkflow } from '@jjrawlins/cdk-diff-pr-github-action';
|
|
32
|
-
|
|
33
|
-
const project = new awscdk.AwsCdkConstructLibrary({
|
|
34
|
-
// ... your usual settings ...
|
|
35
|
-
name: 'my-lib',
|
|
36
|
-
defaultReleaseBranch: 'main',
|
|
37
|
-
cdkVersion: '2.85.0',
|
|
38
|
-
github: true,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
new CdkDiffStackWorkflow({
|
|
42
|
-
project,
|
|
43
|
-
// Stacks to diff on PRs
|
|
44
|
-
stacks: [
|
|
45
|
-
{
|
|
46
|
-
stackName: 'MyAppStack',
|
|
47
|
-
cdkDiffRoleToAssumeArn: 'arn:aws:iam::123456789012:role/cdk-diff-role',
|
|
48
|
-
cdkDiffRoleToAssumeRegion: 'us-east-1',
|
|
49
|
-
// Optional per‑stack OIDC override (if not using the defaults below)
|
|
50
|
-
// oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',
|
|
51
|
-
// oidcRegion: 'us-east-1',
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
// Default OIDC role/region used by all stacks unless overridden per‑stack
|
|
55
|
-
oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',
|
|
56
|
-
oidcRegion: 'us-east-1',
|
|
57
|
-
// Optional: Node version used in the workflow (default: '24.x')
|
|
58
|
-
// nodeVersion: '20.x',
|
|
59
|
-
// Optional: Yarn command to run CDK (default: 'cdk')
|
|
60
|
-
// cdkYarnCommand: 'cdk',
|
|
61
|
-
// Optional: Where to place the helper script
|
|
62
|
-
// scriptOutputPath: '.github/workflows/scripts/describe-cfn-changeset.ts',
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
project.synth();
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Required properties
|
|
69
|
-
- `project` (AwsCdkTypeScriptApp) — Your Projen project instance.
|
|
70
|
-
- `stacks` (array) — One entry per CDK stack you want a diff for.
|
|
71
|
-
- OIDC configuration: either
|
|
72
|
-
- Provide `oidcRoleArn` and `oidcRegion` at the top level, or
|
|
73
|
-
- Provide `oidcRoleArn` and `oidcRegion` on every stack item.
|
|
74
|
-
|
|
75
|
-
If neither the defaults nor all per‑stack values are supplied, the construct throws with a helpful error.
|
|
76
|
-
|
|
77
|
-
### Stack item fields
|
|
78
|
-
- `stackName` — The CDK stack name to create the change set for.
|
|
79
|
-
- `cdkDiffRoleToAssumeArn` — The ARN of the role used to create the change set (role chaining after OIDC).
|
|
80
|
-
- `cdkDiffRoleToAssumeRegion` — The region for that role.
|
|
81
|
-
- `oidcRoleArn` (optional) — Per‑stack override for the OIDC role.
|
|
82
|
-
- `oidcRegion` (optional) — Per‑stack override for the OIDC region.
|
|
83
|
-
|
|
84
|
-
### What gets generated
|
|
85
|
-
- `.github/workflows/diff-<StackName>.yml` — One workflow per stack, triggered on PR open/sync/reopen.
|
|
86
|
-
- `.github/workflows/scripts/describe-cfn-changeset.ts` — A helper script that:
|
|
87
|
-
- Polls `DescribeChangeSet` until terminal
|
|
88
|
-
- Filters out ignorable logical IDs or resource types using environment variables `IGNORE_LOGICAL_IDS` and `IGNORE_RESOURCE_TYPES`
|
|
89
|
-
- Renders an HTML table with actions, logical IDs, types, replacements, and changed properties
|
|
90
|
-
- Prints the HTML, appends to the GitHub Step Summary, and (if `GITHUB_TOKEN` and `GITHUB_COMMENT_URL` are present) posts a PR comment
|
|
91
|
-
|
|
92
|
-
### Environment variables used by the script
|
|
93
|
-
- `STACK_NAME` (required) — Stack name to describe.
|
|
94
|
-
- `CHANGE_SET_NAME` (default: same as `STACK_NAME`).
|
|
95
|
-
- `AWS_REGION` — Region for CloudFormation API calls. The workflow sets this via the credentials action.
|
|
96
|
-
- `GITHUB_TOKEN` (optional) — If set with `GITHUB_COMMENT_URL`, posts a PR comment.
|
|
97
|
-
- `GITHUB_COMMENT_URL` (optional) — PR comments URL.
|
|
98
|
-
- `GITHUB_STEP_SUMMARY` (optional) — When present, appends the HTML to the step summary file.
|
|
99
|
-
- `IGNORE_LOGICAL_IDS` (optional) — Comma‑separated logical IDs to ignore (default includes `CDKMetadata`).
|
|
100
|
-
- `IGNORE_RESOURCE_TYPES` (optional) — Comma‑separated resource types to ignore (e.g., `AWS::CDK::Metadata`).
|
|
101
|
-
|
|
102
|
-
## Usage: CdkDiffIamTemplate
|
|
103
|
-
|
|
104
|
-
Add `CdkDiffIamTemplate` to your Projen project to emit an example IAM template you can deploy in your account:
|
|
105
|
-
|
|
106
|
-
```ts
|
|
107
|
-
import { awscdk } from 'projen';
|
|
108
|
-
import { CdkDiffIamTemplate } from '@jjrawlins/cdk-diff-pr-github-action';
|
|
109
|
-
|
|
110
|
-
const project = new awscdk.AwsCdkConstructLibrary({
|
|
111
|
-
// ...
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
new CdkDiffIamTemplate({ project });
|
|
115
|
-
|
|
116
|
-
project.synth();
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
This will write `cdk-diff-workflow-iam-template.yaml` at the project root. The template defines:
|
|
120
|
-
- A parameter `GitHubOIDCRoleArn` — pass the ARN of your existing GitHub OIDC role that will assume the change set role.
|
|
121
|
-
- An IAM role `CdkChangesetRole` with minimal permissions for:
|
|
122
|
-
- CloudFormation Change Set operations
|
|
123
|
-
- Access to common CDK bootstrap S3 buckets and SSM parameters
|
|
124
|
-
- `iam:PassRole` to `cloudformation.amazonaws.com`
|
|
125
|
-
- Outputs exporting the role name and ARN.
|
|
126
|
-
|
|
127
|
-
You can deploy the file via CloudFormation/StackSets and then use the created role ARN as the `cdkDiffRoleToAssumeArn` in your workflow configuration.
|
|
128
|
-
|
|
129
|
-
## Testing
|
|
130
|
-
|
|
131
|
-
This repository includes Jest tests that snapshot the synthesized outputs from Projen and assert that:
|
|
132
|
-
- Workflows are created per stack and contain all expected steps.
|
|
133
|
-
- Only one script file is generated.
|
|
134
|
-
- Per‑stack OIDC overrides are respected.
|
|
135
|
-
- Helpful validation errors are thrown for missing OIDC settings.
|
|
136
|
-
- The IAM template file contains the expected resources and outputs.
|
|
137
|
-
|
|
138
|
-
Run tests with:
|
|
139
|
-
|
|
140
|
-
```bash
|
|
141
|
-
yarn test
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
## Notes
|
|
145
|
-
- This package assumes your repository is configured with GitHub Actions and that you have a GitHub OIDC role configured in AWS.
|
|
146
|
-
- The generated script uses the AWS SDK v3 for CloudFormation and posts comments using the GitHub REST API.
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var _a;
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.CdkDiffIamTemplate = void 0;
|
|
5
|
-
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
|
-
const projen_1 = require("projen");
|
|
7
|
-
class CdkDiffIamTemplate {
|
|
8
|
-
constructor(props) {
|
|
9
|
-
const outputPath = props.outputPath ?? 'cdk-diff-workflow-iam-template.yaml';
|
|
10
|
-
new projen_1.TextFile(props.project, outputPath, {
|
|
11
|
-
lines: [
|
|
12
|
-
"AWSTemplateFormatVersion: '2010-09-09'",
|
|
13
|
-
"Description: 'IAM role for CDK Diff Stack Workflow construct'",
|
|
14
|
-
'',
|
|
15
|
-
'Parameters:',
|
|
16
|
-
' GitHubOIDCRoleArn:',
|
|
17
|
-
' Type: String',
|
|
18
|
-
" Description: 'ARN of the existing GitHub OIDC role that can assume this changeset role'",
|
|
19
|
-
" Default: 'arn:aws:iam::123456789012:role/github-oidc-role'",
|
|
20
|
-
'',
|
|
21
|
-
'Resources:',
|
|
22
|
-
' # CloudFormation ChangeSet Role - minimal permissions for changeset operations',
|
|
23
|
-
' CdkChangesetRole:',
|
|
24
|
-
' Type: AWS::IAM::Role',
|
|
25
|
-
' Properties:',
|
|
26
|
-
" RoleName: !Sub '${AWS::StackName}-cdk-changeset-role'",
|
|
27
|
-
' AssumeRolePolicyDocument:',
|
|
28
|
-
" Version: '2012-10-17'",
|
|
29
|
-
' Statement:',
|
|
30
|
-
' - Effect: Allow',
|
|
31
|
-
' Principal:',
|
|
32
|
-
' AWS: !Ref GitHubOIDCRoleArn',
|
|
33
|
-
' Action: sts:AssumeRole',
|
|
34
|
-
' Condition:',
|
|
35
|
-
' StringEquals:',
|
|
36
|
-
" 'aws:RequestedRegion': 'us-east-2' # Adjust region as needed",
|
|
37
|
-
' Policies:',
|
|
38
|
-
' - PolicyName: CloudFormationChangeSetAccess',
|
|
39
|
-
' PolicyDocument:',
|
|
40
|
-
" Version: '2012-10-17'",
|
|
41
|
-
' Statement:',
|
|
42
|
-
' # CloudFormation changeset operations',
|
|
43
|
-
' - Effect: Allow',
|
|
44
|
-
' Action:',
|
|
45
|
-
' - cloudformation:CreateChangeSet',
|
|
46
|
-
' - cloudformation:DescribeChangeSet',
|
|
47
|
-
' - cloudformation:DeleteChangeSet',
|
|
48
|
-
' - cloudformation:ListChangeSets',
|
|
49
|
-
' - cloudformation:DescribeStacks',
|
|
50
|
-
" Resource: '*'",
|
|
51
|
-
' # CDK bootstrap bucket access (for changeset creation)',
|
|
52
|
-
' - Effect: Allow',
|
|
53
|
-
' Action:',
|
|
54
|
-
' - s3:GetObject',
|
|
55
|
-
' - s3:PutObject',
|
|
56
|
-
' - s3:DeleteObject',
|
|
57
|
-
' - s3:ListBucket',
|
|
58
|
-
' Resource:',
|
|
59
|
-
" - !Sub 'arn:aws:s3:::cdk-${AWS::AccountId}-${AWS::Region}-*'",
|
|
60
|
-
" - !Sub 'arn:aws:s3:::cdk-${AWS::AccountId}-${AWS::Region}-*/*'",
|
|
61
|
-
' # CDK bootstrap parameter access',
|
|
62
|
-
' - Effect: Allow',
|
|
63
|
-
' Action:',
|
|
64
|
-
' - ssm:GetParameter',
|
|
65
|
-
' - ssm:GetParameters',
|
|
66
|
-
' - ssm:GetParametersByPath',
|
|
67
|
-
" Resource: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/cdk-bootstrap/*'",
|
|
68
|
-
' # IAM PassRole for CDK operations',
|
|
69
|
-
' - Effect: Allow',
|
|
70
|
-
' Action:',
|
|
71
|
-
' - iam:PassRole',
|
|
72
|
-
" Resource: '*'",
|
|
73
|
-
' Condition:',
|
|
74
|
-
' StringEquals:',
|
|
75
|
-
" 'iam:PassedToService': 'cloudformation.amazonaws.com'",
|
|
76
|
-
'',
|
|
77
|
-
'Outputs:',
|
|
78
|
-
' CdkChangesetRoleArn:',
|
|
79
|
-
" Description: 'ARN of the CDK changeset role'",
|
|
80
|
-
' Value: !GetAtt CdkChangesetRole.Arn',
|
|
81
|
-
' Export:',
|
|
82
|
-
" Name: !Sub '${AWS::StackName}-CdkChangesetRoleArn'",
|
|
83
|
-
'',
|
|
84
|
-
' CdkChangesetRoleName:',
|
|
85
|
-
" Description: 'Name of the CDK changeset role'",
|
|
86
|
-
' Value: !Ref CdkChangesetRole',
|
|
87
|
-
' Export:',
|
|
88
|
-
" Name: !Sub '${AWS::StackName}-CdkChangesetRoleName'",
|
|
89
|
-
],
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
exports.CdkDiffIamTemplate = CdkDiffIamTemplate;
|
|
94
|
-
_a = JSII_RTTI_SYMBOL_1;
|
|
95
|
-
CdkDiffIamTemplate[_a] = { fqn: "@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplate", version: "0.0.0" };
|
|
96
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2RrRGlmZklhbVRlbXBsYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0Nka0RpZmZJYW1UZW1wbGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG1DQUFrQztBQVFsQyxNQUFhLGtCQUFrQjtJQUM3QixZQUFZLEtBQThCO1FBQ3hDLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxVQUFVLElBQUkscUNBQXFDLENBQUM7UUFFN0UsSUFBSSxpQkFBUSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFO1lBQ3RDLEtBQUssRUFBRTtnQkFDTCx3Q0FBd0M7Z0JBQ3hDLCtEQUErRDtnQkFDL0QsRUFBRTtnQkFDRixhQUFhO2dCQUNiLHNCQUFzQjtnQkFDdEIsa0JBQWtCO2dCQUNsQiw2RkFBNkY7Z0JBQzdGLGdFQUFnRTtnQkFDaEUsRUFBRTtnQkFDRixZQUFZO2dCQUNaLGtGQUFrRjtnQkFDbEYscUJBQXFCO2dCQUNyQiwwQkFBMEI7Z0JBQzFCLGlCQUFpQjtnQkFDakIsNkRBQTZEO2dCQUM3RCxpQ0FBaUM7Z0JBQ2pDLCtCQUErQjtnQkFDL0Isb0JBQW9CO2dCQUNwQiwyQkFBMkI7Z0JBQzNCLHdCQUF3QjtnQkFDeEIsMkNBQTJDO2dCQUMzQyxvQ0FBb0M7Z0JBQ3BDLHdCQUF3QjtnQkFDeEIsNkJBQTZCO2dCQUM3QiwrRUFBK0U7Z0JBQy9FLGlCQUFpQjtnQkFDakIscURBQXFEO2dCQUNyRCwyQkFBMkI7Z0JBQzNCLG1DQUFtQztnQkFDbkMsd0JBQXdCO2dCQUN4QixxREFBcUQ7Z0JBQ3JELCtCQUErQjtnQkFDL0IseUJBQXlCO2dCQUN6QixvREFBb0Q7Z0JBQ3BELHNEQUFzRDtnQkFDdEQsb0RBQW9EO2dCQUNwRCxtREFBbUQ7Z0JBQ25ELG1EQUFtRDtnQkFDbkQsK0JBQStCO2dCQUMvQixzRUFBc0U7Z0JBQ3RFLCtCQUErQjtnQkFDL0IseUJBQXlCO2dCQUN6QixrQ0FBa0M7Z0JBQ2xDLGtDQUFrQztnQkFDbEMscUNBQXFDO2dCQUNyQyxtQ0FBbUM7Z0JBQ25DLDJCQUEyQjtnQkFDM0IsZ0ZBQWdGO2dCQUNoRixrRkFBa0Y7Z0JBQ2xGLGdEQUFnRDtnQkFDaEQsK0JBQStCO2dCQUMvQix5QkFBeUI7Z0JBQ3pCLHNDQUFzQztnQkFDdEMsdUNBQXVDO2dCQUN2Qyw2Q0FBNkM7Z0JBQzdDLHlHQUF5RztnQkFDekcsaURBQWlEO2dCQUNqRCwrQkFBK0I7Z0JBQy9CLHlCQUF5QjtnQkFDekIsa0NBQWtDO2dCQUNsQywrQkFBK0I7Z0JBQy9CLDRCQUE0QjtnQkFDNUIsaUNBQWlDO2dCQUNqQywyRUFBMkU7Z0JBQzNFLEVBQUU7Z0JBQ0YsVUFBVTtnQkFDVix3QkFBd0I7Z0JBQ3hCLGtEQUFrRDtnQkFDbEQseUNBQXlDO2dCQUN6QyxhQUFhO2dCQUNiLDBEQUEwRDtnQkFDMUQsRUFBRTtnQkFDRix5QkFBeUI7Z0JBQ3pCLG1EQUFtRDtnQkFDbkQsa0NBQWtDO2dCQUNsQyxhQUFhO2dCQUNiLDJEQUEyRDthQUM1RDtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBckZILGdEQXNGQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRleHRGaWxlIH0gZnJvbSAncHJvamVuJztcblxuZXhwb3J0IGludGVyZmFjZSBDZGtEaWZmSWFtVGVtcGxhdGVQcm9wcyB7XG4gIHJlYWRvbmx5IHByb2plY3Q6IGFueTtcbiAgcmVhZG9ubHkgb3V0cHV0UGF0aD86IHN0cmluZztcbiAgcmVhZG9ubHkgc3RhY2tOYW1lPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgQ2RrRGlmZklhbVRlbXBsYXRlIHtcbiAgY29uc3RydWN0b3IocHJvcHM6IENka0RpZmZJYW1UZW1wbGF0ZVByb3BzKSB7XG4gICAgY29uc3Qgb3V0cHV0UGF0aCA9IHByb3BzLm91dHB1dFBhdGggPz8gJ2Nkay1kaWZmLXdvcmtmbG93LWlhbS10ZW1wbGF0ZS55YW1sJztcblxuICAgIG5ldyBUZXh0RmlsZShwcm9wcy5wcm9qZWN0LCBvdXRwdXRQYXRoLCB7XG4gICAgICBsaW5lczogW1xuICAgICAgICBcIkFXU1RlbXBsYXRlRm9ybWF0VmVyc2lvbjogJzIwMTAtMDktMDknXCIsXG4gICAgICAgIFwiRGVzY3JpcHRpb246ICdJQU0gcm9sZSBmb3IgQ0RLIERpZmYgU3RhY2sgV29ya2Zsb3cgY29uc3RydWN0J1wiLFxuICAgICAgICAnJyxcbiAgICAgICAgJ1BhcmFtZXRlcnM6JyxcbiAgICAgICAgJyAgR2l0SHViT0lEQ1JvbGVBcm46JyxcbiAgICAgICAgJyAgICBUeXBlOiBTdHJpbmcnLFxuICAgICAgICBcIiAgICBEZXNjcmlwdGlvbjogJ0FSTiBvZiB0aGUgZXhpc3RpbmcgR2l0SHViIE9JREMgcm9sZSB0aGF0IGNhbiBhc3N1bWUgdGhpcyBjaGFuZ2VzZXQgcm9sZSdcIixcbiAgICAgICAgXCIgICAgRGVmYXVsdDogJ2Fybjphd3M6aWFtOjoxMjM0NTY3ODkwMTI6cm9sZS9naXRodWItb2lkYy1yb2xlJ1wiLFxuICAgICAgICAnJyxcbiAgICAgICAgJ1Jlc291cmNlczonLFxuICAgICAgICAnICAjIENsb3VkRm9ybWF0aW9uIENoYW5nZVNldCBSb2xlIC0gbWluaW1hbCBwZXJtaXNzaW9ucyBmb3IgY2hhbmdlc2V0IG9wZXJhdGlvbnMnLFxuICAgICAgICAnICBDZGtDaGFuZ2VzZXRSb2xlOicsXG4gICAgICAgICcgICAgVHlwZTogQVdTOjpJQU06OlJvbGUnLFxuICAgICAgICAnICAgIFByb3BlcnRpZXM6JyxcbiAgICAgICAgXCIgICAgICBSb2xlTmFtZTogIVN1YiAnJHtBV1M6OlN0YWNrTmFtZX0tY2RrLWNoYW5nZXNldC1yb2xlJ1wiLFxuICAgICAgICAnICAgICAgQXNzdW1lUm9sZVBvbGljeURvY3VtZW50OicsXG4gICAgICAgIFwiICAgICAgICBWZXJzaW9uOiAnMjAxMi0xMC0xNydcIixcbiAgICAgICAgJyAgICAgICAgU3RhdGVtZW50OicsXG4gICAgICAgICcgICAgICAgICAgLSBFZmZlY3Q6IEFsbG93JyxcbiAgICAgICAgJyAgICAgICAgICAgIFByaW5jaXBhbDonLFxuICAgICAgICAnICAgICAgICAgICAgICBBV1M6ICFSZWYgR2l0SHViT0lEQ1JvbGVBcm4nLFxuICAgICAgICAnICAgICAgICAgICAgQWN0aW9uOiBzdHM6QXNzdW1lUm9sZScsXG4gICAgICAgICcgICAgICAgICAgICBDb25kaXRpb246JyxcbiAgICAgICAgJyAgICAgICAgICAgICAgU3RyaW5nRXF1YWxzOicsXG4gICAgICAgIFwiICAgICAgICAgICAgICAgICdhd3M6UmVxdWVzdGVkUmVnaW9uJzogJ3VzLWVhc3QtMicgICMgQWRqdXN0IHJlZ2lvbiBhcyBuZWVkZWRcIixcbiAgICAgICAgJyAgICAgIFBvbGljaWVzOicsXG4gICAgICAgICcgICAgICAgIC0gUG9saWN5TmFtZTogQ2xvdWRGb3JtYXRpb25DaGFuZ2VTZXRBY2Nlc3MnLFxuICAgICAgICAnICAgICAgICAgIFBvbGljeURvY3VtZW50OicsXG4gICAgICAgIFwiICAgICAgICAgICAgVmVyc2lvbjogJzIwMTItMTAtMTcnXCIsXG4gICAgICAgICcgICAgICAgICAgICBTdGF0ZW1lbnQ6JyxcbiAgICAgICAgJyAgICAgICAgICAgICAgIyBDbG91ZEZvcm1hdGlvbiBjaGFuZ2VzZXQgb3BlcmF0aW9ucycsXG4gICAgICAgICcgICAgICAgICAgICAgIC0gRWZmZWN0OiBBbGxvdycsXG4gICAgICAgICcgICAgICAgICAgICAgICAgQWN0aW9uOicsXG4gICAgICAgICcgICAgICAgICAgICAgICAgICAtIGNsb3VkZm9ybWF0aW9uOkNyZWF0ZUNoYW5nZVNldCcsXG4gICAgICAgICcgICAgICAgICAgICAgICAgICAtIGNsb3VkZm9ybWF0aW9uOkRlc2NyaWJlQ2hhbmdlU2V0JyxcbiAgICAgICAgJyAgICAgICAgICAgICAgICAgIC0gY2xvdWRmb3JtYXRpb246RGVsZXRlQ2hhbmdlU2V0JyxcbiAgICAgICAgJyAgICAgICAgICAgICAgICAgIC0gY2xvdWRmb3JtYXRpb246TGlzdENoYW5nZVNldHMnLFxuICAgICAgICAnICAgICAgICAgICAgICAgICAgLSBjbG91ZGZvcm1hdGlvbjpEZXNjcmliZVN0YWNrcycsXG4gICAgICAgIFwiICAgICAgICAgICAgICAgIFJlc291cmNlOiAnKidcIixcbiAgICAgICAgJyAgICAgICAgICAgICAgIyBDREsgYm9vdHN0cmFwIGJ1Y2tldCBhY2Nlc3MgKGZvciBjaGFuZ2VzZXQgY3JlYXRpb24pJyxcbiAgICAgICAgJyAgICAgICAgICAgICAgLSBFZmZlY3Q6IEFsbG93JyxcbiAgICAgICAgJyAgICAgICAgICAgICAgICBBY3Rpb246JyxcbiAgICAgICAgJyAgICAgICAgICAgICAgICAgIC0gczM6R2V0T2JqZWN0JyxcbiAgICAgICAgJyAgICAgICAgICAgICAgICAgIC0gczM6UHV0T2JqZWN0JyxcbiAgICAgICAgJyAgICAgICAgICAgICAgICAgIC0gczM6RGVsZXRlT2JqZWN0JyxcbiAgICAgICAgJyAgICAgICAgICAgICAgICAgIC0gczM6TGlzdEJ1Y2tldCcsXG4gICAgICAgICcgICAgICAgICAgICAgICAgUmVzb3VyY2U6JyxcbiAgICAgICAgXCIgICAgICAgICAgICAgICAgICAtICFTdWIgJ2Fybjphd3M6czM6OjpjZGstJHtBV1M6OkFjY291bnRJZH0tJHtBV1M6OlJlZ2lvbn0tKidcIixcbiAgICAgICAgXCIgICAgICAgICAgICAgICAgICAtICFTdWIgJ2Fybjphd3M6czM6OjpjZGstJHtBV1M6OkFjY291bnRJZH0tJHtBV1M6OlJlZ2lvbn0tKi8qJ1wiLFxuICAgICAgICAnICAgICAgICAgICAgICAjIENESyBib290c3RyYXAgcGFyYW1ldGVyIGFjY2VzcycsXG4gICAgICAgICcgICAgICAgICAgICAgIC0gRWZmZWN0OiBBbGxvdycsXG4gICAgICAgICcgICAgICAgICAgICAgICAgQWN0aW9uOicsXG4gICAgICAgICcgICAgICAgICAgICAgICAgICAtIHNzbTpHZXRQYXJhbWV0ZXInLFxuICAgICAgICAnICAgICAgICAgICAgICAgICAgLSBzc206R2V0UGFyYW1ldGVycycsXG4gICAgICAgICcgICAgICAgICAgICAgICAgICAtIHNzbTpHZXRQYXJhbWV0ZXJzQnlQYXRoJyxcbiAgICAgICAgXCIgICAgICAgICAgICAgICAgUmVzb3VyY2U6ICFTdWIgJ2Fybjphd3M6c3NtOiR7QVdTOjpSZWdpb259OiR7QVdTOjpBY2NvdW50SWR9OnBhcmFtZXRlci9jZGstYm9vdHN0cmFwLyonXCIsXG4gICAgICAgICcgICAgICAgICAgICAgICMgSUFNIFBhc3NSb2xlIGZvciBDREsgb3BlcmF0aW9ucycsXG4gICAgICAgICcgICAgICAgICAgICAgIC0gRWZmZWN0OiBBbGxvdycsXG4gICAgICAgICcgICAgICAgICAgICAgICAgQWN0aW9uOicsXG4gICAgICAgICcgICAgICAgICAgICAgICAgICAtIGlhbTpQYXNzUm9sZScsXG4gICAgICAgIFwiICAgICAgICAgICAgICAgIFJlc291cmNlOiAnKidcIixcbiAgICAgICAgJyAgICAgICAgICAgICAgICBDb25kaXRpb246JyxcbiAgICAgICAgJyAgICAgICAgICAgICAgICAgIFN0cmluZ0VxdWFsczonLFxuICAgICAgICBcIiAgICAgICAgICAgICAgICAgICAgJ2lhbTpQYXNzZWRUb1NlcnZpY2UnOiAnY2xvdWRmb3JtYXRpb24uYW1hem9uYXdzLmNvbSdcIixcbiAgICAgICAgJycsXG4gICAgICAgICdPdXRwdXRzOicsXG4gICAgICAgICcgIENka0NoYW5nZXNldFJvbGVBcm46JyxcbiAgICAgICAgXCIgICAgRGVzY3JpcHRpb246ICdBUk4gb2YgdGhlIENESyBjaGFuZ2VzZXQgcm9sZSdcIixcbiAgICAgICAgJyAgICBWYWx1ZTogIUdldEF0dCBDZGtDaGFuZ2VzZXRSb2xlLkFybicsXG4gICAgICAgICcgICAgRXhwb3J0OicsXG4gICAgICAgIFwiICAgICAgTmFtZTogIVN1YiAnJHtBV1M6OlN0YWNrTmFtZX0tQ2RrQ2hhbmdlc2V0Um9sZUFybidcIixcbiAgICAgICAgJycsXG4gICAgICAgICcgIENka0NoYW5nZXNldFJvbGVOYW1lOicsXG4gICAgICAgIFwiICAgIERlc2NyaXB0aW9uOiAnTmFtZSBvZiB0aGUgQ0RLIGNoYW5nZXNldCByb2xlJ1wiLFxuICAgICAgICAnICAgIFZhbHVlOiAhUmVmIENka0NoYW5nZXNldFJvbGUnLFxuICAgICAgICAnICAgIEV4cG9ydDonLFxuICAgICAgICBcIiAgICAgIE5hbWU6ICFTdWIgJyR7QVdTOjpTdGFja05hbWV9LUNka0NoYW5nZXNldFJvbGVOYW1lJ1wiLFxuICAgICAgXSxcbiAgICB9KTtcbiAgfVxufVxuIl19
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export interface CdkDiffStack {
|
|
2
|
-
readonly stackName: string;
|
|
3
|
-
readonly cdkDiffRoleToAssumeArn: string;
|
|
4
|
-
readonly cdkDiffRoleToAssumeRegion: string;
|
|
5
|
-
readonly oidcRoleArn?: string;
|
|
6
|
-
readonly oidcRegion?: string;
|
|
7
|
-
}
|
|
8
|
-
export interface CdkDiffStackWorkflowProps {
|
|
9
|
-
readonly project: any;
|
|
10
|
-
readonly stacks: CdkDiffStack[];
|
|
11
|
-
readonly oidcRoleArn: string;
|
|
12
|
-
readonly oidcRegion: string;
|
|
13
|
-
readonly nodeVersion?: string;
|
|
14
|
-
readonly cdkYarnCommand?: string;
|
|
15
|
-
readonly scriptOutputPath?: string;
|
|
16
|
-
}
|
|
17
|
-
export declare class CdkDiffStackWorkflow {
|
|
18
|
-
private static scriptCreated;
|
|
19
|
-
constructor(props: CdkDiffStackWorkflowProps);
|
|
20
|
-
private validateOidcConfiguration;
|
|
21
|
-
private createWorkflowForStack;
|
|
22
|
-
}
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var _a;
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.CdkDiffStackWorkflow = void 0;
|
|
5
|
-
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
|
-
const github_1 = require("projen/lib/github");
|
|
7
|
-
const workflows_model_1 = require("projen/lib/github/workflows-model");
|
|
8
|
-
const cdk_changeset_script_1 = require("./bin/cdk-changeset-script");
|
|
9
|
-
const githubActionsAwsCredentialsVersion = 'v4';
|
|
10
|
-
const githubActionsCheckoutVersion = 'v4';
|
|
11
|
-
const githubActionsSetupNodeVersion = 'v4';
|
|
12
|
-
class CdkDiffStackWorkflow {
|
|
13
|
-
constructor(props) {
|
|
14
|
-
const cdkYarnCommand = props.cdkYarnCommand ?? 'cdk';
|
|
15
|
-
const nodeVersion = props.nodeVersion ?? '24.x';
|
|
16
|
-
const scriptOutputPath = props.scriptOutputPath ?? '.github/workflows/scripts/describe-cfn-changeset.ts';
|
|
17
|
-
// Validate OIDC configuration
|
|
18
|
-
this.validateOidcConfiguration(props);
|
|
19
|
-
// Only create the changeset script once to avoid collisions
|
|
20
|
-
if (!CdkDiffStackWorkflow.scriptCreated) {
|
|
21
|
-
new cdk_changeset_script_1.CdkChangesetScript({
|
|
22
|
-
project: props.project,
|
|
23
|
-
outputPath: scriptOutputPath,
|
|
24
|
-
});
|
|
25
|
-
CdkDiffStackWorkflow.scriptCreated = true;
|
|
26
|
-
}
|
|
27
|
-
// Create a separate workflow for each stack
|
|
28
|
-
for (const stack of props.stacks) {
|
|
29
|
-
const workflowName = `diff-${stack.stackName}`;
|
|
30
|
-
const gh = props.project.github ?? new github_1.GitHub(props.project);
|
|
31
|
-
const diffDeployWorkflow = new github_1.GithubWorkflow(gh, workflowName, { fileName: `${workflowName}.yml` });
|
|
32
|
-
this.createWorkflowForStack(diffDeployWorkflow, stack, cdkYarnCommand, nodeVersion, scriptOutputPath, props.oidcRoleArn, props.oidcRegion);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
validateOidcConfiguration(props) {
|
|
36
|
-
const hasDefaultOidcRole = !!props.oidcRoleArn;
|
|
37
|
-
const hasDefaultOidcRegion = !!props.oidcRegion;
|
|
38
|
-
// Check if all stacks have their own OIDC configuration
|
|
39
|
-
const allStacksHaveOidcRole = props.stacks.every(stack => !!stack.oidcRoleArn);
|
|
40
|
-
const allStacksHaveOidcRegion = props.stacks.every(stack => !!stack.oidcRegion);
|
|
41
|
-
// Either defaults must be provided OR all stacks must have their own OIDC config
|
|
42
|
-
if (!hasDefaultOidcRole && !allStacksHaveOidcRole) {
|
|
43
|
-
throw new Error('Either provide default oidcRoleArn or specify oidcRoleArn for each stack');
|
|
44
|
-
}
|
|
45
|
-
if (!hasDefaultOidcRegion && !allStacksHaveOidcRegion) {
|
|
46
|
-
throw new Error('Either provide default oidcRegion or specify oidcRegion for each stack');
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
createWorkflowForStack(workflow, stack, cdkYarnCommand, nodeVersion, scriptOutputPath, defaultOidcRoleArn, defaultOidcRegion) {
|
|
50
|
-
// Configure workflow triggers
|
|
51
|
-
workflow.on({
|
|
52
|
-
pullRequest: {
|
|
53
|
-
types: ['opened', 'synchronize', 'reopened'],
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
// Add the diff job
|
|
57
|
-
workflow.addJobs({
|
|
58
|
-
diff: {
|
|
59
|
-
runsOn: ['ubuntu-latest'],
|
|
60
|
-
permissions: {
|
|
61
|
-
idToken: workflows_model_1.JobPermission.WRITE,
|
|
62
|
-
contents: workflows_model_1.JobPermission.READ,
|
|
63
|
-
issues: workflows_model_1.JobPermission.WRITE,
|
|
64
|
-
pullRequests: workflows_model_1.JobPermission.WRITE,
|
|
65
|
-
packages: workflows_model_1.JobPermission.READ,
|
|
66
|
-
},
|
|
67
|
-
env: {
|
|
68
|
-
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}',
|
|
69
|
-
},
|
|
70
|
-
steps: [
|
|
71
|
-
// Checkout code
|
|
72
|
-
{
|
|
73
|
-
uses: `actions/checkout@${githubActionsCheckoutVersion}`,
|
|
74
|
-
},
|
|
75
|
-
// Setup Node.js
|
|
76
|
-
{
|
|
77
|
-
uses: `actions/setup-node@${githubActionsSetupNodeVersion}`,
|
|
78
|
-
with: {
|
|
79
|
-
'node-version': nodeVersion,
|
|
80
|
-
'registry-url': 'https://npm.pkg.github.com',
|
|
81
|
-
'scope': '@${{ github.repository_owner }}',
|
|
82
|
-
'token': '${{ secrets.GITHUB_TOKEN }}',
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
// Install dependencies
|
|
86
|
-
{
|
|
87
|
-
run: 'yarn install --frozen-lockfile',
|
|
88
|
-
env: {
|
|
89
|
-
NODE_AUTH_TOKEN: '${{ secrets.GITHUB_TOKEN }}',
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
id: 'creds',
|
|
94
|
-
uses: `aws-actions/configure-aws-credentials@${githubActionsAwsCredentialsVersion}`,
|
|
95
|
-
with: {
|
|
96
|
-
'role-to-assume': stack.oidcRoleArn ?? defaultOidcRoleArn,
|
|
97
|
-
'aws-region': stack.oidcRegion ?? defaultOidcRegion,
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
name: 'Assume CDK Deploy Role',
|
|
102
|
-
id: 'deploy-role',
|
|
103
|
-
uses: 'aws-actions/configure-aws-credentials@v4',
|
|
104
|
-
with: {
|
|
105
|
-
'role-to-assume': stack.cdkDiffRoleToAssumeArn,
|
|
106
|
-
'role-chaining': true,
|
|
107
|
-
'role-skip-session-tagging': true,
|
|
108
|
-
'aws-region': stack.cdkDiffRoleToAssumeRegion,
|
|
109
|
-
'aws-access-key-id': '${{ steps.creds.outputs.aws-access-key-id }}',
|
|
110
|
-
'aws-secret-access-key': '${{ steps.creds.outputs.aws-secret-access-key }}',
|
|
111
|
-
'aws-session-token': '${{ steps.creds.outputs.aws-session-token }}',
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
// Add changeset creation step
|
|
115
|
-
{
|
|
116
|
-
name: `Create Changeset for ${stack.stackName}`,
|
|
117
|
-
run: `yarn ${cdkYarnCommand} deploy ${stack.stackName} --no-execute --change-set-name ${stack.stackName} --require-approval never`,
|
|
118
|
-
},
|
|
119
|
-
// Add changeset description step
|
|
120
|
-
{
|
|
121
|
-
name: `Describe change set for ${stack.stackName}`,
|
|
122
|
-
run: `npx ts-node ${scriptOutputPath}`,
|
|
123
|
-
env: {
|
|
124
|
-
STACK_NAME: stack.stackName,
|
|
125
|
-
CHANGE_SET_NAME: stack.stackName,
|
|
126
|
-
GITHUB_COMMENT_URL: '${{ github.event.pull_request.comments_url }}',
|
|
127
|
-
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}',
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
// Add changeset cleanup step
|
|
131
|
-
{
|
|
132
|
-
name: `Delete changeset for ${stack.stackName}`,
|
|
133
|
-
run: `aws cloudformation delete-change-set --change-set-name ${stack.stackName} --stack-name ${stack.stackName} --region ${stack.cdkDiffRoleToAssumeRegion}`,
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
},
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
exports.CdkDiffStackWorkflow = CdkDiffStackWorkflow;
|
|
141
|
-
_a = JSII_RTTI_SYMBOL_1;
|
|
142
|
-
CdkDiffStackWorkflow[_a] = { fqn: "@jjrawlins/cdk-diff-pr-github-action.CdkDiffStackWorkflow", version: "0.0.0" };
|
|
143
|
-
CdkDiffStackWorkflow.scriptCreated = false;
|
|
144
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2RrRGlmZlN0YWNrV29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvQ2RrRGlmZlN0YWNrV29ya2Zsb3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw4Q0FBMkQ7QUFDM0QsdUVBQWtFO0FBQ2xFLHFFQUFnRTtBQUVoRSxNQUFNLGtDQUFrQyxHQUFHLElBQUksQ0FBQztBQUNoRCxNQUFNLDRCQUE0QixHQUFHLElBQUksQ0FBQztBQUMxQyxNQUFNLDZCQUE2QixHQUFHLElBQUksQ0FBQztBQW1CM0MsTUFBYSxvQkFBb0I7SUFHL0IsWUFBWSxLQUFnQztRQUMxQyxNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUMsY0FBYyxJQUFJLEtBQUssQ0FBQztRQUNyRCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBQztRQUNoRCxNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsSUFBSSxxREFBcUQsQ0FBQztRQUV6Ryw4QkFBOEI7UUFDOUIsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLDREQUE0RDtRQUM1RCxJQUFJLENBQUMsb0JBQW9CLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDeEMsSUFBSSx5Q0FBa0IsQ0FBQztnQkFDckIsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO2dCQUN0QixVQUFVLEVBQUUsZ0JBQWdCO2FBQzdCLENBQUMsQ0FBQztZQUNILG9CQUFvQixDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDNUMsQ0FBQztRQUVELDRDQUE0QztRQUM1QyxLQUFLLE1BQU0sS0FBSyxJQUFJLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNqQyxNQUFNLFlBQVksR0FBRyxRQUFRLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUMvQyxNQUFNLEVBQUUsR0FBSSxLQUFhLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLGVBQU0sQ0FB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RyxFQUFFLDBEQUEwRCxLQUFLLENBQUMsU0FBUyxpQkFBaUIsS0FBSyxDQUFDLFNBQVMsYUFBYSxLQUFLLENBQUMseUJBQXlCLEVBQUU7cUJBQzdKO2lCQUNGO2FBQ0Y7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDOztBQWxKSCxvREFtSkM7OztBQWxKZ0Isa0NBQWEsR0FBRyxLQUFLLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHaXRIdWIsIEdpdGh1YldvcmtmbG93IH0gZnJvbSAncHJvamVuL2xpYi9naXRodWInO1xuaW1wb3J0IHsgSm9iUGVybWlzc2lvbiB9IGZyb20gJ3Byb2plbi9saWIvZ2l0aHViL3dvcmtmbG93cy1tb2RlbCc7XG5pbXBvcnQgeyBDZGtDaGFuZ2VzZXRTY3JpcHQgfSBmcm9tICcuL2Jpbi9jZGstY2hhbmdlc2V0LXNjcmlwdCc7XG5cbmNvbnN0IGdpdGh1YkFjdGlvbnNBd3NDcmVkZW50aWFsc1ZlcnNpb24gPSAndjQnO1xuY29uc3QgZ2l0aHViQWN0aW9uc0NoZWNrb3V0VmVyc2lvbiA9ICd2NCc7XG5jb25zdCBnaXRodWJBY3Rpb25zU2V0dXBOb2RlVmVyc2lvbiA9ICd2NCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2RrRGlmZlN0YWNrIHtcbiAgcmVhZG9ubHkgc3RhY2tOYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNka0RpZmZSb2xlVG9Bc3N1bWVBcm46IHN0cmluZztcbiAgcmVhZG9ubHkgY2RrRGlmZlJvbGVUb0Fzc3VtZVJlZ2lvbjogc3RyaW5nO1xuICByZWFkb25seSBvaWRjUm9sZUFybj86IHN0cmluZzsgLy8gT3B0aW9uYWwgb3ZlcnJpZGUgZm9yIE9JREMgcm9sZVxuICByZWFkb25seSBvaWRjUmVnaW9uPzogc3RyaW5nOyAvLyBPcHRpb25hbCBvdmVycmlkZSBmb3IgT0lEQyByZWdpb25cbn1cblxuZXhwb3J0IGludGVyZmFjZSBDZGtEaWZmU3RhY2tXb3JrZmxvd1Byb3BzIHtcbiAgcmVhZG9ubHkgcHJvamVjdDogYW55OyAvLyBhdm9pZCBleHBvcnRpbmcgcHJvamVuIHR5cGVzIGluIHB1YmxpYyBBUElcbiAgcmVhZG9ubHkgc3RhY2tzOiBDZGtEaWZmU3RhY2tbXTtcbiAgcmVhZG9ubHkgb2lkY1JvbGVBcm46IHN0cmluZzsgLy8gUmVxdWlyZWQgT0lEQyByb2xlIEFSTiBmb3IgYWxsIHN0YWNrcyAob3IgZWFjaCBzdGFjayBtdXN0IGhhdmUgaXRzIG93bilcbiAgcmVhZG9ubHkgb2lkY1JlZ2lvbjogc3RyaW5nOyAvLyBSZXF1aXJlZCBPSURDIHJlZ2lvbiBmb3IgYWxsIHN0YWNrcyAob3IgZWFjaCBzdGFjayBtdXN0IGhhdmUgaXRzIG93bilcbiAgcmVhZG9ubHkgbm9kZVZlcnNpb24/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNka1lhcm5Db21tYW5kPzogc3RyaW5nO1xuICByZWFkb25seSBzY3JpcHRPdXRwdXRQYXRoPzogc3RyaW5nO1xufVxuZXhwb3J0IGNsYXNzIENka0RpZmZTdGFja1dvcmtmbG93IHtcbiAgcHJpdmF0ZSBzdGF0aWMgc2NyaXB0Q3JlYXRlZCA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBDZGtEaWZmU3RhY2tXb3JrZmxvd1Byb3BzKSB7XG4gICAgY29uc3QgY2RrWWFybkNvbW1hbmQgPSBwcm9wcy5jZGtZYXJuQ29tbWFuZCA/PyAnY2RrJztcbiAgICBjb25zdCBub2RlVmVyc2lvbiA9IHByb3BzLm5vZGVWZXJzaW9uID8/ICcyNC54JztcbiAgICBjb25zdCBzY3JpcHRPdXRwdXRQYXRoID0gcHJvcHMuc2NyaXB0T3V0cHV0UGF0aCA/PyAnLmdpdGh1Yi93b3JrZmxvd3Mvc2NyaXB0cy9kZXNjcmliZS1jZm4tY2hhbmdlc2V0LnRzJztcblxuICAgIC8vIFZhbGlkYXRlIE9JREMgY29uZmlndXJhdGlvblxuICAgIHRoaXMudmFsaWRhdGVPaWRjQ29uZmlndXJhdGlvbihwcm9wcyk7XG5cbiAgICAvLyBPbmx5IGNyZWF0ZSB0aGUgY2hhbmdlc2V0IHNjcmlwdCBvbmNlIHRvIGF2b2lkIGNvbGxpc2lvbnNcbiAgICBpZiAoIUNka0RpZmZTdGFja1dvcmtmbG93LnNjcmlwdENyZWF0ZWQpIHtcbiAgICAgIG5ldyBDZGtDaGFuZ2VzZXRTY3JpcHQoe1xuICAgICAgICBwcm9qZWN0OiBwcm9wcy5wcm9qZWN0LFxuICAgICAgICBvdXRwdXRQYXRoOiBzY3JpcHRPdXRwdXRQYXRoLFxuICAgICAgfSk7XG4gICAgICBDZGtEaWZmU3RhY2tXb3JrZmxvdy5zY3JpcHRDcmVhdGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgYSBzZXBhcmF0ZSB3b3JrZmxvdyBmb3IgZWFjaCBzdGFja1xuICAgIGZvciAoY29uc3Qgc3RhY2sgb2YgcHJvcHMuc3RhY2tzKSB7XG4gICAgICBjb25zdCB3b3JrZmxvd05hbWUgPSBgZGlmZi0ke3N0YWNrLnN0YWNrTmFtZX1gO1xuICAgICAgY29uc3QgZ2ggPSAocHJvcHMgYXMgYW55KS5wcm9qZWN0LmdpdGh1YiA/PyBuZXcgR2l0SHViKChwcm9wcyBhcyBhbnkpLnByb2plY3QpO1xuICAgICAgY29uc3QgZGlmZkRlcGxveVdvcmtmbG93ID0gbmV3IEdpdGh1YldvcmtmbG93KGdoLCB3b3JrZmxvd05hbWUsIHsgZmlsZU5hbWU6IGAke3dvcmtmbG93TmFtZX0ueW1sYCB9KTtcblxuICAgICAgdGhpcy5jcmVhdGVXb3JrZmxvd0ZvclN0YWNrKGRpZmZEZXBsb3lXb3JrZmxvdywgc3RhY2ssIGNka1lhcm5Db21tYW5kLCBub2RlVmVyc2lvbiwgc2NyaXB0T3V0cHV0UGF0aCwgcHJvcHMub2lkY1JvbGVBcm4sIHByb3BzLm9pZGNSZWdpb24pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVPaWRjQ29uZmlndXJhdGlvbihwcm9wczogQ2RrRGlmZlN0YWNrV29ya2Zsb3dQcm9wcyk6IHZvaWQge1xuICAgIGNvbnN0IGhhc0RlZmF1bHRPaWRjUm9sZSA9ICEhcHJvcHMub2lkY1JvbGVBcm47XG4gICAgY29uc3QgaGFzRGVmYXVsdE9pZGNSZWdpb24gPSAhIXByb3BzLm9pZGNSZWdpb247XG5cbiAgICAvLyBDaGVjayBpZiBhbGwgc3RhY2tzIGhhdmUgdGhlaXIgb3duIE9JREMgY29uZmlndXJhdGlvblxuICAgIGNvbnN0IGFsbFN0YWNrc0hhdmVPaWRjUm9sZSA9IHByb3BzLnN0YWNrcy5ldmVyeShzdGFjayA9PiAhIXN0YWNrLm9pZGNSb2xlQXJuKTtcbiAgICBjb25zdCBhbGxTdGFja3NIYXZlT2lkY1JlZ2lvbiA9IHByb3BzLnN0YWNrcy5ldmVyeShzdGFjayA9PiAhIXN0YWNrLm9pZGNSZWdpb24pO1xuXG4gICAgLy8gRWl0aGVyIGRlZmF1bHRzIG11c3QgYmUgcHJvdmlkZWQgT1IgYWxsIHN0YWNrcyBtdXN0IGhhdmUgdGhlaXIgb3duIE9JREMgY29uZmlnXG4gICAgaWYgKCFoYXNEZWZhdWx0T2lkY1JvbGUgJiYgIWFsbFN0YWNrc0hhdmVPaWRjUm9sZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFaXRoZXIgcHJvdmlkZSBkZWZhdWx0IG9pZGNSb2xlQXJuIG9yIHNwZWNpZnkgb2lkY1JvbGVBcm4gZm9yIGVhY2ggc3RhY2snKTtcbiAgICB9XG5cbiAgICBpZiAoIWhhc0RlZmF1bHRPaWRjUmVnaW9uICYmICFhbGxTdGFja3NIYXZlT2lkY1JlZ2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFaXRoZXIgcHJvdmlkZSBkZWZhdWx0IG9pZGNSZWdpb24gb3Igc3BlY2lmeSBvaWRjUmVnaW9uIGZvciBlYWNoIHN0YWNrJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVXb3JrZmxvd0ZvclN0YWNrKFxuICAgIHdvcmtmbG93OiBHaXRodWJXb3JrZmxvdyxcbiAgICBzdGFjazogQ2RrRGlmZlN0YWNrLFxuICAgIGNka1lhcm5Db21tYW5kOiBzdHJpbmcsXG4gICAgbm9kZVZlcnNpb246IHN0cmluZyxcbiAgICBzY3JpcHRPdXRwdXRQYXRoOiBzdHJpbmcsXG4gICAgZGVmYXVsdE9pZGNSb2xlQXJuOiBzdHJpbmcsXG4gICAgZGVmYXVsdE9pZGNSZWdpb246IHN0cmluZyxcbiAgKSB7XG4gICAgLy8gQ29uZmlndXJlIHdvcmtmbG93IHRyaWdnZXJzXG4gICAgd29ya2Zsb3cub24oe1xuICAgICAgcHVsbFJlcXVlc3Q6IHtcbiAgICAgICAgdHlwZXM6IFsnb3BlbmVkJywgJ3N5bmNocm9uaXplJywgJ3Jlb3BlbmVkJ10sXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gQWRkIHRoZSBkaWZmIGpvYlxuICAgIHdvcmtmbG93LmFkZEpvYnMoe1xuICAgICAgZGlmZjoge1xuICAgICAgICBydW5zT246IFsndWJ1bnR1LWxhdGVzdCddLFxuICAgICAgICBwZXJtaXNzaW9uczoge1xuICAgICAgICAgIGlkVG9rZW46IEpvYlBlcm1pc3Npb24uV1JJVEUsXG4gICAgICAgICAgY29udGVudHM6IEpvYlBlcm1pc3Npb24uUkVBRCxcbiAgICAgICAgICBpc3N1ZXM6IEpvYlBlcm1pc3Npb24uV1JJVEUsXG4gICAgICAgICAgcHVsbFJlcXVlc3RzOiBKb2JQZXJtaXNzaW9uLldSSVRFLFxuICAgICAgICAgIHBhY2thZ2VzOiBKb2JQZXJtaXNzaW9uLlJFQUQsXG4gICAgICAgIH0sXG4gICAgICAgIGVudjoge1xuICAgICAgICAgIEdJVEhVQl9UT0tFTjogJyR7eyBzZWNyZXRzLkdJVEhVQl9UT0tFTiB9fScsXG4gICAgICAgIH0sXG4gICAgICAgIHN0ZXBzOiBbXG4gICAgICAgICAgLy8gQ2hlY2tvdXQgY29kZVxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVzZXM6IGBhY3Rpb25zL2NoZWNrb3V0QCR7Z2l0aHViQWN0aW9uc0NoZWNrb3V0VmVyc2lvbn1gLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgLy8gU2V0dXAgTm9kZS5qc1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVzZXM6IGBhY3Rpb25zL3NldHVwLW5vZGVAJHtnaXRodWJBY3Rpb25zU2V0dXBOb2RlVmVyc2lvbn1gLFxuICAgICAgICAgICAgd2l0aDoge1xuICAgICAgICAgICAgICAnbm9kZS12ZXJzaW9uJzogbm9kZVZlcnNpb24sXG4gICAgICAgICAgICAgICdyZWdpc3RyeS11cmwnOiAnaHR0cHM6Ly9ucG0ucGtnLmdpdGh1Yi5jb20nLFxuICAgICAgICAgICAgICAnc2NvcGUnOiAnQCR7eyBnaXRodWIucmVwb3NpdG9yeV9vd25lciB9fScsXG4gICAgICAgICAgICAgICd0b2tlbic6ICcke3sgc2VjcmV0cy5HSVRIVUJfVE9LRU4gfX0nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIC8vIEluc3RhbGwgZGVwZW5kZW5jaWVzXG4gICAgICAgICAge1xuICAgICAgICAgICAgcnVuOiAneWFybiBpbnN0YWxsIC0tZnJvemVuLWxvY2tmaWxlJyxcbiAgICAgICAgICAgIGVudjoge1xuICAgICAgICAgICAgICBOT0RFX0FVVEhfVE9LRU46ICcke3sgc2VjcmV0cy5HSVRIVUJfVE9LRU4gfX0nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnY3JlZHMnLFxuICAgICAgICAgICAgdXNlczogYGF3cy1hY3Rpb25zL2NvbmZpZ3VyZS1hd3MtY3JlZGVudGlhbHNAJHtnaXRodWJBY3Rpb25zQXdzQ3JlZGVudGlhbHNWZXJzaW9ufWAsXG4gICAgICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgICAgICdyb2xlLXRvLWFzc3VtZSc6IHN0YWNrLm9pZGNSb2xlQXJuID8/IGRlZmF1bHRPaWRjUm9sZUFybixcbiAgICAgICAgICAgICAgJ2F3cy1yZWdpb24nOiBzdGFjay5vaWRjUmVnaW9uID8/IGRlZmF1bHRPaWRjUmVnaW9uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdBc3N1bWUgQ0RLIERlcGxveSBSb2xlJyxcbiAgICAgICAgICAgIGlkOiAnZGVwbG95LXJvbGUnLFxuICAgICAgICAgICAgdXNlczogJ2F3cy1hY3Rpb25zL2NvbmZpZ3VyZS1hd3MtY3JlZGVudGlhbHNAdjQnLFxuICAgICAgICAgICAgd2l0aDoge1xuICAgICAgICAgICAgICAncm9sZS10by1hc3N1bWUnOiBzdGFjay5jZGtEaWZmUm9sZVRvQXNzdW1lQXJuLFxuICAgICAgICAgICAgICAncm9sZS1jaGFpbmluZyc6IHRydWUsXG4gICAgICAgICAgICAgICdyb2xlLXNraXAtc2Vzc2lvbi10YWdnaW5nJzogdHJ1ZSxcbiAgICAgICAgICAgICAgJ2F3cy1yZWdpb24nOiBzdGFjay5jZGtEaWZmUm9sZVRvQXNzdW1lUmVnaW9uLFxuICAgICAgICAgICAgICAnYXdzLWFjY2Vzcy1rZXktaWQnOiAnJHt7IHN0ZXBzLmNyZWRzLm91dHB1dHMuYXdzLWFjY2Vzcy1rZXktaWQgfX0nLFxuICAgICAgICAgICAgICAnYXdzLXNlY3JldC1hY2Nlc3Mta2V5JzogJyR7eyBzdGVwcy5jcmVkcy5vdXRwdXRzLmF3cy1zZWNyZXQtYWNjZXNzLWtleSB9fScsXG4gICAgICAgICAgICAgICdhd3Mtc2Vzc2lvbi10b2tlbic6ICcke3sgc3RlcHMuY3JlZHMub3V0cHV0cy5hd3Mtc2Vzc2lvbi10b2tlbiB9fScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgLy8gQWRkIGNoYW5nZXNldCBjcmVhdGlvbiBzdGVwXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogYENyZWF0ZSBDaGFuZ2VzZXQgZm9yICR7c3RhY2suc3RhY2tOYW1lfWAsXG4gICAgICAgICAgICBydW46IGB5YXJuICR7Y2RrWWFybkNvbW1hbmR9IGRlcGxveSAke3N0YWNrLnN0YWNrTmFtZX0gLS1uby1leGVjdXRlIC0tY2hhbmdlLXNldC1uYW1lICR7c3RhY2suc3RhY2tOYW1lfSAtLXJlcXVpcmUtYXBwcm92YWwgbmV2ZXJgLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgLy8gQWRkIGNoYW5nZXNldCBkZXNjcmlwdGlvbiBzdGVwXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogYERlc2NyaWJlIGNoYW5nZSBzZXQgZm9yICR7c3RhY2suc3RhY2tOYW1lfWAsXG4gICAgICAgICAgICBydW46IGBucHggdHMtbm9kZSAke3NjcmlwdE91dHB1dFBhdGh9YCxcbiAgICAgICAgICAgIGVudjoge1xuICAgICAgICAgICAgICBTVEFDS19OQU1FOiBzdGFjay5zdGFja05hbWUsXG4gICAgICAgICAgICAgIENIQU5HRV9TRVRfTkFNRTogc3RhY2suc3RhY2tOYW1lLFxuICAgICAgICAgICAgICBHSVRIVUJfQ09NTUVOVF9VUkw6ICcke3sgZ2l0aHViLmV2ZW50LnB1bGxfcmVxdWVzdC5jb21tZW50c191cmwgfX0nLFxuICAgICAgICAgICAgICBHSVRIVUJfVE9LRU46ICcke3sgc2VjcmV0cy5HSVRIVUJfVE9LRU4gfX0nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIC8vIEFkZCBjaGFuZ2VzZXQgY2xlYW51cCBzdGVwXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogYERlbGV0ZSBjaGFuZ2VzZXQgZm9yICR7c3RhY2suc3RhY2tOYW1lfWAsXG4gICAgICAgICAgICBydW46IGBhd3MgY2xvdWRmb3JtYXRpb24gZGVsZXRlLWNoYW5nZS1zZXQgLS1jaGFuZ2Utc2V0LW5hbWUgJHtzdGFjay5zdGFja05hbWV9IC0tc3RhY2stbmFtZSAke3N0YWNrLnN0YWNrTmFtZX0gLS1yZWdpb24gJHtzdGFjay5jZGtEaWZmUm9sZVRvQXNzdW1lUmVnaW9ufWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
|