ci: 合并为 ci + deploy 两个 job,check 先于 build
单台 self-hosted runner 下并行 job 只是排队,多 job 拆分带来的 artifact 传递、重复 checkout、调度延迟反而更慢。 改动: - 原 version/check/build-linux/publish-release 四个 job 合并为单个 ci job - 步骤顺序:版本拦截 → fmt/clippy/test → build → 打 tag → 发 Release - tag 在构建成功后才创建,避免失败提交留下脏 tag - Release 创建+上传+发布合并为单步,去掉草稿中转 - deploy job 仅保留 artifact 下载 + SSH 部署逻辑,不再重复编译 - 整体从 400 行缩减至 244 行 Made-with: Cursor
This commit is contained in:
@@ -27,175 +27,49 @@ env:
|
|||||||
MUSL_TARGET: x86_64-unknown-linux-musl
|
MUSL_TARGET: x86_64-unknown-linux-musl
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
version:
|
ci:
|
||||||
name: 版本 & Release
|
name: 检查 / 构建 / 发版
|
||||||
runs-on: debian
|
runs-on: debian
|
||||||
|
timeout-minutes: 40
|
||||||
outputs:
|
outputs:
|
||||||
version: ${{ steps.ver.outputs.version }}
|
|
||||||
tag: ${{ steps.ver.outputs.tag }}
|
tag: ${{ steps.ver.outputs.tag }}
|
||||||
tag_exists: ${{ steps.ver.outputs.tag_exists }}
|
version: ${{ steps.ver.outputs.version }}
|
||||||
release_id: ${{ steps.release.outputs.release_id }}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
# ── 版本检查(提前拦截,避免后续步骤白跑)──────────────────────────
|
||||||
- name: 解析版本
|
- name: 解析版本
|
||||||
id: ver
|
id: ver
|
||||||
run: |
|
run: |
|
||||||
version=$(grep -m1 '^version' crates/secrets-mcp/Cargo.toml | sed 's/.*"\(.*\)".*/\1/')
|
version=$(grep -m1 '^version' crates/secrets-mcp/Cargo.toml | sed 's/.*"\(.*\)".*/\1/')
|
||||||
tag="secrets-mcp-${version}"
|
tag="secrets-mcp-${version}"
|
||||||
previous_tag=$(git tag --list 'secrets-mcp-*' --sort=-v:refname | awk -v tag="$tag" '$0 != tag { print; exit }')
|
|
||||||
|
|
||||||
echo "version=${version}" >> "$GITHUB_OUTPUT"
|
echo "version=${version}" >> "$GITHUB_OUTPUT"
|
||||||
echo "tag=${tag}" >> "$GITHUB_OUTPUT"
|
echo "tag=${tag}" >> "$GITHUB_OUTPUT"
|
||||||
echo "previous_tag=${previous_tag}" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
if git rev-parse "refs/tags/${tag}" >/dev/null 2>&1; then
|
if git rev-parse "refs/tags/${tag}" >/dev/null 2>&1; then
|
||||||
echo "tag_exists=true" >> "$GITHUB_OUTPUT"
|
echo "错误: 版本 ${tag} 已存在,禁止重复发版。"
|
||||||
echo "版本 ${tag} 已存在"
|
echo "请先 bump crates/secrets-mcp/Cargo.toml 中的 version,再执行 cargo build 同步 Cargo.lock。"
|
||||||
else
|
exit 1
|
||||||
echo "tag_exists=false" >> "$GITHUB_OUTPUT"
|
fi
|
||||||
echo "将创建新版本 ${tag}"
|
echo "将创建新版本 ${tag}"
|
||||||
fi
|
|
||||||
|
|
||||||
- name: 检测重复版本
|
# ── Rust 工具链 ──────────────────────────────────────────────────────
|
||||||
if: steps.ver.outputs.tag_exists == 'true'
|
- name: 安装 Rust 与 musl 工具链
|
||||||
run: |
|
|
||||||
echo "提示: 版本 ${{ steps.ver.outputs.tag }} 已存在,将复用现有 tag 继续构建。"
|
|
||||||
|
|
||||||
- name: 创建 Tag
|
|
||||||
if: steps.ver.outputs.tag_exists == 'false'
|
|
||||||
run: |
|
|
||||||
git config user.name "github-actions[bot]"
|
|
||||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
||||||
git tag -a "${{ steps.ver.outputs.tag }}" -m "Release ${{ steps.ver.outputs.tag }}"
|
|
||||||
git push origin "${{ steps.ver.outputs.tag }}"
|
|
||||||
|
|
||||||
- name: 解析或创建 Release
|
|
||||||
id: release
|
|
||||||
env:
|
|
||||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
||||||
run: |
|
|
||||||
if [ -z "$RELEASE_TOKEN" ]; then
|
|
||||||
echo "release_id=" >> "$GITHUB_OUTPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
command -v jq >/dev/null 2>&1 || (sudo apt-get update -qq && sudo apt-get install -y -qq jq)
|
|
||||||
|
|
||||||
tag="${{ steps.ver.outputs.tag }}"
|
|
||||||
version="${{ steps.ver.outputs.version }}"
|
|
||||||
release_api="${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases"
|
|
||||||
|
|
||||||
http_code=$(curl -sS -o /tmp/release.json -w '%{http_code}' \
|
|
||||||
-H "Authorization: token $RELEASE_TOKEN" \
|
|
||||||
"${release_api}/tags/${tag}")
|
|
||||||
|
|
||||||
if [ "$http_code" = "200" ]; then
|
|
||||||
release_id=$(jq -r '.id // empty' /tmp/release.json)
|
|
||||||
if [ -n "$release_id" ]; then
|
|
||||||
echo "已找到现有 Release: ${release_id}"
|
|
||||||
echo "release_id=${release_id}" >> "$GITHUB_OUTPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
previous_tag="${{ steps.ver.outputs.previous_tag }}"
|
|
||||||
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")
|
|
||||||
|
|
||||||
payload=$(jq -n \
|
|
||||||
--arg tag "$tag" \
|
|
||||||
--arg name "secrets-mcp ${version}" \
|
|
||||||
--arg body "$body" \
|
|
||||||
'{tag_name: $tag, name: $name, body: $body, draft: true}')
|
|
||||||
|
|
||||||
http_code=$(curl -sS -o /tmp/create-release.json -w '%{http_code}' \
|
|
||||||
-H "Authorization: token $RELEASE_TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-X POST "$release_api" \
|
|
||||||
-d "$payload")
|
|
||||||
|
|
||||||
if [ "$http_code" = "201" ] || [ "$http_code" = "200" ]; then
|
|
||||||
release_id=$(jq -r '.id // empty' /tmp/create-release.json)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$release_id" ]; then
|
|
||||||
echo "已创建草稿 Release: ${release_id}"
|
|
||||||
echo "release_id=${release_id}" >> "$GITHUB_OUTPUT"
|
|
||||||
else
|
|
||||||
echo "⚠ 创建 Release 失败 (HTTP ${http_code}),跳过产物上传"
|
|
||||||
cat /tmp/create-release.json 2>/dev/null || true
|
|
||||||
echo "release_id=" >> "$GITHUB_OUTPUT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# check 与 build-linux 并行执行,互不阻塞
|
|
||||||
check:
|
|
||||||
name: 质量检查 (fmt / clippy / test)
|
|
||||||
needs: [version]
|
|
||||||
runs-on: debian
|
|
||||||
timeout-minutes: 15
|
|
||||||
steps:
|
|
||||||
- name: 安装 Rust
|
|
||||||
run: |
|
run: |
|
||||||
|
sudo apt-get update -qq
|
||||||
|
sudo apt-get install -y -qq pkg-config musl-tools binutils jq
|
||||||
if ! command -v rustup >/dev/null 2>&1; then
|
if ! command -v rustup >/dev/null 2>&1; then
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain "${RUST_TOOLCHAIN}"
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain "${RUST_TOOLCHAIN}"
|
||||||
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||||
fi
|
fi
|
||||||
source "$HOME/.cargo/env" 2>/dev/null || true
|
source "$HOME/.cargo/env" 2>/dev/null || true
|
||||||
rustup toolchain install "${RUST_TOOLCHAIN}" --profile minimal --component rustfmt --component clippy
|
rustup toolchain install "${RUST_TOOLCHAIN}" --profile minimal \
|
||||||
|
--component rustfmt --component clippy
|
||||||
rustup default "${RUST_TOOLCHAIN}"
|
rustup default "${RUST_TOOLCHAIN}"
|
||||||
rustc -V
|
rustup target add "${MUSL_TARGET}" --toolchain "${RUST_TOOLCHAIN}"
|
||||||
cargo -V
|
rustc -V && cargo -V
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 缓存 Cargo
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
~/.cargo/registry/index
|
|
||||||
~/.cargo/registry/cache
|
|
||||||
~/.cargo/git/db
|
|
||||||
target
|
|
||||||
key: cargo-check-${{ env.RUST_TOOLCHAIN }}-${{ hashFiles('Cargo.lock') }}
|
|
||||||
restore-keys: |
|
|
||||||
cargo-check-${{ env.RUST_TOOLCHAIN }}-
|
|
||||||
cargo-check-
|
|
||||||
|
|
||||||
- run: cargo fmt -- --check
|
|
||||||
- run: cargo clippy --locked -- -D warnings
|
|
||||||
- run: cargo test --locked
|
|
||||||
|
|
||||||
build-linux:
|
|
||||||
name: Build Linux (musl)
|
|
||||||
needs: [version]
|
|
||||||
runs-on: debian
|
|
||||||
timeout-minutes: 25
|
|
||||||
steps:
|
|
||||||
- name: 安装依赖
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y pkg-config musl-tools binutils curl
|
|
||||||
if ! command -v rustup >/dev/null 2>&1; then
|
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain "${RUST_TOOLCHAIN}"
|
|
||||||
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
|
||||||
fi
|
|
||||||
source "$HOME/.cargo/env" 2>/dev/null || true
|
|
||||||
rustup toolchain install "${RUST_TOOLCHAIN}" --profile minimal
|
|
||||||
rustup default "${RUST_TOOLCHAIN}"
|
|
||||||
rustup target add ${{ env.MUSL_TARGET }} --toolchain "${RUST_TOOLCHAIN}"
|
|
||||||
rustc -V
|
|
||||||
cargo -V
|
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 缓存 Cargo
|
- name: 缓存 Cargo
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
@@ -210,10 +84,21 @@ jobs:
|
|||||||
cargo-${{ env.MUSL_TARGET }}-${{ env.RUST_TOOLCHAIN }}-
|
cargo-${{ env.MUSL_TARGET }}-${{ env.RUST_TOOLCHAIN }}-
|
||||||
cargo-${{ env.MUSL_TARGET }}-
|
cargo-${{ env.MUSL_TARGET }}-
|
||||||
|
|
||||||
|
# ── 质量检查(先于构建,失败即止)──────────────────────────────────
|
||||||
|
- name: fmt
|
||||||
|
run: cargo fmt -- --check
|
||||||
|
|
||||||
|
- name: clippy
|
||||||
|
run: cargo clippy --locked -- -D warnings
|
||||||
|
|
||||||
|
- name: test
|
||||||
|
run: cargo test --locked
|
||||||
|
|
||||||
|
# ── 构建(质量检查通过后才执行)────────────────────────────────────
|
||||||
- name: 构建 secrets-mcp (musl)
|
- name: 构建 secrets-mcp (musl)
|
||||||
run: |
|
run: |
|
||||||
cargo build --release --locked --target ${{ env.MUSL_TARGET }} -p secrets-mcp
|
cargo build --release --locked --target "${MUSL_TARGET}" -p secrets-mcp
|
||||||
strip target/${{ env.MUSL_TARGET }}/release/${{ env.MCP_BINARY }}
|
strip "target/${MUSL_TARGET}/release/${MCP_BINARY}"
|
||||||
|
|
||||||
- name: 上传构建产物
|
- name: 上传构建产物
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
@@ -222,46 +107,89 @@ jobs:
|
|||||||
path: target/${{ env.MUSL_TARGET }}/release/${{ env.MCP_BINARY }}
|
path: target/${{ env.MUSL_TARGET }}/release/${{ env.MCP_BINARY }}
|
||||||
retention-days: 3
|
retention-days: 3
|
||||||
|
|
||||||
- name: 上传 Release 产物
|
# ── 创建 Tag(构建成功后才打,避免留下指向失败提交的 tag)──────────
|
||||||
if: needs.version.outputs.release_id != ''
|
- name: 创建 Tag
|
||||||
|
run: |
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git tag -a "${{ steps.ver.outputs.tag }}" -m "Release ${{ steps.ver.outputs.tag }}"
|
||||||
|
git push origin "${{ steps.ver.outputs.tag }}"
|
||||||
|
|
||||||
|
# ── Release(可选,需配置 RELEASE_TOKEN)───────────────────────────
|
||||||
|
- name: 创建并发布 Release
|
||||||
|
if: env.RELEASE_TOKEN != ''
|
||||||
env:
|
env:
|
||||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
[ -z "$RELEASE_TOKEN" ] && exit 0
|
tag="${{ steps.ver.outputs.tag }}"
|
||||||
command -v jq >/dev/null 2>&1 || (sudo apt-get update -qq && sudo apt-get install -y -qq jq)
|
version="${{ steps.ver.outputs.version }}"
|
||||||
|
release_api="${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases"
|
||||||
|
|
||||||
tag="${{ needs.version.outputs.tag }}"
|
previous_tag=$(git tag --list 'secrets-mcp-*' --sort=-v:refname | awk -v t="$tag" '$0 != t { print; exit }')
|
||||||
bin="target/${{ env.MUSL_TARGET }}/release/${{ env.MCP_BINARY }}"
|
if [ -n "$previous_tag" ]; then
|
||||||
archive="${{ env.MCP_BINARY }}-${tag}-x86_64-linux-musl.tar.gz"
|
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")
|
||||||
|
|
||||||
|
payload=$(jq -n \
|
||||||
|
--arg tag "$tag" \
|
||||||
|
--arg name "secrets-mcp ${version}" \
|
||||||
|
--arg body "$body" \
|
||||||
|
'{tag_name: $tag, name: $name, body: $body, draft: false}')
|
||||||
|
|
||||||
|
http_code=$(curl -sS -o /tmp/release.json -w '%{http_code}' \
|
||||||
|
-H "Authorization: token $RELEASE_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-X POST "$release_api" -d "$payload")
|
||||||
|
|
||||||
|
if [ "$http_code" != "201" ] && [ "$http_code" != "200" ]; then
|
||||||
|
echo "创建 Release 失败 (HTTP ${http_code})"
|
||||||
|
cat /tmp/release.json || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
release_id=$(jq -r '.id' /tmp/release.json)
|
||||||
|
|
||||||
|
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")"
|
tar -czf "$archive" -C "$(dirname "$bin")" "$(basename "$bin")"
|
||||||
sha256sum "$archive" > "${archive}.sha256"
|
sha256sum "$archive" > "${archive}.sha256"
|
||||||
release_api="${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases/${{ needs.version.outputs.release_id }}"
|
|
||||||
release_url="${release_api}/assets"
|
|
||||||
curl -fsS -H "Authorization: token $RELEASE_TOKEN" \
|
|
||||||
"$release_api" -o /tmp/release-assets.json
|
|
||||||
|
|
||||||
for asset_name in "$archive" "${archive}.sha256"; do
|
asset_url="${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases/${release_id}/assets"
|
||||||
asset_ids=$(jq -r --arg name "$asset_name" '.assets[]? | select(.name == $name) | .id' /tmp/release-assets.json)
|
curl -fsS -H "Authorization: token $RELEASE_TOKEN" -F "attachment=@${archive}" "$asset_url"
|
||||||
if [ -n "$asset_ids" ]; then
|
curl -fsS -H "Authorization: token $RELEASE_TOKEN" -F "attachment=@${archive}.sha256" "$asset_url"
|
||||||
while IFS= read -r asset_id; do
|
echo "Release ${tag} 已发布"
|
||||||
[ -z "$asset_id" ] && continue
|
|
||||||
echo "删除已有产物: ${asset_name} (${asset_id})"
|
|
||||||
curl -fsS -X DELETE -H "Authorization: token $RELEASE_TOKEN" \
|
|
||||||
"${release_url}/${asset_id}"
|
|
||||||
done <<< "$asset_ids"
|
|
||||||
fi
|
|
||||||
|
|
||||||
curl -fsS -H "Authorization: token $RELEASE_TOKEN" \
|
# ── 飞书汇总通知 ─────────────────────────────────────────────────────
|
||||||
-F "attachment=@${asset_name}" "$release_url"
|
- name: 飞书通知
|
||||||
done
|
if: always()
|
||||||
|
env:
|
||||||
|
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}
|
||||||
|
提交:${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-mcp:
|
deploy:
|
||||||
name: 部署 secrets-mcp
|
name: 部署 secrets-mcp
|
||||||
needs: [version, check, build-linux]
|
needs: [ci]
|
||||||
if: |
|
if: |
|
||||||
needs.check.result == 'success' &&
|
github.ref == 'refs/heads/main' ||
|
||||||
needs.build-linux.result == 'success' &&
|
github.ref == 'refs/heads/feat/mcp' ||
|
||||||
(github.ref == 'refs/heads/main' || github.ref == 'refs/heads/feat/mcp' || github.ref == 'refs/heads/mcp')
|
github.ref == 'refs/heads/mcp'
|
||||||
runs-on: debian
|
runs-on: debian
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
@@ -278,16 +206,15 @@ jobs:
|
|||||||
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||||
run: |
|
run: |
|
||||||
if [ -z "$DEPLOY_HOST" ] || [ -z "$DEPLOY_USER" ] || [ -z "$DEPLOY_SSH_KEY" ]; then
|
if [ -z "$DEPLOY_HOST" ] || [ -z "$DEPLOY_USER" ] || [ -z "$DEPLOY_SSH_KEY" ]; then
|
||||||
echo "部署跳过:请在仓库 Actions 中配置 vars.DEPLOY_HOST、vars.DEPLOY_USER 与 secrets.DEPLOY_SSH_KEY"
|
echo "部署跳过:请配置 vars.DEPLOY_HOST、vars.DEPLOY_USER 与 secrets.DEPLOY_SSH_KEY"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "$DEPLOY_SSH_KEY" > /tmp/deploy_key
|
echo "$DEPLOY_SSH_KEY" > /tmp/deploy_key
|
||||||
chmod 600 /tmp/deploy_key
|
chmod 600 /tmp/deploy_key
|
||||||
|
|
||||||
SCP="scp -i /tmp/deploy_key -o StrictHostKeyChecking=no"
|
scp -i /tmp/deploy_key -o StrictHostKeyChecking=no \
|
||||||
|
"/tmp/artifact/${MCP_BINARY}" \
|
||||||
$SCP /tmp/artifact/${{ env.MCP_BINARY }} \
|
|
||||||
"${DEPLOY_USER}@${DEPLOY_HOST}:/tmp/secrets-mcp.new"
|
"${DEPLOY_USER}@${DEPLOY_HOST}:/tmp/secrets-mcp.new"
|
||||||
|
|
||||||
ssh -i /tmp/deploy_key -o StrictHostKeyChecking=no "${DEPLOY_USER}@${DEPLOY_HOST}" "
|
ssh -i /tmp/deploy_key -o StrictHostKeyChecking=no "${DEPLOY_USER}@${DEPLOY_HOST}" "
|
||||||
@@ -297,7 +224,6 @@ jobs:
|
|||||||
sleep 2
|
sleep 2
|
||||||
sudo systemctl is-active secrets-mcp && echo '服务启动成功' || (sudo journalctl -u secrets-mcp -n 20 && exit 1)
|
sudo systemctl is-active secrets-mcp && echo '服务启动成功' || (sudo journalctl -u secrets-mcp -n 20 && exit 1)
|
||||||
"
|
"
|
||||||
|
|
||||||
rm -f /tmp/deploy_key
|
rm -f /tmp/deploy_key
|
||||||
|
|
||||||
- name: 飞书通知
|
- name: 飞书通知
|
||||||
@@ -306,94 +232,13 @@ jobs:
|
|||||||
WEBHOOK_URL: ${{ vars.WEBHOOK_URL }}
|
WEBHOOK_URL: ${{ vars.WEBHOOK_URL }}
|
||||||
run: |
|
run: |
|
||||||
[ -z "$WEBHOOK_URL" ] && exit 0
|
[ -z "$WEBHOOK_URL" ] && exit 0
|
||||||
command -v jq >/dev/null 2>&1 || (sudo apt-get update -qq && sudo apt-get install -y -qq jq)
|
tag="${{ needs.ci.outputs.tag }}"
|
||||||
tag="${{ needs.version.outputs.tag }}"
|
|
||||||
url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}"
|
url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}"
|
||||||
result="${{ job.status }}"
|
result="${{ job.status }}"
|
||||||
if [ "$result" = "success" ]; then icon="✅"; else icon="❌"; fi
|
if [ "$result" = "success" ]; then icon="✅"; else icon="❌"; fi
|
||||||
msg="secrets-mcp 部署${icon}
|
msg="secrets-mcp 部署 ${icon}
|
||||||
版本:${tag}
|
版本:${tag}
|
||||||
作者:${{ github.actor }}
|
作者:${{ github.actor }}
|
||||||
详情:${url}"
|
详情:${url}"
|
||||||
payload=$(jq -n --arg text "$msg" '{msg_type: "text", content: {text: $text}}')
|
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"
|
curl -sS -H "Content-Type: application/json" -X POST -d "$payload" "$WEBHOOK_URL"
|
||||||
|
|
||||||
publish-release:
|
|
||||||
name: 发布草稿 Release
|
|
||||||
needs: [version, check, build-linux]
|
|
||||||
if: always() && needs.version.outputs.release_id != ''
|
|
||||||
runs-on: debian
|
|
||||||
timeout-minutes: 5
|
|
||||||
steps:
|
|
||||||
- name: 发布草稿
|
|
||||||
env:
|
|
||||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
||||||
run: |
|
|
||||||
[ -z "$RELEASE_TOKEN" ] && exit 0
|
|
||||||
|
|
||||||
check_r="${{ needs.check.result }}"
|
|
||||||
linux_r="${{ needs.build-linux.result }}"
|
|
||||||
if [ "$check_r" != "success" ] || [ "$linux_r" != "success" ]; then
|
|
||||||
echo "质量检查或构建未成功(check=${check_r}, build=${linux_r}),保留草稿 Release"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
release_api="${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases/${{ needs.version.outputs.release_id }}"
|
|
||||||
http_code=$(curl -sS -o /tmp/publish-release.json -w '%{http_code}' \
|
|
||||||
-H "Authorization: token $RELEASE_TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-X PATCH "$release_api" \
|
|
||||||
-d '{"draft":false}')
|
|
||||||
|
|
||||||
if [ "$http_code" != "200" ]; then
|
|
||||||
echo "发布草稿 Release 失败 (HTTP ${http_code})"
|
|
||||||
cat /tmp/publish-release.json 2>/dev/null || true
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Release 已发布"
|
|
||||||
|
|
||||||
- name: 飞书汇总通知
|
|
||||||
if: always()
|
|
||||||
env:
|
|
||||||
WEBHOOK_URL: ${{ vars.WEBHOOK_URL }}
|
|
||||||
run: |
|
|
||||||
[ -z "$WEBHOOK_URL" ] && exit 0
|
|
||||||
command -v jq >/dev/null 2>&1 || (sudo apt-get update -qq && sudo apt-get install -y -qq jq)
|
|
||||||
|
|
||||||
tag="${{ needs.version.outputs.tag }}"
|
|
||||||
tag_exists="${{ needs.version.outputs.tag_exists }}"
|
|
||||||
commit="${{ github.event.head_commit.message }}"
|
|
||||||
[ -z "$commit" ] && commit="${{ github.sha }}"
|
|
||||||
url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}"
|
|
||||||
|
|
||||||
check_r="${{ needs.check.result }}"
|
|
||||||
linux_r="${{ needs.build-linux.result }}"
|
|
||||||
publish_r="${{ job.status }}"
|
|
||||||
|
|
||||||
icon() { case "$1" in success) echo "✅";; skipped) echo "⏭";; *) echo "❌";; esac; }
|
|
||||||
|
|
||||||
if [ "$check_r" = "success" ] && [ "$linux_r" = "success" ] && [ "$publish_r" = "success" ]; then
|
|
||||||
status="发布成功 ✅"
|
|
||||||
elif [ "$check_r" != "success" ]; then
|
|
||||||
status="检查失败 ❌"
|
|
||||||
elif [ "$linux_r" != "success" ]; then
|
|
||||||
status="构建失败 ❌"
|
|
||||||
else
|
|
||||||
status="发布失败 ❌"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$tag_exists" = "false" ]; then
|
|
||||||
version_line="🆕 新版本 ${tag}"
|
|
||||||
else
|
|
||||||
version_line="🔄 重复构建 ${tag}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg="secrets-mcp ${status}
|
|
||||||
${version_line}
|
|
||||||
check $(icon "$check_r") | linux $(icon "$linux_r") | Release $(icon "$publish_r")
|
|
||||||
提交:${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"
|
|
||||||
|
|||||||
Reference in New Issue
Block a user