This commit is contained in:
@@ -43,12 +43,11 @@ npm run build
|
||||
|
||||
## R1 Preview 一键安装
|
||||
|
||||
Release 发布后,在 Linux 服务器执行下面一组命令即可安装。代码仓库和更新源固定为私有 Gitea
|
||||
`https://git.awaioi.com/ERP-Team/kaidi`;服务器读取
|
||||
`https://git.awaioi.com/api/v1/repos/ERP-Team/kaidi/releases/latest`,不在生产机执行 `git pull` 或现场编译。
|
||||
先从受信任的 CI 输出或内部发布记录取得 `RELEASE_TAG`、`INSTALLER_SHA256` 和 `PUBLIC_KEY_SHA256`。
|
||||
后两项也会写入 Release 的 `bootstrap-checksums.txt`,但首次安装必须通过独立渠道核对,不能把同源下载值
|
||||
直接当作信任根。私有仓库 Token 只授予仓库/Release 读取权限,不得复用 CI 的发布写 Token。
|
||||
代码仓库和 Release 已公开,Linux 服务器不需要 Gitea Token。安装器读取
|
||||
`https://git.awaioi.com/api/v1/repos/ERP-Team/kaidi/releases/latest`,生产机不执行 `git pull` 或现场编译。
|
||||
安装脚本内置固定的发布公钥指纹,下载的应用包、清单、SBOM 和更新脚本仍须通过 RSA 签名与 SHA-256 校验。
|
||||
本版只支持由运维人员预先准备的外部 MySQL 8.4.x;安装器不会安装 MySQL、创建数据库容器或修改现有
|
||||
PostgreSQL 18。PostgreSQL 兼容开发已冻结,不属于本次 Preview.9 发布范围。
|
||||
|
||||
执行命令的机器需预装 `bash`、`sudo`、`curl`、`mktemp` 和 `sha256sum`,并能访问目标 Gitea;`jq`、Java、
|
||||
Nginx 和数据库客户端由安装器补齐。应用固定安装到 `/opt/kaidi`、`/var/lib/kaidi`、
|
||||
@@ -58,60 +57,38 @@ Nginx 和数据库客户端由安装器补齐。应用固定安装到 `/opt/kaid
|
||||
### 直接 curl 安装
|
||||
|
||||
```bash
|
||||
(
|
||||
set -Eeuo pipefail
|
||||
RELEASE_TAG=v1.0.0-preview.8
|
||||
INSTALLER_SHA256=33d4921bcad7ef2be12f20bc0512a5f6df4227ea6dd3b7e6225164077d9cd9e7
|
||||
PUBLIC_KEY_SHA256=807c6aec1dc3f7ce494db16aa9d763c66f292033c38f328afd0390d2715a8cd9
|
||||
REINSTALL=false
|
||||
SETUP_WIZARD=true
|
||||
read -rsp 'Gitea 只读 Token: ' GITEA_READ_TOKEN; printf '\n'
|
||||
token_file=$(mktemp); header_file=$(mktemp); installer=$(mktemp)
|
||||
trap 'rm -f "$token_file" "$header_file" "$installer"' EXIT
|
||||
printf '%s' "$GITEA_READ_TOKEN" > "$token_file"
|
||||
printf 'Authorization: token %s\n' "$GITEA_READ_TOKEN" > "$header_file"
|
||||
unset GITEA_READ_TOKEN
|
||||
chmod 0600 "$token_file" "$header_file" "$installer"
|
||||
curl --fail --silent --show-error --proto '=https' --tlsv1.2 \
|
||||
--header "@$header_file" \
|
||||
"https://git.awaioi.com/ERP-Team/kaidi/releases/download/$RELEASE_TAG/install.sh" \
|
||||
-o "$installer"
|
||||
printf '%s %s\n' "$INSTALLER_SHA256" "$installer" | sha256sum -c -
|
||||
sudo env \
|
||||
KAIDI_RELEASE_API_URL=https://git.awaioi.com/api/v1/repos/ERP-Team/kaidi/releases/latest \
|
||||
KAIDI_RELEASE_TOKEN_FILE="$token_file" \
|
||||
KAIDI_RELEASE_PUBLIC_KEY_SHA256="$PUBLIC_KEY_SHA256" \
|
||||
KAIDI_REINSTALL="$REINSTALL" \
|
||||
KAIDI_SETUP_WIZARD="$SETUP_WIZARD" \
|
||||
bash "$installer"
|
||||
)
|
||||
curl -fsSL https://git.awaioi.com/ERP-Team/kaidi/releases/download/v1.0.0-preview.9/install.sh | sudo bash
|
||||
```
|
||||
|
||||
这条命令会安装最新签名 Release,并默认进入 `/setup` 安装向导。需要在执行前独立校验安装脚本时使用:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://git.awaioi.com/ERP-Team/kaidi/releases/download/v1.0.0-preview.9/install.sh -o /tmp/kaidi-install.sh
|
||||
printf '%s %s\n' faf52cc902abbc2bd48571caee3f4207de50ce339b82ce88fe23f9c4ce8f89ef /tmp/kaidi-install.sh | sha256sum -c -
|
||||
sudo bash /tmp/kaidi-install.sh
|
||||
rm -f /tmp/kaidi-install.sh
|
||||
```
|
||||
|
||||
### 从固定 Git tag 拉取后安装
|
||||
|
||||
需要保留源码快照时,可以拉取与 Release 对应的固定 tag,再运行仓库内包装器。私有仓库会在 `git clone`
|
||||
时要求 Gitea 凭据,包装器随后单独要求只读 Release Token;它会在 `sudo` 前校验 `deploy/install.sh`
|
||||
的固定 SHA-256,再按同一公钥信任链安装最新签名 Release。
|
||||
需要保留源码快照时,可以拉取与 Release 对应的固定 tag,再运行仓库内包装器。公共仓库不要求凭据,
|
||||
包装器会在 `sudo` 前校验 `deploy/install.sh` 的固定 SHA-256,再按同一公钥信任链安装最新签名 Release。
|
||||
|
||||
```bash
|
||||
git clone --branch v1.0.0-preview.8 --depth 1 https://git.awaioi.com/ERP-Team/kaidi.git kaidi-preview
|
||||
git clone --branch v1.0.0-preview.9 --depth 1 https://git.awaioi.com/ERP-Team/kaidi.git kaidi-preview
|
||||
cd kaidi-preview
|
||||
KAIDI_SETUP_WIZARD=true ./deploy/install-from-git.sh
|
||||
./deploy/install-from-git.sh
|
||||
```
|
||||
|
||||
首次安装使用向导时不要传 `KAIDI_DB_URL`、`KAIDI_DB_USERNAME` 或 `KAIDI_DB_PASSWORD`;这些值在浏览器中填写。
|
||||
只有已完成安装的修复性重装才从运行时配置读取数据库值,详见下文。
|
||||
|
||||
```bash
|
||||
KAIDI_DB_URL='jdbc:mysql://MYSQL_HOST:3306/kaidi_finance?useUnicode=true&characterEncoding=utf8&connectionTimeZone=UTC&serverTimezone=UTC' \
|
||||
KAIDI_DB_USERNAME=kaidi KAIDI_DB_PASSWORD='DB_PASSWORD' ./deploy/install-from-git.sh
|
||||
```
|
||||
|
||||
安装器会完成以下动作:
|
||||
|
||||
- 仅在 Linux + systemd 环境执行;首版 32 位支持基线为带 systemd 的 Debian/Ubuntu x86 32 位 Linux。
|
||||
- 不安装或创建数据库;在 `/setup` 中连接运维人员预先准备的外部 MySQL 8.4.x。
|
||||
- 识别 `x86_64`、`aarch64`、`armv7` 或 32 位 `i386/i486/i586/i686`,校验 SHA-256 后安装对应的 Azul Java 17 JRE。
|
||||
- 使用安装命令固定的 SHA-256 指纹校验 Release 公钥,再用该公钥验证发布清单 RSA 签名。
|
||||
- 使用安装器内置的 SHA-256 指纹校验 Release 公钥,再用该公钥验证发布清单 RSA 签名。
|
||||
- 首次安装默认启用 `/setup` 向导,不在命令行保存数据库密码;向导只接受 MySQL 8.4.x,并在提交前验证 DDL/DML 权限。
|
||||
- 安装签名 Release 到 `/opt/kaidi/releases/<version>`,以 `/opt/kaidi/current` 原子切换当前版本。
|
||||
- 安装 Nginx、`kaidi-finance.service`、更新监听服务和健康检查。
|
||||
@@ -137,21 +114,7 @@ sudo cat /root/kaidi-first-login.txt
|
||||
32 位服务端镜像,因此 32 位主机需要预先连接一台 MySQL 8.4 数据库,之后仍然只执行一个安装命令:
|
||||
|
||||
```bash
|
||||
(
|
||||
set -Eeuo pipefail
|
||||
RELEASE_TAG=v1.0.0-preview.8; INSTALLER_SHA256=33d4921bcad7ef2be12f20bc0512a5f6df4227ea6dd3b7e6225164077d9cd9e7; PUBLIC_KEY_SHA256=807c6aec1dc3f7ce494db16aa9d763c66f292033c38f328afd0390d2715a8cd9
|
||||
read -rsp 'Gitea 只读 Token: ' GITEA_READ_TOKEN; printf '\n'
|
||||
token_file=$(mktemp); header_file=$(mktemp); installer=$(mktemp)
|
||||
trap 'rm -f "$token_file" "$header_file" "$installer"' EXIT
|
||||
printf '%s' "$GITEA_READ_TOKEN" > "$token_file"
|
||||
printf 'Authorization: token %s\n' "$GITEA_READ_TOKEN" > "$header_file"
|
||||
unset GITEA_READ_TOKEN; chmod 0600 "$token_file" "$header_file" "$installer"
|
||||
curl --fail --silent --show-error --proto '=https' --tlsv1.2 --header "@$header_file" \
|
||||
"https://git.awaioi.com/ERP-Team/kaidi/releases/download/$RELEASE_TAG/install.sh" -o "$installer"
|
||||
printf '%s %s\n' "$INSTALLER_SHA256" "$installer" | sha256sum -c -
|
||||
sudo env KAIDI_RELEASE_TOKEN_FILE="$token_file" KAIDI_RELEASE_PUBLIC_KEY_SHA256="$PUBLIC_KEY_SHA256" \
|
||||
KAIDI_SETUP_WIZARD=true bash "$installer"
|
||||
)
|
||||
curl -fsSL https://git.awaioi.com/ERP-Team/kaidi/releases/download/v1.0.0-preview.9/install.sh | sudo bash
|
||||
```
|
||||
|
||||
32 位主机不能运行安装器自动创建的 MySQL 容器,因此在打开向导前,需要预先创建 `kaidi_finance`,并授予安装账号该库的
|
||||
@@ -171,14 +134,19 @@ GRANT ALL PRIVILEGES ON kaidi_finance.* TO 'kaidi'@'KAIDI_SERVER_IP';
|
||||
管理员数据和运维人员新增的环境变量:
|
||||
|
||||
```bash
|
||||
# 使用上方同一安装命令,把 REINSTALL=false 改成 REINSTALL=true。
|
||||
curl -fsSL https://git.awaioi.com/ERP-Team/kaidi/releases/download/v1.0.0-preview.9/install.sh \
|
||||
| sudo env KAIDI_REINSTALL=true KAIDI_SETUP_WIZARD=false bash
|
||||
```
|
||||
|
||||
重装失败会恢复原应用链接、Java 运行时、环境文件、systemd 单元和 Nginx 配置;脚本会明确报告回滚不完整,
|
||||
不会把恢复失败吞掉。
|
||||
|
||||
如果安装器已完成但向导尚未提交,可使用同一命令同时设置 `REINSTALL=true` 和 `KAIDI_SETUP_WIZARD=true` 重新生成一次性安装码;
|
||||
该恢复路径只接受仍处于向导模式且未锁定的安装,正式模式不会被覆盖。
|
||||
如果安装器已完成但向导尚未提交,可执行下面的命令重新生成一次性安装码;该恢复路径只接受仍处于向导模式且未锁定的安装,正式模式不会被覆盖。
|
||||
|
||||
```bash
|
||||
curl -fsSL https://git.awaioi.com/ERP-Team/kaidi/releases/download/v1.0.0-preview.9/install.sh \
|
||||
| sudo env KAIDI_REINSTALL=true bash
|
||||
```
|
||||
|
||||
### 停用并移除程序
|
||||
|
||||
@@ -205,8 +173,8 @@ base64 < release-signing-private.pem | tr -d '\n'
|
||||
```
|
||||
|
||||
将私钥的 Base64 内容保存为 Gitea Actions Secret `RELEASE_SIGNING_KEY_B64`,并将命令输出的公钥 SHA-256
|
||||
保存为 Gitea Actions Variable `KAIDI_RELEASE_PUBLIC_KEY_SHA256`。Gitea 内建 `GITEA_TOKEN` 只用于该工作流创建
|
||||
Release;生产服务器使用另一个只读 Token。私钥不得提交到 Git。`.gitea/workflows/release.yml` 要求
|
||||
保存为 Gitea Actions Variable `KAIDI_RELEASE_PUBLIC_KEY_SHA256`。Gitea 发布 Token 只用于该工作流创建
|
||||
Release;生产服务器从公共 Release 下载,不保存 Token。私钥不得提交到 Git。`.gitea/workflows/release.yml` 要求
|
||||
act_runner 提供 `ubuntu-24.04` 标签,并在 tag 发布时执行后端、前端、OpenAPI、Shell、安装/更新和浏览器门禁。
|
||||
|
||||
工作流先建立不可见草稿,再显式上传并核对 9 个资产的名称和大小,最后才发布为 `/releases/latest`。Gitea 的
|
||||
@@ -214,13 +182,13 @@ act_runner 提供 `ubuntu-24.04` 标签,并在 tag 发布时执行后端、前
|
||||
Preview 属性由 SemVer 版本名表达。之后推送 tag 即会构建、测试、签名并发布:
|
||||
|
||||
```bash
|
||||
git tag v1.0.0-preview.8
|
||||
git push origin v1.0.0-preview.8
|
||||
git tag v1.0.0-preview.9
|
||||
git push origin v1.0.0-preview.9
|
||||
```
|
||||
|
||||
在线更新使用独立的 TDesign 页面:隔离的系统管理员进入“系统治理 → 系统更新”。权限与配置页只管理用户、角色、数据范围、表单模板和参数版本,不配置系统名称或域名。
|
||||
更新源由 root 在 `/etc/kaidi/update.env` 固定为私有 Gitea Latest Release API;页面和普通 API 都看不到 Token,
|
||||
也不能提交 URL、脚本或命令。更新流程固定为:
|
||||
更新源由 root 在 `/etc/kaidi/update.env` 固定为公共 Gitea Latest Release API;页面和普通 API 不能提交
|
||||
URL、Token、脚本或命令。更新流程固定为:
|
||||
|
||||
1. 点击“获取更新”,后端先读取 Release 元数据,再自动排队 `DOWNLOAD`;root 更新器从 Gitea 下载 manifest、签名和应用包,执行 RSA、
|
||||
SHA-256、版本、文件名和压缩包路径校验后缓存到 `/var/lib/kaidi-update/cache/<version>`。业务服务不停机。
|
||||
@@ -235,10 +203,9 @@ git push origin v1.0.0-preview.8
|
||||
忙碌期间检查、下载和安装按钮保持禁用,防止重复请求;这就是更新执行冷却。10 秒只用于成功后的页面刷新,
|
||||
不会延迟服务端切换。systemd 在 300 秒内连续失败 3 次后停止自动重试,避免失败任务空跑。
|
||||
|
||||
安装器会把 API 地址和只读 Token 同步写入 root-only 的 `/etc/kaidi/kaidi.env` 与
|
||||
`/etc/kaidi/update.env`,两者权限均为 `0600`:前者供 Java 后端“检查更新”读取,后者供 root 更新器下载资产。
|
||||
轮换 Token 时必须同时更新两个文件,再执行 `sudo systemctl restart kaidi-finance`;Token 不写入页面、状态 JSON、
|
||||
审计参数或更新日志。
|
||||
安装器会把公共 API 地址写入 root-only 的 `/etc/kaidi/kaidi.env` 与 `/etc/kaidi/update.env`,两者权限均为
|
||||
`0600`:前者供 Java 后端“检查更新”读取,后者供 root 更新器下载资产。默认 Token 为空;如改接私有镜像,
|
||||
可由运维人员在这两个文件中配置独立只读 Token,Token 不写入页面、状态 JSON、审计参数或更新日志。
|
||||
|
||||
数据库迁移必须保持至少一个版本的向后兼容。查看状态和日志:
|
||||
|
||||
@@ -267,7 +234,7 @@ cat /var/lib/kaidi-update/status.json
|
||||
```bash
|
||||
KAIDI_RELEASE_SIGNING_KEY=/secure/release-signing-private.pem \
|
||||
KAIDI_TRUSTED_RELEASE_PUBLIC_KEY_SHA256=807c6aec1dc3f7ce494db16aa9d763c66f292033c38f328afd0390d2715a8cd9 \
|
||||
./scripts/package-release.sh 1.0.0-preview.8
|
||||
./scripts/package-release.sh 1.0.0-preview.9
|
||||
KAIDI_TRUSTED_RELEASE_PUBLIC_KEY_SHA256=807c6aec1dc3f7ce494db16aa9d763c66f292033c38f328afd0390d2715a8cd9 \
|
||||
./scripts/verify-release.sh dist/release
|
||||
```
|
||||
|
||||
@@ -14,10 +14,10 @@ FILE_SCANNER_ENABLED=false
|
||||
FINANCE_BOOTSTRAP_ENABLED=false
|
||||
FINANCE_BOOTSTRAP_PASSWORD=
|
||||
|
||||
APP_VERSION=1.0.0-preview.8
|
||||
APP_VERSION=1.0.0-preview.9
|
||||
UPDATE_CURRENT_VERSION_FILE=/opt/kaidi/current/VERSION
|
||||
FINANCE_UPDATE_ENABLED=true
|
||||
# Use either a stable direct asset base URL or the private Gitea latest-release API.
|
||||
# Use either a stable direct asset base URL or the public Gitea latest-release API.
|
||||
UPDATE_RELEASE_BASE_URL=
|
||||
UPDATE_RELEASE_API_URL=https://git.awaioi.com/api/v1/repos/ERP-Team/kaidi/releases/latest
|
||||
UPDATE_RELEASE_TOKEN=READ_ONLY_GITEA_TOKEN
|
||||
|
||||
@@ -5,20 +5,14 @@ umask 077
|
||||
|
||||
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||
INSTALLER="$ROOT/deploy/install.sh"
|
||||
INSTALLER_SHA256=${KAIDI_INSTALLER_SHA256:-33d4921bcad7ef2be12f20bc0512a5f6df4227ea6dd3b7e6225164077d9cd9e7}
|
||||
INSTALLER_SHA256=${KAIDI_INSTALLER_SHA256:-faf52cc902abbc2bd48571caee3f4207de50ce339b82ce88fe23f9c4ce8f89ef}
|
||||
RELEASE_API_URL=${KAIDI_RELEASE_API_URL:-https://git.awaioi.com/api/v1/repos/ERP-Team/kaidi/releases/latest}
|
||||
PUBLIC_KEY_SHA256=${KAIDI_RELEASE_PUBLIC_KEY_SHA256:-807c6aec1dc3f7ce494db16aa9d763c66f292033c38f328afd0390d2715a8cd9}
|
||||
TOKEN_FILE=${KAIDI_RELEASE_TOKEN_FILE:-}
|
||||
TEMP_TOKEN_FILE=
|
||||
|
||||
log() { printf '[kaidi-git-install] %s\n' "$*"; }
|
||||
die() { printf '[kaidi-git-install] ERROR: %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
cleanup() {
|
||||
[ -z "$TEMP_TOKEN_FILE" ] || rm -f "$TEMP_TOKEN_FILE"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
[ -f "$INSTALLER" ] || die "deploy/install.sh is missing; run this command from the Kaidi Git checkout"
|
||||
command -v sha256sum >/dev/null 2>&1 || die "sha256sum is required"
|
||||
[[ "$INSTALLER_SHA256" =~ ^[0-9A-Fa-f]{64}$ ]] || die "The installer SHA-256 is invalid"
|
||||
@@ -29,25 +23,6 @@ normalized_installer_sha256=$(printf '%s' "$INSTALLER_SHA256" | tr '[:upper:]' '
|
||||
[ "$normalized_actual_installer_sha256" = "$normalized_installer_sha256" ] \
|
||||
|| die "deploy/install.sh does not match the trusted SHA-256 for this Git tag"
|
||||
|
||||
if [ -z "$TOKEN_FILE" ]; then
|
||||
TOKEN_FILE=$(mktemp)
|
||||
TEMP_TOKEN_FILE=$TOKEN_FILE
|
||||
chmod 0600 "$TOKEN_FILE"
|
||||
if [ -t 0 ]; then
|
||||
read -rsp 'Gitea read-only token: ' token
|
||||
printf '\n'
|
||||
printf '%s' "$token" > "$TOKEN_FILE"
|
||||
unset token
|
||||
else
|
||||
die "Set KAIDI_RELEASE_TOKEN_FILE or run interactively to enter the Gitea read-only token"
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -f "$TOKEN_FILE" ] && [ ! -L "$TOKEN_FILE" ] || die "The Gitea token file must be a regular file"
|
||||
token_size=$(wc -c < "$TOKEN_FILE" | tr -d '[:space:]')
|
||||
[ "$token_size" -gt 0 ] && [ "$token_size" -le 512 ] || die "The Gitea token file must contain 1 to 512 bytes"
|
||||
LC_ALL=C grep -q '[[:cntrl:]]' "$TOKEN_FILE" && die "The Gitea token file contains invalid control characters"
|
||||
|
||||
root_command=(env)
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
command -v sudo >/dev/null 2>&1 || die "sudo is required when not running as root"
|
||||
@@ -56,10 +31,17 @@ fi
|
||||
|
||||
install_env=(
|
||||
"KAIDI_RELEASE_API_URL=$RELEASE_API_URL"
|
||||
"KAIDI_RELEASE_TOKEN_FILE=$TOKEN_FILE"
|
||||
"KAIDI_RELEASE_PUBLIC_KEY_SHA256=$PUBLIC_KEY_SHA256"
|
||||
)
|
||||
|
||||
if [ -n "$TOKEN_FILE" ]; then
|
||||
[ -f "$TOKEN_FILE" ] && [ ! -L "$TOKEN_FILE" ] || die "The Gitea token file must be a regular file"
|
||||
token_size=$(wc -c < "$TOKEN_FILE" | tr -d '[:space:]')
|
||||
[ "$token_size" -gt 0 ] && [ "$token_size" -le 512 ] || die "The Gitea token file must contain 1 to 512 bytes"
|
||||
LC_ALL=C grep -q '[[:cntrl:]]' "$TOKEN_FILE" && die "The Gitea token file contains invalid control characters"
|
||||
install_env+=("KAIDI_RELEASE_TOKEN_FILE=$TOKEN_FILE")
|
||||
fi
|
||||
|
||||
KAIDI_REINSTALL=${KAIDI_REINSTALL:-}
|
||||
KAIDI_SETUP_WIZARD=${KAIDI_SETUP_WIZARD:-}
|
||||
KAIDI_DB_URL=${KAIDI_DB_URL:-}
|
||||
|
||||
+4
-67
@@ -12,9 +12,9 @@ RELEASE_API_URL=${KAIDI_RELEASE_API_URL:-https://git.awaioi.com/api/v1/repos/ERP
|
||||
RELEASE_TOKEN=${KAIDI_RELEASE_TOKEN:-}
|
||||
RELEASE_TOKEN_FILE=${KAIDI_RELEASE_TOKEN_FILE:-}
|
||||
HEALTH_URL=${KAIDI_HEALTH_URL:-http://127.0.0.1:18080/actuator/health}
|
||||
TRUSTED_PUBLIC_KEY_SHA256=${KAIDI_RELEASE_PUBLIC_KEY_SHA256:-}
|
||||
TRUSTED_PUBLIC_KEY_SHA256=${KAIDI_RELEASE_PUBLIC_KEY_SHA256:-807c6aec1dc3f7ce494db16aa9d763c66f292033c38f328afd0390d2715a8cd9}
|
||||
REINSTALL=${KAIDI_REINSTALL:-false}
|
||||
SETUP_WIZARD=${KAIDI_SETUP_WIZARD:-false}
|
||||
SETUP_WIZARD=${KAIDI_SETUP_WIZARD:-true}
|
||||
WORK_DIR=
|
||||
RELEASE_AUTH_HEADER_FILE=
|
||||
INSTALL_TRANSACTION_ARMED=false
|
||||
@@ -24,8 +24,6 @@ BACKUP_DIR=
|
||||
JAVA_STAGED_DIR=
|
||||
JAVA_PREVIOUS_DIR=
|
||||
JAVA_ACTIVATED=false
|
||||
CREATED_DB_CONTAINER=false
|
||||
CREATED_DB_VOLUME=false
|
||||
|
||||
log() { printf '[kaidi-install] %s\n' "$*"; }
|
||||
die() { printf '[kaidi-install] ERROR: %s\n' "$*" >&2; exit 1; }
|
||||
@@ -160,18 +158,6 @@ install_packages() {
|
||||
fi
|
||||
}
|
||||
|
||||
install_docker() {
|
||||
command -v docker >/dev/null 2>&1 && return
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
apt-get install -y -qq docker.io
|
||||
elif command -v dnf >/dev/null 2>&1; then
|
||||
dnf install -y docker
|
||||
else
|
||||
yum install -y docker
|
||||
fi
|
||||
systemctl enable --now docker
|
||||
}
|
||||
|
||||
azul_arch() {
|
||||
case "$(uname -m)" in
|
||||
x86_64|amd64) printf x86 ;;
|
||||
@@ -312,48 +298,7 @@ configure_database() {
|
||||
fi
|
||||
[ "$REINSTALL" != true ] \
|
||||
|| die "KAIDI_REINSTALL needs database credentials in the existing installation or command environment"
|
||||
case "$(uname -m)" in
|
||||
i386|i486|i586|i686)
|
||||
die "32-bit Linux needs an external MySQL 8.4 database; set KAIDI_DB_URL, KAIDI_DB_USERNAME, and KAIDI_DB_PASSWORD"
|
||||
;;
|
||||
esac
|
||||
install_docker
|
||||
DB_USERNAME=kaidi
|
||||
DB_PASSWORD=$(random_secret)
|
||||
DB_ROOT_PASSWORD=$(random_secret)
|
||||
! docker inspect kaidi-finance-mysql >/dev/null 2>&1 \
|
||||
|| die "Docker container kaidi-finance-mysql already exists; provide explicit database parameters"
|
||||
! docker volume inspect kaidi_mysql_data >/dev/null 2>&1 \
|
||||
|| die "Docker volume kaidi_mysql_data already exists; provide explicit database parameters"
|
||||
docker volume create kaidi_mysql_data >/dev/null
|
||||
CREATED_DB_VOLUME=true
|
||||
docker run -d \
|
||||
--name kaidi-finance-mysql \
|
||||
--restart unless-stopped \
|
||||
-e MYSQL_DATABASE=kaidi_finance \
|
||||
-e MYSQL_USER="$DB_USERNAME" \
|
||||
-e MYSQL_PASSWORD="$DB_PASSWORD" \
|
||||
-e MYSQL_ROOT_PASSWORD="$DB_ROOT_PASSWORD" \
|
||||
-e TZ=Asia/Shanghai \
|
||||
-p 127.0.0.1:3307:3306 \
|
||||
-v kaidi_mysql_data:/var/lib/mysql \
|
||||
--health-cmd='mysqladmin ping -h localhost -uroot -p$MYSQL_ROOT_PASSWORD --silent' \
|
||||
--health-interval=5s --health-timeout=5s --health-retries=30 \
|
||||
mysql:8.4 \
|
||||
--character-set-server=utf8mb4 \
|
||||
--collation-server=utf8mb4_0900_ai_ci \
|
||||
--default-time-zone=+00:00 >/dev/null
|
||||
CREATED_DB_CONTAINER=true
|
||||
local attempts=0 health
|
||||
while [ "$attempts" -lt 60 ]; do
|
||||
health=$(docker inspect --format '{{.State.Health.Status}}' kaidi-finance-mysql 2>/dev/null || true)
|
||||
[ "$health" = healthy ] && break
|
||||
[ "$health" = unhealthy ] && die "MySQL container failed its health check"
|
||||
attempts=$((attempts + 1))
|
||||
sleep 2
|
||||
done
|
||||
[ "$health" = healthy ] || die "MySQL did not become ready"
|
||||
DB_URL='jdbc:mysql://127.0.0.1:3307/kaidi_finance?useUnicode=true&characterEncoding=utf8&connectionTimeZone=UTC&serverTimezone=UTC'
|
||||
die "An external MySQL 8.4 database is required; set KAIDI_DB_URL, KAIDI_DB_USERNAME, and KAIDI_DB_PASSWORD"
|
||||
}
|
||||
|
||||
database_host() {
|
||||
@@ -599,14 +544,6 @@ cleanup() {
|
||||
&& [ "$INSTALL_COMMITTED" != true ]; then
|
||||
rollback_install || log "ERROR: rollback was incomplete; inspect systemd and Nginx state"
|
||||
fi
|
||||
if [ "$result" -ne 0 ] && [ "$INSTALL_COMMITTED" != true ] \
|
||||
&& [ "$CREATED_DB_CONTAINER" = true ]; then
|
||||
docker rm -f kaidi-finance-mysql >/dev/null 2>&1 || true
|
||||
fi
|
||||
if [ "$result" -ne 0 ] && [ "$INSTALL_COMMITTED" != true ] \
|
||||
&& [ "$CREATED_DB_VOLUME" = true ]; then
|
||||
docker volume rm kaidi_mysql_data >/dev/null 2>&1 || true
|
||||
fi
|
||||
[ -z "$WORK_DIR" ] || rm -rf "$WORK_DIR"
|
||||
exit "$result"
|
||||
}
|
||||
@@ -755,7 +692,7 @@ write_env_file "$CONFIG_ROOT/update.env" \
|
||||
KAIDI_UPDATE_STATE_ROOT "$UPDATE_STATE_ROOT" \
|
||||
KAIDI_SERVICE_NAME kaidi-finance.service \
|
||||
KAIDI_HEALTH_URL "$HEALTH_URL" \
|
||||
KAIDI_DB_CONTAINER "${KAIDI_DB_CONTAINER:-kaidi-finance-mysql}" \
|
||||
KAIDI_DB_CONTAINER "${KAIDI_DB_CONTAINER:-}" \
|
||||
KAIDI_DB_HOST "$(database_host)" \
|
||||
KAIDI_DB_PORT "$(database_port)" \
|
||||
KAIDI_DB_NAME "$(database_name)" \
|
||||
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
# 财务项目基础系统开发交付总方案
|
||||
|
||||
> 文档编号:KD-FIN-DELIVERY-001<br>
|
||||
> 版本:V3.25(Preview.8 首次安装向导与部署收口)<br>
|
||||
> 版本:V3.26(Preview.9 公共 Release 一键安装)<br>
|
||||
> 状态:第一版 Preview 候选包已具备 22 页功能框架、核心业务链和可部署制品;PAGE-13/14 已通过模块验收,PAGE-12/16/17/18/19/20/21/22 为 `IMPLEMENTED_PENDING_ACCEPTANCE`,PAGE-15 正式业务矩阵仍为 `IN_PROGRESS`;整套 R1 尚未达到第 12.9 节 Definition of Done,不得把 Preview 上线等同于甲方最终验收<br>
|
||||
> 编制依据:2026-08-05 腾讯会议转写、14 张 OA 表单、财务岗位职责资料、项目管理流程图<br>
|
||||
> 最新项目决策:按既定 Java/TDesign 技术栈交付第一版 Preview;2026-08-17 已完成 PAGE-08 来源、记账、档案双向穿透,PAGE-20 审计稳定排序/筛选/脱敏导出、PAGE-21 权限与配置、PAGE-22 私有 Gitea 签名在线更新、OA-04/OA-06 动态附件矩阵、OA-06 财务终审付款投影、Release/SBOM/依赖门禁、Linux i386/i486/i586/i686 外部 MySQL 8.4.x 单命令安装、更新请求持久领取/中断恢复/数据库备份校验/回滚健康复核,以及隔离超级管理员全部功能权限和全局数据范围;本轮新增 PAGE-23 首次安装向导、无业务数据库启动上下文、MySQL 8.4 DDL/DML 预检、一次性安装码和安装状态锁定,数据库基线新增 `V072`。远端仓库已固定为 `https://git.awaioi.com/ERP-Team/kaidi.git`;配置 Gitea Actions 签名 Secret、公钥指纹 Variable、可用 runner 和生产只读 Token 后,推送符合 SemVer 的 `v*` tag 即生成 Release;PAGE-15 完整业务矩阵继续保持 `DRAFT`,须经 D-02/D-09 确认后才允许作为正式规则发布<br>
|
||||
> 最新项目决策:按既定 Java/TDesign 技术栈交付第一版 Preview;2026-08-17 已完成 PAGE-08 来源、记账、档案双向穿透,PAGE-20 审计稳定排序/筛选/脱敏导出、PAGE-21 权限与配置、PAGE-22 公共 Gitea 签名在线更新、OA-04/OA-06 动态附件矩阵、OA-06 财务终审付款投影、Release/SBOM/依赖门禁、Linux i386/i486/i586/i686 外部 MySQL 8.4.x 单命令安装、更新请求持久领取/中断恢复/数据库备份校验/回滚健康复核,以及隔离超级管理员全部功能权限和全局数据范围;本轮新增 PAGE-23 首次安装向导、无业务数据库启动上下文、MySQL 8.4 DDL/DML 预检、一次性安装码和安装状态锁定,数据库基线新增 `V072`。远端仓库 `https://git.awaioi.com/ERP-Team/kaidi.git` 与 Release 均已公开;安装和在线更新默认不使用 Token,安装器内置发布公钥指纹,推送符合 SemVer 的 `v*` tag 后由带签名密钥的发布流程生成 Release;PAGE-15 完整业务矩阵继续保持 `DRAFT`,须经 D-02/D-09 确认后才允许作为正式规则发布<br>
|
||||
> 实际开发技术:Java 17 + Spring Boot 3.5.16 + MyBatis 3.0.5 + MySQL 8.4 + TDesign Vue Next Starter;前端仍只允许在现有 `frontend/` Starter 中原位增加菜单、页面、组件和真实功能
|
||||
> 文档性质:本项目唯一 PRD、SPEC、开发任务书、测试验收与交付基线<br>
|
||||
> 文档用途:甲方需求确认、产品设计、开发拆分、测试验收和交付培训<br>
|
||||
@@ -72,14 +72,14 @@
|
||||
| 超级管理员权限 | V071 将 `SYSTEM_ADMIN` 固定为隔离超级管理员,逐条授予全部 `iam_permission` 和无额度 `GLOBAL` scope,并由启动同步补齐后续权限;前端菜单、直链和按钮统一放行全部 PAGE-04~21。管理员可管理跨人员表单/导入/付款草稿,PAGE-15 增加仅管理员可见的“全部付款”,三类业务工作台显示跨人员项目、资金、档案和全部待办;审批实际处理人、SOD、状态机、资金、附件安全和审计继续强制执行 |
|
||||
| OA-06 付款投影 | V070 发布 OA-06 v2,新增生效合同、供应商和已确认应付稳定引用;财务终审在来源审批事务内生成 `OFFLINE_PENDING` 付款,执行付款检查、冻结项目资金并追加资金流水。余额不足等投影失败时来源状态、审批任务、付款、资金控制和流水整体回滚;不产生银行付款指令,不接网银、U 盾或第三方平台 |
|
||||
| OA 动态附件矩阵 | OA-04/OA-06 的条件附件行支持 TDesign 布尔开关、长文本、不涉及原因和嵌套文件上传;仅 `required=true` 的行要求文件或原因,可选空行不阻断。上传状态按字段和表格单元隔离,上传期间锁定刷新、保存、校验和提交;更新请求不再携带创建专用字段,校验前自动保存当前草稿 |
|
||||
| 本轮运行验收 | 最近完整后端 MySQL 8.4/Testcontainers 基线 `213/213`,Failures/Errors/Skipped 均为 0,迁移基线扩展至 `V072`;本轮新增 setup context smoke、安装器/包装器夹具和 PAGE-23 Playwright 回归;最新签名候选为 `1.0.0-preview.8`,正式 Release 仍须在干净 Git tag 上由 Gitea Actions 重新生成安装器摘要 |
|
||||
| 本轮运行验收 | 最近完整后端 MySQL 8.4/Testcontainers 基线 `213/213`,Failures/Errors/Skipped 均为 0,迁移基线扩展至 `V072`;本轮新增 setup context smoke、安装器/包装器夹具和 PAGE-23 Playwright 回归;`1.0.0-preview.8` 已发布 9 个验签资产,Preview.9 进一步将公共仓库安装入口精简为单行 `curl | sudo bash` |
|
||||
| 第一版 Preview | PAGE-01~22 页面和菜单框架齐备,真实前后端核心链保持可用;Preview 上线与整套 R1 最终验收分开计量 |
|
||||
| 来源表格校验 | V068 为 14 类 OA 的 33 个 TABLE 字段补齐嵌套类型、必填和文件引用规则;V069 保留 OA-02 v1 历史账户表格契约,避免 v2 字段追溯污染 |
|
||||
| PAGE-20 审计 | 增加不可变事件序号、四种稳定排序、URL 查询状态、同排序 CSV 导出、脱敏详情及 OpenAPI `422` 参数门禁 |
|
||||
| PAGE-22 在线更新 | 更新源固定为私有 Gitea Latest Release API;系统管理员点击“获取更新”后自动检查并下载,验签缓存进入 `READY` 后显示“立即重启”。安装健康检查成功后页面从 10 秒倒计时自动刷新;刷新或短暂断线发生在安装中时恢复轮询。后台只写固定结构请求,由 root oneshot 服务验签、验哈希、备份、切换和回滚,不接受页面传入地址、Token 或命令 |
|
||||
| PAGE-22 在线更新 | 更新源固定为公共 Gitea Latest Release API,默认不使用 Token;系统管理员点击“获取更新”后自动检查并下载,验签缓存进入 `READY` 后显示“立即重启”。安装健康检查成功后页面从 10 秒倒计时自动刷新;刷新或短暂断线发生在安装中时恢复轮询。后台只写固定结构请求,由 root oneshot 服务验签、验哈希、备份、切换和回滚,不接受页面传入地址、Token 或命令 |
|
||||
| Release 工程 | `.gitea/workflows/release.yml` 监听严格 SemVer `v*` tag;Maven `revision`、npm、JAR、前后端 SBOM、签名 manifest 与 tag 必须同版本。工作流执行 Java/前端/OpenAPI/Playwright/依赖审计,使用至少 3072 位 RSA 密钥生成并独立验收恰好 9 个资产;先创建不可见草稿、逐项上传并核对名称/大小,最后发布为可被 `/releases/latest` 读取的正式 Release |
|
||||
| Linux 32 位 | i386/i486/i586/i686 下载 Java 17 i686 JRE;JRE 元数据和归档均使用仅允许 HTTPS/TLS 1.2 及以上的受限下载器;由于 MySQL 8.4 无对应服务端镜像,要求预置外部 MySQL 8.4.x,curl 安装只开启 `/setup` 向导,数据库密码在浏览器中提交并完成连接、版本及 DDL/DML 预检 |
|
||||
| 更新可靠性 | 下载和安装拆为两个持久动作;下载阶段不停止业务服务,安装阶段只接受同版本 `READY` 缓存并重新验签。私有 Gitea Token 仅从权限为 `0600` 的 root 配置/临时文件读取,不进入 `curl` 参数、页面、状态或日志,且只允许同源 API/资产使用;请求原子领取到持久 `processing`,systemd 限制失败重试;`mysqldump`、新旧版本健康和回滚均有独立门禁,私有 Gitea、跨来源拒绝、成功、健康回滚、下载失败、备份失败和不安全请求夹具纳入 CI |
|
||||
| 更新可靠性 | 下载和安装拆为两个持久动作;下载阶段不停止业务服务,安装阶段只接受同版本 `READY` 缓存并重新验签。公共 Gitea 默认不使用 Token;如改接私有镜像,Token 仅从权限为 `0600` 的 root 配置/临时文件读取,不进入 `curl` 参数、页面、状态或日志,且只允许同源 API/资产使用;请求原子领取到持久 `processing`,systemd 限制失败重试;`mysqldump`、新旧版本健康和回滚均有独立门禁,跨来源拒绝、成功、健康回滚、下载失败、备份失败和不安全请求夹具纳入 CI |
|
||||
| 阶段口径 | 把“开发前冻结”更新为“R1 开发中”;明确模块级验收与整套 R1 交付是两个层级,避免一页完成后虚报整套系统完成 |
|
||||
| PAGE-13 页面 | 完成合同执行汇总、筛选、服务端分页、来源下钻、CSV 导出、合同详情及变更/结算/应付操作;页面仅使用现有 TDesign Starter 和 TDesign 组件 |
|
||||
| PAGE-13 后端 | 新增 `contractcost:payable:create`,项目经理可登记但不可确认;同人登记/确认返回 `422 SOD_VIOLATION`;应付必须关联已批准 OA-04,结算必须关联已批准 OA-11,同一来源不得重复消费 |
|
||||
@@ -1006,7 +1006,7 @@ PAGE-21 只向超级管理员开放。超级管理员账号不得混授普通业
|
||||
|
||||
更新固定分两阶段。管理员点击“获取更新”后,前端先检查最新版本,再自动提交 `DOWNLOAD` 请求;root oneshot 从固定 Gitea Latest Release API 下载 manifest、签名和应用包,验签/验哈希后写入 root-only 版本缓存并进入 `READY`,期间当前业务版本继续运行。进入 `READY` 后页面显示“立即重启”,点击后只允许安装同版本缓存,并在切换前重新验证。健康检查成功后页面显示 10 秒倒计时并自动刷新;若页面在 `INSTALL_QUEUED/BACKING_UP/INSTALLING/RUNNING` 时刷新或短暂断线,重新进入后自动恢复 3 秒轮询。失败时保留明确状态并恢复已验证的上一版本。
|
||||
|
||||
页面只提交目标版本和原因,不接收下载地址、Token、脚本或任意命令。Gitea 只读 Token 仅存在于权限为 `0600` 的 root 环境文件和临时 Header 文件,不进入进程参数、DTO、状态 JSON、审计参数或页面响应;API 和资产必须同 scheme、host、port,认证请求不跟随跨来源重定向。文件锁和 inbox/processing 双路径防止并发覆盖,独立 root oneshot 执行 RSA/SHA-256 校验、可验证数据库备份、持久事务、应用与运维文件原子切换、新旧版本健康检查和失败回滚。
|
||||
页面只提交目标版本和原因,不接收下载地址、Token、脚本或任意命令。公共 Gitea 默认不配置 Token;如改接私有镜像,只读 Token 仅存在于权限为 `0600` 的 root 环境文件和临时 Header 文件,不进入进程参数、DTO、状态 JSON、审计参数或页面响应;API 和资产必须同 scheme、host、port,认证请求不跟随跨来源重定向。文件锁和 inbox/processing 双路径防止并发覆盖,独立 root oneshot 执行 RSA/SHA-256 校验、可验证数据库备份、持久事务、应用与运维文件原子切换、新旧版本健康检查和失败回滚。
|
||||
|
||||
### 8.23 页面通用要求
|
||||
|
||||
|
||||
@@ -30,7 +30,11 @@ else
|
||||
[ "$KAIDI_DB_USERNAME" = 'kaidi' ]
|
||||
[ "$KAIDI_DB_PASSWORD" = 'fixture-password' ]
|
||||
fi
|
||||
if [ "${EXPECT_TOKEN:-false}" = true ]; then
|
||||
[ "$(cat "$KAIDI_RELEASE_TOKEN_FILE")" = 'fixture-read-token' ]
|
||||
else
|
||||
[ -z "${KAIDI_RELEASE_TOKEN_FILE:-}" ]
|
||||
fi
|
||||
printf 'fixture-installer: PASS\n'
|
||||
SH
|
||||
|
||||
@@ -40,7 +44,6 @@ chmod 0600 "$FIXTURE/token"
|
||||
installer_sha256=$(sha256sum "$FIXTURE/repo/deploy/install.sh" | awk '{print $1}')
|
||||
|
||||
PATH="$FIXTURE/bin:$PATH" \
|
||||
KAIDI_RELEASE_TOKEN_FILE="$FIXTURE/token" \
|
||||
KAIDI_INSTALLER_SHA256="$installer_sha256" \
|
||||
KAIDI_RELEASE_API_URL=https://git.example.test/api/v1/repos/TEAM/REPO/releases/latest \
|
||||
KAIDI_RELEASE_PUBLIC_KEY_SHA256=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
|
||||
@@ -50,6 +53,14 @@ KAIDI_DB_PASSWORD=fixture-password \
|
||||
"$FIXTURE/repo/deploy/install-from-git.sh"
|
||||
|
||||
PATH="$FIXTURE/bin:$PATH" \
|
||||
KAIDI_INSTALLER_SHA256="$installer_sha256" \
|
||||
KAIDI_RELEASE_API_URL=https://git.example.test/api/v1/repos/TEAM/REPO/releases/latest \
|
||||
KAIDI_RELEASE_PUBLIC_KEY_SHA256=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
|
||||
KAIDI_SETUP_WIZARD=true \
|
||||
"$FIXTURE/repo/deploy/install-from-git.sh"
|
||||
|
||||
PATH="$FIXTURE/bin:$PATH" \
|
||||
EXPECT_TOKEN=true \
|
||||
KAIDI_RELEASE_TOKEN_FILE="$FIXTURE/token" \
|
||||
KAIDI_INSTALLER_SHA256="$installer_sha256" \
|
||||
KAIDI_RELEASE_API_URL=https://git.example.test/api/v1/repos/TEAM/REPO/releases/latest \
|
||||
@@ -58,7 +69,6 @@ KAIDI_SETUP_WIZARD=true \
|
||||
"$FIXTURE/repo/deploy/install-from-git.sh"
|
||||
|
||||
if PATH="$FIXTURE/bin:$PATH" \
|
||||
KAIDI_RELEASE_TOKEN_FILE="$FIXTURE/token" \
|
||||
KAIDI_INSTALLER_SHA256=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \
|
||||
"$FIXTURE/repo/deploy/install-from-git.sh" > "$FIXTURE/hash-mismatch.log" 2>&1; then
|
||||
printf 'Mismatched installer SHA-256 was accepted\n' >&2
|
||||
|
||||
@@ -199,7 +199,19 @@ grep -Fq 'java_sha256=$(jq -er' "$ROOT/deploy/install.sh" \
|
||||
grep -Fq '[ "$actual_sha256" = "$java_sha256" ]' "$ROOT/deploy/install.sh" \
|
||||
|| fail 'installer no longer verifies the Java runtime SHA-256'
|
||||
grep -Fq 'https://git.awaioi.com/api/v1/repos/ERP-Team/kaidi/releases/latest' "$ROOT/deploy/install.sh" \
|
||||
|| fail 'installer default release source is not the private Gitea latest API'
|
||||
|| fail 'installer default release source is not the public Gitea latest API'
|
||||
# shellcheck disable=SC2016 # Match literal installer source.
|
||||
grep -Fq 'TRUSTED_PUBLIC_KEY_SHA256=${KAIDI_RELEASE_PUBLIC_KEY_SHA256:-807c6aec1dc3f7ce494db16aa9d763c66f292033c38f328afd0390d2715a8cd9}' "$ROOT/deploy/install.sh" \
|
||||
|| fail 'installer does not pin the default release public-key fingerprint'
|
||||
# shellcheck disable=SC2016 # Match literal installer source.
|
||||
grep -Fq 'SETUP_WIZARD=${KAIDI_SETUP_WIZARD:-true}' "$ROOT/deploy/install.sh" \
|
||||
|| fail 'installer does not enable the first-run setup wizard by default'
|
||||
! grep -Fq 'docker run' "$ROOT/deploy/install.sh" \
|
||||
|| fail 'installer must not create a MySQL container'
|
||||
! grep -Fq 'install_docker' "$ROOT/deploy/install.sh" \
|
||||
|| fail 'installer must not install Docker or MySQL automatically'
|
||||
grep -Fq 'An external MySQL 8.4 database is required' "$ROOT/deploy/install.sh" \
|
||||
|| fail 'installer does not require an operator-managed external MySQL database'
|
||||
grep -Fq 'KAIDI_RELEASE_TOKEN_FILE' "$ROOT/deploy/install.sh" \
|
||||
|| fail 'installer no longer supports a protected initial Gitea token file'
|
||||
grep -Fq 'KAIDI_SETUP_WIZARD' "$ROOT/deploy/install.sh" \
|
||||
@@ -215,7 +227,7 @@ grep -Fq 'EnvironmentFile=-/var/lib/kaidi/setup/application.env' \
|
||||
# shellcheck disable=SC2016 # Match the literal installer source.
|
||||
grep -Fq 'chown root:kaidi "$UPDATE_STATE_ROOT"' "$ROOT/deploy/install.sh" \
|
||||
|| fail 'update state parent is not group-accessible to the application user'
|
||||
grep -Fq 'KAIDI_SETUP_WIZARD=true' "$ROOT/README.md" \
|
||||
|| fail 'README does not document the setup-wizard install path'
|
||||
grep -Fq 'install.sh | sudo bash' "$ROOT/README.md" \
|
||||
|| fail 'README does not document the public one-line setup-wizard install path'
|
||||
|
||||
printf 'Install configuration, private Gitea, i686, setup wizard, and MySQL 8.4 fixtures passed\n'
|
||||
printf 'Install configuration, public Gitea, optional private token, i686, setup wizard, and MySQL 8.4 fixtures passed\n'
|
||||
|
||||
Reference in New Issue
Block a user