-
Notifications
You must be signed in to change notification settings - Fork 2.5k
146 lines (121 loc) · 5.24 KB
/
build-pull-request.yml
File metadata and controls
146 lines (121 loc) · 5.24 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
# 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@9934ab3fdf63239da75d9e0fbd339c48620c72c4
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 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