From f9e2d3310f0b6b68f4e38746360d4b8d1de82b5f Mon Sep 17 00:00:00 2001 From: Wang Defa <1+wangdefa@noreply.gitea.bcde.io> Date: Wed, 5 Aug 2026 13:10:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20CI=20=E5=92=8C=20Release?= =?UTF-8?q?=20=E6=B5=81=E6=B0=B4=E7=BA=BF=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E4=B8=8E=E5=8F=91=E5=B8=83=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0=20VERSION=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=BB=A5=E7=BB=9F=E4=B8=80=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/ci.yaml | 230 ----------------------------------- .gitea/workflows/ci.yml | 81 ++++++++++++ .gitea/workflows/release.yml | 163 +++++++++++++++++++++++++ CLAUDE.md | 10 +- README.md | 16 +-- VERSION | 1 + 6 files changed, 259 insertions(+), 242 deletions(-) delete mode 100644 .gitea/workflows/ci.yaml create mode 100644 .gitea/workflows/ci.yml create mode 100644 .gitea/workflows/release.yml create mode 100644 VERSION diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml deleted file mode 100644 index 3ec2f90..0000000 --- a/.gitea/workflows/ci.yaml +++ /dev/null @@ -1,230 +0,0 @@ -# .gitea/workflows/ci.yaml -name: Build and Release - -on: - push: - branches: [main, develop] - tags: ['*'] - -env: - DOCKER_BUILDKIT: "1" - PRODUCT_NAME: "xxxig" - PACKAGE_VERSION: "6.26.0" - BUILDX_NO_DEFAULT_ATTESTATIONS: "1" - -jobs: - build-and-test: - runs-on: ${{ matrix.arch == 'amd64' && 'ubuntu-latest-amd64' || 'ubuntu-latest-arm64' }} - strategy: - matrix: - arch: [amd64, arm64] - steps: - - uses: actions/checkout@v4 - - - name: Setup Docker Buildx - run: | - # 创建 buildx builder(原生构建不需要 QEMU) - docker buildx create --use --name native-builder \ - --driver docker-container \ - --driver-opt network=host \ - --driver-opt env.BUILDKIT_STEP_LOG_MAX_SIZE=50000000 \ - --driver-opt env.BUILDKIT_STEP_LOG_MAX_SPEED=10000000 \ - || true - docker buildx inspect --bootstrap - - - name: Build binaries - run: | - XXXIG_VERSION=v${PACKAGE_VERSION} # 上游源码 git tag 带 v 前缀,需补回 - PLATFORM="linux/${{ matrix.arch }}" - - echo "🏗️ Building ${PLATFORM} on native ${{ matrix.arch }} runner" - echo "📦 Build: musl 全静态 (docker/Dockerfile, 基于 alpine)" - - # 设置 BuildKit 优化参数 - export BUILDKIT_PROGRESS=plain - - docker buildx build --pull \ - --platform ${PLATFORM} \ - --build-arg XXXIG_VERSION=${XXXIG_VERSION} \ - --output type=local,dest=./output \ - -f docker/Dockerfile . - - - name: Package and test - run: | - DIR="./output/linux_${{ matrix.arch }}" - - if [ ! -d "$DIR" ]; then - echo "❌ 构建输出目录不存在: $DIR" - exit 1 - fi - - TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-linux-static-${PACKAGE_VERSION}.tar.gz" - tar -czf "${TARGZ}" -C "$DIR" . - - echo "📦 Created package: ${TARGZ}" - ls -lh "${TARGZ}" - - # 快速验证 - mkdir -p test && tar -xzf "${TARGZ}" -C test - test/xxxigDaemon --version 2>/dev/null || echo "⚠️ 跳过版本检查" - rm -rf test - - - name: Build Debian package - run: | - # 安装 dpkg-deb(如果需要) - sudo apt-get update && sudo apt-get install -y dpkg-dev - - TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-linux-static-${PACKAGE_VERSION}.tar.gz" - - echo "📦 Building Debian package for ${{ matrix.arch }}..." - chmod +x debian/build-deb.sh - ./debian/build-deb.sh ${{ matrix.arch }} ${PACKAGE_VERSION} "${TARGZ}" - - ls -lh *.deb - - - uses: https://github.com/ChristopherHX/gitea-upload-artifact@v4 - with: - name: binaries-${{ matrix.arch }} - path: | - *.tar.gz - *.deb - retention-days: 1 - - release: - runs-on: ubuntu-latest-amd64 - needs: build-and-test - if: startsWith(github.ref, 'refs/tags/') - steps: - - uses: https://github.com/ChristopherHX/gitea-download-artifact@v4 - with: - pattern: binaries-* - path: ./packages - merge-multiple: true - - - name: Upload packages and create release - env: - TOKEN: ${{ secrets.BUILD_TOKEN }} - TAG: ${{ github.ref_name }} - run: | - cd packages - - # 提取仓库信息(移除 https:// 前缀和仓库路径) - REGISTRY=$(echo "${{ gitea.server_url }}" | sed 's|https\?://||') - OWNER="${{ gitea.repository_owner }}" - REPO_NAME=$(echo "${{ gitea.repository }}" | cut -d'/' -f2) - VERSION="${TAG#v}" # 包版本:去掉 git tag 的 v 前缀(registry 路径/下载名/Release 标题用) - - echo "📦 上传包到 Generic Package Registry..." - echo " Registry: ${REGISTRY}" - echo " Owner: ${OWNER}" - echo " Package: ${PRODUCT_NAME}" - echo " Version: ${VERSION}" - - # 上传所有 tar.gz 包到 Generic Package Registry - for file in *.tar.gz; do - [ ! -f "$file" ] && continue - echo " ⬆️ $file" - curl -fsSL -X PUT \ - -H "Authorization: token ${TOKEN}" \ - --upload-file "$file" \ - "https://${REGISTRY}/api/packages/${OWNER}/generic/${PRODUCT_NAME}/${VERSION}/$file" || { - echo "❌ 上传失败: $file" - exit 1 - } - done - - # 上传 Debian 包到 Debian Package Registry (通用稳定版) - echo "" - echo "📦 上传 Debian 包到 Debian Package Registry..." - for file in *.deb; do - [ ! -f "$file" ] && continue - - # 上传到 stable (通用稳定版) - echo " ⬆️ $file → stable" - curl -fsSL -X PUT \ - -H "Authorization: token ${TOKEN}" \ - --upload-file "$file" \ - "https://${REGISTRY}/api/packages/${OWNER}/debian/pool/stable/main/upload" || { - echo "❌ Debian 包上传失败: $file (stable)" - exit 1 - } - done - - # 生成 Release 描述 - echo "" - echo "📝 生成 Release..." - - # 拼接 tar.gz 下载链接 - ASSETS=$(for f in *.tar.gz; do - [ -f "$f" ] || continue - echo "- [\`$f\`](https://${REGISTRY}/api/packages/${OWNER}/generic/${PRODUCT_NAME}/${VERSION}/$f)" - done) - - BODY=$(cat <> "$GITHUB_ENV" + docker buildx inspect --bootstrap + + - name: 构建 ${{ matrix.arch }} 二进制 + run: | + VERSION=$(tr -d '\r\n' < VERSION) + docker buildx build --pull \ + --platform "linux/${{ matrix.arch }}" \ + --build-arg "XXXIG_VERSION=v${VERSION}" \ + --output type=local,dest=./output \ + -f docker/Dockerfile . + + - name: 冒烟测试 + run: | + DIR="./output/linux_${{ matrix.arch }}" + test -x "${DIR}/xxxigDaemon" + test -x "${DIR}/xxxig" + test -x "${DIR}/xxxigServer" + test -f "${DIR}/config.json" + test -f "${DIR}/config_cc.json" + "${DIR}/xxxigDaemon" --version + + - name: 验证 Debian 打包 + run: | + VERSION=$(tr -d '\r\n' < VERSION) + TARGZ="xxxig-${{ matrix.arch }}-linux-static-${VERSION}.tar.gz" + tar -czf "${TARGZ}" -C "./output/linux_${{ matrix.arch }}" . + if ! command -v dpkg-deb >/dev/null; then + sudo apt-get update + sudo apt-get install -y dpkg-dev + fi + ./debian/build-deb.sh "${{ matrix.arch }}" "${VERSION}" "${TARGZ}" + DEB="xxxig_${VERSION}_${{ matrix.arch }}.deb" + CONTENTS=$(dpkg-deb --contents "${DEB}") + grep -Fq 'usr/libexec/xxxig-enable-1gb-pages' <<<"${CONTENTS}" + grep -Fq 'lib/systemd/system/xxxig-hugepages.service' <<<"${CONTENTS}" + + - name: 清理 Buildx + if: always() + run: docker buildx rm "${BUILDER}" || true diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..3151bb5 --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,163 @@ +name: Release + +on: + push: + tags: ["*"] + +env: + DOCKER_BUILDKIT: "1" + BUILDX_NO_DEFAULT_ATTESTATIONS: "1" + BUILDKIT_PROGRESS: plain + PRODUCT_NAME: xxxig + +jobs: + build: + runs-on: ${{ matrix.arch == 'amd64' && 'ubuntu-latest-amd64' || 'ubuntu-latest-arm64' }} + strategy: + fail-fast: false + matrix: + arch: [amd64, arm64] + steps: + - uses: actions/checkout@v4 + + - name: 校验 tag 与源码版本 + env: + TAG: ${{ gitea.ref_name }} + run: | + VERSION=$(tr -d '\r\n' < VERSION) + TAG_VERSION="${TAG#v}" + [[ "${TAG_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] + [ "${TAG_VERSION}" = "${VERSION}" ] || { + echo "tag ${TAG_VERSION} 与 VERSION ${VERSION} 不一致" + exit 1 + } + echo "VERSION=${VERSION}" >> "$GITHUB_ENV" + + - name: 准备原生 Buildx + run: | + BUILDER=$(docker buildx create --use \ + --driver docker-container \ + --driver-opt network=host) + echo "BUILDER=${BUILDER}" >> "$GITHUB_ENV" + docker buildx inspect --bootstrap + + - name: 构建 ${{ matrix.arch }} 二进制 + run: | + docker buildx build --pull \ + --platform "linux/${{ matrix.arch }}" \ + --build-arg "XXXIG_VERSION=v${VERSION}" \ + --output type=local,dest=./output \ + -f docker/Dockerfile . + + - name: 打包并冒烟测试 + run: | + DIR="./output/linux_${{ matrix.arch }}" + TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-linux-static-${VERSION}.tar.gz" + test -x "${DIR}/xxxigDaemon" + test -x "${DIR}/xxxig" + test -x "${DIR}/xxxigServer" + tar -czf "${TARGZ}" -C "${DIR}" . + TEST_DIR=$(mktemp -d) + trap 'rm -rf "${TEST_DIR}"' EXIT + tar -xzf "${TARGZ}" -C "${TEST_DIR}" + "${TEST_DIR}/xxxigDaemon" --version + + - name: 构建 Debian 包 + run: | + if ! command -v dpkg-deb >/dev/null; then + sudo apt-get update + sudo apt-get install -y dpkg-dev + fi + TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-linux-static-${VERSION}.tar.gz" + ./debian/build-deb.sh "${{ matrix.arch }}" "${VERSION}" "${TARGZ}" + DEB="${PRODUCT_NAME}_${VERSION}_${{ matrix.arch }}.deb" + CONTENTS=$(dpkg-deb --contents "${DEB}") + grep -Fq 'usr/libexec/xxxig-enable-1gb-pages' <<<"${CONTENTS}" + grep -Fq 'lib/systemd/system/xxxig-hugepages.service' <<<"${CONTENTS}" + + - uses: https://github.com/ChristopherHX/gitea-upload-artifact@v4 + with: + name: packages-${{ matrix.arch }} + path: | + *.tar.gz + *.deb + if-no-files-found: error + retention-days: 1 + + - name: 清理 Buildx + if: always() + run: docker buildx rm "${BUILDER}" || true + + release: + needs: build + runs-on: ubuntu-latest-amd64 + steps: + - uses: actions/checkout@v4 + + - uses: https://github.com/ChristopherHX/gitea-download-artifact@v4 + with: + pattern: packages-* + path: ./packages + merge-multiple: true + + - name: 校验发布文件并生成校验和 + env: + TAG: ${{ gitea.ref_name }} + run: | + VERSION=$(tr -d '\r\n' < VERSION) + TAG_VERSION="${TAG#v}" + [ "${TAG_VERSION}" = "${VERSION}" ] + for arch in amd64 arm64; do + test -f "packages/${PRODUCT_NAME}-${arch}-linux-static-${VERSION}.tar.gz" + test -f "packages/${PRODUCT_NAME}_${VERSION}_${arch}.deb" + done + (cd packages && sha256sum *.tar.gz *.deb > SHA256SUMS) + REGISTRY=$(echo "${{ gitea.server_url }}" | sed 's|https\?://||') + echo "VERSION=${VERSION}" >> "$GITHUB_ENV" + echo "REGISTRY=${REGISTRY}" >> "$GITHUB_ENV" + + - name: 上传 Generic 和 Debian 软件包 + env: + TOKEN: ${{ secrets.BUILD_TOKEN }} + run: | + OWNER="${{ gitea.repository_owner }}" + for file in packages/*.tar.gz; do + name=$(basename "${file}") + curl -fsSL -X PUT \ + -H "Authorization: token ${TOKEN}" \ + --upload-file "${file}" \ + "https://${REGISTRY}/api/packages/${OWNER}/generic/${PRODUCT_NAME}/${VERSION}/${name}" + done + for file in packages/*.deb; do + curl -fsSL -X PUT \ + -H "Authorization: token ${TOKEN}" \ + --upload-file "${file}" \ + "https://${REGISTRY}/api/packages/${OWNER}/debian/pool/stable/main/upload" + done + + - name: 生成 Release 描述 + run: | + cat > release-notes.md </) docker buildx build --platform linux/amd64 \ - --build-arg XXXIG_VERSION=v6.26.0 \ + --build-arg XXXIG_VERSION="v$(cat VERSION)" \ --output type=local,dest=./output \ -f docker/Dockerfile . diff --git a/README.md b/README.md index 76db490..be0a5b5 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ sudo bash <(wget --no-check-certificate -qO- 'https://gitea.bcde.io/wangdefa/xxx sudo bash <(wget --no-check-certificate -qO- 'https://gitea.bcde.io/wangdefa/xxxig/raw/branch/main/script/install.deb.sh') \ -o pool.example.com:3333 \ -w YOUR_WALLET - + # 卸载(自动识别安装方式) sudo bash <(wget --no-check-certificate -qO- 'https://gitea.bcde.io/wangdefa/xxxig/raw/branch/main/script/uninstall.sh') ``` @@ -46,17 +46,17 @@ sudo bash <(wget --no-check-certificate -qO- 'https://gitea.bcde.io/wangdefa/xxx ## 构建与发布 -CI 定义于 [.gitea/workflows/ci.yaml](.gitea/workflows/ci.yaml): +Gitea Actions 分为两条流水线: -- **push 到 `main`/`develop`**:矩阵 `arch=[amd64,arm64]`,在原生 runner 上用 Docker(musl 全静态)编译为 tar.gz 并打 `.deb`。 -- **打 tag**:产物上传到 Generic / Debian 包仓库并创建 Release。 +- [.gitea/workflows/ci.yml](.gitea/workflows/ci.yml):分支推送时检查版本和 shell 语法,并在 amd64、arm64 原生 runner 上编译、冒烟测试和验证 DEB 包内容。 +- [.gitea/workflows/release.yml](.gitea/workflows/release.yml):tag 推送时构建 tar.gz 和 DEB,生成 `SHA256SUMS`,上传包仓库并创建或更新 Release。 本地构建: ```bash # 编译某架构/发行版二进制(输出到 ./output/linux_/) docker buildx build --platform linux/amd64 \ - --build-arg XXXIG_VERSION=v6.26.0 \ + --build-arg XXXIG_VERSION="v$(cat VERSION)" \ --output type=local,dest=./output \ -f docker/Dockerfile . @@ -66,10 +66,12 @@ docker buildx build --platform linux/amd64 \ ## 版本号约定 -- **上游源码 git tag** 带 `v`(如 `v6.26.0`),CI 用 `XXXIG_VERSION=v${PACKAGE_VERSION}` 检出。 +- 根目录 [VERSION](VERSION) 是唯一版本来源,使用不带 `v` 的版本号。 +- **上游源码 git tag** 带 `v`(如 `v6.26.0`),CI 构建时自动补回。 - **包版本**(tar.gz / deb / registry 路径)一律用数字(如 `6.26.0`),符合 Debian 版本规范。 +- 发布 tag 可写成 `6.26.0` 或 `v6.26.0`,去掉 `v` 后必须与 VERSION 一致。 -发版只需改 ci.yaml 的 `PACKAGE_VERSION`。 +发版时先更新 VERSION 并提交,再创建同版本 tag。 ## 目录结构 diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..4c6a35f --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +6.26.0