-
-
Notifications
You must be signed in to change notification settings - Fork 8
148 lines (135 loc) · 6.72 KB
/
Copy pathrelease.yml
File metadata and controls
148 lines (135 loc) · 6.72 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
name: Release
# Cut a GitHub Release whenever a vX.Y.Z tag is pushed. The tag is the
# trigger and the contract: the workflow re-runs the verify gate against
# the exact tagged commit, then publishes a Release whose body is that
# version's CHANGELOG section. A tag only ships if the build is green.
#
# Tags are pushed by scripts/cut-release.ps1 after it bumps every version
# site (library pom, aggregator, examples/benchmarks parents, README
# install snippets) in the release commit, so the version guard in the
# verify step below passes by construction.
on:
push:
tags:
- 'v*'
permissions:
contents: write
# One GitHub Release per tag. A re-pushed tag queues behind the in-flight run
# for that same tag rather than racing it; cancel-in-progress is false so a
# release is never aborted mid-creation. Distinct tags carry distinct refs and
# still proceed in parallel.
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
release:
name: Verify and publish GitHub Release
runs-on: ubuntu-latest
env:
JAVA_TOOL_OPTIONS: -Djava.awt.headless=true
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Set up Temurin JDK 17
uses: actions/setup-java@v6
with:
distribution: temurin
java-version: '17'
cache: maven
- name: Verify (gate the release on a green build)
run: ./mvnw -B -ntp clean verify
# The pack describes the API of the commit being tagged, and `verify`
# above has already produced the classes it reads. --check first, so a tag
# cannot ship a pack that disagrees with the code it claims to describe;
# the write that follows is then a no-op for tracked files and exists only
# to produce target/knowledge/provenance.json, which the bundle carries.
- name: Set up Node for the knowledge bundle
uses: actions/setup-node@v7
with:
node-version: '20'
- name: Build the knowledge bundle
run: |
node knowledge/tools/api-surface/extract-api.mjs --from-reactor --check
node knowledge/tools/api-surface/extract-api.mjs --from-reactor
# The bundle carries claims/ and routing/ too, so a correct API surface
# is not enough to publish it: a hand-authored route or a stale claims
# index would ship as a release asset unchallenged. The tag re-checks
# them against the exact commit being tagged rather than trusting that
# a PR run covered it. (check-routes has no --check: routes have no
# generated counterpart, so validating them is the check.)
node knowledge/tools/claims/check-claims.mjs --check
node knowledge/tools/routing/check-routes.mjs
# And the tool fixtures, for the same reason. build-bundle --verify
# asserts exit codes only, which cannot see whether the version
# comparison inside the shipped bin/query.mjs is right — and that copy
# exists precisely because the bundle cannot import the shared module.
# Without this, the one thing pinning it never runs at a tag.
for suite in $(find knowledge/tools -type f -name '*.test.mjs' | sort); do
echo "--- $suite"
node "$suite"
done
node knowledge/tools/bundle/build-bundle.mjs --verify
- name: Extract CHANGELOG section for the tag
id: notes
run: |
TAG="${GITHUB_REF_NAME}"
# A pre-release (vX.Y.Z-rc.N / -alpha / -beta) has no CHANGELOG section of its
# own — it is cut against the upcoming FINAL version's notes. Strip the
# pre-release suffix so the lookup uses the final section (## vX.Y.Z, whether
# still "— Planned" or already dated). A final tag has no suffix, so NOTES_TAG
# == TAG.
NOTES_TAG="${TAG%%-*}"
NOTES_FILE="${RUNNER_TEMP}/release-notes.md"
# Print the "## <NOTES_TAG> — ..." heading and every line up to the
# next "## v" heading. index()==1 is a literal prefix match, so
# the dots in the version are not treated as regex wildcards and
# the trailing space stops "## v1.6.5 " from matching "v1.6.50".
awk -v hdr="## ${NOTES_TAG} " '
index($0, hdr) == 1 { flag = 1; print; next }
/^## v/ && flag { flag = 0 }
flag { print }
' CHANGELOG.md > "${NOTES_FILE}"
if [ ! -s "${NOTES_FILE}" ]; then
echo "::warning::No CHANGELOG section found for ${NOTES_TAG}; using a generic note."
printf '%s\n' "Release ${TAG}. See [CHANGELOG.md](CHANGELOG.md) for details." > "${NOTES_FILE}"
fi
# GitHub refuses a Release body over 125 000 characters (HTTP 422), which is
# how the v2.4.0 tag's Release failed after its build had passed. A section
# that fits is left as written; a longer one is cut to its entry leads with a
# link to the full section at the tag.
node scripts/release-notes.mjs "${NOTES_FILE}" "${TAG}" "${GITHUB_REPOSITORY}"
echo "notes_file=${NOTES_FILE}" >> "${GITHUB_OUTPUT}"
# Tags carrying a pre-release suffix (e.g. v1.7.0-rc.1) ship as
# GitHub pre-releases so they never become "Latest".
if printf '%s' "${TAG}" | grep -q '-'; then
echo "prerelease=true" >> "${GITHUB_OUTPUT}"
else
echo "prerelease=false" >> "${GITHUB_OUTPUT}"
fi
- name: Create or update GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${GITHUB_REF_NAME}"
PRERELEASE_FLAG=""
if [ "${{ steps.notes.outputs.prerelease }}" = "true" ]; then
PRERELEASE_FLAG="--prerelease"
fi
if gh release view "${TAG}" >/dev/null 2>&1; then
echo "Release ${TAG} already exists — updating its notes."
gh release edit "${TAG}" --notes-file "${{ steps.notes.outputs.notes_file }}"
else
gh release create "${TAG}" \
--title "GraphCompose ${TAG}" \
--notes-file "${{ steps.notes.outputs.notes_file }}" \
--verify-tag \
${PRERELEASE_FLAG}
fi
# The archive and its checksum go up as two assets. The checksum sits
# BESIDE the archive, never inside it: a hash stored in the file it
# describes is rewritten by whatever rewrote the file.
- name: Attach the knowledge bundle to the release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload "${GITHUB_REF_NAME}" target/knowledge/graph-compose-knowledge-*.zip target/knowledge/graph-compose-knowledge-*.zip.sha256 --clobber