Compare commits

...

3 Commits

Author SHA1 Message Date
wangjia f4beb90769 fix(ci): nginx reload 改用 systemctl reload-or-restart,避免空 PID 文件报错
Deploy / build-linux-web (push) Successful in 1m1s
Deploy / build-windows (push) Successful in 1m42s
Deploy / build-macos (push) Successful in 1m2s
Deploy / release-deploy (push) Failing after 1m17s
nginx -s reload 依赖 /run/nginx.pid,该文件为空时报 invalid PID number。
改用 systemctl reload-or-restart(经 systemd MAINPID 发 HUP,运行中则 reload、
未运行则启动),并 enable nginx 保证重启后自启。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 09:33:24 +08:00
wangjia 6f0b273950 fix(ci): Windows 构建清除 cp 复制的插件软链,避免 PathExists(errno 183)
Deploy / build-windows (push) Successful in 1m31s
Deploy / build-linux-web (push) Successful in 55s
Deploy / build-macos (push) Successful in 58s
Deploy / release-deploy (push) Failing after 1m20s
cp -r 把 windows/flutter/ephemeral/.plugin_symlinks 复制成真实目录,
flutter createPluginSymlinks 只清软链、清不掉真目录,重建时撞车。
复制后删除 ephemeral/.dart_tool/build,由 flutter 干净重建。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 09:06:36 +08:00
wangjia b43601b4fd ci: 运行环境自愈预置 + 发版任务串行 + 删 ci.yml/暂停备份
Deploy / build-windows (push) Failing after 25s
Deploy / build-macos (push) Has been cancelled
Deploy / release-deploy (push) Has been cancelled
Deploy / build-linux-web (push) Has been cancelled
- 新增 scripts/ci/provision-{mac,windows}.sh:幂等预置,按 Flutter 版本
  stamp 短路,pipeline 首跑自动 precache + 预热缓存,运行时不再下载 engine
- scripts/ci/_env.sh:抽出共用镜像 env,compile 脚本统一 source
- deploy.yml:build-macos needs build-linux-web,同一 mac runner 串行
  执行,避免排队超时;各 build job 加 Provision 前置步骤
