-
Notifications
You must be signed in to change notification settings - Fork 2.5k
155 lines (126 loc) · 5.53 KB
/
build-pull-request.yml
File metadata and controls
155 lines (126 loc) · 5.53 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
# 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:
- '**'
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@v4
# 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@27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99
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
npm install -g eslint > /dev/null
# 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 }}
# install CDK CLI from npm if not typescript, so that npx can find it later
# ts will use the one from the particular cdk app
if [[ ${{ matrix.language }} != 'typescript' ]]; then
npm install -g aws-cdk
npx cdk --version
fi
# Run the build_file function in parallel for each project to be built
# Halt the execution if any of the build_file invocations fail
echo "::group::Build Output"
echo "Starting builds for all projects..."
parallel --keep-order --halt-on-error 2 build_file ::: "${apps_to_build[@]}"
echo "::endgroup::"
# Check the exit status of parallel
parallel_exit=$?
# If parallel failed, make sure the workflow fails too
if [ $parallel_exit -ne 0 ]; then
echo "::error::One or more builds failed. See build output above for details."
exit $parallel_exit
else
echo "✅ All builds completed successfully!"
fi