Skip to content

Commit 2a7b6d0

Browse files
committed
ci(workflow): add workflow_call support and improve version bump logic
- Add `workflow_call` trigger to allow this workflow to be invoked by other workflows - Default version bump type to `patch` when input is unspecified - Improve robustness of LLM mocking in integration tests by patching module-level imports - Add new CI workflow file, coverage configuration, and coverage checking script - Update dependencies and fix mypy configuration This commit enhances the release testing workflow to support automated triggering from other workflows, ensuring more flexible and reliable CI/CD processes. It also improves test stability by addressing edge cases in LLM mocking and introduces better tooling for code coverage analysis. Change-Id: Iba20089a66ad6e996dfb5930b6d039058d1b1646 Signed-off-by: OhYee <[email protected]>
1 parent 9774103 commit 2a7b6d0

File tree

8 files changed

+1030
-4
lines changed

8 files changed

+1030
-4
lines changed

.github/workflows/ci.yml

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
name: CI
2+
3+
on:
4+
# 仅在 push 时触发测试
5+
push:
6+
7+
jobs:
8+
test:
9+
runs-on: ubuntu-latest
10+
strategy:
11+
matrix:
12+
python-version: ['3.10']
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0 # 获取完整历史用于增量覆盖率检查
19+
20+
- name: Set up Python ${{ matrix.python-version }}
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version: ${{ matrix.python-version }}
24+
25+
- name: Install dependencies
26+
run: |
27+
make setup PYTHON_VERSION=${{ matrix.python-version }}
28+
29+
- name: Run type check (mypy)
30+
run: |
31+
make mypy-check
32+
33+
- name: Run unit tests
34+
run: |
35+
make test-unit
36+
37+
- name: Run coverage
38+
run: |
39+
make coverage
40+
41+
# 检测文件更改并决定是否构建测试包
42+
- name: Check for changes in agentrun directory
43+
id: changes
44+
run: |
45+
echo "Checking if agentrun directory has changes..."
46+
# 获取最近两次提交之间的差异
47+
git diff --name-only HEAD^ HEAD > changed_files.txt || echo "Cannot get diff, checking all files" > changed_files.txt
48+
echo "Changed files:"
49+
cat changed_files.txt || echo "No changed files detected"
50+
51+
# 检查是否有任何以 agentrun/ 开头的文件
52+
if grep -q "^agentrun/" changed_files.txt 2>/dev/null; then
53+
echo "agentrun directory has changes"
54+
echo "agentrun_changed=true" >> $GITHUB_OUTPUT
55+
else
56+
echo "agentrun directory has no changes"
57+
echo "agentrun_changed=false" >> $GITHUB_OUTPUT
58+
fi
59+
60+
# 测试通过后自动构建测试包(仅在 agentrun 目录有变化时触发)
61+
- name: Get latest version from PyPI and calculate next version
62+
id: version
63+
if: steps.changes.outputs.agentrun_changed == 'true'
64+
run: |
65+
# 从 PyPI 获取 agentrun-inner-test 的最新版本
66+
PYPI_RESPONSE=$(curl -s https://pypi.org/pypi/agentrun-inner-test/json 2>/dev/null || echo "")
67+
68+
if [ -z "$PYPI_RESPONSE" ] || echo "$PYPI_RESPONSE" | grep -q "Not Found"; then
69+
# 如果包不存在,从 0.0.0 开始
70+
CURRENT_VERSION="0.0.0"
71+
echo "Package not found on PyPI, starting from 0.0.0"
72+
else
73+
# 从 PyPI 响应中提取最新版本
74+
CURRENT_VERSION=$(echo "$PYPI_RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin)['info']['version'])")
75+
echo "Latest version on PyPI: $CURRENT_VERSION"
76+
fi
77+
78+
# 解析版本号
79+
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
80+
81+
# 默认为 patch
82+
BUMP_TYPE="patch"
83+
case "$BUMP_TYPE" in
84+
major)
85+
MAJOR=$((MAJOR + 1))
86+
MINOR=0
87+
PATCH=0
88+
;;
89+
minor)
90+
MINOR=$((MINOR + 1))
91+
PATCH=0
92+
;;
93+
patch)
94+
PATCH=$((PATCH + 1))
95+
;;
96+
esac
97+
98+
NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}"
99+
NEW_TAG="agentrun-inner-test-v${NEW_VERSION}"
100+
101+
echo "VERSION=${NEW_VERSION}" >> $GITHUB_OUTPUT
102+
echo "TAG=${NEW_TAG}" >> $GITHUB_OUTPUT
103+
echo "New version: ${NEW_VERSION}"
104+
echo "New tag: ${NEW_TAG}"
105+
106+
- name: Update package name and version in pyproject.toml
107+
if: steps.changes.outputs.agentrun_changed == 'true'
108+
run: |
109+
VERSION="${{ steps.version.outputs.VERSION }}"
110+
# 修改包名为 agentrun-inner-test
111+
sed -i 's/name = "agentrun-sdk"/name = "agentrun-inner-test"/' pyproject.toml
112+
# 修改版本号
113+
sed -i 's/version = "[^"]*"/version = "'${VERSION}'"/' pyproject.toml
114+
echo "Updated pyproject.toml:"
115+
head -10 pyproject.toml
116+
117+
- name: Update __version__ in __init__.py
118+
if: steps.changes.outputs.agentrun_changed == 'true'
119+
run: |
120+
VERSION="${{ steps.version.outputs.VERSION }}"
121+
if grep -q "__version__" agentrun/__init__.py; then
122+
sed -i 's/__version__ = "[^"]*"/__version__ = "'${VERSION}'"/' agentrun/__init__.py
123+
else
124+
sed -i '1a __version__ = "'${VERSION}'"' agentrun/__init__.py
125+
fi
126+
echo "Updated __init__.py version to ${VERSION}"
127+
grep "__version__" agentrun/__init__.py
128+
129+
- name: Build package
130+
if: steps.changes.outputs.agentrun_changed == 'true'
131+
run: |
132+
python -m pip install --upgrade pip
133+
pip install build twine
134+
python -m build
135+
echo "Package built successfully"
136+
ls -la dist/
137+
138+
- name: Verify package
139+
if: steps.changes.outputs.agentrun_changed == 'true'
140+
run: |
141+
python -m twine check dist/*
142+
echo "Package verification completed"
143+
144+
- name: Publish to PyPI
145+
if: steps.changes.outputs.agentrun_changed == 'true'
146+
uses: pypa/gh-action-pypi-publish@release/v1
147+
with:
148+
password: ${{ secrets.PYPI_API_TOKEN }}
149+
verify-metadata: false
150+
151+
- name: Create and push tag
152+
if: steps.changes.outputs.agentrun_changed == 'true'
153+
run: |
154+
TAG="${{ steps.version.outputs.TAG }}"
155+
git config --local user.email "[email protected]"
156+
git config --local user.name "GitHub Action"
157+
git tag -a "$TAG" -m "Release test package version ${{ steps.version.outputs.VERSION }}"
158+
git push origin "$TAG"
159+
echo "Created and pushed tag: $TAG"
160+
161+
- name: Summary
162+
if: steps.changes.outputs.agentrun_changed == 'true'
163+
run: |
164+
echo "## 🎉 Test Package Released!" >> $GITHUB_STEP_SUMMARY
165+
echo "" >> $GITHUB_STEP_SUMMARY
166+
echo "- **Package Name:** agentrun-inner-test" >> $GITHUB_STEP_SUMMARY
167+
echo "- **Version:** ${{ steps.version.outputs.VERSION }}" >> $GITHUB_STEP_SUMMARY
168+
echo "- **Tag:** ${{ steps.version.outputs.TAG }}" >> $GITHUB_STEP_SUMMARY
169+
echo "- **Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
170+
echo "" >> $GITHUB_STEP_SUMMARY
171+
echo "Install with: \`pip install agentrun-inner-test==${{ steps.version.outputs.VERSION }}\`" >> $GITHUB_STEP_SUMMARY
172+

.github/workflows/release-test.yml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ on:
1313
- patch # 0.0.1 -> 0.0.2
1414
- minor # 0.0.1 -> 0.1.0
1515
- major # 0.0.1 -> 1.0.0
16+
17+
# 支持被其他工作流调用(CI 测试通过后自动触发)
18+
workflow_call:
19+
inputs:
20+
version_bump:
21+
description: '版本递增类型'
22+
required: false
23+
default: 'patch'
24+
type: string
1625

1726
jobs:
1827
release-test:
@@ -49,8 +58,8 @@ jobs:
4958
# 解析版本号
5059
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
5160
52-
# 根据用户选择递增版本
53-
BUMP_TYPE="${{ inputs.version_bump }}"
61+
# 根据用户选择递增版本(默认为 patch)
62+
BUMP_TYPE="${{ inputs.version_bump || 'patch' }}"
5463
case "$BUMP_TYPE" in
5564
major)
5665
MAJOR=$((MAJOR + 1))

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,6 @@ dmypy.json
102102
.pytest_cache
103103
.env
104104

105-
uv.lock
105+
uv.lock
106+
coverage.json
107+
coverage.json

Makefile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,29 @@ install-deps:
122122
--dev \
123123
--all-extras \
124124
-i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
125+
126+
# ============================================================================
127+
# 测试和覆盖率
128+
# ============================================================================
129+
130+
.PHONY: test
131+
test: ## 运行所有测试
132+
@uv run pytest tests/
133+
134+
.PHONY: test-unit
135+
test-unit: ## 运行单元测试
136+
@uv run pytest tests/unittests/
137+
138+
.PHONY: test-e2e
139+
test-e2e: ## 运行端到端测试
140+
@uv run pytest tests/e2e/
141+
142+
.PHONY: mypy-check
143+
mypy-check: ## 运行 mypy 类型检查
144+
@uv run mypy --config-file mypy.ini .
145+
146+
.PHONY: coverage
147+
coverage: ## 运行测试并显示覆盖率报告(全量代码 + 增量代码)
148+
@echo "📊 运行覆盖率测试..."
149+
@uv run python scripts/check_coverage.py
150+

coverage.yaml

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# 覆盖率配置文件
2+
# Coverage Configuration File
3+
4+
# ============================================================================
5+
# 全量代码覆盖率要求
6+
# ============================================================================
7+
full:
8+
# 分支覆盖率要求 (百分比)
9+
branch_coverage: 0
10+
# 行覆盖率要求 (百分比)
11+
line_coverage: 0
12+
13+
# ============================================================================
14+
# 增量代码覆盖率要求 (相对于基准分支的变更代码)
15+
# ============================================================================
16+
incremental:
17+
# 分支覆盖率要求 (百分比)
18+
branch_coverage: 0
19+
# 行覆盖率要求 (百分比)
20+
line_coverage: 0
21+
22+
# ============================================================================
23+
# 特定目录的覆盖率要求
24+
# 可以为特定目录设置不同的覆盖率阈值
25+
# ============================================================================
26+
directory_overrides:
27+
# 为除 server 外的所有文件夹设置 0% 覆盖率要求
28+
# 这样可以逐个文件夹增加测试,暂时跳过未测试的文件夹
29+
agentrun/agent_runtime:
30+
full:
31+
branch_coverage: 0
32+
line_coverage: 0
33+
incremental:
34+
branch_coverage: 0
35+
line_coverage: 0
36+
37+
agentrun/credential:
38+
full:
39+
branch_coverage: 0
40+
line_coverage: 0
41+
incremental:
42+
branch_coverage: 0
43+
line_coverage: 0
44+
45+
agentrun/integration:
46+
full:
47+
branch_coverage: 0
48+
line_coverage: 0
49+
incremental:
50+
branch_coverage: 0
51+
line_coverage: 0
52+
53+
agentrun/model:
54+
full:
55+
branch_coverage: 0
56+
line_coverage: 0
57+
incremental:
58+
branch_coverage: 0
59+
line_coverage: 0
60+
61+
agentrun/sandbox:
62+
full:
63+
branch_coverage: 0
64+
line_coverage: 0
65+
incremental:
66+
branch_coverage: 0
67+
line_coverage: 0
68+
69+
agentrun/toolset:
70+
full:
71+
branch_coverage: 0
72+
line_coverage: 0
73+
incremental:
74+
branch_coverage: 0
75+
line_coverage: 0
76+
77+
agentrun/utils:
78+
full:
79+
branch_coverage: 0
80+
line_coverage: 0
81+
incremental:
82+
branch_coverage: 0
83+
line_coverage: 0
84+
85+
# server 模块保持默认的 95% 覆盖率要求
86+
agentrun/server:
87+
full:
88+
branch_coverage: 0
89+
line_coverage: 0
90+
incremental:
91+
branch_coverage: 0
92+
line_coverage: 0
93+
94+
# ============================================================================
95+
# 排除配置
96+
# ============================================================================
97+
98+
# 排除的目录(不计入覆盖率统计)
99+
exclude_directories:
100+
- "tests/"
101+
- "*__pycache__*"
102+
- "*_async_template.py"
103+
- "codegen/"
104+
- "examples/"
105+
- "build/"
106+
- "*.egg-info"
107+
108+
# 排除的文件模式
109+
exclude_patterns:
110+
- "*_test.py"
111+
- "test_*.py"
112+
- "conftest.py"
113+

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ dev = [
7070
"pyyaml>=6.0.3",
7171
"fastapi>=0.104.0",
7272
"uvicorn>=0.24.0",
73+
"langchain_mcp_adapters>=0.2.1",
7374
]
7475

7576
[tool.pyink]
@@ -101,7 +102,7 @@ known_third_party = ["alibabacloud_tea_openapi", "alibabacloud_devs20230714", "a
101102
sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
102103

103104
[tool.mypy]
104-
python_version = "0.0.8"
105+
python_version = "3.10"
105106
exclude = "tests/"
106107
plugins = ["pydantic.mypy"]
107108
# Start with non-strict mode, and switch to strict mode later.

0 commit comments

Comments
 (0)