-
Notifications
You must be signed in to change notification settings - Fork 0
177 lines (160 loc) · 6.21 KB
/
release.yml
File metadata and controls
177 lines (160 loc) · 6.21 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
name: specs release
on:
workflow_dispatch:
inputs:
version:
description: 'Release version (e.g., 0.1.0)'
required: true
notes:
description: 'Additional release notes (optional)'
required: false
adr_url:
description: 'ADR discussion URL'
required: true
spec_issue:
description: 'Spec issue number'
required: true
wiki_url:
description: 'Wiki page URL'
required: true
permissions:
contents: write
pull-requests: read
issues: write
discussions: write
jobs:
release:
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
INPUT_VERSION: ${{ github.event.inputs.version }}
INPUT_NOTES: ${{ github.event.inputs.notes }}
ADR_URL: ${{ github.event.inputs.adr_url }}
SPEC_ISSUE: ${{ github.event.inputs.spec_issue }}
WIKI_URL: ${{ github.event.inputs.wiki_url }}
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
steps:
- uses: actions/checkout@v4
- name: Set up git identity
run: |
git config user.name "specs-bot"
git config user.email "specs-bot@users.noreply.github.com"
- name: Prepare variables
id: prep
run: |
VERSION="$INPUT_VERSION"
if [ -z "$VERSION" ]; then
echo "Release version input is required."
exit 1
fi
TAG="v${VERSION}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
- name: Ensure changelog contains version entry
run: |
TAG="${{ steps.prep.outputs.tag }}"
VERSION="${{ steps.prep.outputs.version }}"
if ! grep -qE "## (v?${VERSION}|${TAG})" CHANGELOG.md; then
echo "CHANGELOG.md missing entry for ${TAG} (accepts headings like '## ${TAG}' or '## ${VERSION}')."
exit 1
fi
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 18
- name: Checkout specs tool
uses: actions/checkout@v4
with:
repository: ganesh47/specs
path: .specs-tool
- name: Install specs tool deps
working-directory: .specs-tool
run: npm install
- name: Build specs CLI
working-directory: .specs-tool
run: npm run build --workspace packages/specs-cli
- name: spec-kit availability
run: npm run spec-kit:check
- name: Run specs coverage for artifacts
run: node .specs-tool/packages/specs-cli/bin/specs.js coverage
- name: Extract changelog section
id: notes
env:
TAG: ${{ steps.prep.outputs.tag }}
INPUT_NOTES: ${{ env.INPUT_NOTES }}
run: |
awk -v tag="## ${TAG}" '
$0 ~ tag {flag=1; next}
/^## / && flag {flag=0}
flag {print}
' CHANGELOG.md > release-notes.md
if [ ! -s release-notes.md ]; then
echo "No release notes extracted for ${TAG}. Ensure CHANGELOG.md has a section."
exit 1
fi
if [ -n "$INPUT_NOTES" ]; then
printf "\n## Additional Notes\n%s\n" "$INPUT_NOTES" >> release-notes.md
fi
- name: Create GitHub Release (creates tag if missing)
env:
TAG: ${{ steps.prep.outputs.tag }}
run: |
if gh release view "$TAG" >/dev/null 2>&1; then
gh release edit "$TAG" --latest --notes-file release-notes.md
else
gh release create "$TAG" --latest --notes-file release-notes.md --target main
fi
- name: Upload coverage artifact to release
env:
TAG: ${{ steps.prep.outputs.tag }}
run: |
if [ -f .specs/coverage-report.json ]; then
gh release upload "$TAG" .specs/coverage-report.json --clobber
else
echo "No coverage report found to upload."
fi
- name: Comment in ADR discussion
env:
TAG: ${{ steps.prep.outputs.tag }}
run: |
adr_number=$(printf "%s" "$ADR_URL" | sed -E 's#.*/discussions/([0-9]+).*#\1#')
body=$(cat <<'EOF'
Release {TAG} published.
- Release: https://github.com/{REPO}/releases/{TAG}
- Changelog: https://github.com/{REPO}/blob/main/CHANGELOG.md
- Issue: https://github.com/{REPO}/issues/{ISSUE}
- Wiki: {WIKI}
EOF
)
body="${body//\{TAG\}/$TAG}"
body="${body//\{ISSUE\}/$SPEC_ISSUE}"
body="${body//\{WIKI\}/$WIKI_URL}"
body="${body//\{REPO\}/$GITHUB_REPOSITORY}"
gh api graphql -f query='mutation($id:ID!,$body:String!){addDiscussionComment(input:{discussionId:$id,body:$body}){comment{id}}}' \
-f id="$(gh api graphql -f query='query($owner:String!,$name:String!,$number:Int!){repository(owner:$owner,name:$name){discussion(number:$number){id}}}' -f owner=${GITHUB_REPOSITORY%/*} -f name=${GITHUB_REPOSITORY#*/} -F number="$adr_number" --jq .data.repository.discussion.id)" \
-f body="$body"
- name: Update wiki with release entry
env:
TAG: ${{ steps.prep.outputs.tag }}
run: |
page=$(basename "$WIKI_URL")
tmpdir=$(mktemp -d)
git clone "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.wiki.git" "$tmpdir/wiki"
cd "$tmpdir/wiki"
git config user.name "specs-bot"
git config user.email "specs-bot@users.noreply.github.com"
cat >> "${page}.md" <<EOF
## ${TAG}
- Release: https://github.com/${GITHUB_REPOSITORY}/releases/${TAG}
- Changelog: https://github.com/${GITHUB_REPOSITORY}/blob/main/CHANGELOG.md
- ADR: ${ADR_URL}
- Issue: https://github.com/${GITHUB_REPOSITORY}/issues/${SPEC_ISSUE}
EOF
git add "${page}.md"
git commit -m "Add release notes for ${TAG}"
git push origin master
- name: Comment on related spec issue
env:
TAG: ${{ steps.prep.outputs.tag }}
run: |
gh issue comment "$SPEC_ISSUE" --body "Released ${TAG}: https://github.com/${GITHUB_REPOSITORY}/releases/${TAG}\nChangelog updated, ADR discussion noted, wiki updated: $WIKI_URL"