@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.
Files changed (43) hide show
  1. package/.jsii +475 -33
  2. package/.mergify.yml +102 -0
  3. package/API.md +351 -11
  4. package/README.md +223 -39
  5. package/lib/CdkDiffIamTemplate.d.ts +3 -1
  6. package/lib/CdkDiffIamTemplate.js +10 -5
  7. package/lib/CdkDiffStackWorkflow.d.ts +2 -2
  8. package/lib/CdkDiffStackWorkflow.js +19 -20
  9. package/lib/CdkDriftDetectionWorkflow.d.ts +32 -0
  10. package/lib/CdkDriftDetectionWorkflow.js +281 -0
  11. package/lib/CdkDriftIamTemplate.d.ts +10 -0
  12. package/lib/CdkDriftIamTemplate.js +77 -0
  13. package/lib/bin/cdk-changeset-script.js +3 -3
  14. package/lib/bin/cdk-drift-detection-script.d.ts +15 -0
  15. package/lib/bin/cdk-drift-detection-script.js +196 -0
  16. package/lib/bin/detect-drift.js +162 -0
  17. package/lib/index.d.ts +2 -0
  18. package/lib/index.js +3 -1
  19. package/package.json +7 -2
  20. package/sonar-project.properties +17 -0
  21. package/.junie/guidelines.md +0 -62
  22. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/.jsii +0 -3917
  23. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/.junie/guidelines.md +0 -62
  24. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/.tool-versions +0 -3
  25. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/API.md +0 -276
  26. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/LICENSE +0 -202
  27. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/README.md +0 -146
  28. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/CdkDiffIamTemplate.d.ts +0 -8
  29. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/CdkDiffIamTemplate.js +0 -96
  30. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/CdkDiffStackWorkflow.d.ts +0 -22
  31. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/CdkDiffStackWorkflow.js +0 -144
  32. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/bin/cdk-changeset-script.d.ts +0 -9
  33. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/bin/cdk-changeset-script.js +0 -256
  34. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/bin/describe-cfn-changeset.js +0 -204
  35. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/index.d.ts +0 -2
  36. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/index.js +0 -19
  37. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/package.json +0 -137
  38. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/yalc.lock +0 -10
  39. package/.yalc/@jjrawlins/cdk-diff-pr-github-action/yalc.sig +0 -1
  40. package/lib/bin/describe-cfn-changeset.d.ts +0 -1
  41. package/lib/bin/describe-cfn-changeset.js +0 -204
  42. package/yalc.lock +0 -10
  43. /package/{.yalc/@jjrawlins/cdk-diff-pr-github-action/lib/bin/describe-cfn-changeset.d.ts → lib/bin/detect-drift.d.ts} +0 -0
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CdkDriftDetectionScript = void 0;
4
+ const projen_1 = require("projen");
5
+ /**
6
+ * Projen helper to emit the drift detection script into the repository so
7
+ * GitHub workflows can execute it from a stable location.
8
+ *
9
+ * This mirrors the pattern used by CdkChangesetScript, but writes the
10
+ * drift script (detect-drift.ts) under the workflows scripts directory by default.
11
+ */
12
+ class CdkDriftDetectionScript {
13
+ constructor(props) {
14
+ const outputPath = props.outputPath ?? '.github/workflows/scripts/detect-drift.ts';
15
+ new projen_1.TextFile(props.project, outputPath, {
16
+ lines: [
17
+ "import {\n CloudFormationClient,\n DescribeStackDriftDetectionStatusCommand,\n DetectStackDriftCommand,\n DescribeStackResourceDriftsCommand,\n type DescribeStackResourceDriftsCommandOutput,\n type StackResourceDriftStatus,\n} from '@aws-sdk/client-cloudformation';",
18
+ '',
19
+ 'async function sleep(ms: number) {',
20
+ ' return new Promise((r) => setTimeout(r, ms));',
21
+ '}',
22
+ '',
23
+ 'async function main() {',
24
+ ' const stackName = process.env.STACK_NAME;',
25
+ ' if (!stackName) {',
26
+ " console.error('STACK_NAME env var is required');",
27
+ ' process.exit(1);',
28
+ ' }',
29
+ '',
30
+ ' // Region and credentials pulled from environment set by actions/configure-aws-credentials',
31
+ ' const client = new CloudFormationClient({});',
32
+ '',
33
+ ' const detect = await client.send(new DetectStackDriftCommand({ StackName: stackName }));',
34
+ ' if (!detect.StackDriftDetectionId) {',
35
+ " console.error('Failed to start drift detection');",
36
+ ' process.exit(1);',
37
+ ' }',
38
+ '',
39
+ ' const id = detect.StackDriftDetectionId;',
40
+ ' console.log(`Drift detection started: ${id}`);',
41
+ '',
42
+ " let detectionStatus = 'DETECTION_IN_PROGRESS';",
43
+ ' let stackDriftStatus: string | undefined;',
44
+ '',
45
+ " while (detectionStatus === 'DETECTION_IN_PROGRESS') {",
46
+ ' await sleep(5000);',
47
+ ' const res = await client.send(',
48
+ ' new DescribeStackDriftDetectionStatusCommand({ StackDriftDetectionId: id }),',
49
+ ' );',
50
+ " detectionStatus = res.DetectionStatus ?? 'UNKNOWN';",
51
+ ' stackDriftStatus = res.StackDriftStatus;',
52
+ ' console.log(`Detection status: ${detectionStatus}`);',
53
+ ' }',
54
+ '',
55
+ ' // Helper to build an HTML report of drifted resources',
56
+ ' const buildHtml = (stack: string, drifts: any[]): string => {',
57
+ ' let body = `<h1>Drift report</h1><h2>Stack Name: ${stack}</h2><br>`;',
58
+ ' if (drifts.length === 0) {',
59
+ " body += 'no drift.';",
60
+ ' return body;',
61
+ ' }',
62
+ " body += '<table>' +",
63
+ " '<tr><th>Status</th><th>ID</th><th>Type</th><th>Differences</th></tr>';",
64
+ ' for (const d of drifts) {',
65
+ " const status = d.StackResourceDriftStatus ?? '-';",
66
+ " const logicalId = d.LogicalResourceId ?? '-';",
67
+ " const type = d.ResourceType ?? '-';",
68
+ ' const diffs = (d.PropertyDifferences ?? []).map((pd: any) => {',
69
+ " const p = pd.PropertyPath ?? '-';",
70
+ " const t = pd.DifferenceType ?? '-';",
71
+ ' return `- ${t}: ${p}`;',
72
+ " }).join('<br>');",
73
+ " const statusEmoji = status === 'MODIFIED' ? '🟠' : status === 'DELETED' ? '🔴' : status === 'NOT_CHECKED' ? '⚪' : '🟢';",
74
+ " body += '<tr>' +",
75
+ ' `<td>${statusEmoji} ${status}</td>` +',
76
+ ' `<td>${logicalId}</td>` +',
77
+ ' `<td>${type}</td>` +',
78
+ ' `<td>${diffs}</td>` +',
79
+ " '</tr>';",
80
+ ' }',
81
+ " body += '</table>';",
82
+ ' return body;',
83
+ ' };',
84
+ '',
85
+ ' async function listDriftedResources(): Promise<any[]> {',
86
+ ' const results: any[] = [];',
87
+ ' // Only include resources that are not IN_SYNC',
88
+ " const filters: StackResourceDriftStatus[] = ['MODIFIED', 'DELETED', 'NOT_CHECKED'];",
89
+ ' let nextToken: string | undefined = undefined;',
90
+ ' do {',
91
+ ' const resp: DescribeStackResourceDriftsCommandOutput = await client.send(new DescribeStackResourceDriftsCommand({',
92
+ ' StackName: stackName,',
93
+ ' NextToken: nextToken,',
94
+ ' StackResourceDriftStatusFilters: filters,',
95
+ ' }));',
96
+ ' if (resp.StackResourceDrifts) results.push(...resp.StackResourceDrifts);',
97
+ ' nextToken = resp.NextToken;',
98
+ ' } while (nextToken);',
99
+ ' return results;',
100
+ ' }',
101
+ '',
102
+ ' async function postGithubComment(url: string, token: string, body: string): Promise<void> {',
103
+ ' const res = await fetch(url, {',
104
+ " method: 'POST',",
105
+ ' headers: {',
106
+ " 'Authorization': `token ${token}`,",
107
+ " 'Content-Type': 'application/json',",
108
+ " 'Accept': 'application/vnd.github+json',",
109
+ ' },',
110
+ ' body: JSON.stringify({ body }),',
111
+ ' });',
112
+ ' if (!res.ok) {',
113
+ ' const text = await res.text().catch(() => \'\');',
114
+ ' console.error(`Failed to post GitHub comment: ${res.status} ${res.statusText} ${text}`);',
115
+ ' }',
116
+ ' }',
117
+ '',
118
+ ' // When there is drift, collect details and post a PR comment + step summary',
119
+ ' const outputFile = process.env.DRIFT_DETECTION_OUTPUT;',
120
+ " if (stackDriftStatus !== 'IN_SYNC') {",
121
+ ' console.error(`Drift detected (status: ${stackDriftStatus})`);',
122
+ ' const drifts = await listDriftedResources();',
123
+ ' const html = buildHtml(stackName, drifts);',
124
+ '',
125
+ ' // Write machine-readable JSON if requested',
126
+ ' if (outputFile) {',
127
+ ' try {',
128
+ " const { writeFile } = await import('fs/promises');",
129
+ ' const result = [',
130
+ ' {',
131
+ ' stackName,',
132
+ ' driftStatus: stackDriftStatus,',
133
+ ' driftedResources: (drifts || []).map(d => ({',
134
+ ' logicalResourceId: d.LogicalResourceId,',
135
+ ' resourceType: d.ResourceType,',
136
+ ' stackResourceDriftStatus: d.StackResourceDriftStatus,',
137
+ ' propertyDifferences: d.PropertyDifferences,',
138
+ ' })),',
139
+ ' },',
140
+ ' ];',
141
+ " await writeFile(outputFile, JSON.stringify(result, null, 2), { encoding: 'utf8' });",
142
+ ' } catch (e: any) {',
143
+ " console.error('Failed to write drift JSON results:', e?.message || e);",
144
+ ' }',
145
+ ' }',
146
+ '',
147
+ ' // Print to stdout and append to summary if available',
148
+ ' console.log(html);',
149
+ ' const stepSummary = process.env.GITHUB_STEP_SUMMARY;',
150
+ ' if (stepSummary) {',
151
+ ' try {',
152
+ " const { appendFile } = await import('fs/promises');",
153
+ " await appendFile(stepSummary, `${html}\\n`, { encoding: 'utf8' });",
154
+ ' } catch (e: any) {',
155
+ " console.error('Failed to append to GITHUB_STEP_SUMMARY:', e?.message || e);",
156
+ ' }',
157
+ ' }',
158
+ '',
159
+ ' const commentUrl = process.env.GITHUB_COMMENT_URL;',
160
+ ' const token = process.env.GITHUB_TOKEN;',
161
+ ' if (commentUrl && token) {',
162
+ ' await postGithubComment(commentUrl, token, html);',
163
+ ' }',
164
+ '',
165
+ ' process.exit(1);',
166
+ ' }',
167
+ '',
168
+ ' // No drift case',
169
+ ' if (outputFile) {',
170
+ ' try {',
171
+ " const { writeFile } = await import('fs/promises');",
172
+ ' const result = [',
173
+ ' {',
174
+ ' stackName,',
175
+ " driftStatus: 'IN_SYNC',",
176
+ ' driftedResources: [],',
177
+ ' },',
178
+ ' ];',
179
+ " await writeFile(outputFile, JSON.stringify(result, null, 2), { encoding: 'utf8' });",
180
+ ' } catch (e: any) {',
181
+ " console.error('Failed to write drift JSON results:', e?.message || e);",
182
+ ' }',
183
+ ' }',
184
+ " console.log('No drift detected (IN_SYNC)');",
185
+ '}',
186
+ '',
187
+ 'main().catch((e) => {',
188
+ ' console.error(e);',
189
+ ' process.exit(1);',
190
+ '});',
191
+ ],
192
+ });
193
+ }
194
+ }
195
+ exports.CdkDriftDetectionScript = CdkDriftDetectionScript;
196
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RrLWRyaWZ0LWRldGVjdGlvbi1zY3JpcHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYmluL2Nkay1kcmlmdC1kZXRlY3Rpb24tc2NyaXB0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUFrQztBQVFsQzs7Ozs7O0dBTUc7QUFDSCxNQUFhLHVCQUF1QjtJQUNsQyxZQUFZLEtBQW1DO1FBQzdDLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxVQUFVLElBQUksMkNBQTJDLENBQUM7UUFFbkYsSUFBSSxpQkFBUSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFO1lBQ3RDLEtBQUssRUFBRTtnQkFDTCxpUkFBaVI7Z0JBQ2pSLEVBQUU7Z0JBQ0Ysb0NBQW9DO2dCQUNwQyxpREFBaUQ7Z0JBQ2pELEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRix5QkFBeUI7Z0JBQ3pCLDZDQUE2QztnQkFDN0MscUJBQXFCO2dCQUNyQixzREFBc0Q7Z0JBQ3RELHNCQUFzQjtnQkFDdEIsS0FBSztnQkFDTCxFQUFFO2dCQUNGLDhGQUE4RjtnQkFDOUYsZ0RBQWdEO2dCQUNoRCxFQUFFO2dCQUNGLDRGQUE0RjtnQkFDNUYsd0NBQXdDO2dCQUN4Qyx1REFBdUQ7Z0JBQ3ZELHNCQUFzQjtnQkFDdEIsS0FBSztnQkFDTCxFQUFFO2dCQUNGLDRDQUE0QztnQkFDNUMsa0RBQWtEO2dCQUNsRCxFQUFFO2dCQUNGLGtEQUFrRDtnQkFDbEQsNkNBQTZDO2dCQUM3QyxFQUFFO2dCQUNGLHlEQUF5RDtnQkFDekQsd0JBQXdCO2dCQUN4QixvQ0FBb0M7Z0JBQ3BDLG9GQUFvRjtnQkFDcEYsUUFBUTtnQkFDUix5REFBeUQ7Z0JBQ3pELDhDQUE4QztnQkFDOUMsMERBQTBEO2dCQUMxRCxLQUFLO2dCQUNMLEVBQUU7Z0JBQ0YsMERBQTBEO2dCQUMxRCxpRUFBaUU7Z0JBQ2pFLDBFQUEwRTtnQkFDMUUsZ0NBQWdDO2dCQUNoQyw0QkFBNEI7Z0JB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aWxlIH0gZnJvbSAncHJvamVuJztcblxuaW50ZXJmYWNlIENka0RyaWZ0RGV0ZWN0aW9uU2NyaXB0UHJvcHMge1xuICAvLyBBdm9pZCBleHBvcnRpbmcgcHJvamVuIHR5cGVzIGluIHB1YmxpYyBBUElcbiAgcHJvamVjdDogYW55O1xuICBvdXRwdXRQYXRoPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFByb2plbiBoZWxwZXIgdG8gZW1pdCB0aGUgZHJpZnQgZGV0ZWN0aW9uIHNjcmlwdCBpbnRvIHRoZSByZXBvc2l0b3J5IHNvXG4gKiBHaXRIdWIgd29ya2Zsb3dzIGNhbiBleGVjdXRlIGl0IGZyb20gYSBzdGFibGUgbG9jYXRpb24uXG4gKlxuICogVGhpcyBtaXJyb3JzIHRoZSBwYXR0ZXJuIHVzZWQgYnkgQ2RrQ2hhbmdlc2V0U2NyaXB0LCBidXQgd3JpdGVzIHRoZVxuICogZHJpZnQgc2NyaXB0IChkZXRlY3QtZHJpZnQudHMpIHVuZGVyIHRoZSB3b3JrZmxvd3Mgc2NyaXB0cyBkaXJlY3RvcnkgYnkgZGVmYXVsdC5cbiAqL1xuZXhwb3J0IGNsYXNzIENka0RyaWZ0RGV0ZWN0aW9uU2NyaXB0IHtcbiAgY29uc3RydWN0b3IocHJvcHM6IENka0RyaWZ0RGV0ZWN0aW9uU2NyaXB0UHJvcHMpIHtcbiAgICBjb25zdCBvdXRwdXRQYXRoID0gcHJvcHMub3V0cHV0UGF0aCA/PyAnLmdpdGh1Yi93b3JrZmxvd3Mvc2NyaXB0cy9kZXRlY3QtZHJpZnQudHMnO1xuXG4gICAgbmV3IFRleHRGaWxlKHByb3BzLnByb2plY3QsIG91dHB1dFBhdGgsIHtcbiAgICAgIGxpbmVzOiBbXG4gICAgICAgIFwiaW1wb3J0IHtcXG4gIENsb3VkRm9ybWF0aW9uQ2xpZW50LFxcbiAgRGVzY3JpYmVTdGFja0RyaWZ0RGV0ZWN0aW9uU3RhdHVzQ29tbWFuZCxcXG4gIERldGVjdFN0YWNrRHJpZnRDb21tYW5kLFxcbiAgRGVzY3JpYmVTdGFja1Jlc291cmNlRHJpZnRzQ29tbWFuZCxcXG4gIHR5cGUgRGVzY3JpYmVTdGFja1Jlc291cmNlRHJpZnRzQ29tbWFuZE91dHB1dCxcXG4gIHR5cGUgU3RhY2tSZXNvdXJjZURyaWZ0U3RhdHVzLFxcbn0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWNsb3VkZm9ybWF0aW9uJztcIixcbiAgICAgICAgJycsXG4gICAgICAgICdhc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKSB7JyxcbiAgICAgICAgJyAgcmV0dXJuIG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIG1zKSk7JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2FzeW5jIGZ1bmN0aW9uIG1haW4oKSB7JyxcbiAgICAgICAgJyAgY29uc3Qgc3RhY2tOYW1lID0gcHJvY2Vzcy5lbnYuU1RBQ0tfTkFNRTsnLFxuICAgICAgICAnICBpZiAoIXN0YWNrTmFtZSkgeycsXG4gICAgICAgIFwiICAgIGNvbnNvbGUuZXJyb3IoJ1NUQUNLX05BTUUgZW52IHZhciBpcyByZXF1aXJlZCcpO1wiLFxuICAgICAgICAnICAgIHByb2Nlc3MuZXhpdCgxKTsnLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJycsXG4gICAgICAgICcgIC8vIFJlZ2lvbiBhbmQgY3JlZGVudGlhbHMgcHVsbGVkIGZyb20gZW52aXJvbm1lbnQgc2V0IGJ5IGFjdGlvbnMvY29uZmlndXJlLWF3cy1jcmVkZW50aWFscycsXG4gICAgICAgICcgIGNvbnN0IGNsaWVudCA9IG5ldyBDbG91ZEZvcm1hdGlvbkNsaWVudCh7fSk7JyxcbiAgICAgICAgJycsXG4gICAgICAgICcgIGNvbnN0IGRldGVjdCA9IGF3YWl0IGNsaWVudC5zZW5kKG5ldyBEZXRlY3RTdGFja0RyaWZ0Q29tbWFuZCh7IFN0YWNrTmFtZTogc3RhY2tOYW1lIH0pKTsnLFxuICAgICAgICAnICBpZiAoIWRldGVjdC5TdGFja0RyaWZ0RGV0ZWN0aW9uSWQpIHsnLFxuICAgICAgICBcIiAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gc3RhcnQgZHJpZnQgZGV0ZWN0aW9uJyk7XCIsXG4gICAgICAgICcgICAgcHJvY2Vzcy5leGl0KDEpOycsXG4gICAgICAgICcgIH0nLFxuICAgICAgICAnJyxcbiAgICAgICAgJyAgY29uc3QgaWQgPSBkZXRlY3QuU3RhY2tEcmlmdERldGVjdGlvbklkOycsXG4gICAgICAgICcgIGNvbnNvbGUubG9nKGBEcmlmdCBkZXRlY3Rpb24gc3RhcnRlZDogJHtpZH1gKTsnLFxuICAgICAgICAnJyxcbiAgICAgICAgXCIgIGxldCBkZXRlY3Rpb25TdGF0dXMgPSAnREVURUNUSU9OX0lOX1BST0dSRVNTJztcIixcbiAgICAgICAgJyAgbGV0IHN0YWNrRHJpZnRTdGF0dXM6IHN0cmluZyB8IHVuZGVmaW5lZDsnLFxuICAgICAgICAnJyxcbiAgICAgICAgXCIgIHdoaWxlIChkZXRlY3Rpb25TdGF0dXMgPT09ICdERVRFQ1RJT05fSU5fUFJPR1JFU1MnKSB7XCIsXG4gICAgICAgICcgICAgYXdhaXQgc2xlZXAoNTAwMCk7JyxcbiAgICAgICAgJyAgICBjb25zdCByZXMgPSBhd2FpdCBjbGllbnQuc2VuZCgnLFxuICAgICAgICAnICAgICAgbmV3IERlc2NyaWJlU3RhY2tEcmlmdERldGVjdGlvblN0YXR1c0NvbW1hbmQoeyBTdGFja0RyaWZ0RGV0ZWN0aW9uSWQ6IGlkIH0pLCcsXG4gICAgICAgICcgICAgKTsnLFxuICAgICAgICBcIiAgICBkZXRlY3Rpb25TdGF0dXMgPSByZXMuRGV0ZWN0aW9uU3RhdHVzID8/ICdVTktOT1dOJztcIixcbiAgICAgICAgJyAgICBzdGFja0RyaWZ0U3RhdHVzID0gcmVzLlN0YWNrRHJpZnRTdGF0dXM7JyxcbiAgICAgICAgJyAgICBjb25zb2xlLmxvZyhgRGV0ZWN0aW9uIHN0YXR1czogJHtkZXRlY3Rpb25TdGF0dXN9YCk7JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcnLFxuICAgICAgICAnICAvLyBIZWxwZXIgdG8gYnVpbGQgYW4gSFRNTCByZXBvcnQgb2YgZHJpZnRlZCByZXNvdXJjZXMnLFxuICAgICAgICAnICBjb25zdCBidWlsZEh0bWwgPSAoc3RhY2s6IHN0cmluZywgZHJpZnRzOiBhbnlbXSk6IHN0cmluZyA9PiB7JyxcbiAgICAgICAgJyAgICBsZXQgYm9keSA9IGA8aDE+RHJpZnQgcmVwb3J0PC9oMT48aDI+U3RhY2sgTmFtZTogJHtzdGFja308L2gyPjxicj5gOycsXG4gICAgICAgICcgICAgaWYgKGRyaWZ0cy5sZW5ndGggPT09IDApIHsnLFxuICAgICAgICBcIiAgICAgIGJvZHkgKz0gJ25vIGRyaWZ0Lic7XCIsXG4gICAgICAgICcgICAgICByZXR1cm4gYm9keTsnLFxuICAgICAgICAnICAgIH0nLFxuICAgICAgICBcIiAgICBib2R5ICs9ICc8dGFibGU+JyArXCIsXG4gICAgICAgIFwiICAgICAgJzx0cj48dGg+U3RhdHVzPC90aD48dGg+SUQ8L3RoPjx0aD5UeXBlPC90aD48dGg+RGlmZmVyZW5jZXM8L3RoPjwvdHI+JztcIixcbiAgICAgICAgJyAgICBmb3IgKGNvbnN0IGQgb2YgZHJpZnRzKSB7JyxcbiAgICAgICAgXCIgICAgICBjb25zdCBzdGF0dXMgPSBkLlN0YWNrUmVzb3VyY2VEcmlmdFN0YXR1cyA/PyAnLSc7XCIsXG4gICAgICAgIFwiICAgICAgY29uc3QgbG9naWNhbElkID0gZC5Mb2dpY2FsUmVzb3VyY2VJZCA/PyAnLSc7XCIsXG4gICAgICAgIFwiICAgICAgY29uc3QgdHlwZSA9IGQuUmVzb3VyY2VUeXBlID8/ICctJztcIixcbiAgICAgICAgJyAgICAgIGNvbnN0IGRpZmZzID0gKGQuUHJvcGVydHlEaWZmZXJlbmNlcyA/PyBbXSkubWFwKChwZDogYW55KSA9PiB7JyxcbiAgICAgICAgXCIgICAgICAgIGNvbnN0IHAgPSBwZC5Qcm9wZXJ0eVBhdGggPz8gJy0nO1wiLFxuICAgICAgICBcIiAgICAgICAgY29uc3QgdCA9IHBkLkRpZmZlcmVuY2VUeXBlID8/ICctJztcIixcbiAgICAgICAgJyAgICAgICAgcmV0dXJuIGAtICR7dH06ICR7cH1gOycsXG4gICAgICAgIFwiICAgICAgfSkuam9pbignPGJyPicpO1wiLFxuICAgICAgICBcIiAgICAgIGNvbnN0IHN0YXR1c0Vtb2ppID0gc3RhdHVzID09PSAnTU9ESUZJRUQnID8gJ/Cfn6AnIDogc3RhdHVzID09PSAnREVMRVRFRCcgPyAn8J+UtCcgOiBzdGF0dXMgPT09ICdOT1RfQ0hFQ0tFRCcgPyAn4pqqJyA6ICfwn5+iJztcIixcbiAgICAgICAgXCIgICAgICBib2R5ICs9ICc8dHI+JyArXCIsXG4gICAgICAgICcgICAgICAgIGA8dGQ+JHtzdGF0dXNFbW9qaX0gJHtzdGF0dXN9PC90ZD5gICsnLFxuICAgICAgICAnICAgICAgICBgPHRkPiR7bG9naWNhbElkfTwvdGQ+YCArJyxcbiAgICAgICAgJyAgICAgICAgYDx0ZD4ke3R5cGV9PC90ZD5gICsnLFxuICAgICAgICAnICAgICAgICBgPHRkPiR7ZGlmZnN9PC90ZD5gICsnLFxuICAgICAgICBcIiAgICAgICAgJzwvdHI+JztcIixcbiAgICAgICAgJyAgICB9JyxcbiAgICAgICAgXCIgICAgYm9keSArPSAnPC90YWJsZT4nO1wiLFxuICAgICAgICAnICAgIHJldHVybiBib2R5OycsXG4gICAgICAgICcgIH07JyxcbiAgICAgICAgJycsXG4gICAgICAgICcgIGFzeW5jIGZ1bmN0aW9uIGxpc3REcmlmdGVkUmVzb3VyY2VzKCk6IFByb21pc2U8YW55W10+IHsnLFxuICAgICAgICAnICAgIGNvbnN0IHJlc3VsdHM6IGFueVtdID0gW107JyxcbiAgICAgICAgJyAgICAvLyBPbmx5IGluY2x1ZGUgcmVzb3VyY2VzIHRoYXQgYXJlIG5vdCBJTl9TWU5DJyxcbiAgICAgICAgXCIgICAgY29uc3QgZmlsdGVyczogU3RhY2tSZXNvdXJjZURyaWZ0U3RhdHVzW10gPSBbJ01PRElGSUVEJywgJ0RFTEVURUQnLCAnTk9UX0NIRUNLRUQnXTtcIixcbiAgICAgICAgJyAgICBsZXQgbmV4dFRva2VuOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7JyxcbiAgICAgICAgJyAgICBkbyB7JyxcbiAgICAgICAgJyAgICAgIGNvbnN0IHJlc3A6IERlc2NyaWJlU3RhY2tSZXNvdXJjZURyaWZ0c0NvbW1hbmRPdXRwdXQgPSBhd2FpdCBjbGllbnQuc2VuZChuZXcgRGVzY3JpYmVTdGFja1Jlc291cmNlRHJpZnRzQ29tbWFuZCh7JyxcbiAgICAgICAgJyAgICAgICAgU3RhY2tOYW1lOiBzdGFja05hbWUsJyxcbiAgICAgICAgJyAgICAgICAgTmV4dFRva2VuOiBuZXh0VG9rZW4sJyxcbiAgICAgICAgJyAgICAgICAgU3RhY2tSZXNvdXJjZURyaWZ0U3RhdHVzRmlsdGVyczogZmlsdGVycywnLFxuICAgICAgICAnICAgICAgfSkpOycsXG4gICAgICAgICcgICAgICBpZiAocmVzcC5TdGFja1Jlc291cmNlRHJpZnRzKSByZXN1bHRzLnB1c2goLi4ucmVzcC5TdGFja1Jlc291cmNlRHJpZnRzKTsnLFxuICAgICAgICAnICAgICAgbmV4dFRva2VuID0gcmVzcC5OZXh0VG9rZW47JyxcbiAgICAgICAgJyAgICB9IHdoaWxlIChuZXh0VG9rZW4pOycsXG4gICAgICAgICcgICAgcmV0dXJuIHJlc3VsdHM7JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcnLFxuICAgICAgICAnICBhc3luYyBmdW5jdGlvbiBwb3N0R2l0aHViQ29tbWVudCh1cmw6IHN0cmluZywgdG9rZW46IHN0cmluZywgYm9keTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7JyxcbiAgICAgICAgJyAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCh1cmwsIHsnLFxuICAgICAgICBcIiAgICAgIG1ldGhvZDogJ1BPU1QnLFwiLFxuICAgICAgICAnICAgICAgaGVhZGVyczogeycsXG4gICAgICAgIFwiICAgICAgICAnQXV0aG9yaXphdGlvbic6IGB0b2tlbiAke3Rva2VufWAsXCIsXG4gICAgICAgIFwiICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFwiLFxuICAgICAgICBcIiAgICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi92bmQuZ2l0aHViK2pzb24nLFwiLFxuICAgICAgICAnICAgICAgfSwnLFxuICAgICAgICAnICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBib2R5IH0pLCcsXG4gICAgICAgICcgICAgfSk7JyxcbiAgICAgICAgJyAgICBpZiAoIXJlcy5vaykgeycsXG4gICAgICAgICcgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVzLnRleHQoKS5jYXRjaCgoKSA9PiBcXCdcXCcpOycsXG4gICAgICAgICcgICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcG9zdCBHaXRIdWIgY29tbWVudDogJHtyZXMuc3RhdHVzfSAke3Jlcy5zdGF0dXNUZXh0fSAke3RleHR9YCk7JyxcbiAgICAgICAgJyAgICB9JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcnLFxuICAgICAgICAnICAvLyBXaGVuIHRoZXJlIGlzIGRyaWZ0LCBjb2xsZWN0IGRldGFpbHMgYW5kIHBvc3QgYSBQUiBjb21tZW50ICsgc3RlcCBzdW1tYXJ5JyxcbiAgICAgICAgJyAgY29uc3Qgb3V0cHV0RmlsZSA9IHByb2Nlc3MuZW52LkRSSUZUX0RFVEVDVElPTl9PVVRQVVQ7JyxcbiAgICAgICAgXCIgIGlmIChzdGFja0RyaWZ0U3RhdHVzICE9PSAnSU5fU1lOQycpIHtcIixcbiAgICAgICAgJyAgICBjb25zb2xlLmVycm9yKGBEcmlmdCBkZXRlY3RlZCAoc3RhdHVzOiAke3N0YWNrRHJpZnRTdGF0dXN9KWApOycsXG4gICAgICAgICcgICAgY29uc3QgZHJpZnRzID0gYXdhaXQgbGlzdERyaWZ0ZWRSZXNvdXJjZXMoKTsnLFxuICAgICAgICAnICAgIGNvbnN0IGh0bWwgPSBidWlsZEh0bWwoc3RhY2tOYW1lLCBkcmlmdHMpOycsXG4gICAgICAgICcnLFxuICAgICAgICAnICAgIC8vIFdyaXRlIG1hY2hpbmUtcmVhZGFibGUgSlNPTiBpZiByZXF1ZXN0ZWQnLFxuICAgICAgICAnICAgIGlmIChvdXRwdXRGaWxlKSB7JyxcbiAgICAgICAgJyAgICAgIHRyeSB7JyxcbiAgICAgICAgXCIgICAgICAgIGNvbnN0IHsgd3JpdGVGaWxlIH0gPSBhd2FpdCBpbXBvcnQoJ2ZzL3Byb21pc2VzJyk7XCIsXG4gICAgICAgICcgICAgICAgIGNvbnN0IHJlc3VsdCA9IFsnLFxuICAgICAgICAnICAgICAgICAgIHsnLFxuICAgICAgICAnICAgICAgICAgICAgc3RhY2tOYW1lLCcsXG4gICAgICAgICcgICAgICAgICAgICBkcmlmdFN0YXR1czogc3RhY2tEcmlmdFN0YXR1cywnLFxuICAgICAgICAnICAgICAgICAgICAgZHJpZnRlZFJlc291cmNlczogKGRyaWZ0cyB8fCBbXSkubWFwKGQgPT4gKHsnLFxuICAgICAgICAnICAgICAgICAgICAgICBsb2dpY2FsUmVzb3VyY2VJZDogZC5Mb2dpY2FsUmVzb3VyY2VJZCwnLFxuICAgICAgICAnICAgICAgICAgICAgICByZXNvdXJjZVR5cGU6IGQuUmVzb3VyY2VUeXBlLCcsXG4gICAgICAgICcgICAgICAgICAgICAgIHN0YWNrUmVzb3VyY2VEcmlmdFN0YXR1czogZC5TdGFja1Jlc291cmNlRHJpZnRTdGF0dXMsJyxcbiAgICAgICAgJyAgICAgICAgICAgICAgcHJvcGVydHlEaWZmZXJlbmNlczogZC5Qcm9wZXJ0eURpZmZlcmVuY2VzLCcsXG4gICAgICAgICcgICAgICAgICAgICB9KSksJyxcbiAgICAgICAgJyAgICAgICAgICB9LCcsXG4gICAgICAgICcgICAgICAgIF07JyxcbiAgICAgICAgXCIgICAgICAgIGF3YWl0IHdyaXRlRmlsZShvdXRwdXRGaWxlLCBKU09OLnN0cmluZ2lmeShyZXN1bHQsIG51bGwsIDIpLCB7IGVuY29kaW5nOiAndXRmOCcgfSk7XCIsXG4gICAgICAgICcgICAgICB9IGNhdGNoIChlOiBhbnkpIHsnLFxuICAgICAgICBcIiAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIHdyaXRlIGRyaWZ0IEpTT04gcmVzdWx0czonLCBlPy5tZXNzYWdlIHx8IGUpO1wiLFxuICAgICAgICAnICAgICAgfScsXG4gICAgICAgICcgICAgfScsXG4gICAgICAgICcnLFxuICAgICAgICAnICAgIC8vIFByaW50IHRvIHN0ZG91dCBhbmQgYXBwZW5kIHRvIHN1bW1hcnkgaWYgYXZhaWxhYmxlJyxcbiAgICAgICAgJyAgICBjb25zb2xlLmxvZyhodG1sKTsnLFxuICAgICAgICAnICAgIGNvbnN0IHN0ZXBTdW1tYXJ5ID0gcHJvY2Vzcy5lbnYuR0lUSFVCX1NURVBfU1VNTUFSWTsnLFxuICAgICAgICAnICAgIGlmIChzdGVwU3VtbWFyeSkgeycsXG4gICAgICAgICcgICAgICB0cnkgeycsXG4gICAgICAgIFwiICAgICAgICBjb25zdCB7IGFwcGVuZEZpbGUgfSA9IGF3YWl0IGltcG9ydCgnZnMvcHJvbWlzZXMnKTtcIixcbiAgICAgICAgXCIgICAgICAgIGF3YWl0IGFwcGVuZEZpbGUoc3RlcFN1bW1hcnksIGAke2h0bWx9XFxcXG5gLCB7IGVuY29kaW5nOiAndXRmOCcgfSk7XCIsXG4gICAgICAgICcgICAgICB9IGNhdGNoIChlOiBhbnkpIHsnLFxuICAgICAgICBcIiAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGFwcGVuZCB0byBHSVRIVUJfU1RFUF9TVU1NQVJZOicsIGU/Lm1lc3NhZ2UgfHwgZSk7XCIsXG4gICAgICAgICcgICAgICB9JyxcbiAgICAgICAgJyAgICB9JyxcbiAgICAgICAgJycsXG4gICAgICAgICcgICAgY29uc3QgY29tbWVudFVybCA9IHByb2Nlc3MuZW52LkdJVEhVQl9DT01NRU5UX1VSTDsnLFxuICAgICAgICAnICAgIGNvbnN0IHRva2VuID0gcHJvY2Vzcy5lbnYuR0lUSFVCX1RPS0VOOycsXG4gICAgICAgICcgICAgaWYgKGNvbW1lbnRVcmwgJiYgdG9rZW4pIHsnLFxuICAgICAgICAnICAgICAgYXdhaXQgcG9zdEdpdGh1YkNvbW1lbnQoY29tbWVudFVybCwgdG9rZW4sIGh0bWwpOycsXG4gICAgICAgICcgICAgfScsXG4gICAgICAgICcnLFxuICAgICAgICAnICAgIHByb2Nlc3MuZXhpdCgxKTsnLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJycsXG4gICAgICAgICcgIC8vIE5vIGRyaWZ0IGNhc2UnLFxuICAgICAgICAnICBpZiAob3V0cHV0RmlsZSkgeycsXG4gICAgICAgICcgICAgdHJ5IHsnLFxuICAgICAgICBcIiAgICAgIGNvbnN0IHsgd3JpdGVGaWxlIH0gPSBhd2FpdCBpbXBvcnQoJ2ZzL3Byb21pc2VzJyk7XCIsXG4gICAgICAgICcgICAgICBjb25zdCByZXN1bHQgPSBbJyxcbiAgICAgICAgJyAgICAgICAgeycsXG4gICAgICAgICcgICAgICAgICAgc3RhY2tOYW1lLCcsXG4gICAgICAgIFwiICAgICAgICAgIGRyaWZ0U3RhdHVzOiAnSU5fU1lOQycsXCIsXG4gICAgICAgICcgICAgICAgICAgZHJpZnRlZFJlc291cmNlczogW10sJyxcbiAgICAgICAgJyAgICAgICAgfSwnLFxuICAgICAgICAnICAgICAgXTsnLFxuICAgICAgICBcIiAgICAgIGF3YWl0IHdyaXRlRmlsZShvdXRwdXRGaWxlLCBKU09OLnN0cmluZ2lmeShyZXN1bHQsIG51bGwsIDIpLCB7IGVuY29kaW5nOiAndXRmOCcgfSk7XCIsXG4gICAgICAgICcgICAgfSBjYXRjaCAoZTogYW55KSB7JyxcbiAgICAgICAgXCIgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gd3JpdGUgZHJpZnQgSlNPTiByZXN1bHRzOicsIGU/Lm1lc3NhZ2UgfHwgZSk7XCIsXG4gICAgICAgICcgICAgfScsXG4gICAgICAgICcgIH0nLFxuICAgICAgICBcIiAgY29uc29sZS5sb2coJ05vIGRyaWZ0IGRldGVjdGVkIChJTl9TWU5DKScpO1wiLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnbWFpbigpLmNhdGNoKChlKSA9PiB7JyxcbiAgICAgICAgJyAgY29uc29sZS5lcnJvcihlKTsnLFxuICAgICAgICAnICBwcm9jZXNzLmV4aXQoMSk7JyxcbiAgICAgICAgJ30pOycsXG4gICAgICBdLFxuICAgIH0pO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
4
+ async function sleep(ms) {
5
+ return new Promise((r) => setTimeout(r, ms));
6
+ }
7
+ async function main() {
8
+ const stackName = process.env.STACK_NAME;
9
+ if (!stackName) {
10
+ console.error('STACK_NAME env var is required');
11
+ process.exit(1);
12
+ }
13
+ // Region and credentials pulled from environment set by actions/configure-aws-credentials
14
+ const client = new client_cloudformation_1.CloudFormationClient({});
15
+ const detect = await client.send(new client_cloudformation_1.DetectStackDriftCommand({ StackName: stackName }));
16
+ if (!detect.StackDriftDetectionId) {
17
+ console.error('Failed to start drift detection');
18
+ process.exit(1);
19
+ }
20
+ const id = detect.StackDriftDetectionId;
21
+ console.log(`Drift detection started: ${id}`);
22
+ let detectionStatus = 'DETECTION_IN_PROGRESS';
23
+ let stackDriftStatus;
24
+ while (detectionStatus === 'DETECTION_IN_PROGRESS') {
25
+ await sleep(5000);
26
+ const res = await client.send(new client_cloudformation_1.DescribeStackDriftDetectionStatusCommand({ StackDriftDetectionId: id }));
27
+ detectionStatus = res.DetectionStatus ?? 'UNKNOWN';
28
+ stackDriftStatus = res.StackDriftStatus;
29
+ console.log(`Detection status: ${detectionStatus}`);
30
+ }
31
+ // Helper to build an HTML report of drifted resources
32
+ const buildHtml = (stack, drifts) => {
33
+ let body = `<h1>Drift report</h1><h2>Stack Name: ${stack}</h2><br>`;
34
+ if (drifts.length === 0) {
35
+ body += 'no drift.';
36
+ return body;
37
+ }
38
+ body += '<table>' +
39
+ '<tr><th>Status</th><th>ID</th><th>Type</th><th>Differences</th></tr>';
40
+ for (const d of drifts) {
41
+ const status = d.StackResourceDriftStatus ?? '-';
42
+ const logicalId = d.LogicalResourceId ?? '-';
43
+ const type = d.ResourceType ?? '-';
44
+ const diffs = (d.PropertyDifferences ?? []).map((pd) => {
45
+ const p = pd.PropertyPath ?? '-';
46
+ const t = pd.DifferenceType ?? '-';
47
+ return `- ${t}: ${p}`;
48
+ }).join('<br>');
49
+ const statusEmoji = status === 'MODIFIED' ? '🟠' : status === 'DELETED' ? '🔴' : status === 'NOT_CHECKED' ? '⚪' : '🟢';
50
+ body += '<tr>' +
51
+ `<td>${statusEmoji} ${status}</td>` +
52
+ `<td>${logicalId}</td>` +
53
+ `<td>${type}</td>` +
54
+ `<td>${diffs}</td>` +
55
+ '</tr>';
56
+ }
57
+ body += '</table>';
58
+ return body;
59
+ };
60
+ async function listDriftedResources() {
61
+ const results = [];
62
+ // Only include resources that are not IN_SYNC
63
+ const filters = ['MODIFIED', 'DELETED', 'NOT_CHECKED'];
64
+ let nextToken = undefined;
65
+ do {
66
+ const resp = await client.send(new client_cloudformation_1.DescribeStackResourceDriftsCommand({
67
+ StackName: stackName,
68
+ NextToken: nextToken,
69
+ StackResourceDriftStatusFilters: filters,
70
+ }));
71
+ if (resp.StackResourceDrifts)
72
+ results.push(...resp.StackResourceDrifts);
73
+ nextToken = resp.NextToken;
74
+ } while (nextToken);
75
+ return results;
76
+ }
77
+ async function postGithubComment(url, token, body) {
78
+ const res = await fetch(url, {
79
+ method: 'POST',
80
+ headers: {
81
+ 'Authorization': `token ${token}`,
82
+ 'Content-Type': 'application/json',
83
+ 'Accept': 'application/vnd.github+json',
84
+ },
85
+ body: JSON.stringify({ body }),
86
+ });
87
+ if (!res.ok) {
88
+ const text = await res.text().catch(() => '');
89
+ console.error(`Failed to post GitHub comment: ${res.status} ${res.statusText} ${text}`);
90
+ }
91
+ }
92
+ // When there is drift, collect details and post a PR comment + step summary
93
+ const outputFile = process.env.DRIFT_DETECTION_OUTPUT;
94
+ if (stackDriftStatus !== 'IN_SYNC') {
95
+ console.error(`Drift detected (status: ${stackDriftStatus})`);
96
+ const drifts = await listDriftedResources();
97
+ const html = buildHtml(stackName, drifts);
98
+ // Write machine-readable JSON if requested
99
+ if (outputFile) {
100
+ try {
101
+ const { writeFile } = await Promise.resolve().then(() => require('fs/promises'));
102
+ const result = [
103
+ {
104
+ stackName,
105
+ driftStatus: stackDriftStatus,
106
+ driftedResources: (drifts || []).map(d => ({
107
+ logicalResourceId: d.LogicalResourceId,
108
+ resourceType: d.ResourceType,
109
+ stackResourceDriftStatus: d.StackResourceDriftStatus,
110
+ propertyDifferences: d.PropertyDifferences,
111
+ })),
112
+ },
113
+ ];
114
+ await writeFile(outputFile, JSON.stringify(result, null, 2), { encoding: 'utf8' });
115
+ }
116
+ catch (e) {
117
+ console.error('Failed to write drift JSON results:', e?.message || e);
118
+ }
119
+ }
120
+ // Print to stdout and append to summary if available
121
+ console.log(html);
122
+ const stepSummary = process.env.GITHUB_STEP_SUMMARY;
123
+ if (stepSummary) {
124
+ try {
125
+ const { appendFile } = await Promise.resolve().then(() => require('fs/promises'));
126
+ await appendFile(stepSummary, `${html}\n`, { encoding: 'utf8' });
127
+ }
128
+ catch (e) {
129
+ console.error('Failed to append to GITHUB_STEP_SUMMARY:', e?.message || e);
130
+ }
131
+ }
132
+ const commentUrl = process.env.GITHUB_COMMENT_URL;
133
+ const token = process.env.GITHUB_TOKEN;
134
+ if (commentUrl && token) {
135
+ await postGithubComment(commentUrl, token, html);
136
+ }
137
+ process.exit(1);
138
+ }
139
+ // No drift case
140
+ if (outputFile) {
141
+ try {
142
+ const { writeFile } = await Promise.resolve().then(() => require('fs/promises'));
143
+ const result = [
144
+ {
145
+ stackName,
146
+ driftStatus: 'IN_SYNC',
147
+ driftedResources: [],
148
+ },
149
+ ];
150
+ await writeFile(outputFile, JSON.stringify(result, null, 2), { encoding: 'utf8' });
151
+ }
152
+ catch (e) {
153
+ console.error('Failed to write drift JSON results:', e?.message || e);
154
+ }
155
+ }
156
+ console.log('No drift detected (IN_SYNC)');
157
+ }
158
+ main().catch((e) => {
159
+ console.error(e);
160
+ process.exit(1);
161
+ });
162
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV0ZWN0LWRyaWZ0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Jpbi9kZXRlY3QtZHJpZnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwwRUFPd0M7QUFFeEMsS0FBSyxVQUFVLEtBQUssQ0FBQyxFQUFVO0lBQzdCLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMvQyxDQUFDO0FBRUQsS0FBSyxVQUFVLElBQUk7SUFDakIsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUM7SUFDekMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1FBQ2hELE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEIsQ0FBQztJQUVELDBGQUEwRjtJQUMxRixNQUFNLE1BQU0sR0FBRyxJQUFJLDRDQUFvQixDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRTVDLE1BQU0sTUFBTSxHQUFHLE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLCtDQUF1QixDQUFDLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN4RixJQUFJLENBQUMsTUFBTSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDbEMsT0FBTyxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1FBQ2pELE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEIsQ0FBQztJQUVELE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQztJQUN4QyxPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBRTlDLElBQUksZUFBZSxHQUFHLHVCQUF1QixDQUFDO0lBQzlDLElBQUksZ0JBQW9DLENBQUM7SUFFekMsT0FBTyxlQUFlLEtBQUssdUJBQXVCLEVBQUUsQ0FBQztRQUNuRCxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQixNQUFNLEdBQUcsR0FBRyxNQUFNLE1BQU0sQ0FBQyxJQUFJLENBQzNCLElBQUksZ0VBQXdDLENBQUMsRUFBRSxxQkFBcUIsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUM1RSxDQUFDO1FBQ0YsZUFBZSxHQUFHLEdBQUcsQ0FBQyxlQUFlLElBQUksU0FBUyxDQUFDO1FBQ25ELGdCQUFnQixHQUFHLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQztRQUN4QyxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixlQUFlLEVBQUUsQ0FBQyxDQUFDO0lBQ3RELENBQUM7SUFFRCxzREFBc0Q7SUFDdEQsTUFBTSxTQUFTLEdBQUcsQ0FBQyxLQUFhLEVBQUUsTUFBYSxFQUFVLEVBQUU7UUFDekQsSUFBSSxJQUFJLEdBQUcsd0NBQXdDLEtBQUssV0FBVyxDQUFDO1FBQ3BFLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN4QixJQUFJLElBQUksV0FBVyxDQUFDO1lBQ3BCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELElBQUksSUFBSSxTQUFTO1lBQ2Ysc0VBQXNFLENBQUM7UUFDekUsS0FBSyxNQUFNLENBQUMsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUN2QixNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUMsd0JBQXdCLElBQUksR0FBRyxDQUFDO1lBQ2pELE1BQU0sU0FBUyxHQUFHLENBQUMsQ0FBQyxpQkFBaUIsSUFBSSxHQUFHLENBQUM7WUFDN0MsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLFlBQVksSUFBSSxHQUFHLENBQUM7WUFDbkMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBTyxFQUFFLEVBQUU7Z0JBQzFELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxZQUFZLElBQUksR0FBRyxDQUFDO2dCQUNqQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsY0FBYyxJQUFJLEdBQUcsQ0FBQztnQkFDbkMsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN4QixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDaEIsTUFBTSxXQUFXLEdBQUcsTUFBTSxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxhQUFhLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ3ZILElBQUksSUFBSSxNQUFNO2dCQUNaLE9BQU8sV0FBVyxJQUFJLE1BQU0sT0FBTztnQkFDbkMsT0FBTyxTQUFTLE9BQU87Z0JBQ3ZCLE9BQU8sSUFBSSxPQUFPO2dCQUNsQixPQUFPLEtBQUssT0FBTztnQkFDbkIsT0FBTyxDQUFDO1FBQ1osQ0FBQztRQUNELElBQUksSUFBSSxVQUFVLENBQUM7UUFDbkIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDLENBQUM7SUFFRixLQUFLLFVBQVUsb0JBQW9CO1FBQ2pDLE1BQU0sT0FBTyxHQUFVLEVBQUUsQ0FBQztRQUMxQiw4Q0FBOEM7UUFDOUMsTUFBTSxPQUFPLEdBQStCLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUNuRixJQUFJLFNBQVMsR0FBdUIsU0FBUyxDQUFDO1FBQzlDLEdBQUcsQ0FBQztZQUNGLE1BQU0sSUFBSSxHQUE2QyxNQUFNLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSwwREFBa0MsQ0FBQztnQkFDOUcsU0FBUyxFQUFFLFNBQVM7Z0JBQ3BCLFNBQVMsRUFBRSxTQUFTO2dCQUNwQiwrQkFBK0IsRUFBRSxPQUFPO2FBQ3pDLENBQUMsQ0FBQyxDQUFDO1lBQ0osSUFBSSxJQUFJLENBQUMsbUJBQW1CO2dCQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQztZQUN4RSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUM3QixDQUFDLFFBQVEsU0FBUyxFQUFFO1FBQ3BCLE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRCxLQUFLLFVBQVUsaUJBQWlCLENBQUMsR0FBVyxFQUFFLEtBQWEsRUFBRSxJQUFZO1FBQ3ZFLE1BQU0sR0FBRyxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsRUFBRTtZQUMzQixNQUFNLEVBQUUsTUFBTTtZQUNkLE9BQU8sRUFBRTtnQkFDUCxlQUFlLEVBQUUsU0FBUyxLQUFLLEVBQUU7Z0JBQ2pDLGNBQWMsRUFBRSxrQkFBa0I7Z0JBQ2xDLFFBQVEsRUFBRSw2QkFBNkI7YUFDeEM7WUFDRCxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDO1NBQy9CLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDWixNQUFNLElBQUksR0FBRyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDOUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsR0FBRyxDQUFDLE1BQU0sSUFBSSxHQUFHLENBQUMsVUFBVSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7UUFDMUYsQ0FBQztJQUNILENBQUM7SUFFRCw0RUFBNEU7SUFDNUUsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQztJQUN0RCxJQUFJLGdCQUFnQixLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ25DLE9BQU8sQ0FBQyxLQUFLLENBQUMsMkJBQTJCLGdCQUFnQixHQUFHLENBQUMsQ0FBQztRQUM5RCxNQUFNLE1BQU0sR0FBRyxNQUFNLG9CQUFvQixFQUFFLENBQUM7UUFDNUMsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUUxQywyQ0FBMkM7UUFDM0MsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQztnQkFDSCxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsMkNBQWEsYUFBYSxFQUFDLENBQUM7Z0JBQ2xELE1BQU0sTUFBTSxHQUFHO29CQUNiO3dCQUNFLFNBQVM7d0JBQ1QsV0FBVyxFQUFFLGdCQUFnQjt3QkFDN0IsZ0JBQWdCLEVBQUUsQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQzs0QkFDekMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLGlCQUFpQjs0QkFDdEMsWUFBWSxFQUFFLENBQUMsQ0FBQyxZQUFZOzRCQUM1Qix3QkFBd0IsRUFBRSxDQUFDLENBQUMsd0JBQXdCOzRCQUNwRCxtQkFBbUIsRUFBRSxDQUFDLENBQUMsbUJBQW1CO3lCQUMzQyxDQUFDLENBQUM7cUJBQ0o7aUJBQ0YsQ0FBQztnQkFDRixNQUFNLFNBQVMsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDckYsQ0FBQztZQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7Z0JBQ2hCLE9BQU8sQ0FBQyxLQUFLLENBQUMscUNBQXFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQztZQUN4RSxDQUFDO1FBQ0gsQ0FBQztRQUVELHFEQUFxRDtRQUNyRCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xCLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUM7UUFDcEQsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUM7Z0JBQ0gsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLDJDQUFhLGFBQWEsRUFBQyxDQUFDO2dCQUNuRCxNQUFNLFVBQVUsQ0FBQyxXQUFXLEVBQUUsR0FBRyxJQUFJLElBQUksRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ25FLENBQUM7WUFBQyxPQUFPLENBQU0sRUFBRSxDQUFDO2dCQUNoQixPQUFPLENBQUMsS0FBSyxDQUFDLDBDQUEwQyxFQUFFLENBQUMsRUFBRSxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDN0UsQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDO1FBQ2xELE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDO1FBQ3ZDLElBQUksVUFBVSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ3hCLE1BQU0saUJBQWlCLENBQUMsVUFBVSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNuRCxDQUFDO1FBRUQsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsQixDQUFDO0lBRUQsZ0JBQWdCO0lBQ2hCLElBQUksVUFBVSxFQUFFLENBQUM7UUFDZixJQUFJLENBQUM7WUFDSCxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsMkNBQWEsYUFBYSxFQUFDLENBQUM7WUFDbEQsTUFBTSxNQUFNLEdBQUc7Z0JBQ2I7b0JBQ0UsU0FBUztvQkFDVCxXQUFXLEVBQUUsU0FBUztvQkFDdEIsZ0JBQWdCLEVBQUUsRUFBRTtpQkFDckI7YUFDRixDQUFDO1lBQ0YsTUFBTSxTQUFTLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3JGLENBQUM7UUFBQyxPQUFPLENBQU0sRUFBRSxDQUFDO1lBQ2hCLE9BQU8sQ0FBQyxLQUFLLENBQUMscUNBQXFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN4RSxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsNkJBQTZCLENBQUMsQ0FBQztBQUM3QyxDQUFDO0FBRUQsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7SUFDakIsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqQixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2xvdWRGb3JtYXRpb25DbGllbnQsXG4gIERlc2NyaWJlU3RhY2tEcmlmdERldGVjdGlvblN0YXR1c0NvbW1hbmQsXG4gIERldGVjdFN0YWNrRHJpZnRDb21tYW5kLFxuICBEZXNjcmliZVN0YWNrUmVzb3VyY2VEcmlmdHNDb21tYW5kLFxuICB0eXBlIERlc2NyaWJlU3RhY2tSZXNvdXJjZURyaWZ0c0NvbW1hbmRPdXRwdXQsXG4gIHR5cGUgU3RhY2tSZXNvdXJjZURyaWZ0U3RhdHVzLFxufSBmcm9tICdAYXdzLXNkay9jbGllbnQtY2xvdWRmb3JtYXRpb24nO1xuXG5hc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBtcykpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBtYWluKCkge1xuICBjb25zdCBzdGFja05hbWUgPSBwcm9jZXNzLmVudi5TVEFDS19OQU1FO1xuICBpZiAoIXN0YWNrTmFtZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoJ1NUQUNLX05BTUUgZW52IHZhciBpcyByZXF1aXJlZCcpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuXG4gIC8vIFJlZ2lvbiBhbmQgY3JlZGVudGlhbHMgcHVsbGVkIGZyb20gZW52aXJvbm1lbnQgc2V0IGJ5IGFjdGlvbnMvY29uZmlndXJlLWF3cy1jcmVkZW50aWFsc1xuICBjb25zdCBjbGllbnQgPSBuZXcgQ2xvdWRGb3JtYXRpb25DbGllbnQoe30pO1xuXG4gIGNvbnN0IGRldGVjdCA9IGF3YWl0IGNsaWVudC5zZW5kKG5ldyBEZXRlY3RTdGFja0RyaWZ0Q29tbWFuZCh7IFN0YWNrTmFtZTogc3RhY2tOYW1lIH0pKTtcbiAgaWYgKCFkZXRlY3QuU3RhY2tEcmlmdERldGVjdGlvbklkKSB7XG4gICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIHN0YXJ0IGRyaWZ0IGRldGVjdGlvbicpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuXG4gIGNvbnN0IGlkID0gZGV0ZWN0LlN0YWNrRHJpZnREZXRlY3Rpb25JZDtcbiAgY29uc29sZS5sb2coYERyaWZ0IGRldGVjdGlvbiBzdGFydGVkOiAke2lkfWApO1xuXG4gIGxldCBkZXRlY3Rpb25TdGF0dXMgPSAnREVURUNUSU9OX0lOX1BST0dSRVNTJztcbiAgbGV0IHN0YWNrRHJpZnRTdGF0dXM6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICB3aGlsZSAoZGV0ZWN0aW9uU3RhdHVzID09PSAnREVURUNUSU9OX0lOX1BST0dSRVNTJykge1xuICAgIGF3YWl0IHNsZWVwKDUwMDApO1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGNsaWVudC5zZW5kKFxuICAgICAgbmV3IERlc2NyaWJlU3RhY2tEcmlmdERldGVjdGlvblN0YXR1c0NvbW1hbmQoeyBTdGFja0RyaWZ0RGV0ZWN0aW9uSWQ6IGlkIH0pLFxuICAgICk7XG4gICAgZGV0ZWN0aW9uU3RhdHVzID0gcmVzLkRldGVjdGlvblN0YXR1cyA/PyAnVU5LTk9XTic7XG4gICAgc3RhY2tEcmlmdFN0YXR1cyA9IHJlcy5TdGFja0RyaWZ0U3RhdHVzO1xuICAgIGNvbnNvbGUubG9nKGBEZXRlY3Rpb24gc3RhdHVzOiAke2RldGVjdGlvblN0YXR1c31gKTtcbiAgfVxuXG4gIC8vIEhlbHBlciB0byBidWlsZCBhbiBIVE1MIHJlcG9ydCBvZiBkcmlmdGVkIHJlc291cmNlc1xuICBjb25zdCBidWlsZEh0bWwgPSAoc3RhY2s6IHN0cmluZywgZHJpZnRzOiBhbnlbXSk6IHN0cmluZyA9PiB7XG4gICAgbGV0IGJvZHkgPSBgPGgxPkRyaWZ0IHJlcG9ydDwvaDE+PGgyPlN0YWNrIE5hbWU6ICR7c3RhY2t9PC9oMj48YnI+YDtcbiAgICBpZiAoZHJpZnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgYm9keSArPSAnbm8gZHJpZnQuJztcbiAgICAgIHJldHVybiBib2R5O1xuICAgIH1cbiAgICBib2R5ICs9ICc8dGFibGU+JyArXG4gICAgICAnPHRyPjx0aD5TdGF0dXM8L3RoPjx0aD5JRDwvdGg+PHRoPlR5cGU8L3RoPjx0aD5EaWZmZXJlbmNlczwvdGg+PC90cj4nO1xuICAgIGZvciAoY29uc3QgZCBvZiBkcmlmdHMpIHtcbiAgICAgIGNvbnN0IHN0YXR1cyA9IGQuU3RhY2tSZXNvdXJjZURyaWZ0U3RhdHVzID8/ICctJztcbiAgICAgIGNvbnN0IGxvZ2ljYWxJZCA9IGQuTG9naWNhbFJlc291cmNlSWQgPz8gJy0nO1xuICAgICAgY29uc3QgdHlwZSA9IGQuUmVzb3VyY2VUeXBlID8/ICctJztcbiAgICAgIGNvbnN0IGRpZmZzID0gKGQuUHJvcGVydHlEaWZmZXJlbmNlcyA/PyBbXSkubWFwKChwZDogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IHAgPSBwZC5Qcm9wZXJ0eVBhdGggPz8gJy0nO1xuICAgICAgICBjb25zdCB0ID0gcGQuRGlmZmVyZW5jZVR5cGUgPz8gJy0nO1xuICAgICAgICByZXR1cm4gYC0gJHt0fTogJHtwfWA7XG4gICAgICB9KS5qb2luKCc8YnI+Jyk7XG4gICAgICBjb25zdCBzdGF0dXNFbW9qaSA9IHN0YXR1cyA9PT0gJ01PRElGSUVEJyA/ICfwn5+gJyA6IHN0YXR1cyA9PT0gJ0RFTEVURUQnID8gJ/CflLQnIDogc3RhdHVzID09PSAnTk9UX0NIRUNLRUQnID8gJ+KaqicgOiAn8J+foic7XG4gICAgICBib2R5ICs9ICc8dHI+JyArXG4gICAgICAgIGA8dGQ+JHtzdGF0dXNFbW9qaX0gJHtzdGF0dXN9PC90ZD5gICtcbiAgICAgICAgYDx0ZD4ke2xvZ2ljYWxJZH08L3RkPmAgK1xuICAgICAgICBgPHRkPiR7dHlwZX08L3RkPmAgK1xuICAgICAgICBgPHRkPiR7ZGlmZnN9PC90ZD5gICtcbiAgICAgICAgJzwvdHI+JztcbiAgICB9XG4gICAgYm9keSArPSAnPC90YWJsZT4nO1xuICAgIHJldHVybiBib2R5O1xuICB9O1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGxpc3REcmlmdGVkUmVzb3VyY2VzKCk6IFByb21pc2U8YW55W10+IHtcbiAgICBjb25zdCByZXN1bHRzOiBhbnlbXSA9IFtdO1xuICAgIC8vIE9ubHkgaW5jbHVkZSByZXNvdXJjZXMgdGhhdCBhcmUgbm90IElOX1NZTkNcbiAgICBjb25zdCBmaWx0ZXJzOiBTdGFja1Jlc291cmNlRHJpZnRTdGF0dXNbXSA9IFsnTU9ESUZJRUQnLCAnREVMRVRFRCcsICdOT1RfQ0hFQ0tFRCddO1xuICAgIGxldCBuZXh0VG9rZW46IHN0cmluZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICBkbyB7XG4gICAgICBjb25zdCByZXNwOiBEZXNjcmliZVN0YWNrUmVzb3VyY2VEcmlmdHNDb21tYW5kT3V0cHV0ID0gYXdhaXQgY2xpZW50LnNlbmQobmV3IERlc2NyaWJlU3RhY2tSZXNvdXJjZURyaWZ0c0NvbW1hbmQoe1xuICAgICAgICBTdGFja05hbWU6IHN0YWNrTmFtZSxcbiAgICAgICAgTmV4dFRva2VuOiBuZXh0VG9rZW4sXG4gICAgICAgIFN0YWNrUmVzb3VyY2VEcmlmdFN0YXR1c0ZpbHRlcnM6IGZpbHRlcnMsXG4gICAgICB9KSk7XG4gICAgICBpZiAocmVzcC5TdGFja1Jlc291cmNlRHJpZnRzKSByZXN1bHRzLnB1c2goLi4ucmVzcC5TdGFja1Jlc291cmNlRHJpZnRzKTtcbiAgICAgIG5leHRUb2tlbiA9IHJlc3AuTmV4dFRva2VuO1xuICAgIH0gd2hpbGUgKG5leHRUb2tlbik7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBwb3N0R2l0aHViQ29tbWVudCh1cmw6IHN0cmluZywgdG9rZW46IHN0cmluZywgYm9keTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2godXJsLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0F1dGhvcml6YXRpb24nOiBgdG9rZW4gJHt0b2tlbn1gLFxuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAnQWNjZXB0JzogJ2FwcGxpY2F0aW9uL3ZuZC5naXRodWIranNvbicsXG4gICAgICB9LFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBib2R5IH0pLFxuICAgIH0pO1xuICAgIGlmICghcmVzLm9rKSB7XG4gICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVzLnRleHQoKS5jYXRjaCgoKSA9PiAnJyk7XG4gICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcG9zdCBHaXRIdWIgY29tbWVudDogJHtyZXMuc3RhdHVzfSAke3Jlcy5zdGF0dXNUZXh0fSAke3RleHR9YCk7XG4gICAgfVxuICB9XG5cbiAgLy8gV2hlbiB0aGVyZSBpcyBkcmlmdCwgY29sbGVjdCBkZXRhaWxzIGFuZCBwb3N0IGEgUFIgY29tbWVudCArIHN0ZXAgc3VtbWFyeVxuICBjb25zdCBvdXRwdXRGaWxlID0gcHJvY2Vzcy5lbnYuRFJJRlRfREVURUNUSU9OX09VVFBVVDtcbiAgaWYgKHN0YWNrRHJpZnRTdGF0dXMgIT09ICdJTl9TWU5DJykge1xuICAgIGNvbnNvbGUuZXJyb3IoYERyaWZ0IGRldGVjdGVkIChzdGF0dXM6ICR7c3RhY2tEcmlmdFN0YXR1c30pYCk7XG4gICAgY29uc3QgZHJpZnRzID0gYXdhaXQgbGlzdERyaWZ0ZWRSZXNvdXJjZXMoKTtcbiAgICBjb25zdCBodG1sID0gYnVpbGRIdG1sKHN0YWNrTmFtZSwgZHJpZnRzKTtcblxuICAgIC8vIFdyaXRlIG1hY2hpbmUtcmVhZGFibGUgSlNPTiBpZiByZXF1ZXN0ZWRcbiAgICBpZiAob3V0cHV0RmlsZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyB3cml0ZUZpbGUgfSA9IGF3YWl0IGltcG9ydCgnZnMvcHJvbWlzZXMnKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHN0YWNrTmFtZSxcbiAgICAgICAgICAgIGRyaWZ0U3RhdHVzOiBzdGFja0RyaWZ0U3RhdHVzLFxuICAgICAgICAgICAgZHJpZnRlZFJlc291cmNlczogKGRyaWZ0cyB8fCBbXSkubWFwKGQgPT4gKHtcbiAgICAgICAgICAgICAgbG9naWNhbFJlc291cmNlSWQ6IGQuTG9naWNhbFJlc291cmNlSWQsXG4gICAgICAgICAgICAgIHJlc291cmNlVHlwZTogZC5SZXNvdXJjZVR5cGUsXG4gICAgICAgICAgICAgIHN0YWNrUmVzb3VyY2VEcmlmdFN0YXR1czogZC5TdGFja1Jlc291cmNlRHJpZnRTdGF0dXMsXG4gICAgICAgICAgICAgIHByb3BlcnR5RGlmZmVyZW5jZXM6IGQuUHJvcGVydHlEaWZmZXJlbmNlcyxcbiAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuICAgICAgICBhd2FpdCB3cml0ZUZpbGUob3V0cHV0RmlsZSwgSlNPTi5zdHJpbmdpZnkocmVzdWx0LCBudWxsLCAyKSwgeyBlbmNvZGluZzogJ3V0ZjgnIH0pO1xuICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byB3cml0ZSBkcmlmdCBKU09OIHJlc3VsdHM6JywgZT8ubWVzc2FnZSB8fCBlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBQcmludCB0byBzdGRvdXQgYW5kIGFwcGVuZCB0byBzdW1tYXJ5IGlmIGF2YWlsYWJsZVxuICAgIGNvbnNvbGUubG9nKGh0bWwpO1xuICAgIGNvbnN0IHN0ZXBTdW1tYXJ5ID0gcHJvY2Vzcy5lbnYuR0lUSFVCX1NURVBfU1VNTUFSWTtcbiAgICBpZiAoc3RlcFN1bW1hcnkpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgYXBwZW5kRmlsZSB9ID0gYXdhaXQgaW1wb3J0KCdmcy9wcm9taXNlcycpO1xuICAgICAgICBhd2FpdCBhcHBlbmRGaWxlKHN0ZXBTdW1tYXJ5LCBgJHtodG1sfVxcbmAsIHsgZW5jb2Rpbmc6ICd1dGY4JyB9KTtcbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gYXBwZW5kIHRvIEdJVEhVQl9TVEVQX1NVTU1BUlk6JywgZT8ubWVzc2FnZSB8fCBlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBjb21tZW50VXJsID0gcHJvY2Vzcy5lbnYuR0lUSFVCX0NPTU1FTlRfVVJMO1xuICAgIGNvbnN0IHRva2VuID0gcHJvY2Vzcy5lbnYuR0lUSFVCX1RPS0VOO1xuICAgIGlmIChjb21tZW50VXJsICYmIHRva2VuKSB7XG4gICAgICBhd2FpdCBwb3N0R2l0aHViQ29tbWVudChjb21tZW50VXJsLCB0b2tlbiwgaHRtbCk7XG4gICAgfVxuXG4gICAgcHJvY2Vzcy5leGl0KDEpO1xuICB9XG5cbiAgLy8gTm8gZHJpZnQgY2FzZVxuICBpZiAob3V0cHV0RmlsZSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IHdyaXRlRmlsZSB9ID0gYXdhaXQgaW1wb3J0KCdmcy9wcm9taXNlcycpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gW1xuICAgICAgICB7XG4gICAgICAgICAgc3RhY2tOYW1lLFxuICAgICAgICAgIGRyaWZ0U3RhdHVzOiAnSU5fU1lOQycsXG4gICAgICAgICAgZHJpZnRlZFJlc291cmNlczogW10sXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgYXdhaXQgd3JpdGVGaWxlKG91dHB1dEZpbGUsIEpTT04uc3RyaW5naWZ5KHJlc3VsdCwgbnVsbCwgMiksIHsgZW5jb2Rpbmc6ICd1dGY4JyB9KTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byB3cml0ZSBkcmlmdCBKU09OIHJlc3VsdHM6JywgZT8ubWVzc2FnZSB8fCBlKTtcbiAgICB9XG4gIH1cbiAgY29uc29sZS5sb2coJ05vIGRyaWZ0IGRldGVjdGVkIChJTl9TWU5DKScpO1xufVxuXG5tYWluKCkuY2F0Y2goKGUpID0+IHtcbiAgY29uc29sZS5lcnJvcihlKTtcbiAgcHJvY2Vzcy5leGl0KDEpO1xufSk7XG4iXX0=
package/lib/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
1
  export * from './CdkDiffStackWorkflow';
