Files

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