- 删除 .gitea/workflows/ci.yml
- backup.yml:暂停定时备份(保留 workflow_dispatch 手动触发)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 01:04:23 +08:00
11 changed files with 170 additions and 44 deletions
+3 -2
View File
@@ -1,8 +1,9 @@
name: DB Backup
on:
schedule:
- cron: '0 18 * * *' # UTC 18:00 = 北京时间 02:00
# 定时备份已暂停(保留手动触发)。恢复时取消下面 schedule 的注释即可。
# schedule:
# - cron: '0 18 * * *' # UTC 18:00 = 北京时间 02:00
workflow_dispatch:
jobs:
-30
View File
@@ -1,30 +0,0 @@
name: CI
on:
push:
branches-ignore: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: backend/go.mod
cache-dependency-path: backend/go.sum
- name: Go tests
working-directory: backend
run: go test ./...
- uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Flutter tests
working-directory: client
run: flutter test
+13
View File
@@ -16,6 +16,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Provision (idempotent — auto-runs if host not initialized)
run: sh scripts/ci/provision-mac.sh
- name: Compile (Linux backend + Flutter Web)
run: sh scripts/ci/compile.sh "${{ gitea.ref_name }}"
@@ -26,6 +29,9 @@ jobs:
path: dist/
build-macos:
# Same physical runner as build-linux-web (label: mac, capacity 1). Run them
# serially via needs so the second job doesn't sit queued and time out.
needs: build-linux-web
runs-on: mac
env:
PUB_HOSTED_URL: https://pub.flutter-io.cn
@@ -34,6 +40,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Provision (idempotent — auto-runs if host not initialized)
run: sh scripts/ci/provision-mac.sh
- name: Compile (Flutter macOS)
run: sh scripts/ci/compile-macos.sh "${{ gitea.ref_name }}"
@@ -53,6 +62,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Provision (idempotent — auto-runs if host not initialized)
shell: bash
run: sh scripts/ci/provision-windows.sh
- name: Compile (Flutter Windows)
shell: bash
run: sh scripts/ci/compile-windows.sh "${{ gitea.ref_name }}"
+17
View File
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.0.8] - 2026-06-03
### 修复
- 修复 EC2 部署最后一步 nginx reload 失败(`invalid PID number`):改用 `systemctl reload-or-restart nginx`(经 systemd MAINPID 发 HUP,不依赖空的 /run/nginx.pid),并 `enable nginx` 确保重启后自启
## [1.0.7] - 2026-06-03
### 修复
- 修复 Windows 构建 `PathExistsException`errno 183):复制 client/ 到 C:\jiu-build 后,先清除 cp 复制成真实目录的插件软链(windows/flutter/ephemeral)及 .dart_tool/build,再交给 flutter 干净重建
## [1.0.6] - 2026-06-03
### 改进
- CI 运行环境自愈预置:mac/windows runner 首次构建自动 `flutter precache` 并预热 pub/go/npm 缓存(stamp 文件按 Flutter 版本短路),后续构建不再运行时下载 engine
- 发版流水线同一 mac runner 上的任务改为串行(build-macos 依赖 build-linux-web),避免排队等待超时失败
- 暂停定时数据库备份(保留手动触发)
## [1.0.5] - 2026-06-03
### 修复
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# _env.sh — shared CI mirror env. `source` this from other scripts.
# Idempotent: only sets vars if not already provided by the environment.
export GOPROXY="${GOPROXY:-https://goproxy.cn,direct}"
export PUB_HOSTED_URL="${PUB_HOSTED_URL:-https://pub.flutter-io.cn}"
export FLUTTER_STORAGE_BASE_URL="${FLUTTER_STORAGE_BASE_URL:-https://storage.flutter-io.cn}"
# Ensure Homebrew tools are on PATH (macOS runners); harmless elsewhere.
case ":${PATH}:" in
*":/opt/homebrew/bin:"*) ;;
*) export PATH="/opt/homebrew/bin:${PATH}" ;;
esac
+2 -3
View File
@@ -2,9 +2,8 @@
# compile-macos.sh <tag> — build Flutter macOS desktop, package into dist/
set -euo pipefail
export GOPROXY="${GOPROXY:-https://goproxy.cn,direct}"
export PUB_HOSTED_URL="${PUB_HOSTED_URL:-https://pub.flutter-io.cn}"
export FLUTTER_STORAGE_BASE_URL="${FLUTTER_STORAGE_BASE_URL:-https://storage.flutter-io.cn}"
# shellcheck source=scripts/ci/_env.sh
. "$(dirname "$0")/_env.sh"
TAG="$1"
VER="${TAG#v}"
+10 -3
View File
@@ -2,9 +2,8 @@
# compile-windows.sh <tag> — build Flutter Windows desktop, package into dist/
set -euo pipefail
export GOPROXY="${GOPROXY:-https://goproxy.cn,direct}"
export PUB_HOSTED_URL="${PUB_HOSTED_URL:-https://pub.flutter-io.cn}"
export FLUTTER_STORAGE_BASE_URL="${FLUTTER_STORAGE_BASE_URL:-https://storage.flutter-io.cn}"
# shellcheck source=scripts/ci/_env.sh
. "$(dirname "$0")/_env.sh"
TAG="$1"
VER="${TAG#v}"
@@ -28,6 +27,14 @@ rm -rf "$BUILD_ROOT"
mkdir -p "$BUILD_ROOT"
cp -r client "$BUILD_CLIENT"
# `cp -r` turns Flutter's plugin symlinks (windows/flutter/ephemeral/.plugin_symlinks/*)
# into real directories. flutter's createPluginSymlinks only cleans up *symlinks*, so it
# then fails to create a symlink over the copied real dir (errno 183 / PathExists).
# Drop all regenerable artifacts so the build below recreates them cleanly.
rm -rf "${BUILD_CLIENT}/windows/flutter/ephemeral" \
"${BUILD_CLIENT}/.dart_tool" \
"${BUILD_CLIENT}/build"
# Build (run from the clean path; pushd/popd avoids needing $() to save cwd)
pushd "$BUILD_CLIENT" > /dev/null
flutter create --platforms=windows . --project-name jiu_client
+2 -4
View File
@@ -2,10 +2,8 @@
# compile.sh <tag> — build backend + Flutter web, package into dist/
set -euo pipefail
export PATH="/opt/homebrew/bin:$PATH"
export GOPROXY="${GOPROXY:-https://goproxy.cn,direct}"
export PUB_HOSTED_URL="${PUB_HOSTED_URL:-https://pub.flutter-io.cn}"
export FLUTTER_STORAGE_BASE_URL="${FLUTTER_STORAGE_BASE_URL:-https://storage.flutter-io.cn}"
# shellcheck source=scripts/ci/_env.sh
. "$(dirname "$0")/_env.sh"
TAG="$1"
VER="${TAG#v}"
+6 -2
View File
@@ -126,9 +126,13 @@ mkdir -p /opt/jiu/marketing
rsync -a --delete /tmp/jiu-marketing-new/ /opt/jiu/marketing/
rm -rf /tmp/jiu-marketing-new
# Update nginx config and reload
# Update nginx config and reload.
# reload-or-restart: reload if nginx is running, start it if it's not — avoids
# `nginx -s reload` failing with "invalid PID number" when nginx isn't running
# (e.g. after an EC2 reboot where nginx didn't auto-start).
sudo cp /tmp/nginx-jiu.conf /etc/nginx/conf.d/jiu.conf
sudo nginx -t && sudo nginx -s reload
sudo systemctl enable nginx >/dev/null 2>&1 || true # auto-start on future reboots
sudo nginx -t && sudo systemctl reload-or-restart nginx
echo "Deploy complete!"
ENDSSH
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
# provision-mac.sh — idempotent provisioning for the macOS host runner.
#
# Pre-warms everything the build jobs (compile.sh / compile-macos.sh) would
# otherwise download at runtime: Flutter macOS+web engine artifacts, pub
# packages, Go modules, npm deps. Safe to run on every pipeline run — it
# short-circuits via a stamp file keyed to the installed Flutter version, so
# once provisioned it returns in milliseconds and downloads nothing.
set -euo pipefail
SCRIPT_DIR="$(dirname "$0")"
# shellcheck source=scripts/ci/_env.sh
. "${SCRIPT_DIR}/_env.sh"
STAMP_DIR="${HOME}/.cache/jiu-ci"
STAMP="${STAMP_DIR}/provisioned-mac"
CUR="${STAMP_DIR}/.flutter-version-mac.cur"
mkdir -p "$STAMP_DIR"
# --- detection: skip if already provisioned for this Flutter version ---
if ! command -v flutter >/dev/null 2>&1; then
echo "ERROR: flutter not found on PATH. Install Flutter on this runner first." >&2
exit 1
fi
flutter --version --machine > "$CUR" 2>/dev/null || flutter --version > "$CUR" 2>&1 || true
if [ -s "$STAMP" ] && cmp -s "$STAMP" "$CUR"; then
echo "==> provision-mac: already provisioned (Flutter unchanged), skipping."
exit 0
fi
echo "==> provision-mac: not provisioned (or Flutter changed) — running."
# --- toolchain presence (do not auto-install system-level tools) ---
for tool in go node npm; do
if ! command -v "$tool" >/dev/null 2>&1; then
echo "ERROR: '$tool' not found on PATH. Install it on this runner first." >&2
exit 1
fi
done
# --- warm Flutter platform engines (the macOS SDK download seen in CI) ---
echo "==> precache Flutter engines (macos, web)"
flutter precache --macos --web --universal
# --- warm dependency caches ---
echo "==> flutter pub get (client)"
(cd "${SCRIPT_DIR}/../../client" && flutter pub get)
echo "==> go mod download (backend)"
(cd "${SCRIPT_DIR}/../../backend" && go mod download)
echo "==> npm ci (web)"
(cd "${SCRIPT_DIR}/../../web" && npm ci --prefer-offline)
# --- mark provisioned ---
cp "$CUR" "$STAMP"
echo "==> provision-mac: done."
echo "--- versions ---"
flutter --version | head -1
go version
node --version
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# provision-windows.sh — idempotent provisioning for the Windows host runner.
#
# Pre-warms what compile-windows.sh would download at runtime: Flutter Windows
# engine artifacts and pub packages. Short-circuits via a stamp file keyed to
# the installed Flutter version, so repeat runs return immediately.
set -euo pipefail
SCRIPT_DIR="$(dirname "$0")"
# shellcheck source=scripts/ci/_env.sh
. "${SCRIPT_DIR}/_env.sh"
STAMP_DIR="${HOME}/.cache/jiu-ci"
STAMP="${STAMP_DIR}/provisioned-windows"
CUR="${STAMP_DIR}/.flutter-version-win.cur"
mkdir -p "$STAMP_DIR"
# --- detection ---
if ! command -v flutter >/dev/null 2>&1; then
echo "ERROR: flutter not found on PATH. Install Flutter on this runner first." >&2
exit 1
fi
flutter --version --machine > "$CUR" 2>/dev/null || flutter --version > "$CUR" 2>&1 || true
if [ -s "$STAMP" ] && cmp -s "$STAMP" "$CUR"; then
echo "==> provision-windows: already provisioned (Flutter unchanged), skipping."
exit 0
fi
echo "==> provision-windows: not provisioned (or Flutter changed) — running."
# --- warm Flutter Windows engine + pub deps ---
echo "==> precache Flutter engine (windows)"
flutter precache --windows
echo "==> flutter pub get (client)"
(cd "${SCRIPT_DIR}/../../client" && flutter pub get)
# --- mark provisioned ---
cp "$CUR" "$STAMP"
echo "==> provision-windows: done."
flutter --version | head -1