name: 代码测试 on: push: branches: [main] pull_request: workflow_dispatch: jobs: test: name: ruff + pytest runs-on: ubuntu-latest # 固定官方 python 镜像:保证 python3.13 + pip 在场(runner 默认镜像 # 工具链不明,SDK 仓库实测任务曾 7s 即死);runner 不支持 container # 时回落宿主机 python,此时 uv 经下方镜像变量自行下载 CPython container: python:3.13-slim steps: # 不用 actions/checkout、不用 git:runner 对 github 连通性不稳 # (SDK 仓库 probe 实测),改走 Gitea archive 接口拉源码 tarball。 # slim 镜像没有 curl/wget/git,网络操作一律用容器里保证在场的 # python 标准库;每步结果写进 commit status(日志匿名不可读, # status 远程可读;GITEA_TOKEN 未配置时静默降级,不影响流程) - name: 拉源码、装依赖并执行测试 env: TOKEN: ${{ secrets.GITEA_TOKEN }} UV_PYTHON_INSTALL_MIRROR: https://registry.npmmirror.com/-/binary/python-build-standalone run: | set -e export SERVER="${GITHUB_SERVER_URL:-https://gitea.4i.hk}" note() { python3 -c ' import sys, os, json, urllib.request ctx, desc, state = sys.argv[1:4] req = urllib.request.Request( os.environ["SERVER"] + "/api/v1/repos/" + os.environ["GITHUB_REPOSITORY"] + "/statuses/" + os.environ["GITHUB_SHA"], data=json.dumps( {"state": state, "context": "ci/" + ctx, "description": desc} ).encode(), headers={ "Content-Type": "application/json", "Authorization": "token " + os.environ["TOKEN"], }, ) try: urllib.request.urlopen(req, timeout=10) except Exception: pass # status 只是旁路:token 未配置或网络抖动都不能影响主流程 ' "$1" "$2" "$3" } trap 'note error "步骤意外失败,详见 Actions 日志" failure' ERR python3 -c "import urllib.request; urllib.request.urlretrieve( '$SERVER/api/v1/repos/$GITHUB_REPOSITORY/archive/$GITHUB_SHA.tar.gz', 'src.tgz')" \ && mkdir src && tar -xzf src.tgz -C src --strip-components=1 && cd src \ || { note fetch "archive 拉取失败" failure; exit 1; } note fetch ok success pip install uv \ || { note pip "pip 安装 uv 失败" failure; exit 1; } note pip ok success # qqbotsdk 依赖解析自 GitHub archive(uv.lock 锁定内容 hash), # runner 到 github 时通时不通,sync 失败自动重试 sync_ok="" for _ in 1 2 3; do if uv sync; then sync_ok=1; break; fi sleep 5 done [ -n "$sync_ok" ] || { note sync "uv sync 失败(已重试 3 次)" failure; exit 1; } note sync ok success uv run ruff check musicbot tests \ || { note ruff "ruff check 未通过" failure; exit 1; } note ruff ok success uv run pytest \ || { note pytest "pytest 未通过" failure; exit 1; } note pytest ok success