feat(v3): migrate workspace to API, Tauri desktop, and v3 crates; remove legacy MCP stack
Some checks failed
Secrets v3 CI / 检查 (push) Has been cancelled
Some checks failed
Secrets v3 CI / 检查 (push) Has been cancelled
- Add apps/api, desktop Tauri shell, domain/application/crypto/device-auth/infrastructure-db - Replace desktop-daemon vault integration; drop secrets-core and secrets-mcp* - Ignore apps/desktop/dist and generated Tauri icons; document icon/dist steps in AGENTS.md - Apply rustfmt; fix clippy (collapsible_if, HTTP method as str)
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
# MCP 分支:仅构建/发布 secrets-mcp(CLI 在 main 分支维护)
|
||||
name: Secrets MCP — Build & Release
|
||||
name: Secrets v3 CI
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -18,7 +17,6 @@ permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
MCP_BINARY: secrets-mcp
|
||||
RUST_TOOLCHAIN: 1.94.0
|
||||
CARGO_INCREMENTAL: 0
|
||||
CARGO_NET_RETRY: 10
|
||||
@@ -28,46 +26,14 @@ env:
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
name: 检查 / 构建 / 发版
|
||||
name: 检查
|
||||
runs-on: debian
|
||||
timeout-minutes: 40
|
||||
outputs:
|
||||
tag: ${{ steps.ver.outputs.tag }}
|
||||
version: ${{ steps.ver.outputs.version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# ── 版本解析 ────────────────────────────────────────────────────────
|
||||
- name: 解析版本
|
||||
id: ver
|
||||
run: |
|
||||
version=$(grep -m1 '^version' crates/secrets-mcp/Cargo.toml | sed 's/.*"\(.*\)".*/\1/')
|
||||
tag="secrets-mcp-${version}"
|
||||
echo "version=${version}" >> "$GITHUB_OUTPUT"
|
||||
echo "tag=${tag}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# 版本 bump 硬检查:若本次推送包含 crates/ 或 Cargo.toml 变更,
|
||||
# 但版本号与上一提交一致,则视为未发版,直接失败。
|
||||
prev_version=$(git show HEAD^:crates/secrets-mcp/Cargo.toml 2>/dev/null | grep -m1 '^version' | sed 's/.*"\(.*\)".*/\1/' || true)
|
||||
if [ -n "$prev_version" ] && [ "$version" = "$prev_version" ]; then
|
||||
# 确认本次推送是否包含 crates/ 或 Cargo.toml 变更
|
||||
if git diff --name-only HEAD^ HEAD 2>/dev/null | grep -qE '^crates/|^Cargo\.toml$'; then
|
||||
echo "::error::工作区包含 crates/ 或 Cargo.toml 变更,但版本号未 bump(${version} == ${prev_version})"
|
||||
echo "按规则,每次代码变更必须 bump crates/secrets-mcp/Cargo.toml 中的 version。"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if git rev-parse "refs/tags/${tag}" >/dev/null 2>&1; then
|
||||
echo "⚠ 版本 ${tag} 已存在,将覆盖重新发版。"
|
||||
echo "tag_exists=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "将创建新版本 ${tag}"
|
||||
echo "tag_exists=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
# ── Rust 工具链 ──────────────────────────────────────────────────────
|
||||
- name: 安装 Rust 与 musl 工具链
|
||||
run: |
|
||||
@@ -107,76 +73,13 @@ jobs:
|
||||
- name: test
|
||||
run: cargo test --locked
|
||||
|
||||
# ── 构建(质量检查通过后才执行)────────────────────────────────────
|
||||
- name: 构建 secrets-mcp (musl)
|
||||
- name: 构建 secrets-api
|
||||
run: |
|
||||
cargo build --release --locked --target "${MUSL_TARGET}" -p secrets-mcp
|
||||
strip "target/${MUSL_TARGET}/release/${MCP_BINARY}"
|
||||
cargo build --release --locked -p secrets-api
|
||||
|
||||
- name: 上传构建产物
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ env.MCP_BINARY }}-linux-musl
|
||||
path: target/${{ env.MUSL_TARGET }}/release/${{ env.MCP_BINARY }}
|
||||
retention-days: 3
|
||||
|
||||
# ── 创建 / 覆盖 Tag(构建成功后才打)───────────────────────────────
|
||||
- name: 创建 Tag
|
||||
- name: 构建 secrets-desktop-daemon
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
tag="${{ steps.ver.outputs.tag }}"
|
||||
if [ "${{ steps.ver.outputs.tag_exists }}" = "true" ]; then
|
||||
git tag -d "$tag" 2>/dev/null || true
|
||||
git push origin ":refs/tags/$tag" 2>/dev/null || true
|
||||
fi
|
||||
git tag -a "$tag" -m "Release $tag"
|
||||
git push origin "$tag"
|
||||
|
||||
# ── Release(可选,需配置 RELEASE_TOKEN)───────────────────────────
|
||||
- name: Upsert Release
|
||||
if: env.RELEASE_TOKEN != ''
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
tag="${{ steps.ver.outputs.tag }}"
|
||||
version="${{ steps.ver.outputs.version }}"
|
||||
api="${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases"
|
||||
auth="Authorization: token $RELEASE_TOKEN"
|
||||
|
||||
previous_tag=$(git tag --list 'secrets-mcp-*' --sort=-v:refname | awk -v t="$tag" '$0 != t { print; exit }')
|
||||
if [ -n "$previous_tag" ]; then
|
||||
changes=$(git log --pretty=format:'- %s (%h)' "${previous_tag}..HEAD")
|
||||
else
|
||||
changes=$(git log --pretty=format:'- %s (%h)')
|
||||
fi
|
||||
[ -z "$changes" ] && changes="- 首次发布"
|
||||
body=$(printf '## 变更日志\n\n%s' "$changes")
|
||||
|
||||
# Upsert: 存在 → PATCH + 清旧 assets;不存在 → POST
|
||||
release_id=$(curl -sS -H "$auth" "${api}/tags/${tag}" 2>/dev/null | jq -r '.id // empty')
|
||||
if [ -n "$release_id" ]; then
|
||||
curl -sS -o /dev/null -H "$auth" -H "Content-Type: application/json" \
|
||||
-X PATCH "${api}/${release_id}" \
|
||||
-d "$(jq -n --arg n "secrets-mcp ${version}" --arg b "$body" '{name:$n,body:$b,draft:false}')"
|
||||
curl -sS -H "$auth" "${api}/${release_id}/assets" | \
|
||||
jq -r '.[].id' | xargs -I{} curl -sS -o /dev/null -H "$auth" -X DELETE "${api}/${release_id}/assets/{}"
|
||||
echo "已更新 Release ${release_id}"
|
||||
else
|
||||
release_id=$(curl -fsS -H "$auth" -H "Content-Type: application/json" \
|
||||
-X POST "$api" \
|
||||
-d "$(jq -n --arg t "$tag" --arg n "secrets-mcp ${version}" --arg b "$body" \
|
||||
'{tag_name:$t,name:$n,body:$b,draft:false}')" | jq -r '.id')
|
||||
echo "已创建 Release ${release_id}"
|
||||
fi
|
||||
|
||||
bin="target/${MUSL_TARGET}/release/${MCP_BINARY}"
|
||||
archive="${MCP_BINARY}-${tag}-x86_64-linux-musl.tar.gz"
|
||||
tar -czf "$archive" -C "$(dirname "$bin")" "$(basename "$bin")"
|
||||
sha256sum "$archive" > "${archive}.sha256"
|
||||
curl -fsS -H "$auth" -F "attachment=@${archive}" "${api}/${release_id}/assets"
|
||||
curl -fsS -H "$auth" -F "attachment=@${archive}.sha256" "${api}/${release_id}/assets"
|
||||
echo "Release ${tag} 已发布"
|
||||
cargo build --release --locked -p secrets-desktop-daemon
|
||||
|
||||
# ── 飞书汇总通知 ─────────────────────────────────────────────────────
|
||||
- name: 飞书通知
|
||||
@@ -185,84 +88,14 @@ jobs:
|
||||
WEBHOOK_URL: ${{ vars.WEBHOOK_URL }}
|
||||
run: |
|
||||
[ -z "$WEBHOOK_URL" ] && exit 0
|
||||
tag="${{ steps.ver.outputs.tag }}"
|
||||
commit="${{ github.event.head_commit.message }}"
|
||||
[ -z "$commit" ] && commit="${{ github.sha }}"
|
||||
url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}"
|
||||
result="${{ job.status }}"
|
||||
if [ "$result" = "success" ]; then icon="✅"; else icon="❌"; fi
|
||||
msg="secrets-mcp 构建&发版 ${icon}
|
||||
版本:${tag}
|
||||
msg="secrets v3 CI ${icon}
|
||||
提交:${commit}
|
||||
作者:${{ github.actor }}
|
||||
详情:${url}"
|
||||
payload=$(jq -n --arg text "$msg" '{msg_type: "text", content: {text: $text}}')
|
||||
curl -sS -H "Content-Type: application/json" -X POST -d "$payload" "$WEBHOOK_URL"
|
||||
|
||||
deploy:
|
||||
name: 部署 secrets-mcp
|
||||
needs: [ci]
|
||||
if: |
|
||||
github.ref == 'refs/heads/main' ||
|
||||
github.ref == 'refs/heads/feat/mcp' ||
|
||||
github.ref == 'refs/heads/mcp'
|
||||
runs-on: debian
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: 下载构建产物
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ env.MCP_BINARY }}-linux-musl
|
||||
path: /tmp/artifact
|
||||
|
||||
- name: 部署到阿里云 ECS
|
||||
env:
|
||||
DEPLOY_HOST: ${{ vars.DEPLOY_HOST }}
|
||||
DEPLOY_USER: ${{ vars.DEPLOY_USER }}
|
||||
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
DEPLOY_KNOWN_HOSTS: ${{ vars.DEPLOY_KNOWN_HOSTS }}
|
||||
run: |
|
||||
if [ -z "$DEPLOY_HOST" ] || [ -z "$DEPLOY_USER" ] || [ -z "$DEPLOY_SSH_KEY" ]; then
|
||||
echo "部署跳过:请配置 vars.DEPLOY_HOST、vars.DEPLOY_USER 与 secrets.DEPLOY_SSH_KEY"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
install -m 600 /dev/null /tmp/deploy_key
|
||||
echo "$DEPLOY_SSH_KEY" > /tmp/deploy_key
|
||||
trap 'rm -f /tmp/deploy_key' EXIT
|
||||
|
||||
if [ -n "$DEPLOY_KNOWN_HOSTS" ]; then
|
||||
echo "$DEPLOY_KNOWN_HOSTS" > /tmp/deploy_known_hosts
|
||||
ssh_opts="-o UserKnownHostsFile=/tmp/deploy_known_hosts -o StrictHostKeyChecking=yes"
|
||||
else
|
||||
ssh_opts="-o StrictHostKeyChecking=accept-new"
|
||||
fi
|
||||
|
||||
scp -i /tmp/deploy_key $ssh_opts \
|
||||
"/tmp/artifact/${MCP_BINARY}" \
|
||||
"${DEPLOY_USER}@${DEPLOY_HOST}:/tmp/secrets-mcp.new"
|
||||
|
||||
ssh -i /tmp/deploy_key $ssh_opts "${DEPLOY_USER}@${DEPLOY_HOST}" "
|
||||
sudo mv /tmp/secrets-mcp.new /opt/secrets-mcp/secrets-mcp
|
||||
sudo chmod +x /opt/secrets-mcp/secrets-mcp
|
||||
sudo systemctl restart secrets-mcp
|
||||
sleep 2
|
||||
sudo systemctl is-active secrets-mcp && echo '服务启动成功' || (sudo journalctl -u secrets-mcp -n 20 && exit 1)
|
||||
"
|
||||
|
||||
- name: 飞书通知
|
||||
if: always()
|
||||
env:
|
||||
WEBHOOK_URL: ${{ vars.WEBHOOK_URL }}
|
||||
run: |
|
||||
[ -z "$WEBHOOK_URL" ] && exit 0
|
||||
tag="${{ needs.ci.outputs.tag }}"
|
||||
url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}"
|
||||
result="${{ job.status }}"
|
||||
if [ "$result" = "success" ]; then icon="✅"; else icon="❌"; fi
|
||||
msg="secrets-mcp 部署 ${icon}
|
||||
版本:${tag}
|
||||
作者:${{ github.actor }}
|
||||
详情:${url}"
|
||||
payload=$(jq -n --arg text "$msg" '{msg_type: "text", content: {text: $text}}')
|
||||
curl -sS -H "Content-Type: application/json" -X POST -d "$payload" "$WEBHOOK_URL"
|
||||
|
||||
Reference in New Issue
Block a user