2
2
  export * from './CdkDiffIamTemplate';
3
+ export * from './CdkDriftIamTemplate';
4
+ export * from './CdkDriftDetectionWorkflow';
package/lib/index.js CHANGED
@@ -16,4 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./CdkDiffStackWorkflow"), exports);
18
18
  __exportStar(require("./CdkDiffIamTemplate"), exports);
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHlEQUF1QztBQUN2Qyx1REFBcUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL0Nka0RpZmZTdGFja1dvcmtmbG93JztcbmV4cG9ydCAqIGZyb20gJy4vQ2RrRGlmZklhbVRlbXBsYXRlJztcbiJdfQ==
19
+ __exportStar(require("./CdkDriftIamTemplate"), exports);
20
+ __exportStar(require("./CdkDriftDetectionWorkflow"), exports);
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHlEQUF1QztBQUN2Qyx1REFBcUM7QUFDckMsd0RBQXNDO0FBQ3RDLDhEQUE0QyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vQ2RrRGlmZlN0YWNrV29ya2Zsb3cnO1xuZXhwb3J0ICogZnJvbSAnLi9DZGtEaWZmSWFtVGVtcGxhdGUnO1xuZXhwb3J0ICogZnJvbSAnLi9DZGtEcmlmdElhbVRlbXBsYXRlJztcbmV4cG9ydCAqIGZyb20gJy4vQ2RrRHJpZnREZXRlY3Rpb25Xb3JrZmxvdyc7XG4iXX0=
package/package.json CHANGED
@@ -19,11 +19,13 @@
19
19
  "package-all": "npx projen package-all",
