mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-11-10 21:20:56 +08:00
- Add powerpc64le-unknown-linux-musl target in .cargo/config.toml - Add linux-ppc64le target to core.yml build matrix with mimalloc - Add ppc64le support in Dockerfile and docker.yml multiarch builds - Add binstall overrides for powerpc64le musl and gnu - Add ppc64le platform detection in install.sh
445 lines
15 KiB
YAML
445 lines
15 KiB
YAML
name: EasyTier Core
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
sign_windows:
|
|
description: Submit Windows artifacts for SignPath test signing
|
|
type: boolean
|
|
default: true
|
|
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
|
|
|
|
defaults:
|
|
run:
|
|
# necessary for windows
|
|
shell: bash
|
|
|
|
jobs:
|
|
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/**",
|
|
"pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "easytier/**",
|
|
"easytier-core/**", "easytier-proto/**", "easytier-rpc-build/**",
|
|
"easytier-web/**", "easytier-contrib/easytier-magisk/**",
|
|
".github/workflows/core.yml", ".github/actions/**"]
|
|
FRONTEND_PATHS: >-
|
|
["easytier-web/frontend/**", "easytier-web/frontend-lib/**",
|
|
"easytier-web/config-generator/**", "easytier-proto/proto/**",
|
|
"easytier-core/src/config/**", "easytier-core/src/lib.rs",
|
|
"pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json",
|
|
"Cargo.toml", "Cargo.lock", "rust-toolchain.toml", ".cargo/**",
|
|
"easytier-core/Cargo.toml", "easytier-proto/Cargo.toml",
|
|
".github/workflows/core.yml", ".github/actions/prepare-pnpm/**"]
|
|
outputs:
|
|
full_build: ${{ github.event_name == 'workflow_dispatch' || startsWith(github.ref_name, 'releases/') }}
|
|
frontend_changed: ${{ steps.path_filter.outputs.frontend }}
|
|
# Release builds must run even if they only change release metadata.
|
|
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: 'same_content_newer'
|
|
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 }}
|
|
frontend: ${{ env.FRONTEND_PATHS }}
|
|
|
|
check:
|
|
name: Check (${{ matrix.TARGET }})
|
|
needs: pre_job
|
|
if: needs.pre_job.outputs.should_skip != 'true' && needs.pre_job.outputs.full_build != 'true'
|
|
strategy:
|
|
fail-fast: true
|
|
matrix:
|
|
include:
|
|
- TARGET: x86_64-unknown-linux-musl
|
|
OS: ubuntu-24.04
|
|
FEATURES: jemalloc
|
|
- TARGET: aarch64-apple-darwin
|
|
OS: macos-latest
|
|
FEATURES: jemalloc
|
|
- TARGET: x86_64-pc-windows-msvc
|
|
OS: windows-latest
|
|
FEATURES: mimalloc
|
|
runs-on: ${{ matrix.OS }}
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
|
|
- uses: ./.github/actions/prepare-build
|
|
with:
|
|
target: ${{ matrix.TARGET }}
|
|
gui: false
|
|
pnpm: false
|
|
token: ${{ github.token }}
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
with:
|
|
shared-key: core-check-${{ matrix.TARGET }}
|
|
save-if: ${{ github.event_name != 'pull_request' }}
|
|
|
|
- name: Check Core and Web
|
|
run: cargo check --locked --all-targets --target ${{ matrix.TARGET }} --features ${{ matrix.FEATURES }}
|
|
|
|
build_web:
|
|
runs-on: ubuntu-latest
|
|
needs: pre_job
|
|
if: >-
|
|
needs.pre_job.outputs.should_skip != 'true' &&
|
|
(
|
|
needs.pre_job.outputs.full_build == 'true' ||
|
|
github.event_name != 'pull_request' ||
|
|
needs.pre_job.outputs.frontend_changed == 'true'
|
|
)
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
|
|
- name: Setup Frontend Environment
|
|
uses: ./.github/actions/prepare-pnpm
|
|
with:
|
|
token: ${{ github.token }}
|
|
build-filter: './easytier-web/*'
|
|
|
|
- name: Archive artifact
|
|
if: needs.pre_job.outputs.full_build == 'true'
|
|
uses: actions/upload-artifact@v5
|
|
with:
|
|
name: easytier-web-dashboard
|
|
path: |
|
|
easytier-web/frontend/dist/*
|
|
build:
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- TARGET: x86_64-unknown-linux-musl
|
|
OS: ubuntu-24.04
|
|
ARTIFACT_NAME: linux-x86_64
|
|
- TARGET: aarch64-unknown-linux-musl
|
|
OS: ubuntu-24.04-arm
|
|
ARTIFACT_NAME: linux-aarch64
|
|
|
|
- TARGET: riscv64gc-unknown-linux-musl
|
|
OS: ubuntu-24.04
|
|
ARTIFACT_NAME: linux-riscv64
|
|
- TARGET: loongarch64-unknown-linux-musl
|
|
OS: ubuntu-24.04
|
|
ARTIFACT_NAME: linux-loongarch64
|
|
- TARGET: powerpc64le-unknown-linux-musl
|
|
OS: ubuntu-24.04
|
|
ARTIFACT_NAME: linux-ppc64le
|
|
|
|
- TARGET: armv7-unknown-linux-musleabihf # raspberry pi 2-3-4, not tested
|
|
OS: ubuntu-24.04
|
|
ARTIFACT_NAME: linux-armv7hf
|
|
- TARGET: armv7-unknown-linux-musleabi # raspberry pi 2-3-4, not tested
|
|
OS: ubuntu-24.04
|
|
ARTIFACT_NAME: linux-armv7
|
|
- TARGET: arm-unknown-linux-musleabihf # raspberry pi 0-1, not tested
|
|
OS: ubuntu-24.04
|
|
ARTIFACT_NAME: linux-armhf
|
|
- TARGET: arm-unknown-linux-musleabi # raspberry pi 0-1, not tested
|
|
OS: ubuntu-24.04
|
|
ARTIFACT_NAME: linux-arm
|
|
|
|
- TARGET: mips-unknown-linux-musl
|
|
OS: ubuntu-24.04
|
|
ARTIFACT_NAME: linux-mips
|
|
- TARGET: mipsel-unknown-linux-musl
|
|
OS: ubuntu-24.04
|
|
ARTIFACT_NAME: linux-mipsel
|
|
|
|
- TARGET: x86_64-unknown-freebsd
|
|
OS: ubuntu-24.04
|
|
ARTIFACT_NAME: freebsd-13.2-x86_64
|
|
BSD_VERSION: 13.2
|
|
|
|
- TARGET: x86_64-apple-darwin
|
|
OS: macos-latest
|
|
ARTIFACT_NAME: macos-x86_64
|
|
- TARGET: aarch64-apple-darwin
|
|
OS: macos-latest
|
|
ARTIFACT_NAME: macos-aarch64
|
|
|
|
- TARGET: x86_64-pc-windows-msvc
|
|
OS: windows-latest
|
|
ARTIFACT_NAME: windows-x86_64
|
|
- TARGET: i686-pc-windows-msvc
|
|
OS: windows-latest
|
|
ARTIFACT_NAME: windows-i686
|
|
- TARGET: aarch64-pc-windows-msvc
|
|
OS: windows-11-arm
|
|
ARTIFACT_NAME: windows-arm64
|
|
|
|
runs-on: ${{ matrix.OS }}
|
|
env:
|
|
NAME: easytier
|
|
TARGET: ${{ matrix.TARGET }}
|
|
OS: ${{ matrix.OS }}
|
|
OSS_BUCKET: ${{ secrets.ALIYUN_OSS_BUCKET }}
|
|
needs:
|
|
- pre_job
|
|
- build_web
|
|
if: needs.pre_job.outputs.should_skip != 'true' && needs.pre_job.outputs.full_build == 'true'
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
|
|
- name: Set current ref as env variable
|
|
run: |
|
|
echo "GIT_DESC=$(git log -1 --format=%cd.%h --date=format:%Y-%m-%d_%H:%M:%S)" >> $GITHUB_ENV
|
|
|
|
- name: Download web artifact
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: easytier-web-dashboard
|
|
path: easytier-web/frontend/dist/
|
|
|
|
- name: Prepare build environment
|
|
uses: ./.github/actions/prepare-build
|
|
with:
|
|
target: ${{ matrix.TARGET }}
|
|
gui: false
|
|
pnpm: false
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
with:
|
|
# The prefix cache key, this can be changed to start a new cache manually.
|
|
# default: "v0-rust"
|
|
prefix-key: ""
|
|
shared-key: core-release-${{ matrix.TARGET }}
|
|
cache-targets: "true"
|
|
|
|
- uses: mlugg/setup-zig@v2
|
|
if: ${{ contains(matrix.OS, 'ubuntu') }}
|
|
with:
|
|
version: 0.16.0
|
|
use-cache: true
|
|
|
|
- uses: taiki-e/install-action@v2
|
|
if: ${{ contains(matrix.OS, 'ubuntu') }}
|
|
with:
|
|
# v0.23.3 emits -mcpu=generic+v6+strict_align for
|
|
# arm-unknown-linux-musleabi, which zig 0.16.0 rejects;
|
|
# unpin only together with a zig bump.
|
|
tool: cargo-zigbuild@0.23.2
|
|
|
|
- name: Build
|
|
if: ${{ !contains(matrix.TARGET, 'mips') }}
|
|
run: |
|
|
if [[ "$TARGET" == *windows* ]]; then
|
|
SUFFIX=.exe
|
|
else
|
|
SUFFIX=""
|
|
fi
|
|
|
|
if [[ "$TARGET" =~ (x86_64-unknown-linux-musl|aarch64-unknown-linux-musl|windows|darwin) ]]; then
|
|
BUILD=build
|
|
else
|
|
BUILD=zigbuild
|
|
fi
|
|
|
|
if [[ "$TARGET" =~ ^(riscv64|loongarch64|aarch64|powerpc64le).*$ || "$TARGET" =~ (freebsd|windows) ]]; then
|
|
FEATURES="mimalloc"
|
|
else
|
|
FEATURES="jemalloc"
|
|
fi
|
|
|
|
cargo $BUILD --release --target $TARGET --package=easytier-web --features=embed
|
|
mv ./target/$TARGET/release/easytier-web"$SUFFIX" ./target/$TARGET/release/easytier-web-embed"$SUFFIX"
|
|
|
|
cargo $BUILD --release --target $TARGET --features=$FEATURES
|
|
|
|
- name: Build (MIPS)
|
|
if: ${{ contains(matrix.TARGET, 'mips') }}
|
|
env:
|
|
RUSTC_BOOTSTRAP: 1
|
|
run: |
|
|
cargo build -r --target $TARGET -Z build-std=std,panic_abort --package=easytier --features=jemalloc
|
|
|
|
- name: Compress
|
|
run: |
|
|
mkdir -p ./artifacts/objects/
|
|
|
|
# windows is the only OS using a different convention for executable file name
|
|
if [[ $OS =~ ^windows.*$ ]]; then
|
|
SUFFIX=.exe
|
|
case $TARGET in
|
|
x86_64*) ARCH_DIR=x86_64 ;;
|
|
i686*) ARCH_DIR=i686 ;;
|
|
aarch64*) ARCH_DIR=arm64 ;;
|
|
esac
|
|
if [[ -n "$ARCH_DIR" ]]; then
|
|
find "easytier/third_party/${ARCH_DIR}" -maxdepth 1 -type f \( -name "*.dll" -o -name "*.sys" \) -exec cp {} ./artifacts/objects/ \;
|
|
fi
|
|
fi
|
|
|
|
if [[ $GITHUB_REF_TYPE =~ ^tag$ ]]; then
|
|
TAG=$GITHUB_REF_NAME
|
|
else
|
|
TAG=$GITHUB_SHA
|
|
fi
|
|
|
|
if [[ $OS =~ ^ubuntu.*$ && ! $TARGET =~ (loongarch|freebsd) ]]; then
|
|
HOST_ARCH=$(uname -m)
|
|
case $HOST_ARCH in
|
|
x86_64) UPX_ARCH="amd64" ;;
|
|
aarch64) UPX_ARCH="arm64" ;;
|
|
*) UPX_ARCH="amd64" ;;
|
|
esac
|
|
|
|
UPX_VERSION=4.2.4
|
|
UPX_PKG="upx-${UPX_VERSION}-${UPX_ARCH}_linux"
|
|
curl -L "https://github.com/upx/upx/releases/download/v${UPX_VERSION}/${UPX_PKG}.tar.xz" -s | tar xJvf -
|
|
cp "${UPX_PKG}/upx" .
|
|
UPX_BIN=./upx
|
|
fi
|
|
|
|
for BIN in ./target/$TARGET/release/easytier-{core,cli,web,web-embed}"$SUFFIX"; do
|
|
if [[ -f "$BIN" ]]; then
|
|
if [[ -n "$UPX_BIN" ]]; then
|
|
$UPX_BIN --lzma --best "$BIN" || true
|
|
fi
|
|
|
|
mv "$BIN" ./artifacts/objects/
|
|
fi
|
|
done
|
|
|
|
mv ./artifacts/objects/* ./artifacts/
|
|
rm -rf ./artifacts/objects/
|
|
|
|
- name: Archive artifact
|
|
uses: actions/upload-artifact@v5
|
|
with:
|
|
name: easytier-${{ matrix.ARTIFACT_NAME }}
|
|
path: |
|
|
./artifacts/*
|
|
|
|
- name: Prepare SignPath test artifact
|
|
if: ${{ github.event_name == 'workflow_dispatch' && inputs.sign_windows && contains(matrix.TARGET, 'windows') }}
|
|
run: |
|
|
mkdir -p ./signpath-artifacts
|
|
cp \
|
|
./artifacts/easytier-core.exe \
|
|
./artifacts/easytier-cli.exe \
|
|
./artifacts/easytier-web.exe \
|
|
./artifacts/easytier-web-embed.exe \
|
|
./signpath-artifacts/
|
|
|
|
- name: Upload unsigned SignPath test artifact
|
|
if: ${{ github.event_name == 'workflow_dispatch' && inputs.sign_windows && contains(matrix.TARGET, 'windows') }}
|
|
id: signpath-upload
|
|
uses: actions/upload-artifact@v5
|
|
with:
|
|
name: signpath-unsigned-${{ matrix.ARTIFACT_NAME }}
|
|
path: ./signpath-artifacts/*
|
|
if-no-files-found: error
|
|
|
|
- name: Submit SignPath test-signing request
|
|
if: ${{ github.event_name == 'workflow_dispatch' && inputs.sign_windows && contains(matrix.TARGET, 'windows') }}
|
|
uses: signpath/github-action-submit-signing-request@v2
|
|
with:
|
|
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
|
|
organization-id: 368cf38d-86d5-4bfe-a1fa-82a50dce7e9f
|
|
project-slug: EasyTier
|
|
signing-policy-slug: test-signing
|
|
artifact-configuration-slug: initial
|
|
github-artifact-id: ${{ steps.signpath-upload.outputs.artifact-id }}
|
|
wait-for-completion: true
|
|
output-artifact-directory: ./signpath-signed-artifacts
|
|
|
|
- name: Upload signed SignPath test artifact
|
|
if: ${{ github.event_name == 'workflow_dispatch' && inputs.sign_windows && contains(matrix.TARGET, 'windows') }}
|
|
uses: actions/upload-artifact@v5
|
|
with:
|
|
name: signpath-signed-${{ matrix.ARTIFACT_NAME }}
|
|
path: ./signpath-signed-artifacts/*
|
|
if-no-files-found: error
|
|
|
|
build_magisk:
|
|
runs-on: ubuntu-latest
|
|
needs: [ pre_job, build_web, build ]
|
|
if: needs.pre_job.result == 'success' && needs.pre_job.outputs.should_skip != 'true' && needs.pre_job.outputs.full_build == 'true' && !cancelled()
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@v5 # 必须先检出代码才能获取模块配置
|
|
|
|
# 下载二进制文件到独立目录
|
|
- name: Download Linux aarch64 binaries
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: easytier-linux-aarch64
|
|
path: ./downloaded-binaries/ # 独立目录避免冲突
|
|
|
|
- name: Download Magisk WebUI
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: easytier-web-dashboard
|
|
path: ./downloaded-webui/
|
|
|
|
# 将二进制文件和 WebUI 复制到 Magisk 模块目录
|
|
- name: Prepare Magisk module
|
|
run: |
|
|
module_dir=./easytier-contrib/easytier-magisk
|
|
mkdir -p "$module_dir/webroot"
|
|
cp ./downloaded-binaries/easytier-core "$module_dir/"
|
|
cp ./downloaded-binaries/easytier-cli "$module_dir/"
|
|
cp ./downloaded-binaries/easytier-web "$module_dir/"
|
|
cp -R ./downloaded-webui/config-generator/. "$module_dir/webroot/"
|
|
test -f "$module_dir/webroot/index.html"
|
|
|
|
# 上传生成的模块
|
|
- name: Upload Magisk Module
|
|
uses: actions/upload-artifact@v5
|
|
with:
|
|
name: Easytier-Magisk
|
|
path: |
|
|
./easytier-contrib/easytier-magisk
|
|
!./easytier-contrib/easytier-magisk/build.sh
|
|
!./easytier-contrib/easytier-magisk/magisk_update.json
|
|
if-no-files-found: error
|
|
|
|
core-result:
|
|
runs-on: ubuntu-latest
|
|
needs: [ pre_job, check, build_web, build, build_magisk ]
|
|
if: ${{ always() }}
|
|
steps:
|
|
- name: Mark result as failed
|
|
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
|
|
run: exit 1
|