Repository navigation
Merge pull request #120 from ITCraftDevelopmentTeam/dependabot/pip/py… #62
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 'Build (Dev)' | |
| on: | |
| push: | |
| branches: | |
| - master | |
| workflow_dispatch: | |
| jobs: | |
| get-version-number: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| VERSION: ${{ steps.get_version.outputs.VERSION }} | |
| SUB_VERSION: ${{ steps.get_version.outputs.SUB_VERSION }} | |
| steps: | |
| - name: "Checkout" | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: "Setup Python" | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - name: "Get version number" | |
| id: get_version | |
| run: | | |
| pip install toml | |
| # 获取基础版本号 | |
| BASE_VERSION=$(python -c "import version; print(version.VERSION)") | |
| echo "Base version: $BASE_VERSION" | |
| # 获取最近的标签 | |
| LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") | |
| echo "Latest tag: $LATEST_TAG" | |
| # 计算从标签到当前 HEAD 的提交数量 | |
| SUB_VER=$(git rev-list --no-merges --count "$LATEST_TAG"..HEAD 2>/dev/null || echo "0") | |
| echo "Sub version: $SUB_VER" | |
| # 组合完整版本号 | |
| FULL_VERSION="${BASE_VERSION}.${SUB_VER}" | |
| echo "Full version: $FULL_VERSION" | |
| echo "VERSION=$FULL_VERSION" >> $GITHUB_OUTPUT | |
| echo "SUB_VERSION=$SUB_VER" >> $GITHUB_OUTPUT | |
| build-windows: | |
| needs: get-version-number | |
| runs-on: windows-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| arch: [x64] | |
| steps: | |
| - name: "Checkout" | |
| uses: actions/checkout@v6 | |
| - name: "Setup Python" | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| architecture: ${{ matrix.arch }} | |
| - name: "Setup Poetry" | |
| uses: snok/install-poetry@v1 | |
| with: | |
| version: latest | |
| virtualenvs-create: true | |
| virtualenvs-in-project: true | |
| - name: "Install dependencies" | |
| shell: bash | |
| run: | | |
| poetry install --all-groups | |
| - name: "Install zstandard (Nuitka onefile compression)" | |
| shell: bash | |
| run: | | |
| poetry run pip install zstandard | |
| - name: "Build with Nuitka" | |
| shell: bash | |
| run: | | |
| poetry run python -m nuitka \ | |
| --standalone \ | |
| --onefile \ | |
| --include-package=discord \ | |
| --include-package=websockets \ | |
| --include-package=aiosqlite \ | |
| --include-package=sqlalchemy.engine \ | |
| --include-package=sqlalchemy.sql \ | |
| --include-package=sqlalchemy.orm \ | |
| --include-package=sqlalchemy.ext.asyncio \ | |
| --include-package=sqlalchemy.dialects.sqlite \ | |
| --include-package=fastapi \ | |
| --include-package=uvicorn \ | |
| --include-package=httpx \ | |
| --include-package=toml \ | |
| --include-package=starlette \ | |
| --include-package=pydantic \ | |
| --include-package=anyio \ | |
| --nofollow-import-to=sqlalchemy.dialects.postgresql \ | |
| --nofollow-import-to=sqlalchemy.dialects.mysql \ | |
| --nofollow-import-to=sqlalchemy.dialects.oracle \ | |
| --nofollow-import-to=sqlalchemy.dialects.mssql \ | |
| --nofollow-import-to=sqlalchemy.dialects.firebird \ | |
| --nofollow-import-to=sqlalchemy.dialects.sybase \ | |
| --nofollow-import-to=aiohttp.test_utils \ | |
| --nofollow-import-to=unittest \ | |
| --nofollow-import-to=test \ | |
| --nofollow-import-to=tests \ | |
| --nofollow-import-to=pytest \ | |
| --include-data-files=pyproject.toml=pyproject.toml \ | |
| --output-dir=build \ | |
| --output-filename=onedisc.exe \ | |
| --lto=no \ | |
| --jobs=1 \ | |
| --windows-icon-from-ico=icon.ico \ | |
| --windows-console-mode=force \ | |
| --assume-yes-for-downloads \ | |
| main.py | |
| - name: "List build output" | |
| shell: bash | |
| run: | | |
| echo "Build directory contents:" | |
| ls -la build/ || true | |
| find build -type f -name "*.exe" 2>/dev/null || true | |
| - name: "Rename application" | |
| shell: pwsh | |
| run: | | |
| $exeFile = Get-ChildItem -Path "build" -Filter "*.exe" -Recurse | Select-Object -First 1 | |
| if ($exeFile) { | |
| $destPath = "build\onedisc-windows-${{ matrix.arch }}.exe" | |
| Move-Item -Path $exeFile.FullName -Destination $destPath -Force | |
| Write-Host "Moved $($exeFile.Name) to $destPath" | |
| } else { | |
| Write-Host "Error: No exe file found in build directory" | |
| Get-ChildItem -Path "build" -Recurse | |
| exit 1 | |
| } | |
| - name: "Smoke test" | |
| shell: pwsh | |
| run: | | |
| # 冒烟测试:用临时配置启动产物,确认可以正常运行 | |
| $env:PYTHONUTF8 = "1" | |
| '{"account_token":"smoke_test_token","system":{"proxy":null,"logger":{"level":20}},"servers":[]}' | Out-File -Encoding utf8 config.json | |
| $exe = "build\onedisc-windows-${{ matrix.arch }}.exe" | |
| $p = Start-Process -FilePath $exe -PassThru -RedirectStandardOutput smoke.out.log -RedirectStandardError smoke.err.log | |
| Start-Sleep -Seconds 25 | |
| if (-not $p.HasExited) { Stop-Process -Id $p.Id -Force -ErrorAction SilentlyContinue } | |
| Start-Sleep -Seconds 5 | |
| Get-Process | Where-Object { $_.ProcessName -like "onedisc*" } | Stop-Process -Force -ErrorAction SilentlyContinue | |
| $out = "" | |
| foreach ($f in @("smoke.out.log", "smoke.err.log")) { | |
| if (Test-Path $f) { $out += (Get-Content $f -Raw) + "`n" } | |
| } | |
| Write-Host "===== smoke log =====" | |
| Write-Host $out | |
| if ($out -notmatch "OneDisc \(By: IT Craft Development Team\)" -or $out -notmatch "logging in using static token") { | |
| Write-Error "冒烟测试失败:程序未能正常启动" | |
| exit 1 | |
| } | |
| - name: "Upload build" | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: OneDisc-${{ needs.get-version-number.outputs.VERSION }}-windows-${{ matrix.arch }} | |
| path: build/onedisc-windows-${{ matrix.arch }}.exe | |
| build-linux: | |
| needs: get-version-number | |
| runs-on: ubuntu-22.04 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| arch: [x64] | |
| steps: | |
| - name: "Checkout" | |
| uses: actions/checkout@v6 | |
| - name: "Setup Python" | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - name: "Setup Poetry" | |
| uses: snok/install-poetry@v1 | |
| with: | |
| version: latest | |
| virtualenvs-create: true | |
| virtualenvs-in-project: true | |
| - name: "Install system dependencies" | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y patchelf ccache libffi-dev | |
| - name: "Install dependencies" | |
| run: | | |
| poetry install --all-groups | |
| - name: "Install zstandard (Nuitka onefile compression)" | |
| shell: bash | |
| run: | | |
| poetry run pip install zstandard | |
| - name: "Build with Nuitka" | |
| run: | | |
| poetry run python -m nuitka \ | |
| --standalone \ | |
| --onefile \ | |
| --include-package=discord \ | |
| --include-package=websockets \ | |
| --include-package=aiosqlite \ | |
| --include-package=sqlalchemy.engine \ | |
| --include-package=sqlalchemy.sql \ | |
| --include-package=sqlalchemy.orm \ | |
| --include-package=sqlalchemy.ext.asyncio \ | |
| --include-package=sqlalchemy.dialects.sqlite \ | |
| --include-package=fastapi \ | |
| --include-package=uvicorn \ | |
| --include-package=httpx \ | |
| --include-package=toml \ | |
| --include-package=starlette \ | |
| --include-package=pydantic \ | |
| --include-package=anyio \ | |
| --nofollow-import-to=sqlalchemy.dialects.postgresql \ | |
| --nofollow-import-to=sqlalchemy.dialects.mysql \ | |
| --nofollow-import-to=sqlalchemy.dialects.oracle \ | |
| --nofollow-import-to=sqlalchemy.dialects.mssql \ | |
| --nofollow-import-to=sqlalchemy.dialects.firebird \ | |
| --nofollow-import-to=sqlalchemy.dialects.sybase \ | |
| --nofollow-import-to=aiohttp.test_utils \ | |
| --nofollow-import-to=unittest \ | |
| --nofollow-import-to=test \ | |
| --nofollow-import-to=tests \ | |
| --nofollow-import-to=pytest \ | |
| --include-data-files=pyproject.toml=pyproject.toml \ | |
| --output-dir=build \ | |
| --output-filename=onedisc \ | |
| --lto=no \ | |
| --assume-yes-for-downloads \ | |
| --static-libpython=no \ | |
| main.py | |
| - name: "List build output" | |
| run: | | |
| echo "Build directory contents:" | |
| ls -la build/ || true | |
| find build -type f -executable 2>/dev/null || true | |
| - name: "Rename application" | |
| run: | | |
| # 查找生成的可执行文件 | |
| EXE_FILE=$(find build -maxdepth 1 -type f -executable | head -n 1) | |
| if [ -n "$EXE_FILE" ]; then | |
| mv "$EXE_FILE" build/onedisc-linux-${{ matrix.arch }} | |
| chmod +x build/onedisc-linux-${{ matrix.arch }} | |
| echo "Moved $EXE_FILE to build/onedisc-linux-${{ matrix.arch }}" | |
| else | |
| echo "Error: No executable file found in build directory" | |
| ls -la build/ | |
| exit 1 | |
| fi | |
| - name: "Smoke test" | |
| run: | | |
| # 冒烟测试:用临时配置启动产物,确认可以正常运行 | |
| cat > config.json <<'EOF' | |
| { | |
| "account_token": "smoke_test_token", | |
| "system": {"proxy": null, "logger": {"level": 20}}, | |
| "servers": [] | |
| } | |
| EOF | |
| ./build/onedisc-linux-${{ matrix.arch }} > smoke.log 2>&1 & | |
| PID=$! | |
| sleep 20 | |
| kill $PID 2>/dev/null || true | |
| wait $PID 2>/dev/null || true | |
| echo "===== smoke.log =====" | |
| cat smoke.log | |
| if ! grep -q "OneDisc (By: IT Craft Development Team)" smoke.log || ! grep -q "logging in using static token" smoke.log; then | |
| echo "::error::冒烟测试失败:程序未能正常启动" | |
| exit 1 | |
| fi | |
| - name: "Upload build" | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: OneDisc-${{ needs.get-version-number.outputs.VERSION }}-linux-${{ matrix.arch }} | |
| path: build/onedisc-linux-${{ matrix.arch }} | |
| build-macos: | |
| needs: get-version-number | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - arch: x64 | |
| python-arch: x64 | |
| os: macos-26-intel | |
| - arch: arm64 | |
| python-arch: arm64 | |
| os: macos-latest | |
| steps: | |
| - name: "Checkout" | |
| uses: actions/checkout@v6 | |
| - name: "Setup Python" | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| architecture: ${{ matrix.python-arch }} | |
| - name: "Setup Poetry" | |
| uses: snok/install-poetry@v1 | |
| with: | |
| version: latest | |
| virtualenvs-create: true | |
| virtualenvs-in-project: true | |
| - name: "Install dependencies" | |
| run: | | |
| poetry install --all-groups | |
| - name: "Install zstandard (Nuitka onefile compression)" | |
| shell: bash | |
| run: | | |
| poetry run pip install zstandard | |
| - name: "Build with Nuitka" | |
| run: | | |
| poetry run python -m nuitka \ | |
| --standalone \ | |
| --onefile \ | |
| --include-package=discord \ | |
| --include-package=websockets \ | |
| --include-package=aiosqlite \ | |
| --include-package=sqlalchemy.engine \ | |
| --include-package=sqlalchemy.sql \ | |
| --include-package=sqlalchemy.orm \ | |
| --include-package=sqlalchemy.ext.asyncio \ | |
| --include-package=sqlalchemy.dialects.sqlite \ | |
| --include-package=fastapi \ | |
| --include-package=uvicorn \ | |
| --include-package=httpx \ | |
| --include-package=toml \ | |
| --include-package=starlette \ | |
| --include-package=pydantic \ | |
| --include-package=anyio \ | |
| --nofollow-import-to=sqlalchemy.dialects.postgresql \ | |
| --nofollow-import-to=sqlalchemy.dialects.mysql \ | |
| --nofollow-import-to=sqlalchemy.dialects.oracle \ | |
| --nofollow-import-to=sqlalchemy.dialects.mssql \ | |
| --nofollow-import-to=sqlalchemy.dialects.firebird \ | |
| --nofollow-import-to=sqlalchemy.dialects.sybase \ | |
| --nofollow-import-to=aiohttp.test_utils \ | |
| --nofollow-import-to=unittest \ | |
| --nofollow-import-to=test \ | |
| --nofollow-import-to=tests \ | |
| --nofollow-import-to=pytest \ | |
| --include-data-files=pyproject.toml=pyproject.toml \ | |
| --output-dir=build \ | |
| --output-filename=onedisc \ | |
| --lto=no \ | |
| --assume-yes-for-downloads \ | |
| main.py | |
| - name: "List build output" | |
| run: | | |
| echo "Build directory contents:" | |
| ls -la build/ || true | |
| find build -type f -perm +111 2>/dev/null || true | |
| - name: "Rename application" | |
| run: | | |
| # 查找生成的可执行文件 | |
| EXE_FILE=$(find build -maxdepth 1 -type f -perm +111 ! -name "*.so" ! -name "*.dylib" | head -n 1) | |
| if [ -n "$EXE_FILE" ]; then | |
| mv "$EXE_FILE" build/onedisc-macos-${{ matrix.arch }} | |
| chmod +x build/onedisc-macos-${{ matrix.arch }} | |
| echo "Moved $EXE_FILE to build/onedisc-macos-${{ matrix.arch }}" | |
| else | |
| echo "Error: No executable file found in build directory" | |
| ls -la build/ | |
| exit 1 | |
| fi | |
| - name: "Smoke test" | |
| run: | | |
| # 冒烟测试:用临时配置启动产物,确认可以正常运行 | |
| cat > config.json <<'EOF' | |
| { | |
| "account_token": "smoke_test_token", | |
| "system": {"proxy": null, "logger": {"level": 20}}, | |
| "servers": [] | |
| } | |
| EOF | |
| ./build/onedisc-macos-${{ matrix.arch }} > smoke.log 2>&1 & | |
| PID=$! | |
| sleep 20 | |
| kill $PID 2>/dev/null || true | |
| wait $PID 2>/dev/null || true | |
| echo "===== smoke.log =====" | |
| cat smoke.log | |
| if ! grep -q "OneDisc (By: IT Craft Development Team)" smoke.log || ! grep -q "logging in using static token" smoke.log; then | |
| echo "::error::冒烟测试失败:程序未能正常启动" | |
| exit 1 | |
| fi | |
| - name: "Upload build" | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: OneDisc-${{ needs.get-version-number.outputs.VERSION }}-macos-${{ matrix.arch }} | |
| path: build/onedisc-macos-${{ matrix.arch }} | |
| deploy-docs: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: "Checkout" | |
| uses: actions/checkout@v6 | |
| - name: "Set up Node.js" | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '20' | |
| registry-url: 'https://registry.npmjs.org/' | |
| - name: "Install requirements" | |
| run: | | |
| npm install | |
| - name: "Build Documents" | |
| run: | | |
| npm run docs:build | |
| - name: "Deploy to GitHub Pages" | |
| uses: peaceiris/actions-gh-pages@v4 | |
| with: | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| publish_dir: ./docs/.vitepress/dist/ |