From 1772c26d43db7dacc0aa1692eb5cef2a14ea4fb7 Mon Sep 17 00:00:00 2001 From: WHC Date: Wed, 7 Oct 2026 21:43:41 +0800 Subject: [PATCH] ci: auto-publish Windows zip to Gitea Releases After a successful windows-cross build on main or v* tags, upload the zip and .sha256 via scripts/release_windows.sh (creates/updates v$VERSION). Prefer secrets.RELEASE_TOKEN; fall back to GITHUB_TOKEN. Skip on PRs. --- .gitea/workflows/ci.yml | 21 +++++++++++++++++++++ README.md | 4 +++- docs/README-windows.md | 9 ++++++++- scripts/release_windows.sh | 31 +++++++++++++++++++++++-------- 4 files changed, 55 insertions(+), 10 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 12aa86f..cd40f1c 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -2,6 +2,8 @@ name: ci on: push: + branches: [main] + tags: ['v*'] pull_request: concurrency: @@ -112,3 +114,22 @@ jobs: ls -lah dist/cst-agent-*-windows-x86_64.zip cat dist/cst-agent-*-windows-x86_64.zip.sha256 unzip -l dist/cst-agent-*-windows-x86_64.zip | head -20 + # Auto-publish to Gitea Releases (v$CST_VERSION from include/cst_version.h). + # Prefer repo secret RELEASE_TOKEN (write:repository); fall back to the + # job token. Skipped on pull_request and when no token is available. + - name: Publish Gitea Release + if: github.event_name == 'push' + env: + RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CST_GITEA: ${{ github.server_url }} + CST_REPO: ${{ github.repository }} + GITHUB_REF: ${{ github.ref }} + CI: "true" + run: | + export GITEA_TOKEN="${RELEASE_TOKEN:-${GITHUB_TOKEN:-}}" + if [[ -z "${GITEA_TOKEN}" ]]; then + echo "::warning::no RELEASE_TOKEN / GITHUB_TOKEN; skip auto-release" + exit 0 + fi + bash scripts/release_windows.sh diff --git a/README.md b/README.md index 644cd27..7e020a8 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,9 @@ make && make install # 装到 Termux 的 $PREFIX/bin,之后任意目录 ``` 产物:`dist/windows-x86_64/`(静态链接的 `cst-agent.exe` + `busybox.exe`,无其他 DLL)和 -`dist/cst-agent-VERSION-windows-x86_64.zip`;`GITEA_TOKEN=... scripts/release_windows.sh` 上传到 Release。 +`dist/cst-agent-VERSION-windows-x86_64.zip`。CI 在 `main` / `v*` tag 推送且交叉构建成功后会自动上传到 +Gitea Release `vVERSION`(同名资源会被替换);仓库可设 `RELEASE_TOKEN`(`write:repository`),否则用任务自带 token。 +本地:`GITEA_TOKEN=... scripts/release_windows.sh`。 环境变量:`CST_SHELL`、`CST_EXE_DIR`、`CST_AUTO_APPROVE` 等。 diff --git a/docs/README-windows.md b/docs/README-windows.md index 7e8ebc4..356c195 100644 --- a/docs/README-windows.md +++ b/docs/README-windows.md @@ -160,12 +160,19 @@ scripts/bootstrap_msys2.sh ### 发布 +CI:推 `main` 或 `v*` tag 且 `windows-cross` 成功后,自动把 zip / `.sha256` 发到 +Gitea Release `vVERSION`(版本来自 `include/cst_version.h`;同名资源替换)。仓库 Secrets +可设 `RELEASE_TOKEN`(`write:repository`),没有则用 Actions 自带 token。 + +本地: + ```bash GITEA_TOKEN=... scripts/release_windows.sh --build ``` 创建(或复用)`vVERSION` Release,上传 zip 和 `.sha256`。token 只从环境变量读取,经 stdin -交给 curl,不会出现在命令行参数、磁盘或输出里。 +交给 curl,不会出现在命令行参数、磁盘或输出里。发版前先 bump `cst_version.h`;推 +`vX.Y.Z` tag 时必须与头文件一致。 ## 已知限制 diff --git a/scripts/release_windows.sh b/scripts/release_windows.sh index b68b5ba..0f258d8 100755 --- a/scripts/release_windows.sh +++ b/scripts/release_windows.sh @@ -5,13 +5,17 @@ # --build runs scripts/bootstrap_windows.sh first. The token is only read from # the environment and handed to curl on stdin: it never appears in argv, on # disk or in the output. Assets of the same name are replaced. +# +# CI: set GITEA_TOKEN (or GITHUB_TOKEN), CST_GITEA, CST_REPO. The remote-branch +# check is skipped under GITEA_ACTIONS / GITHUB_ACTIONS / CI. set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" -SERVER="${CST_GITEA:-https://git.whcself.xyz}" -REPO="${CST_REPO:-WHC/CST-agent}" +SERVER="${CST_GITEA:-${GITHUB_SERVER_URL:-https://git.whcself.xyz}}" +REPO="${CST_REPO:-${GITHUB_REPOSITORY:-WHC/CST-agent}}" API="$SERVER/api/v1/repos/$REPO" -[[ -n "${GITEA_TOKEN:-}" ]] || { +TOKEN="${GITEA_TOKEN:-${GITHUB_TOKEN:-}}" +[[ -n "$TOKEN" ]] || { echo "set GITEA_TOKEN (a Gitea token with write:repository)" >&2 exit 1 } @@ -26,10 +30,19 @@ for f in "$zip" "$zip.sha256"; do [[ -f "$f" ]] || { echo "missing $f (scripts/package_windows.sh, or --build)" >&2; exit 1; } done +# If this job was triggered by a version tag, it must match cst_version.h. +if [[ "${GITHUB_REF:-}" == refs/tags/v* ]]; then + ref_tag="${GITHUB_REF#refs/tags/}" + if [[ "$ref_tag" != "$tag" ]]; then + echo "pushed tag $ref_tag != cst_version.h $tag; bump include/cst_version.h" >&2 + exit 1 + fi +fi + api() { # METHOD PATH [curl args...] local m="$1" p="$2" shift 2 - printf 'Authorization: token %s\n' "$GITEA_TOKEN" | + printf 'Authorization: token %s\n' "$TOKEN" | curl -fsS -X "$m" -H @- "$API$p" "$@" } json() { # CODE [ARGS...]: d = the JSON on stdin, ARGS in sys.argv[1:] @@ -42,12 +55,14 @@ if rel="$(api GET "/releases/tags/$tag" 2>/dev/null)"; then echo "==> release $tag exists" else head="$(git rev-parse HEAD)" - if ! git branch -r --contains "$head" 2>/dev/null | grep -q .; then - echo "HEAD $head is not on any remote branch; push it first" >&2 - exit 1 + if [[ -z "${CI:-}${GITEA_ACTIONS:-}${GITHUB_ACTIONS:-}" ]]; then + if ! git branch -r --contains "$head" 2>/dev/null | grep -q .; then + echo "HEAD $head is not on any remote branch; push it first" >&2 + exit 1 + fi fi echo "==> creating release $tag at $head" - body="$(python3 -c 'import json,sys; print(json.dumps({"tag_name": sys.argv[1], "target_commitish": sys.argv[2], "name": "CST-Agent " + sys.argv[1], "body": "Windows x86_64: unzip, or install with scripts/install_windows.ps1"}))' "$tag" "$head")" + body="$(python3 -c 'import json,sys; print(json.dumps({"tag_name": sys.argv[1], "target_commitish": sys.argv[2], "name": "CST-Agent " + sys.argv[1], "body": "Windows x86_64: unzip, or install with install_windows.ps1 from the zip.\\n\\nArtifacts: `cst-agent-VERSION-windows-x86_64.zip` + `.sha256`."}))' "$tag" "$head")" rel="$(api POST /releases -H 'Content-Type: application/json' -d "$body")" fi id="$(json 'print(d["id"])' <<<"$rel")"