Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0d967e899a | |||
| 0a21ea5b2a | |||
| 9b6dba4c2b | |||
| 54451f0e52 | |||
| 8fc24b5d36 | |||
| 6ac6b52717 |
@@ -1,152 +0,0 @@
|
||||
---
|
||||
name: archive-design
|
||||
description: 将已确认上线的 Figma 设计稿存档到 docs/design/archive/。接收 Figma 文件链接,通过 Figma MCP 读取设计内容,自动整理并写入存档文档。在设计确认、功能上线后调用。
|
||||
allowed-tools: Read, Write, Glob, Grep
|
||||
user-invocable: true
|
||||
argument-hint: <figma-url> <功能名称> [版本号,默认v1]
|
||||
---
|
||||
|
||||
# 设计存档工作流
|
||||
|
||||
你正在执行 `/archive-design` 命令,将已确认的 Figma 设计存档。
|
||||
|
||||
## 参数解析
|
||||
|
||||
```
|
||||
$ARGUMENTS 格式:<figma-url> <功能名称> [版本]
|
||||
示例:https://figma.com/file/xxx 入库单 v1
|
||||
```
|
||||
|
||||
从 `$ARGUMENTS` 中提取:
|
||||
- `FIGMA_URL`:Figma 文件链接
|
||||
- `FEATURE_NAME`:功能名称(用于目录和文件命名)
|
||||
- `VERSION`:版本号,未提供则默认 `v1`
|
||||
|
||||
## 执行步骤
|
||||
|
||||
### Step 1:读取 Figma 文件
|
||||
|
||||
使用 Figma MCP 工具读取设计文件内容:
|
||||
- 获取所有页面列表
|
||||
- 获取主要页面的组件结构
|
||||
- 获取设计 Token(颜色、文字样式、间距)
|
||||
- 获取组件列表和说明
|
||||
|
||||
如果 Figma MCP 不可用,跳过此步骤,仅记录链接和手动填写的信息。
|
||||
|
||||
### Step 2:读取已有需求和架构文档
|
||||
|
||||
读取以下文件,补充存档上下文:
|
||||
- `docs/requirements/{功能名称}.md`(如存在)
|
||||
- `docs/api/{功能名称}.md`(如存在)
|
||||
- `docs/design/{功能名称}-design-brief.md`(如存在)
|
||||
|
||||
### Step 3:写入存档文档
|
||||
|
||||
创建 `docs/design/archive/{功能名称}/{版本}/design-archive.md`:
|
||||
|
||||
```markdown
|
||||
# {功能名称} — 设计存档 {版本}
|
||||
|
||||
**存档时间**:{当前日期}
|
||||
**Figma 文件**:{FIGMA_URL}
|
||||
**状态**:✅ 已确认上线
|
||||
|
||||
---
|
||||
|
||||
## 设计概览
|
||||
|
||||
### 页面清单
|
||||
|
||||
| 页面名称 | Figma 画板 | 说明 |
|
||||
|---------|-----------|------|
|
||||
| (从 Figma 读取或手动填写)|
|
||||
|
||||
### 核心设计决策
|
||||
|
||||
(从 docs/design/{功能名称}-design-brief.md 中提取设计目标和关键决策)
|
||||
|
||||
---
|
||||
|
||||
## 设计规范
|
||||
|
||||
### 颜色使用
|
||||
|
||||
```yaml
|
||||
(从 Figma 读取,或按项目基础规范填写)
|
||||
主色: #1565C0 用于:顶栏、主按钮、链接
|
||||
成功色: #2E7D32 用于:已审核状态标签
|
||||
危险色: #C62828 用于:删除操作、库存不足警告
|
||||
```
|
||||
|
||||
### 组件清单
|
||||
|
||||
```yaml
|
||||
(列出本功能使用的主要组件)
|
||||
复用现有组件:
|
||||
- AppDataTable:通用数据表格
|
||||
- StatusBadge:状态标签
|
||||
- FormDialog:弹窗表单
|
||||
|
||||
新增组件:
|
||||
- (从 Figma 读取或手动填写)
|
||||
```
|
||||
|
||||
### 关键尺寸
|
||||
|
||||
```yaml
|
||||
(从 Figma 读取,或手动填写关键布局尺寸)
|
||||
弹窗宽度: 720px
|
||||
表格行高: 48px
|
||||
工具栏高: 52px
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 交互说明
|
||||
|
||||
(描述关键交互逻辑,如状态流转、操作确认弹窗等)
|
||||
|
||||
---
|
||||
|
||||
## 与需求的对应关系
|
||||
|
||||
| 用户故事 | 设计实现 |
|
||||
|---------|---------|
|
||||
| (从需求文档提取,对应到具体设计页面)|
|
||||
|
||||
---
|
||||
|
||||
## 历史版本
|
||||
|
||||
| 版本 | 时间 | 变更说明 |
|
||||
|------|------|---------|
|
||||
| {版本} | {当前日期} | 初始版本 |
|
||||
```
|
||||
|
||||
### Step 4:更新设计索引
|
||||
|
||||
在 `docs/design/archive/INDEX.md` 中追加一行记录(如文件不存在则创建):
|
||||
|
||||
```markdown
|
||||
# 设计存档索引
|
||||
|
||||
| 功能 | 版本 | 存档时间 | Figma 链接 | 存档文档 |
|
||||
|------|------|---------|-----------|---------|
|
||||
| {功能名称} | {版本} | {日期} | [查看]({FIGMA_URL}) | [文档](/{功能名称}/{版本}/design-archive.md) |
|
||||
```
|
||||
|
||||
### Step 5:完成提示
|
||||
|
||||
输出:
|
||||
```
|
||||
✅ 设计存档完成
|
||||
|
||||
📁 存档路径:docs/design/archive/{功能名称}/{版本}/design-archive.md
|
||||
🔗 Figma 链接:{FIGMA_URL}
|
||||
📋 索引已更新:docs/design/archive/INDEX.md
|
||||
|
||||
下一步建议:
|
||||
- 运行 /design-review 对比实现与设计稿的差异
|
||||
- 提交存档文件到 git:git add docs/design/archive/
|
||||
```
|
||||
@@ -1,127 +0,0 @@
|
||||
---
|
||||
name: design-review
|
||||
description: 对比 Figma 设计稿与 Flutter 实现代码,输出还原度差异报告。在 flutter-coder 实现完成后、上线前调用,确保实现与设计一致。
|
||||
allowed-tools: Read, Write, Glob, Grep
|
||||
user-invocable: true
|
||||
argument-hint: <figma-url> <功能名称>
|
||||
---
|
||||
|
||||
# 设计还原度检查工作流
|
||||
|
||||
你正在执行 `/design-review` 命令,对比 Figma 设计稿与 Flutter 实现的差异。
|
||||
|
||||
## 参数解析
|
||||
|
||||
```
|
||||
$ARGUMENTS 格式:<figma-url> <功能名称>
|
||||
示例:https://figma.com/file/xxx 入库单
|
||||
```
|
||||
|
||||
## 执行步骤
|
||||
|
||||
### Step 1:读取 Figma 设计规范
|
||||
|
||||
使用 Figma MCP 读取:
|
||||
- 各页面的组件结构和层级
|
||||
- 颜色值(精确到 hex)
|
||||
- 字体大小、字重
|
||||
- 间距数值(padding、margin、gap)
|
||||
- 组件状态(hover、disabled、selected 等)
|
||||
|
||||
如果 Figma MCP 不可用,读取 `docs/design/{功能名称}-design-brief.md` 中的设计规范作为对照基准。
|
||||
|
||||
### Step 2:读取 Flutter 实现代码
|
||||
|
||||
查找并读取相关实现文件:
|
||||
|
||||
```
|
||||
client/lib/screens/ → 找到功能名称相关的 screen 文件
|
||||
client/lib/widgets/ → 找到使用的组件文件
|
||||
client/lib/models/ → 数据模型
|
||||
```
|
||||
|
||||
重点检查:
|
||||
- 颜色是否使用了正确的 hex 值或 Theme 变量
|
||||
- 字体大小、字重是否与设计一致
|
||||
- 间距(padding/margin)数值是否匹配
|
||||
- 组件状态样式是否完整实现
|
||||
- 布局结构是否与设计稿一致
|
||||
|
||||
### Step 3:生成差异报告
|
||||
|
||||
写入 `docs/review/{功能名称}-design-review.md`:
|
||||
|
||||
```markdown
|
||||
# {功能名称} — 设计还原度报告
|
||||
|
||||
**检查时间**:{当前日期}
|
||||
**Figma 设计稿**:{FIGMA_URL}
|
||||
**检查范围**:{列出检查的 Flutter 文件}
|
||||
|
||||
---
|
||||
|
||||
## 总体评分
|
||||
|
||||
还原度:**X / 10**
|
||||
(10分=完全一致,8分=细节有出入,6分=布局基本对但样式差异明显)
|
||||
|
||||
---
|
||||
|
||||
## 必须修复(影响视觉一致性)
|
||||
|
||||
### [DR-001] 颜色不一致
|
||||
**页面**:入库单列表 — 状态标签
|
||||
**设计稿**:已审核状态背景色 `#E8F5E9`,文字 `#2E7D32`
|
||||
**实现**:背景色 `Colors.green.shade100`(实际值 `#DCEDC8`,偏浅)
|
||||
**文件**:`client/lib/widgets/status_badge.dart:34`
|
||||
**修复**:改为 `Color(0xFFE8F5E9)`
|
||||
|
||||
### [DR-002] 间距不一致
|
||||
**页面**:新建入库单弹窗
|
||||
**设计稿**:表单字段间距 16px
|
||||
**实现**:`SizedBox(height: 12)` — 差了 4px
|
||||
**文件**:`client/lib/screens/stock_in/stock_in_form.dart:67`
|
||||
**修复**:改为 `SizedBox(height: 16)`
|
||||
|
||||
---
|
||||
|
||||
## 建议调整(不影响主要功能,但影响精细度)
|
||||
|
||||
### [DR-003] 字体字重
|
||||
**页面**:表格标题行
|
||||
**设计稿**:`FontWeight.w600`
|
||||
**实现**:`FontWeight.bold`(实际是 w700,略粗)
|
||||
**建议**:统一改为 `FontWeight.w600`
|
||||
|
||||
---
|
||||
|
||||
## 通过检查项
|
||||
|
||||
- ✅ 整体布局结构与设计稿一致
|
||||
- ✅ 主色 #1565C0 使用正确
|
||||
- ✅ 顶栏高度 56px 正确
|
||||
- ✅ 侧边栏宽度 200px 正确
|
||||
- ✅ 状态流转交互与设计一致
|
||||
|
||||
---
|
||||
|
||||
## 修复建议
|
||||
|
||||
优先处理 DR-001、DR-002(颜色和间距是最直观的差异)。
|
||||
修复后可再次运行 `/design-review` 验证。
|
||||
```
|
||||
|
||||
### Step 4:完成提示
|
||||
|
||||
输出:
|
||||
```
|
||||
✅ 设计还原度检查完成
|
||||
|
||||
📋 报告路径:docs/review/{功能名称}-design-review.md
|
||||
🔍 发现问题:必须修复 X 项,建议调整 Y 项
|
||||
|
||||
后续步骤:
|
||||
1. 将报告发给 flutter-coder 修复(必须修复项)
|
||||
2. 修复后再次运行 /design-review 验证
|
||||
3. 全部通过后运行 /archive-design 存档设计稿
|
||||
```
|
||||
@@ -55,6 +55,10 @@ coverage/
|
||||
|
||||
# 编译产物(后端可执行文件)
|
||||
backend/issue
|
||||
backend/gencode
|
||||
|
||||
# 全局 todo skill 的本地数据(看板/任务,不入库)
|
||||
/todo/
|
||||
|
||||
# Claude 私有文件
|
||||
.claude/commands/
|
||||
|
||||
@@ -5,6 +5,17 @@ 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.59] - 2026-06-19
|
||||
|
||||
### 新功能
|
||||
- 授权到期后可在界面内直接续费:输入兑换码(形如 JIUKU-XXXX-XXXX)即可为门店叠加授权时长
|
||||
|
||||
### 改进
|
||||
- 品牌焕新:登录页启用「岩美酒库」品牌标识,桌面 / 移动 / 网页各端应用图标统一为品牌图标
|
||||
- 「激活授权」改为「兑换激活码」语义,文案与提示更贴合按时长续期的使用方式
|
||||
- 授权状态实时生效:续费、到期或授权被调整后无需重新登录即可刷新;账号被停用或在其他设备登录时及时自动退出
|
||||
- 「退出登录」收入右上角用户名下拉菜单,界面更聚焦
|
||||
|
||||
## [1.0.58] - 2026-06-18
|
||||
|
||||
### 修复
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
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.61] - 2026-06-19
|
||||
|
||||
### 改进
|
||||
- 平台侧兑换券生成工具随服务端一并发布并部署到服务器,可直接在服务器上批量生成激活码,无需每次本地编译上传;同步清理已退役的授权签名相关配置项
|
||||
|
||||
## [1.0.60] - 2026-06-19
|
||||
|
||||
### 新功能
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNormalizeCode(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
in string
|
||||
want string
|
||||
}{
|
||||
{"展示格式带连字符", "JIUKU-YD9S-7CAP", "JIUKUYD9S7CAP"},
|
||||
{"小写转大写", "jiuku-yd9s-7cap", "JIUKUYD9S7CAP"},
|
||||
{"去除空格", "JIUKU YD9S 7CAP", "JIUKUYD9S7CAP"},
|
||||
{"去除制表/换行/回车", "JIUKU\tYD9S\n7CAP\r", "JIUKUYD9S7CAP"},
|
||||
{"已归一化幂等", "JIUKUYD9S7CAP", "JIUKUYD9S7CAP"},
|
||||
{"空串", "", ""},
|
||||
{"混合大小写与分隔", " jiUKu--yd9s 7caP\n", "JIUKUYD9S7CAP"},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
if got := NormalizeCode(c.in); got != c.want {
|
||||
t.Fatalf("NormalizeCode(%q) = %q, want %q", c.in, got, c.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeCodeIdempotent(t *testing.T) {
|
||||
// 二次归一化结果不变
|
||||
once := NormalizeCode("jiuku-yd9s-7cap")
|
||||
if twice := NormalizeCode(once); twice != once {
|
||||
t.Fatalf("NormalizeCode 非幂等: %q -> %q", once, twice)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateRedeemCodeFormat(t *testing.T) {
|
||||
for i := 0; i < 200; i++ {
|
||||
code := GenerateRedeemCode()
|
||||
|
||||
// 展示格式:JIUKU-XXXX-XXXX
|
||||
parts := strings.Split(code, "-")
|
||||
if len(parts) != 3 {
|
||||
t.Fatalf("码段数应为 3,得到 %d:%q", len(parts), code)
|
||||
}
|
||||
if parts[0] != "JIUKU" {
|
||||
t.Fatalf("前缀应为 JIUKU,得到 %q:%q", parts[0], code)
|
||||
}
|
||||
if len(parts[1]) != 4 || len(parts[2]) != 4 {
|
||||
t.Fatalf("随机段长度应各为 4,得到 %d/%d:%q", len(parts[1]), len(parts[2]), code)
|
||||
}
|
||||
|
||||
// 归一化后 = 前缀 + 8 位随机
|
||||
norm := NormalizeCode(code)
|
||||
if len(norm) != len("JIUKU")+8 {
|
||||
t.Fatalf("归一化长度应为 %d,得到 %d:%q", len("JIUKU")+8, len(norm), norm)
|
||||
}
|
||||
|
||||
// 随机段只含无歧义字母表字符(不含 0/O/1/I/L)
|
||||
random := parts[1] + parts[2]
|
||||
for _, r := range random {
|
||||
if !strings.ContainsRune(codeAlphabet, r) {
|
||||
t.Fatalf("出现字母表外字符 %q:%q", r, code)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodeAlphabetExcludesAmbiguous(t *testing.T) {
|
||||
for _, bad := range []rune{'0', 'O', '1', 'I', 'L'} {
|
||||
if strings.ContainsRune(codeAlphabet, bad) {
|
||||
t.Fatalf("字母表不应包含易混字符 %q", bad)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateRedeemCodeUnique(t *testing.T) {
|
||||
// 不要求绝对唯一,但大量生成应几乎无碰撞(31^8 空间)
|
||||
const n = 1000
|
||||
seen := make(map[string]struct{}, n)
|
||||
dup := 0
|
||||
for i := 0; i < n; i++ {
|
||||
c := NormalizeCode(GenerateRedeemCode())
|
||||
if _, ok := seen[c]; ok {
|
||||
dup++
|
||||
}
|
||||
seen[c] = struct{}{}
|
||||
}
|
||||
if dup > 0 {
|
||||
t.Fatalf("%d 次生成出现 %d 次重复,随机性可疑", n, dup)
|
||||
}
|
||||
}
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
# jiu-gencode.sh — 平台方在 EC2 上批量生成兑换券(激活码)的便捷封装。
|
||||
#
|
||||
# 自动读取 /opt/jiu/config/production.env 的数据库连接,调用同目录的
|
||||
# jiu-gencode 二进制写入码池 license_codes。随 server 发版部署到
|
||||
# /opt/jiu/backend/,无需再本地交叉编译 + scp。
|
||||
#
|
||||
# 远程一行用法(在你的 Mac 上):
|
||||
# ssh -i ~/.ssh/wangjia.pem ec2-user@18.136.60.128 \
|
||||
# '/opt/jiu/backend/jiu-gencode.sh -type annual -days 365 -count 100 -batch 2026-summer'
|
||||
# ssh -i ~/.ssh/wangjia.pem ec2-user@18.136.60.128 \
|
||||
# '/opt/jiu/backend/jiu-gencode.sh -type trial -days 7 -count 1'
|
||||
#
|
||||
# 参数透传给 jiu-gencode:-type trial|monthly|annual|lifetime -days N(0=永久)
|
||||
# -devices N(0=不改门店现值) -count N -batch <批次> -note <备注>
|
||||
set -euo pipefail
|
||||
|
||||
ENV_FILE="${JIU_ENV_FILE:-/opt/jiu/config/production.env}"
|
||||
BIN="$(dirname "$0")/jiu-gencode"
|
||||
|
||||
[ -f "$ENV_FILE" ] || { echo "jiu-gencode: 找不到环境文件 $ENV_FILE" >&2; exit 1; }
|
||||
[ -x "$BIN" ] || { echo "jiu-gencode: 找不到可执行文件 $BIN" >&2; exit 1; }
|
||||
|
||||
# 加载 production.env:跳过注释/空行,逐行 export(不回显,避免泄漏密钥)。
|
||||
while IFS= read -r line; do
|
||||
case "$line" in \#*|'') continue ;; esac
|
||||
export "$line"
|
||||
done < "$ENV_FILE"
|
||||
|
||||
exec "$BIN" "$@"
|
||||
@@ -5,9 +5,6 @@ DATABASE_DSN=root:CHANGE_ME_DB_PASS@tcp(127.0.0.1:3306)/jiu_db?charset=utf8mb4&p
|
||||
JWT_SECRET=CHANGE_ME_RANDOM_32CHARS
|
||||
JWT_ACCESS_EXPIRE_MIN=60
|
||||
JWT_REFRESH_EXPIRE_H=168
|
||||
LICENSE_HMAC_SECRET=CHANGE_ME_RANDOM_32CHARS
|
||||
LICENSE_ED25519_PUBLIC_KEY=zFkRV0E+oMjHbixiBamf2ZAq+n7En2V7EJRIurgtVxo=
|
||||
LICENSE_ED25519_PRIVATE_KEY=CHANGE_ME_ED25519_PRIVATE_FROM_BITWARDEN
|
||||
STORAGE_UPLOAD_DIR=/opt/jiu/images
|
||||
STORAGE_BASE_URL=https://jiu.51yanmei.com/images
|
||||
STORAGE_PUBLIC_URL=https://jiu.51yanmei.com
|
||||
|
||||
@@ -16,7 +16,7 @@ set -euo pipefail
|
||||
# ---- 可配置项 ----
|
||||
RBW="${RBW_BIN:-/opt/homebrew/bin/rbw}"
|
||||
BW_ITEM="${JIU_BW_ITEM:-jiu db password}" # 存放 jiu 密钥字段的 Bitwarden 条目
|
||||
SECRET_KEYS="DATABASE_DSN JWT_SECRET LICENSE_HMAC_SECRET LICENSE_ED25519_PRIVATE_KEY DB_PASSWORD"
|
||||
SECRET_KEYS="DATABASE_DSN JWT_SECRET DB_PASSWORD"
|
||||
|
||||
EC2_HOST="${EC2_HOST:-18.136.60.128}"
|
||||
EC2_USER="${EC2_USER:-ec2-user}"
|
||||
|
||||
@@ -13,10 +13,14 @@ echo "==> compile-backend: tag=${TAG}"
|
||||
# Build Go backend (linux/amd64 for EC2)
|
||||
cd backend
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o jiu-server .
|
||||
# Platform code-minting CLI (gencode) ships alongside the server so codes can be
|
||||
# minted on EC2 without cross-compiling/scp each time.
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o jiu-gencode ./cmd/gencode
|
||||
cd ..
|
||||
|
||||
mkdir -p dist
|
||||
mv backend/jiu-server dist/jiu-server
|
||||
mv backend/jiu-gencode dist/jiu-gencode
|
||||
|
||||
# Shared infrastructure (nginx/systemd/env/compose). version.yaml is NOT here —
|
||||
# it belongs to the client pipeline.
|
||||
@@ -26,7 +30,8 @@ tar -czf dist/configs.tar.gz \
|
||||
deploy/production.env.template \
|
||||
deploy/setup-ec2.sh \
|
||||
deploy/docker-compose.yml \
|
||||
deploy/docker-compose.jiu.yml
|
||||
deploy/docker-compose.jiu.yml \
|
||||
deploy/jiu-gencode.sh
|
||||
|
||||
echo "==> compile-backend: done — dist/ contents:"
|
||||
ls -lh dist/
|
||||
|
||||
@@ -27,6 +27,13 @@ echo "==> deploy-server: uploading files to EC2"
|
||||
${SCP} dist/jiu-server "${EC2_USER}@${EC2_HOST}:/tmp/jiu-server"
|
||||
${SCP} /tmp/jiu-configs/deploy/nginx-jiu.conf "${EC2_USER}@${EC2_HOST}:/tmp/nginx-jiu.conf"
|
||||
|
||||
# Platform code-minting CLI + wrapper (absent when rolling back to a pre-gencode
|
||||
# release — upload only when present).
|
||||
if [ -f dist/jiu-gencode ]; then
|
||||
${SCP} dist/jiu-gencode "${EC2_USER}@${EC2_HOST}:/tmp/jiu-gencode"
|
||||
${SCP} /tmp/jiu-configs/deploy/jiu-gencode.sh "${EC2_USER}@${EC2_HOST}:/tmp/jiu-gencode.sh"
|
||||
fi
|
||||
|
||||
${SSH} "${EC2_USER}@${EC2_HOST}" << 'ENDSSH'
|
||||
set -e
|
||||
|
||||
@@ -35,6 +42,17 @@ sudo systemctl stop jiu
|
||||
cp /tmp/jiu-server /opt/jiu/backend/jiu-server
|
||||
chmod +x /opt/jiu/backend/jiu-server
|
||||
|
||||
# Refresh the code-minting CLI if shipped in this release (skip gracefully on
|
||||
# rollback to a pre-gencode release). Not a service — just a host-side binary.
|
||||
if [ -f /tmp/jiu-gencode ]; then
|
||||
cp /tmp/jiu-gencode /opt/jiu/backend/jiu-gencode
|
||||
chmod +x /opt/jiu/backend/jiu-gencode
|
||||
if [ -f /tmp/jiu-gencode.sh ]; then
|
||||
cp /tmp/jiu-gencode.sh /opt/jiu/backend/jiu-gencode.sh
|
||||
chmod +x /opt/jiu/backend/jiu-gencode.sh
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start and health check
|
||||
sudo systemctl start jiu
|
||||
echo "Waiting for health check..."
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# release-server.sh <tag> — create the Forgejo Release for the backend pipeline
|
||||
# and upload jiu-server + configs.tar.gz.
|
||||
# and upload jiu-server + jiu-gencode + configs.tar.gz.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source=scripts/ci/lib-forgejo.sh
|
||||
@@ -20,6 +20,7 @@ PYEOF
|
||||
|
||||
create_release "$TAG" "$BODY"
|
||||
upload_asset dist/jiu-server
|
||||
upload_asset dist/jiu-gencode
|
||||
upload_asset dist/configs.tar.gz
|
||||
|
||||
echo "==> release-server: done — Release ${TAG} created"
|
||||
|
||||
Reference in New Issue
Block a user