@@ -11,15 +11,59 @@ concurrency:
11
11
cancel-in-progress : true
12
12
13
13
jobs :
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
14
51
examples :
15
- name : Check examples job
52
+ name : Run example
16
53
runs-on : ubuntu-latest
54
+ needs : generate-matrix
17
55
timeout-minutes : 15
18
56
permissions :
19
57
checks : write
20
58
pull-requests : write
21
59
contents : read
22
60
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
+
23
67
services :
24
68
postgres :
25
69
image : pgvector/pgvector:${{ vars.PGVECTOR_IMAGE_TAG || '0.8.0-pg17' }}
@@ -61,13 +105,62 @@ jobs:
61
105
62
106
steps :
63
107
- uses : actions/checkout@v4
108
+ with :
109
+ fetch-depth : 0 # Need full history for git diff
64
110
65
111
- name : Install uv
66
112
uses : astral-sh/setup-uv@v2
67
113
with :
68
114
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-
69
134
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'
71
164
env :
72
165
PR_BRANCH : ${{ github.head_ref }}
73
166
GOOGLE_CLOUD_PROJECT : ${{ secrets.GCP_PROJECT_ID }}
@@ -79,4 +172,43 @@ jobs:
79
172
LOGFIRE_TOKEN : ${{ secrets.LOGFIRE_TOKEN }}
80
173
run : |
81
174
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