Skip to content

Commit 52e55aa

Browse files
0cacursoragent
andcommitted
Add CI workflow to build all challenges in parallel
Discovers all EV-XX challenges under web_exploitation/ that have a docker-compose.yaml, then builds each one in parallel using a matrix strategy. Runs on push to main, weekly (Monday 6:00 UTC), and manual dispatch. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 0daab42 commit 52e55aa

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
name: Build All Challenges
2+
3+
# Run on pushes to main, weekly schedule, and manual trigger
4+
on:
5+
push:
6+
branches: [main]
7+
schedule:
8+
# Every Monday at 6:00 UTC
9+
- cron: '0 6 * * 1'
10+
workflow_dispatch:
11+
12+
jobs:
13+
# -----------------------------------------------------------------------
14+
# Job 1: Discover challenge directories under web_exploitation/
15+
# -----------------------------------------------------------------------
16+
discover:
17+
name: Discover challenges
18+
runs-on: ubuntu-latest
19+
outputs:
20+
challenges: ${{ steps.list.outputs.challenges }}
21+
count: ${{ steps.list.outputs.count }}
22+
steps:
23+
- uses: actions/checkout@v4
24+
25+
- name: Find challenge directories with docker-compose
26+
id: list
27+
run: |
28+
# Build a JSON array of challenge objects.
29+
# Each EV-XX directory under web_exploitation/ that has a
30+
# docker-compose.yaml is included in the build matrix.
31+
challenges='[]'
32+
count=0
33+
34+
for dir in web_exploitation/EV-*/; do
35+
# Strip trailing slash
36+
dir="${dir%/}"
37+
name=$(basename "$dir")
38+
39+
# Only include directories that have a docker-compose file
40+
if [ -f "$dir/docker-compose.yaml" ] || [ -f "$dir/docker-compose.yml" ]; then
41+
count=$((count + 1))
42+
challenges=$(echo "$challenges" | jq \
43+
--arg path "$dir" \
44+
--arg name "$name" \
45+
'. + [{"path": $path, "name": $name}]')
46+
else
47+
echo "::warning::No docker-compose file in $dir, skipping"
48+
fi
49+
done
50+
51+
echo "challenges=$(echo "$challenges" | jq -c .)" >> "$GITHUB_OUTPUT"
52+
echo "count=$count" >> "$GITHUB_OUTPUT"
53+
echo "Found $count challenges with docker-compose files"
54+
55+
# -----------------------------------------------------------------------
56+
# Job 2: Build each challenge in parallel using matrix strategy
57+
# -----------------------------------------------------------------------
58+
build:
59+
name: "Build ${{ matrix.challenge.name }}"
60+
needs: discover
61+
runs-on: ubuntu-latest
62+
timeout-minutes: 20
63+
strategy:
64+
# Don't cancel other builds if one fails
65+
fail-fast: false
66+
matrix:
67+
challenge: ${{ fromJson(needs.discover.outputs.challenges) }}
68+
69+
steps:
70+
- uses: actions/checkout@v4
71+
72+
# Free up disk space - GitHub runners have limited space and Docker
73+
# images can be large. Remove unused tools to make room.
74+
- name: Free disk space
75+
run: |
76+
df -h /
77+
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc || true
78+
df -h /
79+
80+
- name: Build challenge
81+
run: |
82+
CHALLENGE_DIR="${{ matrix.challenge.path }}"
83+
84+
echo "Challenge: ${{ matrix.challenge.name }}"
85+
echo "Directory: $CHALLENGE_DIR"
86+
87+
cd "$CHALLENGE_DIR"
88+
docker compose build
89+
echo "Build completed successfully"
90+
91+
# Clean up Docker images to avoid filling the runner disk
92+
- name: Cleanup Docker images
93+
if: always()
94+
run: docker system prune -af --volumes 2>/dev/null || true
95+
96+
# -----------------------------------------------------------------------
97+
# Job 3: Summary - report overall results
98+
# -----------------------------------------------------------------------
99+
summary:
100+
name: Build Summary
101+
needs: [discover, build]
102+
runs-on: ubuntu-latest
103+
if: always()
104+
steps:
105+
- name: Report results
106+
run: |
107+
echo "## Build Results" >> "$GITHUB_STEP_SUMMARY"
108+
echo "" >> "$GITHUB_STEP_SUMMARY"
109+
echo "Total challenges: ${{ needs.discover.outputs.count }}" >> "$GITHUB_STEP_SUMMARY"
110+
echo "" >> "$GITHUB_STEP_SUMMARY"
111+
112+
if [ "${{ needs.build.result }}" == "success" ]; then
113+
echo "**All challenges built successfully!**" >> "$GITHUB_STEP_SUMMARY"
114+
elif [ "${{ needs.build.result }}" == "failure" ]; then
115+
echo "**Some challenges failed to build.** Check individual job logs for details." >> "$GITHUB_STEP_SUMMARY"
116+
exit 1
117+
else
118+
echo "Build result: ${{ needs.build.result }}" >> "$GITHUB_STEP_SUMMARY"
119+
exit 1
120+
fi

0 commit comments

Comments
 (0)