-
Notifications
You must be signed in to change notification settings - Fork 44
242 lines (215 loc) · 9.44 KB
/
Copy pathpull_request.yml
File metadata and controls
242 lines (215 loc) · 9.44 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
name: Continuous Integration
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:
inputs:
oss_conductor_version:
description: 'OSS Conductor image tag (falls back to the E2E_TEST_OSS_CONDUCTOR_VERSION org var, then to the default in scripts/docker-compose-oss.yaml on fork PRs)'
required: false
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
unit-test:
runs-on: ubuntu-latest
env:
COVERAGE_DIR: .coverage-reports
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install pytest pytest-cov coverage jsonschema
- name: Verify agents import without extras installed
id: agent_base_import
continue-on-error: true
run: |
python -c "import conductor.ai.agents"
- name: Install agents extra
run: |
pip install -e '.[agents]'
pip install pytest-asyncio
- name: Prepare coverage directory
run: |
mkdir -p ${{ env.COVERAGE_DIR }}
- name: Run unit tests
id: unit_tests
continue-on-error: true
env:
COVERAGE_FILE: ${{ env.COVERAGE_DIR }}/.coverage.unit
run: |
coverage run -m pytest tests/unit -v
- name: Run backward compatibility tests
id: bc_tests
continue-on-error: true
env:
COVERAGE_FILE: ${{ env.COVERAGE_DIR }}/.coverage.bc
run: |
coverage run -m pytest tests/backwardcompatibility -v
- name: Run serdeser tests
id: serdeser_tests
continue-on-error: true
env:
COVERAGE_FILE: ${{ env.COVERAGE_DIR }}/.coverage.serdeser
run: |
coverage run -m pytest tests/serdesertest -v
- name: Generate coverage report
id: coverage_report
run: |
coverage combine ${{ env.COVERAGE_DIR }}/.coverage.*
coverage report
coverage xml -o coverage.xml
- name: Verify coverage file
id: verify_coverage
if: always()
run: |
if [ ! -s coverage.xml ]; then
echo "coverage.xml is empty or does not exist"
ls -la coverage.xml ${{ env.COVERAGE_DIR }} || true
exit 1
fi
echo "coverage.xml exists and is not empty"
- name: Check test results
if: steps.unit_tests.outcome == 'failure' || steps.bc_tests.outcome == 'failure' || steps.serdeser_tests.outcome == 'failure' || steps.agent_base_import.outcome == 'failure'
run: exit 1
integration-test:
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
bucket: [test-all, long-sync, long-async, core]
name: integration-test (${{ matrix.bucket }})
env:
CONDUCTOR_SERVER_URL: ${{ vars.SDKDEV_V5_SERVER_URL }}
CONDUCTOR_AUTH_KEY: ${{ vars.SDKDEV_V5_AUTH_KEY }}
CONDUCTOR_AUTH_SECRET: ${{ secrets.SDKDEV_V5_AUTH_SECRET }}
# Force HTTP/1.1 for integration tests: long-lived HTTP/2 connections to
# the shared dev server (through its proxy/LB) intermittently stall
# mid-stream, surfacing as httpcore.ReadTimeout -> ApiException(0). HTTP/1.1
# uses one request per pooled connection, avoiding that failure class.
CONDUCTOR_HTTP2_ENABLED: "false"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install pytest
- name: Run integration tests
run: >-
bash scripts/run_integration_tests.sh --bucket=${{ matrix.bucket }}
-s --log-cli-level=INFO
--log-cli-format='%(asctime)s %(levelname)s %(name)s: %(message)s'
# Integration tests (OSS): spins up Conductor OSS + Postgres via
# scripts/docker-compose-oss.yaml and runs the integration suite
# unauthenticated, with Orkes-only tests gated out via
# CONDUCTOR_SERVER_TYPE=oss (see the individual test files for the
# empirically-confirmed gaps). The same stack can be run locally with
# scripts/run-integration-oss.sh.
#
# Unlike the authenticated integration-test job above, this runs the whole
# suite in one job (--bucket=all) instead of matrix-splitting it: the full
# OSS run finishes in under 5 minutes, so splitting it would just cause
# extra runner usage for no performance benefit.
#
# --bucket=all also means the server_timeout_unreliable carve-out (see
# scripts/run_integration_tests.sh) is not applied here, deliberately: that
# carve-out exists because the shared sdkdev server doesn't fire server-side
# task timeouts on a CI-bounded timeline, which doesn't hold for a dedicated
# local OSS stack. This job is the only CI coverage those cases get.
integration-tests-oss:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
CONDUCTOR_SERVER_URL: http://localhost:8080/api
CONDUCTOR_SERVER_TYPE: oss
# See the comment on CONDUCTOR_HTTP2_ENABLED in the integration-test job
# above; kept consistent here even though the local OSS stack doesn't
# have the same proxy/LB in front of it.
CONDUCTOR_HTTP2_ENABLED: "false"
steps:
# OSS_CONDUCTOR_VERSION is resolved here rather than in the job `env` so
# that the two ways it can come back empty get different treatment:
#
# - Fork PR: GitHub withholds org/repo variables from pull_request runs
# on forks exactly as it withholds secrets, so vars.* is always "" for
# an outside contributor (observed in csharp-sdk#178). This job needs
# no secrets, only a tag, so leave the var unset and let the default
# baked into the `image:` line of scripts/docker-compose-oss.yaml
# apply. That is the same tag a plain local run of
# scripts/run-integration-oss.sh gets, and the one place it is
# written -- no second copy to drift out of sync here.
# - Anything else: the org variable is genuinely missing or its
# repository access policy no longer covers this repo. Fail loudly
# rather than silently drifting onto the default.
- name: Resolve OSS Conductor version
env:
REQUESTED_VERSION: ${{ inputs.oss_conductor_version || vars.E2E_TEST_OSS_CONDUCTOR_VERSION }}
IS_FORK_PR: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }}
run: |
if [ -n "$REQUESTED_VERSION" ]; then
echo "OSS_CONDUCTOR_VERSION=${REQUESTED_VERSION}" >> "$GITHUB_ENV"
elif [ "$IS_FORK_PR" = "true" ]; then
echo "::notice::Fork PR: org variables are withheld, falling back to the default tag in scripts/docker-compose-oss.yaml"
else
echo "::error::No Conductor OSS image tag resolved. Set the E2E_TEST_OSS_CONDUCTOR_VERSION organization variable (and ensure its repository access policy includes this repo), or pass the oss_conductor_version input via workflow_dispatch."
exit 1
fi
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install pytest
# `docker compose up` only pulls an image when it is missing locally. On a
# GitHub-hosted runner the VM is ephemeral and starts with no cached copy
# of this image, so `up` would pull anyway and this step is redundant
# today. It is here deliberately: it costs no extra network pull (`up`
# then finds the image locally), it separates "couldn't pull the image"
# from "the stack didn't come up" into two distinct red steps, and it is
# what keeps a mutable tag from going stale if this job ever moves to a
# self-hosted runner with a warm Docker daemon -- the same reason
# scripts/run-integration-oss.sh pulls. It also prints the tag actually in
# use, which for a fork PR comes from the compose file's default.
- name: Pull Conductor OSS image
run: |
echo "Using $(docker compose -f scripts/docker-compose-oss.yaml config --images | grep -m1 '^conductoross/conductor:')"
docker compose -f scripts/docker-compose-oss.yaml pull conductor-server
- name: Start Conductor OSS stack
run: docker compose -f scripts/docker-compose-oss.yaml up -d
- name: Wait for Conductor to be healthy
run: timeout 180 bash -c 'until curl -sf http://localhost:8080/health; do sleep 5; done'
- name: Run integration tests (OSS)
run: >-
bash scripts/run_integration_tests.sh --bucket=all
-s --log-cli-level=INFO
--log-cli-format='%(asctime)s %(levelname)s %(name)s: %(message)s'
- name: Dump Conductor logs
if: failure()
run: docker compose -f scripts/docker-compose-oss.yaml logs conductor-server