Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 插件测试中使用 uv 来控制 Python 版本并与本体共享依赖 #320

Merged
merged 15 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 0 additions & 54 deletions .github/workflows/docker-test.yml

This file was deleted.

41 changes: 39 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ jobs:
with:
token: ${{ secrets.CODECOV_TOKEN }}

docker:
name: Docker
noneflow-docker:
name: NoneFlow Docker
runs-on: ubuntu-latest
needs: test
steps:
Expand Down Expand Up @@ -70,3 +70,40 @@ jobs:
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}

nonetest-docker:
name: NoneTest Docker
runs-on: ubuntu-latest
needs: test
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Docker
uses: docker/setup-buildx-action@v3

- name: Login to Github Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Generate Tags
uses: docker/metadata-action@v5
id: metadata
with:
images: ghcr.io/nonebot/nonetest
tags: |
type=semver,pattern={{version}}
type=ref,event=branch

- name: Build and Publish
uses: docker/build-push-action@v6
with:
context: .
file: ./src/providers/docker_test/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/lang/zh-CN/

## [Unreleased]

### Added

- 插件测试中使用 uv 来控制 Python 版本并与本体共享依赖

## [4.1.4] - 2024-12-08

### Fixed
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ show-bump = "bump-my-version show-bump"
snapshot-create = "pytest --inline-snapshot=create"
snapshot-fix = "pytest --inline-snapshot=fix"
store-test = "python -m src.providers.store_test"
docker-test = "python -m src.providers.docker_test"

[tool.pyright]
pythonVersion = "3.12"
Expand Down
1 change: 1 addition & 0 deletions src/plugins/github/plugins/publish/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ async def resolve_conflict_pull_requests(
# 如果信息验证失败,则跳过更新
if not result.valid:
logger.error("信息验证失败,已跳过")
logger.error(f"验证结果: {result}")
continue

# 每次切换前都要确保回到主分支
Expand Down
2 changes: 1 addition & 1 deletion src/providers/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@
# 商店测试镜像
# https://github.com/orgs/nonebot/packages/container/package/nonetest
DOCKER_IMAGES_VERSION = os.environ.get("DOCKER_IMAGES_VERSION") or "latest"
DOCKER_IMAGES = f"ghcr.io/nonebot/nonetest:{{}}-{DOCKER_IMAGES_VERSION}"
DOCKER_IMAGES = f"ghcr.io/nonebot/nonetest:{DOCKER_IMAGES_VERSION}"
21 changes: 13 additions & 8 deletions src/providers/docker_test/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
ARG PYTHON_VERSION=3.12
FROM python:3.12.4
COPY --from=ghcr.io/astral-sh/uv:0.5.6 /uv /bin/uv

FROM python:${PYTHON_VERSION}
WORKDIR /app

WORKDIR /tmp
# 设置时区
ENV TZ=Asia/Shanghai

# OpenCV 所需的依赖
RUN apt-get update \
Expand All @@ -11,11 +13,14 @@ RUN apt-get update \
&& apt-get purge -y --auto-remove \
&& rm -rf /var/lib/apt/lists/*

# 测试插件依赖 Poetry
RUN curl -sSL https://install.python-poetry.org | python3 -

# 插件测试需要 Poetry
ENV PATH="${PATH}:/root/.local/bin"
RUN uv tool install poetry

# Python 依赖
COPY pyproject.toml uv.lock /app/
RUN uv sync --project /app/ --no-dev --frozen --compile-bytecode

COPY ./plugin_test.py /tmp/plugin_test.py
COPY src /app/src/

CMD ["python", "plugin_test.py"]
CMD ["uv", "run", "--project", "/app/", "--no-dev", "-m", "src.providers.docker_test"]
21 changes: 10 additions & 11 deletions src/providers/docker_test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
from typing import TypedDict

import docker
from pydantic import BaseModel, Field, SkipValidation, field_validator
from pydantic import BaseModel, SkipValidation, field_validator

from src.providers.constants import DOCKER_IMAGES, REGISTRY_PLUGINS_URL
from src.providers.constants import DOCKER_IMAGES


class Metadata(TypedDict):
Expand All @@ -24,19 +24,19 @@ class DockerTestResult(BaseModel):
""" 是否运行测试 """
load: bool
""" 是否加载成功 """
output: str
""" 测试输出 """
version: str | None = None
""" 测试版本 """
config: str = ""
""" 测试配置 """
test_env: str = Field(default="unknown")
test_env: str = ""
"""测试环境

python==3.12 nonebot2==2.4.0 pydantic==2.10.0
"""
metadata: SkipValidation[Metadata] | None
metadata: SkipValidation[Metadata] | None = None
""" 插件元数据 """
output: str
""" 测试输出 """

@field_validator("config", mode="before")
@classmethod
Expand All @@ -59,20 +59,20 @@ async def run(self, version: str) -> DockerTestResult:
Returns:
DockerTestResult: 测试结果
"""
image_name = DOCKER_IMAGES.format(version)
# 连接 Docker 环境
client = docker.DockerClient(base_url="unix://var/run/docker.sock")

try:
# 运行 Docker 容器,捕获输出。 容器内运行的代码拥有超时设限,此处无需设置超时
output = client.containers.run(
image_name,
DOCKER_IMAGES,
environment={
# 运行测试的 Python 版本
"PYTHON_VERSION": version,
# 插件信息
"PROJECT_LINK": self.project_link,
"MODULE_NAME": self.module_name,
"PLUGIN_CONFIG": self.config,
# 插件测试需要用到的插件列表来验证插件依赖是否正确加载
"PLUGINS_URL": REGISTRY_PLUGINS_URL,
},
detach=False,
remove=True,
Expand All @@ -83,6 +83,5 @@ async def run(self, version: str) -> DockerTestResult:
"run": False,
"load": False,
"output": str(e),
"metadata": None,
}
return DockerTestResult(**data)
27 changes: 27 additions & 0 deletions src/providers/docker_test/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import asyncio
import os

from .plugin_test import PluginTest


def main():
"""根据传入的环境变量进行测试

PYTHON_VERSION 为运行测试的 Python 版本
PROJECT_LINK 为插件的项目名
MODULE_NAME 为插件的模块名
PLUGIN_CONFIG 为该插件的配置
"""
python_version = os.environ.get("PYTHON_VERSION", "")

project_link = os.environ.get("PROJECT_LINK", "")
module_name = os.environ.get("MODULE_NAME", "")
plugin_config = os.environ.get("PLUGIN_CONFIG", None)

plugin = PluginTest(python_version, project_link, module_name, plugin_config)

asyncio.run(plugin.run())


if __name__ == "__main__":
main()
Loading
Loading