Skip to content

Commit 68bb91e

Browse files
committed
Add unified lab validation interface for Docker and PR testing
- Modify CI workflow to accept multiple Batfish/Pybatfish sources: - Git refs (existing behavior + PR testing) - Docker images (for release testing) - PyPI versions with test/prod distinction - Create reusable workflow for external repositories - Add PR comment trigger template for batfish repo - Add Docker release integration example - Support lab filtering for selective testing - Maintain backwards compatibility with existing workflows
1 parent a322526 commit 68bb91e

4 files changed

Lines changed: 432 additions & 20 deletions

File tree

.github/workflows/ci.yml

Lines changed: 77 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,30 @@ on:
77
branches: [ main, develop ]
88
workflow_dispatch:
99
workflow_call:
10+
inputs:
11+
batfish_ref:
12+
description: "Git ref for Batfish version to test"
13+
required: false
14+
default: "master"
15+
type: string
16+
batfish_docker:
17+
description: "Docker image for Batfish (e.g., batfish/batfish:2024.12.20.1234)"
18+
required: false
19+
type: string
20+
pybatfish_ref:
21+
description: "Git ref for Pybatfish version to test"
22+
required: false
23+
default: "master"
24+
type: string
25+
pybatfish_version:
26+
description: "PyPI version for Pybatfish (e.g., 1.2.3)"
27+
required: false
28+
type: string
29+
pybatfish_pypi_repo:
30+
description: "PyPI repository (test or prod)"
31+
required: false
32+
default: "prod"
33+
type: string
1034

1135
jobs:
1236
lint:
@@ -83,16 +107,17 @@ jobs:
83107
echo "labs=$labs" >> $GITHUB_OUTPUT
84108
echo "Discovered labs: $labs"
85109
86-
# Build Batfish JAR once and cache it
110+
# Build Batfish JAR once and cache it (only if not using Docker)
87111
build-batfish:
88112
runs-on: ubuntu-latest
113+
if: inputs.batfish_docker == ''
89114
steps:
90115
- name: Checkout Batfish
91116
uses: actions/checkout@v4
92117
with:
93118
repository: batfish/batfish
94119
path: batfish
95-
ref: master
120+
ref: ${{ inputs.batfish_ref || 'master' }}
96121

97122
- name: Set up Java 17
98123
uses: actions/setup-java@v4
@@ -128,8 +153,9 @@ jobs:
128153
# Matrix job to run each lab in parallel
129154
lab-integration-test:
130155
runs-on: ubuntu-latest
131-
timeout-minutes: 20 # Reduced since we don't build JAR
156+
timeout-minutes: 20
132157
needs: [discover-labs, build-batfish]
158+
if: always() # Run even if build-batfish was skipped (for Docker mode)
133159
strategy:
134160
matrix:
135161
lab: ${{ fromJson(needs.discover-labs.outputs.labs) }}
@@ -155,6 +181,7 @@ jobs:
155181
java-version: '17'
156182

