217 lines
9.5 KiB
YAML
217 lines
9.5 KiB
YAML
# O.M.V. 帝江号 — CircleCI pipeline
|
|
#
|
|
# Transcribed from the original .gitlab-ci.yml. The GitLab job did everything in a
|
|
# single stage; here it is split into a fast, dependency-light gate (`verify-core`,
|
|
# the with_purego / CGO-disabled build that needs no Android NDK) and the heavy
|
|
# `build-android` job (gomobile AAR + Gradle APK). The gate must go green before the
|
|
# expensive Android job starts, so broken patches fail in ~1 minute instead of ~20.
|
|
#
|
|
# Orbs do the undifferentiated heavy lifting:
|
|
# * circleci/android — machine executor with a preinstalled JDK 17 + Android SDK.
|
|
# * circleci/go — pinned Go toolchain install.
|
|
# Caching (Go modules/build cache, Gradle) and artifact upload use the native
|
|
# CircleCI primitives so the keys can be derived from the *generated* works/core/go.sum.
|
|
|
|
version: 2.1
|
|
|
|
orbs:
|
|
android: circleci/android@2.5.0
|
|
go: circleci/go@1.11.0
|
|
|
|
parameters:
|
|
go-version:
|
|
type: string
|
|
default: "1.26.2"
|
|
# We now base directly on upstream SagerNet/sing-box (works/config), whose
|
|
# .gitmodules points clients/android at SagerNet's own app. The O.M.V. Android
|
|
# build must instead use *our* fork (branch dev, `other` flavour, our keystore) —
|
|
# that submodule override was the whole reason omv-dijiang used to build on a
|
|
# private sing-box mirror. So we re-point it in CI, right after pulling upstream.
|
|
android-client-url:
|
|
type: string
|
|
default: "https://git.sfclub.cc/icybear/sing-box-for-android.git"
|
|
android-client-branch:
|
|
type: string
|
|
default: "dev"
|
|
|
|
commands:
|
|
# bin/update clones the latest `testing` sing-box (see works/config) and bin/apply-ci
|
|
# materialises works/core = upstream + works/patch/*. Shared by both jobs.
|
|
sync-upstream:
|
|
description: Fetch latest testing sing-box and apply the O.M.V. patches
|
|
steps:
|
|
- run:
|
|
name: bin/update + bin/apply-ci
|
|
command: |
|
|
git config --global user.name "${GIT_AUTHOR_NAME:-omv-ci}"
|
|
git config --global user.email "${GIT_AUTHOR_EMAIL:-omv-ci@local}"
|
|
bin/update
|
|
bin/apply-ci
|
|
|
|
restore-go-cache:
|
|
description: Restore the Go module + build cache keyed on the generated go.sum
|
|
steps:
|
|
- restore_cache:
|
|
keys:
|
|
- omv-go-v1-{{ arch }}-{{ checksum "works/core/go.sum" }}
|
|
- omv-go-v1-{{ arch }}-
|
|
|
|
jobs:
|
|
# ---------------------------------------------------------------------------
|
|
# Fast gate: prove works/core compiles without CGO/NDK (with_purego).
|
|
# This is the build the machine can actually run; the Android AAR needs an NDK.
|
|
# ---------------------------------------------------------------------------
|
|
verify-core:
|
|
docker:
|
|
- image: golang:<< pipeline.parameters.go-version >>-bookworm
|
|
resource_class: large
|
|
working_directory: ~/project
|
|
environment:
|
|
CGO_ENABLED: "0"
|
|
GOFLAGS: "-mod=mod"
|
|
GOMODCACHE: /go/pkg/mod
|
|
GOCACHE: /root/.cache/go-build
|
|
# OTHERS build tags minus with_naive_outbound (needs cgo), plus with_purego.
|
|
BUILD_TAGS: "with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,with_cloudflared,with_usbip,badlinkname,tfogo_checklinkname0,with_purego"
|
|
steps:
|
|
- checkout
|
|
- run:
|
|
name: Install system dependencies
|
|
command: |
|
|
apt-get update
|
|
apt-get install -y --no-install-recommends git rsync patch unzip curl ca-certificates
|
|
- sync-upstream
|
|
- restore-go-cache
|
|
- run:
|
|
name: Build core + libbox (with_purego, no NDK)
|
|
working_directory: ~/project/works/core
|
|
command: |
|
|
go mod tidy
|
|
version="$(git describe --tags --always)-${CIRCLE_SHA1:0:8}"
|
|
echo "building $version"
|
|
# -checklinkname=0 authorises upstream's //go:linkname pulls (LDFLAGS file).
|
|
go build -v -tags "$BUILD_TAGS" \
|
|
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=$version' -checklinkname=0" \
|
|
-o /tmp/sing-box ./cmd/sing-box
|
|
# The AAR wraps experimental/libbox; compile it too so the mobile-facing
|
|
# code is covered even though we don't cross-compile with gomobile here.
|
|
go build -v -tags "$BUILD_TAGS" ./experimental/libbox
|
|
- run:
|
|
name: Validate O.M.V. sample configs
|
|
command: |
|
|
for c in minecraft/server minecraft/client obfhttp/server obfhttp/client; do
|
|
echo "check config/$c/config.json"
|
|
/tmp/sing-box check -c "config/$c/config.json"
|
|
done
|
|
- save_cache:
|
|
key: omv-go-v1-{{ arch }}-{{ checksum "works/core/go.sum" }}
|
|
paths:
|
|
- /go/pkg/mod
|
|
- /root/.cache/go-build
|
|
- store_artifacts:
|
|
path: /tmp/sing-box
|
|
destination: sing-box-linux-amd64
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Full Android build: gomobile AAR (CGO + NDK) then Gradle assembleOtherRelease.
|
|
# Mirrors the original GitLab job.
|
|
# ---------------------------------------------------------------------------
|
|
build-android:
|
|
executor:
|
|
name: android/android-machine
|
|
resource-class: large
|
|
# `android:default` is CircleCI's rolling Linux+Android machine image (JDK 17,
|
|
# Android SDK preinstalled). Pin to a dated tag (e.g. 2024.11.1) for reproducibility.
|
|
tag: default
|
|
environment:
|
|
ANDROID_NDK_VERSION: r28
|
|
GOFLAGS: "-mod=mod"
|
|
GOMODCACHE: /home/circleci/go/pkg/mod
|
|
GOCACHE: /home/circleci/.cache/go-build
|
|
# Placeholder debug-keystore password carried over from the GitLab CI. For real
|
|
# releases DO NOT commit this — set LOCAL_PROPERTIES in a CircleCI context or
|
|
# project environment variable (base64 of KEYSTORE_PASS/ALIAS_NAME/ALIAS_PASS).
|
|
LOCAL_PROPERTIES: "S0VZU1RPUkVfUEFTUz0xMTQ1MTQKQUxJQVNfTkFNRT1hbGlhcwpBTElBU19QQVNTPTExNDUxNAo="
|
|
steps:
|
|
- checkout
|
|
- go/install:
|
|
version: << pipeline.parameters.go-version >>
|
|
- run:
|
|
name: Install extra system dependencies
|
|
command: sudo apt-get update && sudo apt-get install -y --no-install-recommends rsync patch unzip
|
|
- run:
|
|
name: Provision Android SDK + NDK
|
|
command: bash ./setup-ndk.sh
|
|
- sync-upstream
|
|
- run:
|
|
name: Re-point clients/android at our fork, then init it
|
|
working_directory: ~/project/works/core
|
|
command: |
|
|
# Upstream's gitlink pins a SagerNet android commit our fork doesn't have,
|
|
# so swap the URL, pin the branch, and use --remote to check out our fork's
|
|
# branch tip instead of the (unreachable) pinned SHA.
|
|
git submodule set-url clients/android "<< pipeline.parameters.android-client-url >>"
|
|
git config -f .gitmodules submodule.clients/android.branch "<< pipeline.parameters.android-client-branch >>"
|
|
git submodule sync clients/android
|
|
git submodule update --init --remote --recursive clients/android
|
|
echo "clients/android now:" && git -C clients/android remote get-url origin && git -C clients/android log --oneline -1
|
|
- restore-go-cache
|
|
- restore_cache:
|
|
keys:
|
|
- omv-gradle-v1-{{ checksum "works/core/clients/android/gradle/libs.versions.toml" }}
|
|
- omv-gradle-v1-
|
|
- run:
|
|
name: Build libbox AAR (gomobile)
|
|
working_directory: ~/project/works/core
|
|
command: |
|
|
export ANDROID_HOME="$CIRCLE_WORKING_DIRECTORY/Android/Sdk"
|
|
export ANDROID_SDK_ROOT="$ANDROID_HOME"
|
|
version="$(git describe --tags --always)-${CIRCLE_SHA1:0:8}"
|
|
echo "building version $version"
|
|
make lib_install
|
|
export PATH="$PATH:$(go env GOPATH)/bin"
|
|
go mod tidy
|
|
make lib_android
|
|
- run:
|
|
name: Assemble APK (assembleOtherRelease)
|
|
working_directory: ~/project/works/core
|
|
command: |
|
|
export ANDROID_HOME="$CIRCLE_WORKING_DIRECTORY/Android/Sdk"
|
|
# clients/android is already checked out at our fork's branch tip (see the
|
|
# "Re-point clients/android" step, which uses `submodule update --remote`).
|
|
go run -v ./cmd/internal/update_android_version --ci --nightly
|
|
mkdir -p clients/android/app/libs
|
|
cp ./*.aar clients/android/app/libs
|
|
cd clients/android
|
|
./gradlew --no-daemon :app:assembleOtherRelease
|
|
- run:
|
|
name: Collect artifacts
|
|
working_directory: ~/project/works/core
|
|
command: |
|
|
mkdir -p /tmp/dist
|
|
cp clients/android/app/build/outputs/apk/other/release/*arm64-v8a.apk /tmp/dist/
|
|
VERSION_CODE=$(grep VERSION_CODE clients/android/version.properties | cut -d= -f2)
|
|
VERSION_NAME=$(grep VERSION_NAME clients/android/version.properties | cut -d= -f2)
|
|
echo "Built versionCode=$VERSION_CODE versionName=$VERSION_NAME"
|
|
- save_cache:
|
|
key: omv-go-v1-{{ arch }}-{{ checksum "works/core/go.sum" }}
|
|
paths:
|
|
- /home/circleci/go/pkg/mod
|
|
- /home/circleci/.cache/go-build
|
|
- save_cache:
|
|
key: omv-gradle-v1-{{ checksum "works/core/clients/android/gradle/libs.versions.toml" }}
|
|
paths:
|
|
- /home/circleci/.gradle/caches
|
|
- /home/circleci/.gradle/wrapper
|
|
- store_artifacts:
|
|
path: /tmp/dist
|
|
destination: dist
|
|
|
|
workflows:
|
|
build:
|
|
jobs:
|
|
- verify-core
|
|
- build-android:
|
|
requires:
|
|
- verify-core
|