Skip to content

Commit 84eb08b

Browse files
kaiz-ioMichael Kaiser
andauthored
Update 1/3 of the packages (#1148)
* Update package version * Commit these fixes * Fix api-gateway-lambda-token-authorizer * Fix snapshot tests by normalizing asset hashes * Add documentation for snapshot testing with asset hash normalization * Add script for building all typescript projects * Remove bedrock agent examples as the project is completely broken with update from latest cdklabs * Fix build-pull-request to ignore deleted files * Fix build-pull-request to display errors * Fix build-pull-request to display errors * Ignore this project for right now * Ignore this project for right now * Update snapshot * clean node-modules after success * clean cdk.out after success * install eslint to not use docker for building * 2/3 skip * Reset ec2 instance connect * Reset ec2 instance connect delete files * Improve build output visibility in GitHub Actions workflow * Update snapshot for inspector2 --------- Co-authored-by: Michael Kaiser <kaiser@kaiz.io>
1 parent 82a263d commit 84eb08b

File tree

75 files changed

+615
-2069
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+615
-2069
lines changed

.github/workflows/build-pull-request.yml

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,28 @@ jobs:
3030
with:
3131
language: ${{ matrix.language }}
3232

33-
# Get the list of changed files, excluding Markdown files
33+
# Get the list of changed files, excluding Markdown files and deleted files
3434
- name: Get changed files
3535
id: changed-files
3636
uses: tj-actions/changed-files@27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99
3737
with:
3838
files: ${{ matrix.language }}/**
3939
files_ignore: '**/*.md'
40+
files_separator: ' '
4041

4142
# Build the changed files for the specified language
4243
- name: Build changed files
4344
if: steps.changed-files.outputs.any_changed == 'true'
4445
run: |
46+
# Create a temporary directory for build logs
47+
mkdir -p /tmp/build_logs
48+
npm install -g eslint > /dev/null
49+
4550
# Function to build a single file
4651
build_file() {
4752
echo "Build File $1"
4853
local file="$1"
54+
local log_file="/tmp/build_logs/$(basename "$file" | sed 's/\//_/g').log"
4955
IFS="/" read -ra path_parts <<< "$file"
5056
language=${path_parts[0]}
5157
@@ -57,14 +63,35 @@ jobs:
5763
echo "Build Path $file"
5864
5965
# Run the build script for the current language, passing the project directory and extra path
60-
echo "::group::$file"
61-
if ../scripts/build-${language}.sh "$file"; then
62-
echo "::endgroup::"
66+
echo "::group::Building $file"
67+
# Run the build command and capture output to both the log file and stdout
68+
../scripts/build-${language}.sh "$file" 2>&1 | tee "$log_file"
69+
local exit_code=${PIPESTATUS[0]}
70+
71+
if [ $exit_code -eq 0 ]; then
72+
echo "✅ Build succeeded for $file"
73+
74+
# Clean up node_modules and cdk.out for this project immediately after successful build
75+
echo "Cleaning up build artifacts for $(dirname "$file")"
76+
local project_dir=$(dirname "$file")
77+
78+
# Remove node_modules directory if it exists
79+
if [ -d "$project_dir/node_modules" ]; then
80+
echo "Removing $project_dir/node_modules"
81+
rm -rf "$project_dir/node_modules"
82+
fi
83+
84+
# Remove cdk.out directory if it exists
85+
if [ -d "$project_dir/cdk.out" ]; then
86+
echo "Removing $project_dir/cdk.out"
87+
rm -rf "$project_dir/cdk.out"
88+
fi
6389
else
64-
echo "::endgroup::"
65-
echo "::error::Build failed for $file"
66-
return 1
90+
echo "❌ Build failed for $file with exit code $exit_code"
91+
echo "::error::Build failed for $file with exit code $exit_code"
6792
fi
93+
echo "::endgroup::"
94+
return $exit_code
6895
}
6996
7097
# Export the build_file function for use in parallel
@@ -73,7 +100,8 @@ jobs:
73100
# Create an array to store directories to be built
74101
apps_to_build=()
75102
76-
files=(${{ steps.changed-files.outputs.all_modified_files }})
103+
# Use only added and modified files, ignoring deleted files
104+
files=(${{ steps.changed-files.outputs.added_files }} ${{ steps.changed-files.outputs.modified_files }})
77105
78106
# Check the directories of each changed file for cdk.json
79107
for file in "${files[@]}"; do
@@ -110,4 +138,18 @@ jobs:
110138
111139
# Run the build_file function in parallel for each project to be built
112140
# Halt the execution if any of the build_file invocations fail
141+
echo "::group::Build Output"
142+
echo "Starting builds for all projects..."
113143
parallel --keep-order --halt-on-error 2 build_file ::: "${apps_to_build[@]}"
144+
echo "::endgroup::"
145+
146+
# Check the exit status of parallel
147+
parallel_exit=$?
148+
149+
# If parallel failed, make sure the workflow fails too
150+
if [ $parallel_exit -ne 0 ]; then
151+
echo "::error::One or more builds failed. See build output above for details."
152+
exit $parallel_exit
153+
else
154+
echo "✅ All builds completed successfully!"
155+
fi

SNAPSHOT_TESTING.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# CDK Snapshot Testing Guide
2+
3+
This guide explains how to use the asset hash normalization utility for consistent CDK snapshot testing across different environments.
4+
5+
## Problem
6+
7+
CDK snapshot tests often fail in CI/CD environments because asset hashes change between different environments. This happens because:
8+
9+
- Asset hashes are generated based on content and environment variables
10+
- Different machines or CI/CD environments produce different hashes
11+
- This causes snapshot tests to fail even when there are no actual changes to the infrastructure
12+
13+
## Solution
14+
15+
We've created a utility function that normalizes asset hashes and other environment-specific values in CloudFormation templates before comparing them with snapshots.
16+
17+
## How to Use the Normalization Utility
18+
19+
### 1. Import the Utility
20+
21+
```typescript
22+
import { normalizeTemplate } from '../../test-utils/normalize-template';
23+
```
24+
25+
### 2. Apply Normalization Before Snapshot Comparison
26+
27+
```typescript
28+
import { App } from 'aws-cdk-lib';
29+
import { Template } from 'aws-cdk-lib/assertions';
30+
import { YourStack } from '../lib/your-stack';
31+
import { normalizeTemplate } from '../../test-utils/normalize-template';
32+
33+
test('YourStack creates the expected resources', () => {
34+
const app = new App();
35+
const stack = new YourStack(app, 'TestStack');
36+
37+
// Get the CloudFormation template
38+
const template = Template.fromStack(stack);
39+
40+
// Normalize the template before snapshot comparison
41+
const normalizedTemplate = normalizeTemplate(template.toJSON());
42+
43+
// Compare with snapshot
44+
expect(normalizedTemplate).toMatchSnapshot();
45+
});
46+
```
47+
48+
### 3. Update Existing Snapshots
49+
50+
After adding the normalization to your tests, update your snapshots:
51+
52+
```bash
53+
npm test -- -u
54+
```
55+
56+
## What Gets Normalized
57+
58+
The utility currently normalizes:
59+
60+
1. **S3 Asset Keys**: Replaces asset hashes in S3Key properties
61+
- Pattern with extension: `[64 hex chars].zip``NORMALIZED_ASSET_HASH.zip`
62+
- Pattern without extension: `[64 hex chars]``NORMALIZED_ASSET_HASH`
63+
64+
2. **Docker Image Digests**: Replaces image digests
65+
- Pattern: `sha256:[digest]``NORMALIZED_IMAGE_DIGEST`
66+
67+
## Adding New Test Files
68+
69+
When creating new test files that use snapshot testing:
70+
71+
1. Import the normalization utility
72+
2. Apply it to your template before comparing with snapshots
73+
3. Update your snapshots with the `-u` flag
74+
75+
## Extending the Utility
76+
77+
If you encounter other environment-specific values that need normalization, you can extend the utility at `typescript/test-utils/normalize-template.ts`.
78+
79+
Example of adding a new normalization rule:
80+
81+
```typescript
82+
// Inside the normalizeValues function
83+
if (key === 'NewPropertyToNormalize' && typeof obj[key] === 'string' && /pattern-to-match/.test(obj[key])) {
84+
obj[key] = 'NORMALIZED_VALUE';
85+
}
86+
```
87+
88+
## Troubleshooting
89+
90+
If you're still seeing snapshot test failures:
91+
92+
1. **Check for new patterns**: There might be new types of asset hashes or environment-specific values that need normalization
93+
2. **Verify imports**: Make sure you're importing and using the utility correctly
94+
3. **Check snapshot updates**: Ensure you've updated your snapshots after adding normalization
95+
96+
## Best Practices
97+
98+
1. **Always normalize before snapshot comparison**: This ensures consistent results
99+
2. **Update snapshots deliberately**: Only use the `-u` flag when you expect changes
100+
3. **Review snapshot diffs**: When updating snapshots, review the changes to ensure they're expected
101+
4. **Keep the utility updated**: As new patterns emerge, add them to the normalization utility
102+
103+
## Additional Resources
104+
105+
- [Jest Snapshot Testing Documentation](https://jestjs.io/docs/snapshot-testing)
106+
- [AWS CDK Testing Documentation](https://docs.aws.amazon.com/cdk/v2/guide/testing.html)

scripts/build-all-typescript.sh

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#!/bin/bash
2+
#
3+
# Script to build all TypeScript CDK projects in parallel
4+
#
5+
set -euo pipefail
6+
7+
# Get the directory of this script
8+
SCRIPT_DIR=$(cd $(dirname $0) && pwd)
9+
REPO_ROOT=$(dirname "$SCRIPT_DIR")
10+
TYPESCRIPT_DIR="${REPO_ROOT}/typescript"
11+
BUILD_SCRIPT="$SCRIPT_DIR/build-typescript.sh"
12+
13+
# Check if parallel is installed
14+
if ! command -v parallel &> /dev/null; then
15+
echo "GNU parallel is not installed. Please install it first."
16+
exit 1
17+
fi
18+
19+
# Check if the build script exists
20+
if [ ! -f "$BUILD_SCRIPT" ]; then
21+
echo "Error: Build script not found at $BUILD_SCRIPT"
22+
exit 1
23+
fi
24+
25+
# Create a temporary directory for build logs
26+
TEMP_DIR=$(mktemp -d)
27+
trap 'rm -rf "$TEMP_DIR"' EXIT
28+
29+
# Find all TypeScript CDK projects (directories with cdk.json)
30+
# Exclude any matches from node_modules directories, cdk.out directories, and specific problematic projects
31+
echo "Finding all TypeScript CDK projects..."
32+
PROJECTS=$(find "$TYPESCRIPT_DIR" -name "cdk.json" -type f \
33+
-not -path "*/node_modules/*" \
34+
-not -path "*/cdk.out/*" \
35+
| sort)
36+
37+
# Count total projects
38+
TOTAL_PROJECTS=$(echo "$PROJECTS" | wc -l)
39+
echo "Found $TOTAL_PROJECTS TypeScript CDK projects to build"
40+
echo "=============================="
41+
42+
# Function to build a single project
43+
build_project() {
44+
CDK_JSON_PATH="$1"
45+
PROJECT_DIR=$(dirname "$CDK_JSON_PATH")
46+
REL_PATH=$(realpath --relative-to="$REPO_ROOT" "$PROJECT_DIR")
47+
LOG_FILE="$TEMP_DIR/$(echo "$REL_PATH" | tr '/' '_').log"
48+
49+
# Show start message
50+
echo "▶️ Starting build: $REL_PATH"
51+
52+
# Check for DO_NOT_AUTOTEST file
53+
if [ -f "$PROJECT_DIR/DO_NOT_AUTOTEST" ]; then
54+
echo "⏭️ Skipping $REL_PATH (DO_NOT_AUTOTEST flag found)"
55+
echo "SKIPPED:$REL_PATH" > "$LOG_FILE.status"
56+
return 0
57+
fi
58+
59+
# Find the package.json in the project directory
60+
PACKAGE_JSON="$PROJECT_DIR/package.json"
61+
if [ ! -f "$PACKAGE_JSON" ]; then
62+
echo "⏭️ Skipping $REL_PATH (no package.json found)"
63+
echo "SKIPPED:$REL_PATH" > "$LOG_FILE.status"
64+
return 0
65+
fi
66+
67+
# Get the relative path to package.json for the build script
68+
PACKAGE_JSON_REL_PATH=$(realpath --relative-to="$REPO_ROOT" "$PACKAGE_JSON")
69+
70+
# Create a modified version of the build script that suppresses cdk synth output
71+
TEMP_BUILD_SCRIPT="$TEMP_DIR/build-$(basename "$REL_PATH").sh"
72+
cat > "$TEMP_BUILD_SCRIPT" << 'EOF'
73+
#!/bin/bash
74+
set -euo pipefail
75+
76+
# Get the original script and arguments
77+
ORIGINAL_SCRIPT="$1"
78+
shift
79+
ARGS="$@"
80+
81+
# Run the original script but capture and filter the output
82+
"$ORIGINAL_SCRIPT" "$ARGS" 2>&1 | grep -v "cdk synth" | grep -v "Synthesizing"
83+
EOF
84+
chmod +x "$TEMP_BUILD_SCRIPT"
85+
86+
# Run the build script with filtered output
87+
if "$TEMP_BUILD_SCRIPT" "$BUILD_SCRIPT" "$PACKAGE_JSON_REL_PATH" > "$LOG_FILE" 2>&1; then
88+
echo "✅ Build successful: $REL_PATH"
89+
echo "SUCCESS:$REL_PATH" > "$LOG_FILE.status"
90+
else
91+
echo "❌ Build failed: $REL_PATH"
92+
echo "FAILED:$REL_PATH" > "$LOG_FILE.status"
93+
fi
94+
}
95+
export -f build_project
96+
export SCRIPT_DIR
97+
export REPO_ROOT
98+
export BUILD_SCRIPT
99+
export TEMP_DIR
100+
101+
# Run builds in parallel
102+
echo "$PROJECTS" | parallel --will-cite --jobs 50% build_project
103+
104+
# Collect results
105+
SUCCESSFUL=0
106+
FAILED=0
107+
SKIPPED=0
108+
ALL_PROJECTS=()
109+
110+
for STATUS_FILE in "$TEMP_DIR"/*.status; do
111+
[ -f "$STATUS_FILE" ] || continue
112+
113+
STATUS_CONTENT=$(cat "$STATUS_FILE")
114+
STATUS_TYPE=${STATUS_CONTENT%%:*}
115+
PROJECT_PATH=${STATUS_CONTENT#*:}
116+
117+
case "$STATUS_TYPE" in
118+
"SUCCESS")
119+
((SUCCESSFUL++))
120+
ALL_PROJECTS+=("$PROJECT_PATH")
121+
;;
122+
"FAILED")
123+
((FAILED++))
124+
ALL_PROJECTS+=("$PROJECT_PATH")
125+
;;
126+
"SKIPPED")
127+
((SKIPPED++))
128+
ALL_PROJECTS+=("⏭️ $PROJECT_PATH")
129+
;;
130+
esac
131+
done
132+
133+
# Sort the projects list
134+
IFS=$'\n' SORTED_PROJECTS=($(sort <<<"${ALL_PROJECTS[*]}"))
135+
unset IFS
136+
137+
# Print summary
138+
echo ""
139+
echo "=============================="
140+
echo "BUILD SUMMARY"
141+
echo "=============================="
142+
echo "Total: $((SUCCESSFUL + FAILED + SKIPPED)) (✅ $SUCCESSFUL succeeded, ❌ $FAILED failed, ⏭️ $SKIPPED skipped)"
143+
echo ""
144+
echo "Project Status:"
145+
echo "-----------------------------"
146+
for PROJ in "${SORTED_PROJECTS[@]}"; do
147+
echo "$PROJ"
148+
done
149+
150+
# If any builds failed, print their logs and exit with error
151+
if [ $FAILED -gt 0 ]; then
152+
echo ""
153+
echo "Build logs for failed projects:"
154+
echo "=============================="
155+
for PROJ in "${SORTED_PROJECTS[@]}"; do
156+
if [[ $PROJ ==* ]]; then
157+
PROJECT_PATH=${PROJ#❌ }
158+
echo ""
159+
echo "Log for $PROJECT_PATH:"
160+
echo "-------------------------------------------"
161+
cat "$TEMP_DIR/$(echo "$PROJECT_PATH" | tr '/' '_').log"
162+
echo "-------------------------------------------"
163+
fi
164+
done
165+
exit 1
166+
fi

typescript/amazon-mq-rabbitmq-lambda/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@
1111
"cdk": "cdk"
1212
},
1313
"devDependencies": {
14-
"@types/jest": "^29.5.12",
15-
"@types/node": "22.5.4",
16-
"aws-cdk": "2.160.0",
14+
"@types/jest": "^29.5.14",
15+
"@types/node": "22.7.9",
16+
"aws-cdk": "2.1004.0",
1717
"jest": "^29.7.0",
1818
"ts-jest": "^29.2.5",
1919
"ts-node": "^10.9.2",
20-
"typescript": "~5.6.2"
20+
"typescript": "~5.6.3"
2121
},
2222
"dependencies": {
2323
"@cdklabs/cdk-amazonmq": "^0.0.1",
24-
"aws-cdk-lib": "2.160.0",
24+
"aws-cdk-lib": "2.185.0",
2525
"constructs": "^10.0.0"
2626
}
2727
}

0 commit comments

Comments
 (0)