-
Notifications
You must be signed in to change notification settings - Fork 2.5k
183 lines (152 loc) · 6.25 KB
/
build-pull-request.yml
File metadata and controls
183 lines (152 loc) · 6.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# Name of the workflow
name: Build Pull Request
# Trigger the workflow on pull requests
on:
pull_request:
# Only run the workflow when non-Markdown files are changed
paths:
- '**'
permissions:
contents: read
jobs:
build:
# Run the job on the latest Ubuntu runner
runs-on: ubuntu-latest
# Define a matrix strategy to run the job for multiple languages
strategy:
matrix:
language: ['csharp', 'go', 'python', 'java', 'typescript']
steps:
# Checkout the code from the repository
- name: Checkout code
uses: actions/checkout@v6
# Set up the required environment for the specified language
- name: Setup Language
uses: ./.github/actions/setup-language
with:
language: ${{ matrix.language }}
# Get the list of changed files, excluding Markdown files and deleted files
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@daf9d2d49788d229faa7bd34252ab8ded7f087f3
with:
files: ${{ matrix.language }}/**
files_ignore: '**/*.md'
files_separator: ' '
# Build the changed files for the specified language
- name: Build changed files
if: steps.changed-files.outputs.any_changed == 'true'
run: |
# Create a temporary directory for build logs
mkdir -p /tmp/build_logs
yarn global add eslint@latest
yarn global add aws-cdk@latest
# Function to build a single file
build_file() {
echo "Build File $1"
local file="$1"
local log_file="/tmp/build_logs/$(basename "$file" | sed 's/\//_/g').log"
IFS="/" read -ra path_parts <<< "$file"
language=${path_parts[0]}
# Skip files that don't belong to the current language
if [[ $language != ${{ matrix.language }} ]]; then
return 0
fi
echo "Build Path $file"
# Run the build script for the current language, passing the project directory and extra path
echo "::group::Building $file"
# Run the build command and capture output to both the log file and stdout
../scripts/build-${language}.sh "$file" 2>&1 | tee "$log_file"
local exit_code=${PIPESTATUS[0]}
if [ $exit_code -eq 0 ]; then
echo "✅ Build succeeded for $file"
# Clean up node_modules and cdk.out for this project immediately after successful build
echo "Cleaning up build artifacts for $(dirname "$file")"
local project_dir=$(dirname "$file")
# Remove node_modules directory if it exists
if [ -d "$project_dir/node_modules" ]; then
echo "Removing $project_dir/node_modules"
rm -rf "$project_dir/node_modules"
fi
# Remove cdk.out directory if it exists
if [ -d "$project_dir/cdk.out" ]; then
echo "Removing $project_dir/cdk.out"
rm -rf "$project_dir/cdk.out"
fi
else
echo "❌ Build failed for $file with exit code $exit_code"
echo "::error::Build failed for $file with exit code $exit_code"
fi
echo "::endgroup::"
return $exit_code
}
# Export the build_file function for use in parallel
export -f build_file
# Create an array to store directories to be built
apps_to_build=()
# Use only added and modified files, ignoring deleted files
files=(${{ steps.changed-files.outputs.added_files }} ${{ steps.changed-files.outputs.modified_files }})
# Check the directories of each changed file for cdk.json
for file in "${files[@]}"; do
IFS="/" read -ra path_parts <<< "$file"
language=${path_parts[0]}
dir="${path_parts[0]}/${path_parts[1]}"
# Skip files that don't belong to the current language
if [[ $language != ${{ matrix.language }} ]]; then
continue
fi
apps_to_build+=("$(find "$dir" -name 'cdk.json')")
done
# Remove duplicate projects
apps_to_build=($(printf "%s\n" "${apps_to_build[@]}" | sort -u))
# Print the projects to be built
echo "projects to build:"
for dir in "${apps_to_build[@]}"; do
echo "- $dir"
done
# Change to language directory
cd ./${{ matrix.language }}
# Run the build_file function for each project to be built
echo "::group::Build Output"
echo "Starting builds for all projects..."
# Track failed builds
failed_builds=()
# Process each project one by one with clear grouping
for app in "${apps_to_build[@]}"; do
echo "::group::Building $app"
# Run the build directly
set +e # Don't exit on error
../scripts/build-${language}.sh "$app"
build_exit=$?
set -e # Re-enable exit on error
if [ $build_exit -ne 0 ]; then
echo "❌ BUILD FAILED: $app (exit code $build_exit)"
failed_builds+=("$app")
else
echo "✅ BUILD SUCCEEDED: $app"
fi
echo "::endgroup::"
done
echo "::endgroup::"
# Print summary outside of any group
echo ""
echo "====== BUILD SUMMARY ======"
if [ ${#failed_builds[@]} -gt 0 ]; then
echo "❌ FAILED BUILDS:"
for failed in "${failed_builds[@]}"; do
echo " - $failed"
done
parallel_exit=1
else
echo "✅ ALL BUILDS SUCCEEDED"
parallel_exit=0
fi
echo "=========================="
echo ""
# If parallel failed, make sure the workflow fails too
if [ $parallel_exit -ne 0 ]; then
echo "::error::One or more builds failed. See build summary above for details."
exit $parallel_exit
else
echo "✅ All builds completed successfully!"
fi