@@ -11,15 +11,59 @@ concurrency:
1111 cancel-in-progress : true
1212
1313jobs :
14+ # First job: Generate matrix of examples
15+ generate-matrix :
16+ name : Generate examples matrix
17+ runs-on : ubuntu-latest
18+ outputs :
19+ matrix : ${{ steps.generate.outputs.matrix }}
20+ examples-count : ${{ steps.generate.outputs.count }}
21+ total-count : ${{ steps.generate.outputs.total-count }}
22+ steps :
23+ - uses : actions/checkout@v4
24+ with :
25+ fetch-depth : 0 # Need full history for git diff
26+
27+ - name : Restore example cache
28+ uses : actions/cache@v4
29+ with :
30+ path : .example-cache
31+ # Use branch-specific key (no per-example key here, since we want a shared cache for all examples)
32+ key : examples-cache-${{ github.head_ref || github.ref_name }}-${{ github.sha }}
33+ restore-keys : |
34+ examples-cache-${{ github.head_ref || github.ref_name }}-
35+ examples-cache-main-
36+
37+ - name : Generate matrix
38+ id : generate
39+ run : |
40+ matrix=$(bash .github/scripts/list_examples.sh)
41+ echo "matrix=$matrix" >> $GITHUB_OUTPUT
42+ total_count=$(echo "$matrix" | jq '.include | length')
43+ skipped_count=$(echo "$matrix" | jq '[.include[] | select(.skip == true)] | length')
44+ run_count=$((total_count - skipped_count))
45+ echo "total-count=$total_count" >> $GITHUB_OUTPUT
46+ echo "count=$run_count" >> $GITHUB_OUTPUT
47+ echo "Found $total_count total examples ($run_count to run, $skipped_count cached)"
48+ echo "$matrix" | jq .
49+
50+ # Second job: Run examples in parallel
1451 examples :
15- name : Check examples job
52+ name : Run example
1653 runs-on : ubuntu-latest
54+ needs : generate-matrix
1755 timeout-minutes : 15
1856 permissions :
1957 checks : write
2058 pull-requests : write
2159 contents : read
2260
61+ # Use matrix strategy to run examples in parallel
62+ strategy :
63+ fail-fast : false # Don't stop other examples if one fails
64+ max-parallel : 10 # Limit concurrency to avoid overwhelming resources
65+ matrix : ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
66+
2367 services :
2468 postgres :
2569 image : pgvector/pgvector:${{ vars.PGVECTOR_IMAGE_TAG || '0.8.0-pg17' }}
@@ -61,13 +105,62 @@ jobs:
61105
62106 steps :
63107 - uses : actions/checkout@v4
108+ with :
109+ fetch-depth : 0 # Need full history for git diff
64110
65111 - name : Install uv
66112 uses : astral-sh/setup-uv@v2
67113 with :
68114 version : ${{ vars.UV_VERSION || '0.6.9' }}
115+ enable-cache : true
116+
117+ - name : Cache uv dependencies
118+ uses : actions/cache@v4
119+ with :
120+ path : ~/.cache/uv
121+ key : uv-${{ runner.os }}-${{ hashFiles('**/pyproject.toml', '**/uv.lock') }}
122+ restore-keys : |
123+ uv-${{ runner.os }}-
124+
125+ - name : Restore example cache
126+ uses : actions/cache@v4
127+ with :
128+ path : .example-cache
129+ key : examples-cache-${{ github.head_ref || github.ref_name }}-${{ matrix.example }}-${{ github.sha }}
130+ restore-keys : |
131+ examples-cache-${{ github.head_ref || github.ref_name }}-${{ matrix.example }}-
132+ examples-cache-${{ github.head_ref || github.ref_name }}-
133+ examples-cache-main-
69134
70- - name : Run examples
135+ - name : Check if example should be skipped
136+ id : check-skip
137+ run : |
138+ if [[ "${{ matrix.skip }}" == "true" ]]; then
139+ echo "skip=true" >> $GITHUB_OUTPUT
140+ echo "✅ Skipping ${{ matrix.example }} (cached from previous successful run)"
141+ else
142+ echo "skip=false" >> $GITHUB_OUTPUT
143+ fi
144+
145+ - name : Pre-install common dependencies
146+ if : steps.check-skip.outputs.skip == 'false'
147+ run : |
148+ # Create a temporary environment with common ragbits packages to cache them
149+ uv venv --python 3.10 .temp-env
150+ source .temp-env/bin/activate
151+ # Install the most commonly used packages across examples
152+ uv pip install \
153+ ragbits-core \
154+ ragbits-document-search \
155+ ragbits-agents \
156+ ragbits-chat \
157+ ragbits-evaluate \
158+ ragbits-guardrails
159+ deactivate
160+ rm -rf .temp-env
161+
162+ - name : Run example - ${{ matrix.example }}
163+ if : steps.check-skip.outputs.skip == 'false'
71164 env :
72165 PR_BRANCH : ${{ github.head_ref }}
73166 GOOGLE_CLOUD_PROJECT : ${{ secrets.GCP_PROJECT_ID }}
@@ -79,4 +172,43 @@ jobs:
79172 LOGFIRE_TOKEN : ${{ secrets.LOGFIRE_TOKEN }}
80173 run : |
81174 echo "$GCP_KEY" | base64 --decode > "$GOOGLE_APPLICATION_CREDENTIALS"
82- ./.github/scripts/run_examples.sh
175+ chmod +x .github/scripts/run_single_example.sh
176+ ./.github/scripts/run_single_example.sh "${{ matrix.example }}"
177+
178+ - name : Save example cache
179+ if : always()
180+ uses : actions/cache/save@v4
181+ with :
182+ path : .example-cache
183+ key : examples-cache-${{ github.head_ref || github.ref_name }}-${{ matrix.example }}-${{ github.sha }}
184+
185+ # Summary job: Report overall results
186+ examples-summary :
187+ name : Examples summary
188+ runs-on : ubuntu-latest
189+ needs : [generate-matrix, examples]
190+ if : always()
191+ steps :
192+ - name : Check results
193+ env :
194+ TOTAL_COUNT : ${{ needs.generate-matrix.outputs.total-count }}
195+ RUN_COUNT : ${{ needs.generate-matrix.outputs.examples-count }}
196+ run : |
197+ echo "Examples matrix generation: ${{ needs.generate-matrix.result }}"
198+ echo "Examples execution: ${{ needs.examples.result }}"
199+ echo "Total examples: $TOTAL_COUNT"
200+ echo "Examples run: $RUN_COUNT"
201+ cached_count=$((TOTAL_COUNT - RUN_COUNT))
202+ echo "Examples cached: $cached_count"
203+
204+ if [[ "${{ needs.generate-matrix.result }}" != "success" ]]; then
205+ echo "❌ Failed to generate examples matrix"
206+ exit 1
207+ fi
208+
209+ if [[ "${{ needs.examples.result }}" != "success" ]]; then
210+ echo "❌ Some examples failed"
211+ exit 1
212+ fi
213+
214+ echo "✅ All examples completed successfully ($RUN_COUNT run, $cached_count cached)"
0 commit comments