Files
shadowsocks-libev/.github/workflows/portability.yml
Max Lv bdc77408cb Rename to shadowsocks-c with libuv, async DNS and CI lint (#3051)
Rename the project to shadowsocks-c while retaining ss-* commands, the embedding ABI, and legacy library/package lookup compatibility.

Replace libev with bundled libuv for IOCP/kqueue event backends, expand asynchronous runtime DNS coverage, and add actionlint/Ruff with strict clang-tidy failure handling. Validate native platforms, static builds, packaging, interoperability, sanitizers, and canonical/legacy consumers.

All 22 hosted checks pass at reviewed head a8493250eb.
2026-09-11 14:18:37 +08:00

217 lines
9.3 KiB
YAML

name: portability
on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:
jobs:
bundled:
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, ubuntu-24.04-arm, macos-latest]
minimal: ['OFF', 'ON']
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- name: Build without installed third-party development packages
run: |
cmake -S . -B build -DSS_MINIMAL=${{ matrix.minimal }}
cmake --build build --parallel 4
ctest --test-dir build -L 'unit|vendor' --output-on-failure --no-tests=error
- name: Real TCP and UDP relay
run: python3 tests/interop.py --self --bin build/bin
- name: Asynchronous hostname ACL bypass
run: python3 tests/async_dns_interop.py --bin build/bin
- name: SIP003 transport and child cleanup
if: matrix.minimal == 'OFF'
run: python3 tests/interop.py --self --bin build/bin --plugin tests/sip003_fixture.py
- name: Relocated installation and public API consumers
run: |
cmake --install build --prefix "$PWD/install"
mv install relocated
cmake -S tests/consumer -B consumer -DCMAKE_PREFIX_PATH="$PWD/relocated"
cmake --build consumer
./consumer/consumer_static
./consumer/consumer_shared
cmake -S tests/consumer -B consumer-legacy -DSS_PACKAGE_NAME=shadowsocks-libev -DCMAKE_PREFIX_PATH="$PWD/relocated"
cmake --build consumer-legacy
./consumer-legacy/consumer_static
./consumer-legacy/consumer_shared
windows:
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v6
- uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
update: true
install: >-
mingw-w64-ucrt-x86_64-gcc
mingw-w64-ucrt-x86_64-cmake
mingw-w64-ucrt-x86_64-ninja
mingw-w64-ucrt-x86_64-python
- name: Build and run native Windows binaries
run: |
cmake -S . -B build -G Ninja
cmake --build build --parallel 4
ctest --test-dir build -L 'unit|vendor' --output-on-failure --no-tests=error
objdump -p build/bin/ss-server.exe | sed -n '/DLL Name/p'
python tests/interop.py --self --bin build/bin --isolate-windows-runtime
python tests/async_dns_interop.py --bin build/bin --isolate-windows-runtime
- name: Installed consumers
run: |
cmake --install build --prefix "$PWD/install"
cmake -S tests/consumer -B consumer -G Ninja -DCMAKE_PREFIX_PATH="$PWD/install"
cmake --build consumer
cmake -S tests/consumer -B consumer-legacy -G Ninja -DSS_PACKAGE_NAME=shadowsocks-libev -DCMAKE_PREFIX_PATH="$PWD/install"
cmake --build consumer-legacy
- name: Run installed consumers without toolchain DLLs
shell: pwsh
run: |
$env:PATH = "$env:GITHUB_WORKSPACE\install\bin;$env:SystemRoot\System32;$env:SystemRoot"
& ./consumer/consumer_static.exe
if ($LASTEXITCODE -ne 0) { throw "Static consumer failed: $LASTEXITCODE" }
& ./consumer/consumer_shared.exe
if ($LASTEXITCODE -ne 0) { throw "Shared consumer failed: $LASTEXITCODE" }
& ./consumer-legacy/consumer_static.exe
if ($LASTEXITCODE -ne 0) { throw "Legacy static consumer failed: $LASTEXITCODE" }
& ./consumer-legacy/consumer_shared.exe
if ($LASTEXITCODE -ne 0) { throw "Legacy shared consumer failed: $LASTEXITCODE" }
static-macos:
runs-on: macos-latest
env:
CC: clang
steps:
- uses: actions/checkout@v6
- name: Build Clang static-only installation
run: |
cmake -S . -B build-static -DCMAKE_C_COMPILER=clang -DSS_DEPENDENCY_MODE=bundled -DWITH_STATIC=ON -DSS_BUILD_STATIC_LIBRARY=ON -DSS_BUILD_SHARED_LIBRARY=OFF
cmake --build build-static --parallel 4
ctest --test-dir build-static -L 'unit|vendor' --output-on-failure --no-tests=error
cmake --install build-static --prefix "$PWD/install-static"
mv install-static relocated-static
cmake -S tests/consumer -B consumer-static -DCMAKE_C_COMPILER=clang -DCMAKE_PREFIX_PATH="$PWD/relocated-static"
cmake --build consumer-static
test ! -e consumer-static/consumer_shared
./consumer-static/consumer_static
- name: Reject third-party dynamic libraries
run: python3 tests/check_static_runtime.py relocated-static/bin/ss-* consumer-static/consumer_static
- name: Exercise installed static programs
run: |
python3 tests/interop.py --self --bin relocated-static/bin
python3 tests/async_dns_interop.py --bin relocated-static/bin
python3 tests/interop.py --self --bin relocated-static/bin --plugin tests/sip003_fixture.py
- uses: actions/upload-artifact@v4
with:
name: static-macos-${{ runner.arch }}
path: relocated-static/
if-no-files-found: error
static-windows:
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v6
- uses: msys2/setup-msys2@v2
with:
msystem: CLANG64
update: true
install: >-
mingw-w64-clang-x86_64-clang
mingw-w64-clang-x86_64-llvm
mingw-w64-clang-x86_64-cmake
mingw-w64-clang-x86_64-ninja
mingw-w64-clang-x86_64-python
- name: Build Clang static-only installation
run: |
cmake -S . -B build-static -G Ninja -DCMAKE_C_COMPILER=clang -DSS_DEPENDENCY_MODE=bundled -DWITH_STATIC=ON -DSS_BUILD_STATIC_LIBRARY=ON -DSS_BUILD_SHARED_LIBRARY=OFF
cmake --build build-static --parallel 4
ctest --test-dir build-static -L 'unit|vendor' --output-on-failure --no-tests=error
cmake --install build-static --prefix "$PWD/install-static"
mv install-static relocated-static
cmake -S tests/consumer -B consumer-static -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_PREFIX_PATH="$PWD/relocated-static"
cmake --build consumer-static
test ! -e consumer-static/consumer_shared.exe
- name: Reject third-party DLL imports, including delay imports
run: python tests/check_static_runtime.py relocated-static/bin/ss-*.exe consumer-static/consumer_static.exe
- name: Exercise installed programs without toolchain DLLs
run: |
python tests/interop.py --self --bin relocated-static/bin --isolate-windows-runtime
python tests/async_dns_interop.py --bin relocated-static/bin --isolate-windows-runtime
- name: Run static consumer with only Windows system directories on PATH
shell: pwsh
run: |
$env:PATH = "$env:SystemRoot\System32;$env:SystemRoot"
& ./consumer-static/consumer_static.exe
if ($LASTEXITCODE -ne 0) { throw "Static consumer failed: $LASTEXITCODE" }
- uses: actions/upload-artifact@v4
with:
name: static-windows-${{ runner.arch }}
path: relocated-static/
if-no-files-found: error
static-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Build and test fully static Clang/musl executables
run: docker build -f docker/static/Dockerfile --target artifacts --output type=local,dest=static-linux .
- uses: actions/upload-artifact@v4
with:
name: static-linux-${{ runner.arch }}
path: static-linux/
if-no-files-found: error
freebsd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: vmactions/freebsd-vm@v1
with:
release: '14.3'
usesh: true
prepare: pkg install -y cmake ninja python3
run: |
cmake -S . -B build -G Ninja
cmake --build build --parallel 4
ctest --test-dir build -L 'unit|vendor' --output-on-failure --no-tests=error
python3 tests/interop.py --self --bin build/bin
python3 tests/async_dns_interop.py --bin build/bin
cmake --install build --prefix "$PWD/install"
cmake -S tests/consumer -B consumer -G Ninja -DCMAKE_PREFIX_PATH="$PWD/install"
cmake --build consumer
./consumer/consumer_static
./consumer/consumer_shared
offline-musl:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Source archive
run: python3 scripts/source_archive.py release/shadowsocks-c.tar.gz
- name: Prepare compiler image
run: |
printf 'FROM alpine:3.24\nRUN apk add --no-cache build-base cmake python3 linux-headers\n' > /tmp/ss-toolchain.Dockerfile
docker build -t ss-toolchain -f /tmp/ss-toolchain.Dockerfile /tmp
- name: Build release archive with network disabled
run: |
docker run --rm --network none -v "$PWD/release:/release:ro" ss-toolchain sh -ec '
mkdir /src
tar xzf /release/shadowsocks-c.tar.gz -C /src --strip-components=1
cmake -S /src -B /build -DCMAKE_DISABLE_FIND_PACKAGE_Python3=TRUE
cmake --build /build --parallel 4
ctest --test-dir /build -L "unit|vendor" --output-on-failure --no-tests=error
python3 /src/tests/interop.py --self --bin /build/bin
'