Files
EasyTier/.github/workflows/test.yml
T

219 lines
6.8 KiB
YAML

name: EasyTier Test
on:
workflow_dispatch:
push:
branches: [ "develop", "main", "releases/**" ]
pull_request:
branches: [ "develop", "main" ]
types: [ opened, synchronize, reopened, ready_for_review ]
concurrency:
# A new PR or branch push must not cancel a full build.
group: ${{ github.workflow }}-${{ (github.event_name == 'workflow_dispatch' || startsWith(github.ref_name, 'releases/')) && 'full' || 'check' }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
# RUSTC_WRAPPER: "sccache"
# SCCACHE_GHA_ENABLED: "true"
defaults:
run:
# necessary for windows
shell: bash
jobs:
ci-scripts:
name: Test CI scripts
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 22
- run: node --test .github/scripts/*.test.js
pre_job:
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
env:
RELEVANT_PATHS: >-
["Cargo.toml", "Cargo.lock", "rust-toolchain.toml", ".cargo/**",
".config/nextest.toml",
"pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "easytier/**",
"easytier-core/**", "easytier-proto/**", "easytier-rpc-build/**",
"easytier-web/**", "easytier-gui/src-tauri/**",
"tauri-plugin-vpnservice/**", "easytier-contrib/**",
".github/workflows/test.yml", ".github/actions/**"]
outputs:
full_build: ${{ github.event_name == 'workflow_dispatch' || startsWith(github.ref_name, 'releases/') }}
should_skip: >-
${{
(
steps.skip_check.outputs.should_skip == 'true' ||
(
github.event_name == 'pull_request' &&
steps.path_filter.outputs.relevant != 'true'
)
) &&
github.event_name != 'workflow_dispatch' &&
!startsWith(github.ref_name, 'releases/')
}}
steps:
- id: skip_check
if: github.event_name != 'workflow_dispatch' && !startsWith(github.ref_name, 'releases/')
uses: fkirc/skip-duplicate-actions@v5
with:
concurrent_skipping: 'never'
skip_after_successful_duplicate: 'true'
paths: ${{ env.RELEVANT_PATHS }}
- id: path_filter
if: >-
github.event_name == 'pull_request' &&
steps.skip_check.outputs.should_skip != 'true'
uses: dorny/paths-filter@v4
with:
filters: |
relevant: ${{ env.RELEVANT_PATHS }}
check:
name: Run linters & check
runs-on: ubuntu-latest
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
steps:
- uses: actions/checkout@v5
- name: Prepare build environment
uses: ./.github/actions/prepare-build
with:
gui: true
pnpm: ${{ needs.pre_job.outputs.full_build == 'true' }}
token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: rustfmt,clippy
target: wasm32-wasip1
cache: false
rustflags: ''
- uses: Swatinem/rust-cache@v2
with:
shared-key: test-check
save-if: ${{ github.event_name != 'pull_request' }}
- uses: taiki-e/install-action@cargo-hack
if: needs.pre_job.outputs.full_build == 'true'
- name: Check formatting
if: ${{ !cancelled() }}
run: cargo fmt --all -- --check
- name: Check Clippy
if: ${{ !cancelled() }}
run: cargo clippy --all-targets --features full --all -- -D warnings
- name: Check features
if: ${{ !cancelled() && needs.pre_job.outputs.full_build == 'true' }}
run: cargo hack check --package easytier --each-feature --exclude-features macos-ne --verbose
- name: Check WASI
if: ${{ !cancelled() }}
run: >-
cargo check --package easytier-core --lib --target wasm32-wasip1
--features management-rpc,proxy-smoltcp-stack,ring-crypto,wasi-crypto-offload
- name: Check Cargo.lock is up to date
if: ${{ !cancelled() }}
run: |
if ! cargo metadata --format-version 1 --locked > /dev/null; then
echo "::error::Cargo.lock is out of date. Run cargo generate-lockfile or cargo build locally, then commit Cargo.lock."
exit 1
fi
pre-test:
name: Build test
runs-on: ubuntu-latest
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
steps:
- uses: actions/checkout@v5
- name: Prepare build environment
uses: ./.github/actions/prepare-build
with:
gui: false
pnpm: false
token: ${{ secrets.GITHUB_TOKEN }}
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@nextest
- name: Archive test
run: >-
cargo nextest archive --archive-file tests.tar.zst
--package easytier --package easytier-core --features full
- uses: actions/upload-artifact@v5
with:
name: tests
path: tests.tar.zst
retention-days: 1
run-tests:
name: Run tests
runs-on: ubuntu-latest
needs: [ pre_job, pre-test ]
if: needs.pre_job.outputs.should_skip != 'true'
steps:
- uses: actions/checkout@v5
- name: Setup tools for test
run: sudo apt install bridge-utils
- name: Setup upnpd for test
run: |
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y miniupnpd miniupnpd-iptables iptables
- name: Setup system for test
run: |
sudo modprobe br_netfilter
sudo modprobe tun
if [ ! -e /dev/net/tun ]; then
sudo mkdir -p /dev/net
sudo mknod /dev/net/tun c 10 200
fi
sudo sysctl net.bridge.bridge-nf-call-iptables=0
sudo sysctl net.bridge.bridge-nf-call-ip6tables=0
sudo sysctl net.ipv6.conf.lo.disable_ipv6=0
sudo ip addr add 2001:db8::2/64 dev lo
- uses: taiki-e/install-action@nextest
- name: Download tests
uses: actions/download-artifact@v4
with:
name: tests
- name: Run tests
run: |
sudo prlimit --pid $$ --nofile=1048576:1048576
sudo -E env "PATH=$PATH" EASYTIER_LINUX_BPF_INTEGRATION=required \
cargo nextest run --archive-file tests.tar.zst --profile ci --no-fail-fast
test:
runs-on: ubuntu-latest
needs: [ pre_job, ci-scripts, check, pre-test, run-tests ]
if: ${{ always() }}
steps:
- name: Mark result as failed
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1