Use Git tag as release version, validate SKILL.md version consistency, and fail workflow when API business code is not success.
108 lines
3.9 KiB
YAML
108 lines
3.9 KiB
YAML
name: 技能自动化发布 (测试版-无鉴权)
|
||
on:
|
||
push:
|
||
tags: ["v*"]
|
||
|
||
jobs:
|
||
build-and-deploy:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
# 1. 下载源码
|
||
- uses: http://120.25.191.12:3000/admin/actions-checkout@v4
|
||
|
||
# 2. 环境及工具准备
|
||
- name: Setup Tools
|
||
# 优化:使用国内清华源加速安装速度
|
||
run: pip install pyarmor requests python-frontmatter --break-system-packages -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||
|
||
# 3. 【核心步骤】PyArmor 源代码混淆加密
|
||
- name: Encrypt Source Code
|
||
run: |
|
||
mkdir -p dist/package
|
||
pyarmor gen -O dist/package scripts/*.py
|
||
cp SKILL.md dist/package/
|
||
|
||
# 4. 提取元数据并物理打包
|
||
- name: Parse Metadata and Pack
|
||
id: build_task
|
||
run: |
|
||
python -c "
|
||
import frontmatter, os, json, shutil
|
||
post = frontmatter.load('SKILL.md')
|
||
metadata = post.metadata
|
||
# slug 优先从 openclaw.slug 读取,兼容历史用 name
|
||
openclaw_meta = metadata.get('metadata', {}).get('openclaw', {})
|
||
slug = (openclaw_meta.get('slug') or metadata.get('slug') or metadata.get('name') or '').strip()
|
||
if not slug:
|
||
raise Exception('SKILL.md 缺少 slug/name,无法构建发布包')
|
||
|
||
# 以 Git Tag 为准(严格模式)
|
||
ref_name = (os.environ.get('GITHUB_REF_NAME') or '').strip()
|
||
if not ref_name:
|
||
ref_name = (os.environ.get('GITHUB_REF') or '').strip().split('/')[-1]
|
||
if not ref_name.startswith('v'):
|
||
raise Exception(f'非法标签: {ref_name},要求以 v 开头,例如 v1.0.10')
|
||
|
||
version = ref_name.lstrip('v')
|
||
skill_version = str(metadata.get('version') or '').strip()
|
||
if skill_version != version:
|
||
raise Exception(f'SKILL.md 版本({skill_version})与 Git Tag 版本({version})不一致')
|
||
|
||
# 统一覆盖,确保后续输出与上传完全一致
|
||
metadata['version'] = version
|
||
# 安全写入输出
|
||
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
||
f.write(f'slug={slug}\n')
|
||
f.write(f'version={version}\n')
|
||
f.write(f'metadata={json.dumps(metadata)}\n')
|
||
|
||
# 制作最终的发布 ZIP 包
|
||
shutil.make_archive(slug, 'zip', 'dist/package')
|
||
"
|
||
|
||
# 5. 同步数据库记录
|
||
- name: Sync Database (V2.0)
|
||
env:
|
||
METADATA_JSON: ${{ steps.build_task.outputs.metadata }}
|
||
run: |
|
||
python -c "
|
||
import requests, json, os
|
||
metadata = json.loads(os.environ['METADATA_JSON'])
|
||
url = 'https://jc2009.com/api/skill/update'
|
||
res = requests.post(url, json=metadata)
|
||
print(f'DB Sync Result: {res.text}')
|
||
if res.status_code != 200:
|
||
exit(1)
|
||
try:
|
||
payload = res.json()
|
||
except Exception:
|
||
exit(1)
|
||
if payload.get('code') != 200:
|
||
exit(1)
|
||
"
|
||
|
||
# 6. 上传物理包
|
||
- name: Upload Encrypted ZIP
|
||
env:
|
||
SLUG: ${{ steps.build_task.outputs.slug }}
|
||
VERSION: ${{ steps.build_task.outputs.version }}
|
||
run: |
|
||
python -c "
|
||
import requests, os
|
||
url = 'https://jc2009.com/api/upload'
|
||
slug = os.environ['SLUG']
|
||
version = os.environ['VERSION']
|
||
payload = {'plugin_name': slug, 'version': version, 'artifact_type': 'skill'}
|
||
with open(f'{slug}.zip', 'rb') as f:
|
||
res = requests.post(url, data=payload, files={'file': f})
|
||
print(f'Upload Result: {res.text}')
|
||
if res.status_code != 200:
|
||
exit(1)
|
||
try:
|
||
payload = res.json()
|
||
except Exception:
|
||
exit(1)
|
||
if payload.get('code') != 200:
|
||
exit(1)
|
||
"
|