- TickShield app skills now follow the app-<action> naming convention (e.g. app-publish); dev-app kept as the legacy grandfathered name - convention recorded in AGENTS.md + README skills table; skill-forge step 0 enforces app-<action> for future TickShield app skills - cross-references between dev-app and app-publish updated
105 lines
5.4 KiB
YAML
105 lines
5.4 KiB
YAML
# app-release.yaml — 推 v* tag → 构建推镜像 → aigrego-release 发布上架到 TickShield 应用市场
|
||
# 由 app-publish skill 渲染生成。构建段为最小可用;完整构建规范(基础镜像内网落盘等)见 gitea-actions。
|
||
#
|
||
# 槽位(渲染后不得残留 {{...}}):
|
||
# {{PROJECT}} 项目名(镜像名,默认仓库 basename)
|
||
# {{WEB_DIR}} micro 型前端目录(如 web)
|
||
# {{DIST_DIR}} micro 型构建产物目录(相对仓库根,包根必须直接含 index.html,如 src/web/dist)
|
||
# {{WAIT_SECONDS}} 治理审核等待秒数(默认 600)
|
||
# 可选块(按 manifest type 增删):
|
||
# [OPTIONAL:IMAGE] service/micro 保留;link/native 整块删除
|
||
# [OPTIONAL:DIST_BUILD] micro 保留,其余整块删除
|
||
# [OPTIONAL:DIST] micro 保留,其余删除该行
|
||
#
|
||
# ============ 人工准备清单(照单配置后首发) ============
|
||
# 1. 平台基座「接入应用」获取凭证 → 仓库 Settings → Actions → Secrets:
|
||
# APP_KEY(== app.manifest.json 的 listingKey)、APP_SECRET
|
||
# 2. 可选 Variables:
|
||
# TICKSHIELD_PORTAL_URL(默认 http://gateway:8080)
|
||
# APP_IMAGE_PREFIX(默认 livebook:8418/projects)
|
||
# TICKSHIELD_RAW_BASE(默认 http://livebook:9000/tickshield;二进制路径 cli/aigrego-release-<os>-<arch>)
|
||
# 3. 商店应用详情开 auto_publish(否则 --store 403,CI 停在记录镜像,等平台管理员手动上架)
|
||
# 4. 镜像 host 须在平台 registries 白名单(空表=全拒;发布不拦,商店安装时才拦)
|
||
# 5. registry 推送凭证 Secrets:INNEV_REGISTRY_USER / INNEV_REGISTRY_TOKEN
|
||
# (缺省回退 gitea.actor / GITHUB_TOKEN,同命名空间够用)
|
||
# ======================================================
|
||
|
||
name: app-release
|
||
|
||
on:
|
||
push:
|
||
tags:
|
||
- 'v*'
|
||
workflow_dispatch:
|
||
|
||
jobs:
|
||
release:
|
||
runs-on: self-hosted
|
||
steps:
|
||
- name: Checkout tag source
|
||
run: |
|
||
rm -rf src && git clone --depth 1 --branch "$GITHUB_REF_NAME" . src
|
||
|
||
# [OPTIONAL:IMAGE]
|
||
- name: Setup buildx (LAN registry http=true)
|
||
run: |
|
||
mkdir -p /tmp/buildkitd
|
||
printf '[registry."livebook:8418"]\n http = true\n' > /tmp/buildkitd/buildkitd.toml
|
||
docker buildx create --use --name appx --driver docker-container --config /tmp/buildkitd/buildkitd.toml 2>/dev/null || docker buildx use appx
|
||
docker buildx inspect --bootstrap
|
||
|
||
- name: Build & push image
|
||
run: |
|
||
IMAGE="${{ vars.APP_IMAGE_PREFIX || 'livebook:8418/projects' }}/{{PROJECT}}"
|
||
TAG="${GITHUB_REF_NAME#v}"
|
||
echo "${{ secrets.INNEV_REGISTRY_TOKEN || secrets.GITHUB_TOKEN }}" | docker login livebook:8418 -u "${{ secrets.INNEV_REGISTRY_USER || gitea.actor }}" --password-stdin
|
||
docker buildx build --platform linux/amd64,linux/arm64 --push \
|
||
-t "$IMAGE:$TAG" -t "$IMAGE:latest" ./src
|
||
echo "IMAGE_REF=$IMAGE:$TAG" >> "$GITHUB_ENV"
|
||
# [/OPTIONAL:IMAGE]
|
||
|
||
# [OPTIONAL:DIST_BUILD]
|
||
- name: Build web dist
|
||
run: |
|
||
docker run --rm -v "$PWD/src:/src" -w "/src/{{WEB_DIR}}" node:20-alpine \
|
||
sh -c 'npm ci && npm run build'
|
||
test -f "{{DIST_DIR}}/index.html" || { echo "::error::dist 包根缺 index.html(约束⑤:--dist 必须传产物目录本身)"; exit 1; }
|
||
# [/OPTIONAL:DIST_BUILD]
|
||
|
||
- name: Fetch aigrego-release CLI
|
||
run: |
|
||
# Go 零依赖静态二进制(CGO_ENABLED=0),按 runner 架构下载即用。
|
||
# 禁止改用 code.innev.cn/.../tickshield-dist 旧地址或 aigrego-release.mjs——均已停用/被平台删除(约束③)
|
||
case "$(uname -m)" in
|
||
x86_64|amd64) ARCH=amd64 ;;
|
||
aarch64|arm64) ARCH=arm64 ;;
|
||
*) echo "不支持的 runner 架构:$(uname -m)(矩阵仅 linux × amd64/arm64)"; exit 1 ;;
|
||
esac
|
||
RAW_BASE="${{ vars.TICKSHIELD_RAW_BASE || 'http://livebook:9000/tickshield' }}"
|
||
curl -fsSL "$RAW_BASE/cli/aigrego-release-linux-$ARCH" -o /tmp/aigrego-release
|
||
chmod +x /tmp/aigrego-release
|
||
EXPECT="$(curl -fsSL "$RAW_BASE/cli/sha256sums.txt" | grep "aigrego-release-linux-$ARCH" | awk '{print $1}')"
|
||
ACTUAL="$(sha256sum /tmp/aigrego-release | awk '{print $1}')"
|
||
[ -n "$EXPECT" ] && [ "$EXPECT" != "$ACTUAL" ] && { echo "sha256 不匹配:期望 $EXPECT 实际 $ACTUAL"; exit 1; }
|
||
/tmp/aigrego-release version
|
||
|
||
- name: Verify credentials (whoami)
|
||
run: |
|
||
AIGREGO_PORTAL_URL="${{ vars.TICKSHIELD_PORTAL_URL || 'http://gateway:8080' }}" \
|
||
APP_KEY="${{ secrets.APP_KEY }}" \
|
||
APP_SECRET="${{ secrets.APP_SECRET }}" \
|
||
/tmp/aigrego-release whoami
|
||
|
||
- name: Publish (manifest [+ image] [+ dist] + store + wait)
|
||
run: |
|
||
AIGREGO_PORTAL_URL="${{ vars.TICKSHIELD_PORTAL_URL || 'http://gateway:8080' }}" \
|
||
APP_KEY="${{ secrets.APP_KEY }}" \
|
||
APP_SECRET="${{ secrets.APP_SECRET }}" \
|
||
/tmp/aigrego-release publish \
|
||
--manifest src/app.manifest.json \
|
||
--image "$IMAGE_REF" \
|
||
--dist "src/{{DIST_DIR}}" \
|
||
--store --wait {{WAIT_SECONDS}}
|
||
# 渲染说明:--image 行仅在 [OPTIONAL:IMAGE] 时保留;--dist 行仅在 [OPTIONAL:DIST] 时保留;
|
||
# link/native 型两者皆删,publish 只交 manifest。
|