157183
- name: Download Batfish artifacts
184+
if: inputs.batfish_docker == ''
158185
uses: actions/download-artifact@v4
159186
with:
160187
name: batfish-artifacts
@@ -164,28 +191,54 @@ jobs:
164191
working-directory: lab-validation
165192
run: |
166193
python -m pip install --upgrade pip
194+
195+
# Install base dependencies from requirements.txt
167196
pip install -r requirements.txt
197+
198+
# Install Pybatfish based on input parameters (may override version from requirements.txt)
199+
if [ "${{ inputs.pybatfish_version }}" != "" ]; then
200+
if [ "${{ inputs.pybatfish_pypi_repo }}" = "test" ]; then
201+
pip install -i https://test.pypi.org/simple --extra-index-url https://pypi.org/simple pybatfish==${{ inputs.pybatfish_version }}
202+
else
203+
pip install pybatfish==${{ inputs.pybatfish_version }}
204+
fi
205+
else
206+
# Default: install from git ref (override requirements.txt version)
207+
PYBF_REF="${{ inputs.pybatfish_ref || 'master' }}"
208+
pip install git+https://github.com/batfish/pybatfish.git@${PYBF_REF}
209+
fi
210+
168211
pip install -r requirements-dev.txt
169212
pip install -e .
170213
171214
- name: Start Batfish service
172215
run: |
173-
# Extract questions archive
174-
tar -xzf questions.tgz
175-
176-
# Start Batfish using simple allinone mode (like pybatfish CI)
177-
coordinator_args=(\
178-
-templatedirs=questions \
179-
-periodassignworkms=5 \
180-
)
181-
allinone_args=(\
182-
-runclient=false \
183-
-coordinatorargs="$(echo -n "${coordinator_args[@]}")" \
184-
)
185-
java -cp allinone.jar org.batfish.allinone.Main "${allinone_args[@]}" > batfish.log 2>&1 &
186-
187-
# Wait for service to start
188-
sleep 10
216+
if [ "${{ inputs.batfish_docker }}" != "" ]; then
217+
# Start Batfish using Docker container
218+
docker run -d --name batfish \
219+
-p 9996:9996 \
220+
${{ inputs.batfish_docker }}
221+
222+
# Wait for service to start
223+
sleep 15
224+
else
225+
# Extract questions archive and start from JAR
226+
tar -xzf questions.tgz
227+
228+
# Start Batfish using simple allinone mode (like pybatfish CI)
229+
coordinator_args=(\
230+
-templatedirs=questions \
231+
-periodassignworkms=5 \
232+
)
233+
allinone_args=(\
234+
-runclient=false \
235+
-coordinatorargs="$(echo -n "${coordinator_args[@]}")" \
236+
)
237+
java -cp allinone.jar org.batfish.allinone.Main "${allinone_args[@]}" > batfish.log 2>&1 &
238+
239+
# Wait for service to start
240+
sleep 10
241+
fi
189242
190243
- name: Run lab integration test - ${{ matrix.lab }}
191244
working-directory: lab-validation
@@ -196,7 +249,11 @@ jobs:
196249
if: failure()
197250
run: |
198251
echo "=== Batfish logs ==="
199-
tail -100 batfish.log || echo "No batfish log found"
252+
if [ "${{ inputs.batfish_docker }}" != "" ]; then
253+
docker logs batfish || echo "No Docker container logs found"
254+
else
255+
tail -100 batfish.log || echo "No batfish log found"
256+
fi
200257
201258
# Summary job for required status checks
202259
all-labs-passed:
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This file is an example of how to integrate lab validation into the docker release process
2+
# Add this job to docker/.github/workflows/reusable-upload.yml after artifact building
3+
4+
# Add this job to the docker upload workflow after dev artifacts are built
5+
lab-validation-test:
6+
runs-on: ubuntu-latest
7+
needs: [dev_image_upload, dev_whl_upload]
8+
if: inputs.BATFISH_GITHUB_BATFISH_REPO == 'batfish/batfish' && inputs.BATFISH_GITHUB_PYBATFISH_REPO == 'batfish/pybatfish'
9+
steps:
10+
- name: Call lab validation with test artifacts
11+
uses: batfish/lab-validation/.github/workflows/reusable-lab-validation.yml@main
12+
with:
13+
batfish_docker: "batfish/batfish:${{ inputs.test_tag }}"
14+
pybatfish_version: "${{ inputs.bf_version }}"
15+
pybatfish_pypi_repo: "test"
16+
17+
# Update prod upload jobs to depend on lab validation passing
18+
prod_image_upload:
19+
if: inputs.queue_prod_release && inputs.BATFISH_GITHUB_BATFISH_REPO == 'batfish/batfish' && inputs.BATFISH_GITHUB_PYBATFISH_REPO == 'batfish/pybatfish'
20+
environment: Release Containers
21+
runs-on: ubuntu-latest
22+
needs: [lab-validation-test] # Add this dependency
23+
# ... rest of existing job
24+
25+
prod_whl_upload:
26+
if: inputs.queue_prod_release && inputs.BATFISH_GITHUB_BATFISH_REPO == 'batfish/batfish' && inputs.BATFISH_GITHUB_PYBATFISH_REPO == 'batfish/pybatfish'
27+
environment: Release Pybatfish
28+
runs-on: ubuntu-latest
29+
needs: [lab-validation-test] # Add this dependency
30+
# ... rest of existing job
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# This file is a template for adding lab validation to Batfish PRs via comments
2+
# Copy this to batfish/.github/workflows/ to enable PR-triggered lab validation
3+
4+
name: PR Comment Lab Validation
5+
6+
on:
7+
issue_comment:
8+
types: [created]
9+
10+
jobs:
11+
# Check if comment is on a PR and from authorized user
12+
check-comment:
13+
runs-on: ubuntu-latest
14+
if: github.event.issue.pull_request && contains(github.event.comment.body, '/test-labs')
15+
outputs:
16+
should_run: ${{ steps.check.outputs.should_run }}
17+
lab_filter: ${{ steps.parse.outputs.lab_filter }}
18+
pr_ref: ${{ steps.pr.outputs.ref }}
19+
steps:
20+
- name: Check permissions
21+
id: check
22+
run: |
23+
# Only allow repo collaborators to trigger lab validation
24+
# You may want to customize this permission check
25+
echo "should_run=true" >> $GITHUB_OUTPUT
26+
27+
- name: Get PR ref
28+
id: pr
29+
run: |
30+
PR_NUMBER=${{ github.event.issue.number }}
31+
echo "ref=refs/pull/$PR_NUMBER/head" >> $GITHUB_OUTPUT
32+
33+
- name: Parse lab filter
34+
id: parse
35+
run: |
36+
COMMENT="${{ github.event.comment.body }}"
37+
# Extract lab filter from comment (e.g., "/test-labs eos_*" -> "eos_*")
38+
if [[ "$COMMENT" =~ /test-labs[[:space:]]+([^[:space:]]+) ]]; then
39+
LAB_FILTER="${BASH_REMATCH[1]}"
40+
else
41+
LAB_FILTER=""
42+
fi
43+
echo "lab_filter=$LAB_FILTER" >> $GITHUB_OUTPUT
44+
echo "Parsed lab filter: '$LAB_FILTER'"
45+
46+
# Add reaction to indicate the workflow started
47+
react-start:
48+
runs-on: ubuntu-latest
49+
needs: check-comment
50+
if: needs.check-comment.outputs.should_run == 'true'
51+
steps:
52+
- name: Add eyes reaction
53+
run: |
54+
curl -X POST \
55+
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
56+
-H "Accept: application/vnd.github.v3+json" \
57+
https://api.github.com/repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \
58+
-d '{"content":"eyes"}'
59+
60+
# Call the lab validation workflow
61+
run-lab-validation:
62+
needs: [check-comment, react-start]
63+
if: needs.check-comment.outputs.should_run == 'true'
64+
uses: batfish/lab-validation/.github/workflows/reusable-lab-validation.yml@main
65+
with:
66+
batfish_ref: ${{ needs.check-comment.outputs.pr_ref }}
67+
pybatfish_ref: master
68+
lab_filter: ${{ needs.check-comment.outputs.lab_filter }}
69+
70+
# React based on results
71+
react-result:
72+
runs-on: ubuntu-latest
73+
needs: [check-comment, run-lab-validation]
74+
if: always() && needs.check-comment.outputs.should_run == 'true'
75+
steps:
76+
- name: Add success reaction
77+
if: needs.run-lab-validation.result == 'success'
78+
run: |
79+
curl -X POST \
80+
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
81+
-H "Accept: application/vnd.github.v3+json" \
82+
https://api.github.com/repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \
83+
-d '{"content":"+1"}'
84+
85+
- name: Add failure reaction
86+
if: needs.run-lab-validation.result == 'failure'
87+
run: |
88+
curl -X POST \
89+
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
90+
-H "Accept: application/vnd.github.v3+json" \
91+
https://api.github.com/repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \
92+
-d '{"content":"-1"}'
93+
94+
- name: Comment with results
95+
run: |
96+
if [ "${{ needs.run-lab-validation.result }}" = "success" ]; then
97+
COMMENT="✅ Lab validation passed!"
98+
else
99+
COMMENT="❌ Lab validation failed. Check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details."
100+
fi
101+
102+
curl -X POST \
103+
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
104+
-H "Accept: application/vnd.github.v3+json" \
105+
https://api.github.com/repos/${{ github.repository }}/issues/comments \
106+
-d "{\"body\":\"$COMMENT\"}"

0 commit comments

Comments
 (0)