20
20
  "package:js": "npx projen package:js",
21
21
  "post-compile": "npx projen post-compile",
22
+ "post-upgrade": "npx projen post-upgrade",
22
23
  "pre-compile": "npx projen pre-compile",
23
24
  "release": "npx projen release",
24
25
  "test": "npx projen test",
25
26
  "test:watch": "npx projen test:watch",
26
27
  "unbump": "npx projen unbump",
28
+ "upgrade": "npx projen upgrade",
27
29
  "watch": "npx projen watch",
28
30
  "projen": "npx projen"
29
31
  },
@@ -102,7 +104,10 @@
102
104
  },
103
105
  "main": "lib/index.js",
104
106
  "license": "Apache-2.0",
105
- "version": "0.0.1-beta",
107
+ "publishConfig": {
108
+ "access": "public"
109
+ },
110
+ "version": "0.0.1",
106
111
  "jest": {
107
112
  "coverageProvider": "v8",
108
113
  "testMatch": [
@@ -149,7 +154,7 @@
149
154
  }
150
155
  },
151
156
  "types": "lib/index.d.ts",
152
- "stability": "stable",
157
+ "stability": "experimental",
153
158
  "jsii": {
154
159
  "outdir": "dist",
155
160
  "targets": {},
@@ -0,0 +1,17 @@
1
+ sonar.projectKey=JaysonRawlins_cdk-diff-pr-github-action
2
+ sonar.organization=jaysonrawlins
3
+
4
+
5
+ # This is the name and version displayed in the SonarCloud UI.
6
+ sonar.projectName=cdk-diff-pr-github-action
7
+ #sonar.projectVersion=1.0
8
+
9
+
10
+ # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
11
+
12
+ # Encoding of the source code. Default is default system encoding
13
+ sonar.sourceEncoding=UTF-8
14
+ sonar.sources=src,test
15
+ sonar.host.url=https://sonarcloud.io
16
+ sonar.language=ts
17
+ sonar.exclusions=**/*.spec.ts,**/*.test.ts
@@ -1,62 +0,0 @@
1
- ### Guidelines
2
-
3
- ## AWS Credentials and Environment Setup
4
-
5
- Use the .env file if there is one present
6
-
7
- ### Steps
8
- 1) Load environment variables for the chosen environment:
9
- ```bash
10
- export $(grep -v '^#' .env | xargs)
11
- ```
12
-
13
- 2.) Verify credentials:
14
- ```bash
15
- aws sts get-caller-identity
16
- ```
17
-
18
- # Instructions for Projen Projects
19
-
20
- ## Projen manages project config as code. Look for `.projenrc.<ext>` to understand how the project is defined.
21
-
22
- ### Before you change anything
23
- - Locate `.projenrc.<ext>` (e.g., `.js`, `.ts`, `.py`).
24
- - Identify project type (Node, Python, etc.) and constructs used.
25
- - Check for existing Projen tasks that do what you need.
26
-
27
- ### Typical workflow
28
- 1) Update `.projenrc.*` with desired changes.
29
- 2) Synthesize files:
30
- ```bash
31
- npx projen
32
- ```
33
- 1) Review generated diffs before committing.
34
-
35
- ---
36
-
37
- ## Memory-Aware Workflow (Mem0)
38
-
39
- Always check relevant memories before starting each task, and update them as needed. Follow this lightweight loop:
40
-
41
- 1) Search for relevant memories
42
- - Use concise keywords from the task (1–3 words). Example queries: `projen test`, `deploy creds`, `pytest flags`.
43
- - If a relevant preference is found, apply it during the task.
44
-
45
- 2) Add new preferences when discovered
46
- - When you or the user clarify a repeatable preference or rule, store it as a memory in clear, actionable language.
47
-
48
- 3) Verify memory storage (quick check)
49
- - After adding a memory, immediately retrieve it with a related keyword to confirm it’s indexed and discoverable.
50
-
51
- 4) Re-run with preference when applicable
52
- - If the memory affects execution (e.g., which command to run), ensure the next step uses the remembered preference.
53
-
54
- ### Example (validated)
55
- - Preference: "I prefer npx projen test when there is a .projenrc.ts file present in the project."
56
- - Retrieval keyword: `projen test preference`
57
- - Expected outcome: The preference is found and informs task execution (e.g., run `npx projen test` when `.projenrc.ts` exists).
58
-
59
- ---
60
- ## Web Search
61
-
62
- Use the kagi mcp for web search related needs. Especially when trying to find the latest documents to solve the current task problem.