-
Notifications
You must be signed in to change notification settings - Fork 1
121 lines (110 loc) · 4.6 KB
/
Copy pathrelease.yml
File metadata and controls
121 lines (110 loc) · 4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
name: Release
on:
push:
branches: [master]
paths: ['CHANGELOG.md']
workflow_dispatch:
inputs:
dry_run:
description: '只解析版本号,不创建 tag / Release'
type: boolean
default: false
permissions:
contents: write
env:
GH_TOKEN: ${{ github.token }}
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout (full history for tag enumeration)
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Resolve latest version from CHANGELOG
id: ver
shell: bash
run: |
VER=$(grep -m1 -E '^## +v[0-9]+\.[0-9]+\.[0-9]+' CHANGELOG.md | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+')
echo "version=$VER" >> "$GITHUB_OUTPUT"
echo "解析到版本: ${VER:-(无,跳过)}"
- name: Idempotency guard (skip if tag/release exists)
id: decide
if: steps.ver.outputs.version != ''
shell: bash
run: |
VER=${{ steps.ver.outputs.version }}
if git rev-parse "$VER" >/dev/null 2>&1 || gh release view "$VER" >/dev/null 2>&1; then
echo "skip=1" >> "$GITHUB_OUTPUT"
echo "$VER 已存在,跳过"
else
echo "skip=0" >> "$GITHUB_OUTPUT"
fi
- name: Confirm CI is green (wait for Layer 0 Static Verify)
id: ci
if: steps.ver.outputs.version != ''
shell: bash
env:
SHA: ${{ github.sha }}
run: |
# push 触发时强依赖真实 CI 结果;手动 dispatch 无外部 CI 运行,回退到下方内联 T0 门禁
if [ "${{ github.event_name }}" != "push" ]; then
echo "非 push 触发(${{ github.event_name }}),无外部 CI 运行,依赖下方内联 T0 门禁"
echo "enforced=inline" >> "$GITHUB_OUTPUT"
exit 0
fi
# 轮询等待本 SHA 的 Layer 0 Static Verify 跑完,最多约 6 分钟
for i in $(seq 1 36); do
RUN=$(gh run list --repo "$GITHUB_REPOSITORY" --workflow ci.yml --commit "$SHA" --json databaseId,status,conclusion --limit 1)
STATUS=$(echo "$RUN" | jq -r '.[0].status // empty')
CONCL=$(echo "$RUN" | jq -r '.[0].conclusion // empty')
echo "attempt $i: status=$STATUS conclusion=$CONCL"
if [ "$STATUS" = "completed" ]; then
if [ "$CONCL" = "success" ]; then
echo "CI 全绿,继续发布"
echo "enforced=external" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "::error::CI 未通过(conclusion=$CONCL),中止发布"
exit 1
fi
sleep 10
done
echo "::error::等待 CI 超时(>360s),中止发布"
exit 1
- name: Dry run
if: github.event.inputs.dry_run == 'true' && steps.ver.outputs.version != ''
run: echo "DRY RUN -> 将发 ${{ steps.ver.outputs.version }}"
- name: Gate - Layer 0 static verify (fallback for manual dispatch)
if: steps.decide.outputs.skip == '0' && github.event.inputs.dry_run != 'true' && steps.ci.outputs.enforced != 'external'
shell: pwsh
run: pwsh .opencode/tests/T0-static-verify.ps1
- name: Create tag (concurrency-safe)
if: steps.decide.outputs.skip == '0' && github.event.inputs.dry_run != 'true'
shell: bash
run: |
VER=${{ steps.ver.outputs.version }}
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "$VER" -m "$VER"
git push origin "$VER" \
|| (git rev-parse "$VER" >/dev/null 2>&1 && echo "tag 已存在(并发),视为成功" && exit 0) \
|| exit 1
- name: Create Release + archives
if: steps.decide.outputs.skip == '0' && github.event.inputs.dry_run != 'true'
shell: bash
run: |
VER=${{ steps.ver.outputs.version }}
gh release view "$VER" >/dev/null 2>&1 && { echo "release 已存在"; exit 0; }
git archive --format=zip -o "opencode-moa-$VER.zip" "$VER"
git archive --format=tar.gz -o "opencode-moa-$VER.tar.gz" "$VER"
# extract this version's section (bilingual <details>) from CHANGELOG.md
awk -v ver="$VER" '
/^## +v/ {
if (p) exit
if ($0 ~ ver) p=1
}
p { print }
' CHANGELOG.md > release-notes.md
gh release create "$VER" --title "$VER" --notes-file release-notes.md \
"opencode-moa-$VER.zip" "opencode-moa-$VER.tar.gz"