mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-11 17:47:20 +10:00
297 lines
10 KiB
YAML
297 lines
10 KiB
YAML
name: Publish Docker Images
|
|
|
|
on:
|
|
#push:
|
|
# branches:
|
|
# - stable
|
|
# - testing
|
|
release:
|
|
types:
|
|
- published
|
|
workflow_dispatch:
|
|
inputs:
|
|
tag:
|
|
description: "The tag version you want to build"
|
|
|
|
env:
|
|
REGISTRY_IMAGE: ghcr.io/sagernet/sing-box
|
|
|
|
jobs:
|
|
build_binary:
|
|
name: Build binary
|
|
if: github.event_name != 'release' || github.event.release.target_commitish != 'oldstable'
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: true
|
|
matrix:
|
|
include:
|
|
# Naive-enabled builds (musl)
|
|
- { arch: amd64, naive: true, docker_platform: "linux/amd64" }
|
|
- { arch: arm64, naive: true, docker_platform: "linux/arm64" }
|
|
- { arch: "386", naive: true, docker_platform: "linux/386" }
|
|
- { arch: arm, goarm: "7", naive: true, docker_platform: "linux/arm/v7" }
|
|
- { arch: mipsle, gomips: softfloat, naive: true, docker_platform: "linux/mipsle" }
|
|
- { arch: riscv64, naive: true, docker_platform: "linux/riscv64" }
|
|
- { arch: loong64, naive: true, docker_platform: "linux/loong64" }
|
|
# Non-naive builds
|
|
- { arch: arm, goarm: "6", docker_platform: "linux/arm/v6" }
|
|
- { arch: ppc64le, docker_platform: "linux/ppc64le" }
|
|
- { arch: s390x, docker_platform: "linux/s390x" }
|
|
steps:
|
|
- name: Get commit to build
|
|
id: ref
|
|
run: |-
|
|
if [[ -z "${{ github.event.inputs.tag }}" ]]; then
|
|
ref="${{ github.ref_name }}"
|
|
else
|
|
ref="${{ github.event.inputs.tag }}"
|
|
fi
|
|
echo "ref=$ref"
|
|
echo "ref=$ref" >> $GITHUB_OUTPUT
|
|
- name: Checkout
|
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
|
with:
|
|
ref: ${{ steps.ref.outputs.ref }}
|
|
fetch-depth: 0
|
|
- name: Setup Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version: ~1.25.7
|
|
- name: Clone cronet-go
|
|
if: matrix.naive
|
|
run: |
|
|
set -xeuo pipefail
|
|
CRONET_GO_VERSION=$(cat .github/CRONET_GO_VERSION)
|
|
git init ~/cronet-go
|
|
git -C ~/cronet-go remote add origin https://github.com/sagernet/cronet-go.git
|
|
git -C ~/cronet-go fetch --depth=1 origin "$CRONET_GO_VERSION"
|
|
git -C ~/cronet-go checkout FETCH_HEAD
|
|
git -C ~/cronet-go submodule update --init --recursive --depth=1
|
|
- name: Regenerate Debian keyring
|
|
if: matrix.naive
|
|
run: |
|
|
set -xeuo pipefail
|
|
rm -f ~/cronet-go/naiveproxy/src/build/linux/sysroot_scripts/keyring.gpg
|
|
cd ~/cronet-go
|
|
GPG_TTY=/dev/null ./naiveproxy/src/build/linux/sysroot_scripts/generate_keyring.sh
|
|
- name: Cache Chromium toolchain
|
|
if: matrix.naive
|
|
id: cache-chromium-toolchain
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: |
|
|
~/cronet-go/naiveproxy/src/third_party/llvm-build/
|
|
~/cronet-go/naiveproxy/src/gn/out/
|
|
~/cronet-go/naiveproxy/src/chrome/build/pgo_profiles/
|
|
~/cronet-go/naiveproxy/src/out/sysroot-build/
|
|
key: chromium-toolchain-${{ matrix.arch }}-musl-${{ hashFiles('.github/CRONET_GO_VERSION') }}
|
|
- name: Download Chromium toolchain
|
|
if: matrix.naive
|
|
run: |
|
|
set -xeuo pipefail
|
|
cd ~/cronet-go
|
|
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl download-toolchain
|
|
- name: Set version
|
|
run: |
|
|
set -xeuo pipefail
|
|
VERSION=$(go run ./cmd/internal/read_tag)
|
|
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
|
|
- name: Set Chromium toolchain environment
|
|
if: matrix.naive
|
|
run: |
|
|
set -xeuo pipefail
|
|
cd ~/cronet-go
|
|
go run ./cmd/build-naive --target=linux/${{ matrix.arch }} --libc=musl env >> $GITHUB_ENV
|
|
- name: Set build tags
|
|
run: |
|
|
set -xeuo pipefail
|
|
if [[ "${{ matrix.naive }}" == "true" ]]; then
|
|
TAGS="$(cat release/DEFAULT_BUILD_TAGS),with_musl"
|
|
else
|
|
TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
|
|
fi
|
|
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
|
|
- name: Set shared ldflags
|
|
run: |
|
|
echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
|
|
- name: Build (naive)
|
|
if: matrix.naive
|
|
run: |
|
|
set -xeuo pipefail
|
|
go build -v -trimpath -o sing-box -tags "${BUILD_TAGS}" \
|
|
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${VERSION}' ${LDFLAGS_SHARED} -s -w -buildid=" \
|
|
./cmd/sing-box
|
|
env:
|
|
CGO_ENABLED: "1"
|
|
GOOS: linux
|
|
GOARCH: ${{ matrix.arch }}
|
|
GOARM: ${{ matrix.goarm }}
|
|
GOMIPS: ${{ matrix.gomips }}
|
|
- name: Build (non-naive)
|
|
if: ${{ ! matrix.naive }}
|
|
run: |
|
|
set -xeuo pipefail
|
|
go build -v -trimpath -o sing-box -tags "${BUILD_TAGS}" \
|
|
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${VERSION}' ${LDFLAGS_SHARED} -s -w -buildid=" \
|
|
./cmd/sing-box
|
|
env:
|
|
CGO_ENABLED: "0"
|
|
GOOS: linux
|
|
GOARCH: ${{ matrix.arch }}
|
|
GOARM: ${{ matrix.goarm }}
|
|
- name: Prepare artifact
|
|
run: |
|
|
platform=${{ matrix.docker_platform }}
|
|
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
|
# Rename binary to include arch info for Dockerfile.binary
|
|
BINARY_NAME="sing-box-${{ matrix.arch }}"
|
|
if [[ -n "${{ matrix.goarm }}" ]]; then
|
|
BINARY_NAME="${BINARY_NAME}v${{ matrix.goarm }}"
|
|
fi
|
|
mv sing-box "${BINARY_NAME}"
|
|
echo "BINARY_NAME=${BINARY_NAME}" >> $GITHUB_ENV
|
|
- name: Upload binary
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: binary-${{ env.PLATFORM_PAIR }}
|
|
path: ${{ env.BINARY_NAME }}
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
build_docker:
|
|
name: Build Docker image
|
|
runs-on: ubuntu-latest
|
|
needs:
|
|
- build_binary
|
|
strategy:
|
|
fail-fast: true
|
|
matrix:
|
|
include:
|
|
- { platform: "linux/amd64" }
|
|
- { platform: "linux/arm/v6" }
|
|
- { platform: "linux/arm/v7" }
|
|
- { platform: "linux/arm64" }
|
|
- { platform: "linux/386" }
|
|
# mipsle: no base Docker image available for this platform
|
|
- { platform: "linux/ppc64le" }
|
|
- { platform: "linux/riscv64" }
|
|
- { platform: "linux/s390x" }
|
|
- { platform: "linux/loong64", base_image: "ghcr.io/loong64/alpine:edge" }
|
|
steps:
|
|
- name: Get commit to build
|
|
id: ref
|
|
run: |-
|
|
if [[ -z "${{ github.event.inputs.tag }}" ]]; then
|
|
ref="${{ github.ref_name }}"
|
|
else
|
|
ref="${{ github.event.inputs.tag }}"
|
|
fi
|
|
echo "ref=$ref"
|
|
echo "ref=$ref" >> $GITHUB_OUTPUT
|
|
- name: Checkout
|
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
|
with:
|
|
ref: ${{ steps.ref.outputs.ref }}
|
|
fetch-depth: 0
|
|
- name: Prepare
|
|
run: |
|
|
platform=${{ matrix.platform }}
|
|
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
|
- name: Download binary
|
|
uses: actions/download-artifact@v5
|
|
with:
|
|
name: binary-${{ env.PLATFORM_PAIR }}
|
|
path: .
|
|
- name: Prepare binary
|
|
run: |
|
|
# Find and make the binary executable
|
|
chmod +x sing-box-*
|
|
ls -la sing-box-*
|
|
- name: Setup QEMU
|
|
uses: docker/setup-qemu-action@v3
|
|
- name: Setup Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
- name: Login to GitHub Container Registry
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.repository_owner }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
- name: Docker meta
|
|
id: meta
|
|
uses: docker/metadata-action@v5
|
|
with:
|
|
images: ${{ env.REGISTRY_IMAGE }}
|
|
- name: Build and push by digest
|
|
id: build
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
platforms: ${{ matrix.platform }}
|
|
context: .
|
|
file: Dockerfile.binary
|
|
build-args: |
|
|
BASE_IMAGE=${{ matrix.base_image || 'alpine' }}
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
|
|
- name: Export digest
|
|
run: |
|
|
mkdir -p /tmp/digests
|
|
digest="${{ steps.build.outputs.digest }}"
|
|
touch "/tmp/digests/${digest#sha256:}"
|
|
- name: Upload digest
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: digests-${{ env.PLATFORM_PAIR }}
|
|
path: /tmp/digests/*
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
merge:
|
|
if: github.event_name != 'push'
|
|
runs-on: ubuntu-latest
|
|
needs:
|
|
- build_docker
|
|
steps:
|
|
- name: Get commit to build
|
|
id: ref
|
|
run: |-
|
|
if [[ -z "${{ github.event.inputs.tag }}" ]]; then
|
|
ref="${{ github.ref_name }}"
|
|
else
|
|
ref="${{ github.event.inputs.tag }}"
|
|
fi
|
|
echo "ref=$ref"
|
|
echo "ref=$ref" >> $GITHUB_OUTPUT
|
|
if [[ $ref == *"-"* ]]; then
|
|
latest=latest-beta
|
|
else
|
|
latest=latest
|
|
fi
|
|
echo "latest=$latest"
|
|
echo "latest=$latest" >> $GITHUB_OUTPUT
|
|
- name: Download digests
|
|
uses: actions/download-artifact@v5
|
|
with:
|
|
path: /tmp/digests
|
|
pattern: digests-*
|
|
merge-multiple: true
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
- name: Login to GitHub Container Registry
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.repository_owner }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
- name: Create manifest list and push
|
|
if: github.event_name != 'push'
|
|
working-directory: /tmp/digests
|
|
run: |
|
|
docker buildx imagetools create \
|
|
-t "${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.latest }}" \
|
|
-t "${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.ref }}" \
|
|
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
|
|
- name: Inspect image
|
|
if: github.event_name != 'push'
|
|
run: |
|
|
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.latest }}
|
|
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.ref }}
|