docs: 添加 DNS 配置示例及相关参数说明 #52
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: ci | |
| on: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - "**" | |
| pull_request: {} | |
| env: | |
| COLUMNS: 150 | |
| UV_PYTHON: 3.13 | |
| # Avoid duplicate runs on rapid pushes | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # 检测哪些文件类型发生了变更 | |
| changes: | |
| runs-on: ubuntu-latest | |
| # 如果是 tag push(发版),跳过这个检测,所有 jobs 都运行 | |
| if: "!startsWith(github.ref, 'refs/tags/')" | |
| outputs: | |
| code: ${{ steps.filter.outputs.code }} | |
| docs: ${{ steps.filter.outputs.docs }} | |
| ci: ${{ steps.filter.outputs.ci }} | |
| deps: ${{ steps.filter.outputs.deps }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| filters: | | |
| code: | |
| - 'src/**' | |
| - 'python/**' | |
| - 'tests/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'pyproject.toml' | |
| - 'build.rs' | |
| docs: | |
| - '**.md' | |
| - 'LICENSE' | |
| ci: | |
| - '.github/workflows/**' | |
| - 'Makefile' | |
| deps: | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'pyproject.toml' | |
| coverage: | |
| runs-on: ubuntu-latest | |
| needs: [changes] | |
| if: | | |
| always() && | |
| (startsWith(github.ref, 'refs/tags/') || | |
| needs.changes.result == 'skipped' || | |
| needs.changes.outputs.code == 'true' || | |
| needs.changes.outputs.ci == 'true' || | |
| needs.changes.outputs.deps == 'true') | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # rust-nightly used for `#[coverage(off)]` | |
| - uses: dtolnay/rust-toolchain@nightly | |
| - uses: Swatinem/rust-cache@v2 | |
| - uses: taiki-e/install-action@cargo-llvm-cov | |
| - name: install uv | |
| uses: astral-sh/setup-uv@v6 | |
| - name: install deps | |
| run: uv sync --group testing | |
| - run: rustc --version --verbose | |
| - run: | | |
| source <(cargo llvm-cov show-env --export-prefix) | |
| cargo llvm-cov clean --workspace --profraw-only | |
| make build-dev | |
| env: | |
| RUST_BACKTRACE: 1 | |
| RUSTFLAGS: "-C instrument-coverage" | |
| - run: uv pip freeze | |
| - run: uv run coverage run -m pytest --junitxml=junit.xml -o junit_family=legacy | |
| - run: ls -lha | |
| - run: uv run coverage xml | |
| - run: | | |
| source <(cargo llvm-cov show-env --export-prefix) | |
| cargo llvm-cov --codecov --output-path=codecov.json | |
| - uses: codecov/codecov-action@v5 | |
| with: | |
| files: codecov.json | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| - uses: codecov/test-results-action@v1 | |
| # See https://github.com/PyO3/pyo3/discussions/2781 | |
| # tests intermittently segfault with pypy and cpython 3.7 when using `coverage run ...`, hence separate job | |
| test-python: | |
| name: test ${{ matrix.python-version }} | |
| needs: [changes] | |
| if: | | |
| always() && | |
| (startsWith(github.ref, 'refs/tags/') || | |
| needs.changes.result == 'skipped' || | |
| needs.changes.outputs.code == 'true' || | |
| needs.changes.outputs.ci == 'true' || | |
| needs.changes.outputs.deps == 'true') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: | |
| - "3.10" | |
| - "3.11" | |
| - "3.12" | |
| - "3.13" | |
| runs-on: ubuntu-latest | |
| # TODO: get test suite stable with free-threaded python | |
| continue-on-error: false | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: install rust stable | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: cache rust | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: test-v3 | |
| - name: install uv | |
| uses: astral-sh/setup-uv@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: install deps | |
| run: uv sync --group testing | |
| - run: uv pip install -e . | |
| env: | |
| RUST_BACKTRACE: 1 | |
| - run: uv pip freeze | |
| - run: uv run pytest -n logical | |
| env: | |
| HYPOTHESIS_PROFILE: slow | |
| PYTEST_ADDOPTS: ${{ (endsWith(matrix.python-version, 't') || matrix.python-version == '3.14') && '--parallel-threads=2' || '' }} | |
| test-os: | |
| name: test on ${{ matrix.os }} | |
| needs: [changes] | |
| if: | | |
| always() && | |
| (startsWith(github.ref, 'refs/tags/') || | |
| needs.changes.result == 'skipped' || | |
| needs.changes.outputs.code == 'true' || | |
| needs.changes.outputs.ci == 'true' || | |
| needs.changes.outputs.deps == 'true') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu, macos, windows] | |
| runs-on: ${{ matrix.os }}-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: install rust stable | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: cache rust | |
| uses: Swatinem/rust-cache@v2 | |
| - name: install uv | |
| uses: astral-sh/setup-uv@v6 | |
| - name: install deps | |
| run: uv sync --group testing | |
| - run: uv pip install -e . | |
| env: | |
| RUST_BACKTRACE: 1 | |
| - run: uv pip freeze | |
| - run: uv run pytest -n logical | |
| - run: cargo test | |
| test-msrv: | |
| name: test MSRV | |
| needs: [changes] | |
| if: | | |
| always() && | |
| (startsWith(github.ref, 'refs/tags/') || | |
| needs.changes.result == 'skipped' || | |
| needs.changes.outputs.code == 'true' || | |
| needs.changes.outputs.ci == 'true' || | |
| needs.changes.outputs.deps == 'true') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: install uv | |
| uses: astral-sh/setup-uv@v6 | |
| - name: install deps | |
| run: uv sync --group testing | |
| - name: resolve MSRV | |
| id: resolve-msrv | |
| run: echo MSRV=`uv run python -c 'import tomllib; print(tomllib.load(open("Cargo.toml", "rb"))["package"]["rust-version"])'` >> $GITHUB_OUTPUT | |
| - name: install rust MSRV | |
| uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: ${{ steps.resolve-msrv.outputs.MSRV }} | |
| - name: cache rust | |
| uses: Swatinem/rust-cache@v2 | |
| - run: uv pip install -e . | |
| env: | |
| RUST_BACKTRACE: 1 | |
| - run: uv pip freeze | |
| - run: uv run pytest -n logical | |
| - run: cargo test | |
| # test with a debug build as it picks up errors which optimised release builds do not | |
| test-debug: | |
| name: test-debug ${{ matrix.python-version }} | |
| runs-on: ubuntu-latest | |
| needs: [changes] | |
| if: | | |
| always() && | |
| (startsWith(github.ref, 'refs/tags/') || | |
| needs.changes.result == 'skipped' || | |
| needs.changes.outputs.code == 'true' || | |
| needs.changes.outputs.ci == 'true' || | |
| needs.changes.outputs.deps == 'true') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: | |
| - "3.13" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: install uv | |
| uses: astral-sh/setup-uv@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: install rust stable | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: cache rust | |
| uses: Swatinem/rust-cache@v2 | |
| - name: install deps | |
| run: uv sync --group testing | |
| - run: make build-dev | |
| - run: uv pip freeze | |
| - run: uv run pytest -n logical | |
| lint: | |
| runs-on: ubuntu-latest | |
| needs: [changes] | |
| if: | | |
| always() && | |
| (startsWith(github.ref, 'refs/tags/') || | |
| needs.changes.result == 'skipped' || | |
| needs.changes.outputs.code == 'true' || | |
| needs.changes.outputs.ci == 'true' || | |
| needs.changes.outputs.deps == 'true') | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: install rust stable | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - name: cache rust | |
| uses: Swatinem/rust-cache@v2 | |
| # used to lint js code | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "18" | |
| - name: install uv | |
| uses: astral-sh/setup-uv@v6 | |
| - name: install deps | |
| run: | | |
| uv sync --group linting | |
| make build-dev | |
| uv pip freeze | |
| - run: make lint | |
| # https://github.com/marketplace/actions/alls-green#why used for branch protection checks | |
| check: | |
| if: | | |
| always() && | |
| (startsWith(github.ref, 'refs/tags/') || | |
| needs.changes.result == 'skipped' || | |
| (needs.changes.result == 'success' && | |
| (needs.changes.outputs.code == 'true' || | |
| needs.changes.outputs.ci == 'true' || | |
| needs.changes.outputs.deps == 'true'))) | |
| needs: [coverage, test-python, test-os, test-debug, lint] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Decide whether the needed jobs succeeded or failed | |
| uses: re-actors/alls-green@release/v1 | |
| with: | |
| jobs: ${{ toJSON(needs) }} | |
| allowed-failures: coverage | |
| build-sdist: | |
| name: build sdist | |
| runs-on: ubuntu-latest | |
| needs: [changes] | |
| if: | | |
| always() && | |
| (startsWith(github.ref, 'refs/tags/') || | |
| contains(github.event.pull_request.labels.*.name, 'Full Build') || | |
| needs.changes.result == 'skipped' || | |
| (github.ref == 'refs/heads/main' && | |
| (needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true'))) | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| - uses: PyO3/maturin-action@v1 | |
| with: | |
| command: sdist | |
| args: --out dist | |
| rust-toolchain: stable | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: pypi_files_sdist | |
| path: dist | |
| build: | |
| name: build on ${{ matrix.os }} (${{ matrix.target }} - ${{ matrix.interpreter || 'all' }}${{ matrix.os == 'linux' && format(' - {0}', matrix.manylinux == 'auto' && 'manylinux' || matrix.manylinux) || '' }}) | |
| needs: [changes] | |
| if: | | |
| always() && | |
| (startsWith(github.ref, 'refs/tags/') || | |
| contains(github.event.pull_request.labels.*.name, 'Full Build') || | |
| needs.changes.result == 'skipped' || | |
| (github.ref == 'refs/heads/main' && | |
| (needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true'))) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [linux, macos, windows] | |
| target: [x86_64, aarch64] | |
| manylinux: [auto] | |
| include: | |
| # manylinux for various platforms, plus x86_64 pypy | |
| - os: linux | |
| manylinux: auto | |
| target: i686 | |
| - os: linux | |
| manylinux: auto | |
| target: armv7 | |
| interpreter: 3.10 3.11 3.12 3.13 | |
| - os: linux | |
| manylinux: auto | |
| target: ppc64le | |
| interpreter: 3.10 3.11 3.12 3.13 | |
| - os: linux | |
| manylinux: auto | |
| target: s390x | |
| interpreter: 3.10 3.11 3.12 3.13 | |
| - os: linux | |
| manylinux: auto | |
| target: x86_64 | |
| interpreter: pypy3.11 | |
| # musllinux | |
| - os: linux | |
| manylinux: musllinux_1_1 | |
| target: x86_64 | |
| - os: linux | |
| manylinux: musllinux_1_1 | |
| target: aarch64 | |
| - os: linux | |
| manylinux: musllinux_1_1 | |
| target: armv7 | |
| # macos; | |
| # all versions x86_64 | |
| # arm pypy and older pythons which can't be run on the arm hardware for PGO | |
| - os: macos | |
| target: x86_64 | |
| - os: macos | |
| target: aarch64 | |
| interpreter: pypy3.11 | |
| # windows; | |
| # x86_64 pypy builds are not PGO optimized | |
| # i686 not supported by pypy | |
| # aarch64 only 3.11 and up, also not PGO optimized | |
| - os: windows | |
| target: x86_64 | |
| interpreter: pypy3.11 | |
| - os: windows | |
| target: i686 | |
| python-architecture: x86 | |
| interpreter: 3.10 3.11 3.12 3.13 | |
| exclude: | |
| # See above; disabled for now. | |
| - os: windows | |
| target: aarch64 | |
| runs-on: ${{ (matrix.os == 'linux' && 'ubuntu') || matrix.os }}-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: set up python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| architecture: ${{ matrix.python-architecture || 'x64' }} | |
| - run: pip install -U twine 'ruff==0.5.0' typing_extensions | |
| - name: build wheels | |
| uses: PyO3/maturin-action@v1 | |
| with: | |
| target: ${{ matrix.target }} | |
| manylinux: ${{ matrix.manylinux }} | |
| args: --release --out dist --interpreter ${{ matrix.interpreter || '3.10 3.11 3.12 3.13 pypy3.11' }} | |
| rust-toolchain: stable | |
| docker-options: -e CI | |
| - run: ${{ (matrix.os == 'windows' && 'dir') || 'ls -lh' }} dist/ | |
| - run: twine check --strict dist/* | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: pypi_files_${{ matrix.os }}_${{ matrix.target }}_${{ matrix.interpreter || 'all' }}_${{ matrix.manylinux }} | |
| path: dist | |
| build-pgo: | |
| name: build pgo-optimized on ${{ matrix.os }} / ${{ matrix.interpreter }} | |
| needs: [changes] | |
| if: | | |
| always() && | |
| (startsWith(github.ref, 'refs/tags/') || | |
| contains(github.event.pull_request.labels.*.name, 'Full Build') || | |
| needs.changes.result == 'skipped' || | |
| (github.ref == 'refs/heads/main' && | |
| (needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true'))) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [linux, windows, macos] | |
| interpreter: ["3.10", "3.11", "3.12", "3.13"] | |
| include: | |
| # standard runners with override for macos arm | |
| - os: linux | |
| runs-on: ubuntu-latest | |
| - os: windows | |
| ls: dir | |
| runs-on: windows-latest | |
| - os: macos | |
| runs-on: macos-latest | |
| continue-on-error: false | |
| runs-on: ${{ matrix.runs-on }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: install uv | |
| uses: astral-sh/setup-uv@v6 | |
| with: | |
| python-version: ${{ matrix.interpreter }} | |
| - name: install rust stable | |
| id: rust-toolchain | |
| uses: dtolnay/rust-toolchain@master | |
| with: | |
| components: llvm-tools | |
| toolchain: stable | |
| - name: Build PGO wheel | |
| id: pgo-wheel | |
| uses: ./.github/actions/build-pgo-wheel | |
| with: | |
| interpreter: ${{ matrix.interpreter }} | |
| rust-toolchain: ${{ steps.rust-toolchain.outputs.name }} | |
| - run: ${{ matrix.ls || 'ls -lh' }} dist/ | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: pypi_files_${{ matrix.os }}_${{ matrix.interpreter }} | |
| path: dist | |
| inspect-pypi-assets: | |
| needs: [build, build-sdist, build-pgo] | |
| runs-on: ubuntu-latest | |
| # 只在 build jobs 实际运行时才运行 | |
| if: | | |
| always() && | |
| (needs.build.result == 'success' || | |
| needs.build-sdist.result == 'success' || | |
| needs.build-pgo.result == 'success') | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: get dist artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: pypi_files_* | |
| merge-multiple: true | |
| path: dist | |
| - name: list dist files | |
| run: | | |
| ls -lh dist/ | |
| ls -l dist/ | |
| echo "`ls dist | wc -l` files" | |
| - name: extract and list sdist file | |
| run: | | |
| mkdir sdist-files | |
| tar -xvf dist/*.tar.gz -C sdist-files | |
| tree -a sdist-files | |
| - name: extract and list wheel file | |
| run: | | |
| ls dist/*cp310-manylinux*x86_64.whl | head -n 1 | |
| python -m zipfile --list `ls dist/*cp310-manylinux*x86_64.whl | head -n 1` | |
| test-builds-arch: | |
| name: test build on ${{ matrix.target }}-${{ matrix.distro }} | |
| needs: [build] | |
| runs-on: ubuntu-latest | |
| # 只在 build job 成功后运行 | |
| if: needs.build.result == 'success' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: [aarch64, armv7, s390x, ppc64le] | |
| distro: ["ubuntu22.04"] | |
| include: | |
| - target: aarch64 | |
| distro: alpine_latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: get dist artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: pypi_files_linux_* | |
| merge-multiple: true | |
| path: dist | |
| - uses: uraimo/run-on-arch-action@v3.0.1 | |
| name: install & test | |
| with: | |
| arch: ${{ matrix.target }} | |
| distro: ${{ matrix.distro }} | |
| githubToken: ${{ github.token }} | |
| install: | | |
| set -x | |
| if command -v apt-get &> /dev/null; then | |
| echo "installing python & pip with apt-get..." | |
| apt-get update | |
| apt-get install -y --no-install-recommends python3 python3-pip python3-venv git curl iputils-ping | |
| else | |
| echo "installing python & pip with apk..." | |
| apk update | |
| apk add python3 py3-pip git curl iputils-ping | |
| fi | |
| run: | | |
| set -x | |
| curl -LsSf https://astral.sh/uv/install.sh | sh | |
| source $HOME/.local/bin/env | |
| uv sync --frozen --group testing --no-install-project | |
| uv pip install ping-rs --no-index --no-deps --find-links dist --force-reinstall | |
| uv run --no-sync pytest -n logical | |
| uv run --no-sync python -c 'import ping_rs._ping_rs; print(ping_rs._ping_rs.__version__)' | |
| test-builds-os: | |
| name: test build on ${{ matrix.os }} | |
| needs: [build, build-pgo] | |
| # 只在 build jobs 成功后运行 | |
| if: | | |
| always() && | |
| (needs.build.result == 'success' || needs.build-pgo.result == 'success') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu, macos, windows] | |
| runs-on: ${{ matrix.os }}-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: install uv | |
| uses: astral-sh/setup-uv@v6 | |
| - name: get dist artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: pypi_files_* | |
| merge-multiple: true | |
| path: dist | |
| - run: uv sync --group testing | |
| - run: uv pip install ping-rs --no-index --no-deps --find-links dist --force-reinstall | |
| - run: uv run pytest -n logical | |
| release: | |
| needs: [test-builds-arch, test-builds-os, build-sdist, check] | |
| if: always() && startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: set up python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| - run: pip install -U twine | |
| - name: check package version | |
| run: python .github/check_version.py | |
| - name: get dist artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: pypi_files_* | |
| merge-multiple: true | |
| path: dist | |
| - run: twine check --strict dist/* | |
| - name: Derive version from tag (strip leading 'v') | |
| id: derive_version | |
| run: | | |
| TAG="${GITHUB_REF_NAME}" | |
| VERSION="${TAG#v}" | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| - name: Read Changelog (English) | |
| id: changelog_en | |
| uses: mindsers/changelog-reader-action@v2 | |
| continue-on-error: true | |
| with: | |
| validation_level: none | |
| version: ${{ steps.derive_version.outputs.version }} | |
| path: ./CHANGELOG.md | |
| - name: Read Changelog (Chinese) | |
| id: changelog_zh | |
| uses: mindsers/changelog-reader-action@v2 | |
| continue-on-error: true | |
| with: | |
| validation_level: none | |
| version: ${{ steps.derive_version.outputs.version }} | |
| path: ./CHANGELOG_ZH.md | |
| - name: Create bilingual release notes | |
| run: | | |
| cat << 'EOF' > release_notes.md | |
| ## English | |
| ${{ steps.changelog_en.outputs.changes }} | |
| --- | |
| ## 简体中文 | |
| ${{ steps.changelog_zh.outputs.changes }} | |
| EOF | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| skip-existing: true | |
| - name: upload to github release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| body_path: release_notes.md | |
| files: | | |
| dist/*.whl | |
| dist/*.tar.gz | |
| prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }} |