-
Notifications
You must be signed in to change notification settings - Fork 1
176 lines (157 loc) · 6.28 KB
/
release.yml
File metadata and controls
176 lines (157 loc) · 6.28 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
name: release
# Publish to crates.io.
#
# Triggered by:
# - a GitHub Release published event (release-please drives this via
# PAT, so this fires automatically on merge of the release PR), or
# - a manual workflow_dispatch with an explicit existing tag (for
# re-runs or emergency releases).
#
# Note: the `push: tags:` trigger was removed because release-please
# now uses a PAT (RELEASE_PLEASE_TOKEN) that fires both `release:
# published` AND `push: tags:` events. Keeping both caused duplicate
# runs. For emergency releases that bypass release-please, use
# workflow_dispatch.
#
# Stable tags (v0.1.0) mark the GitHub release as latest; pre-release
# tags (v0.1.0-rc.1) mark it as prerelease so it doesn't show as
# "Latest release" on the repo home.
#
# Publishing is destructive — version numbers on crates.io are
# permanent. This workflow re-runs the full test matrix before
# touching crates.io, and publishes crates strictly in dependency
# order with a small settle delay between each so the index is
# consistent for downstream crates.
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Tag to release (e.g. v0.1.0-rc.1). Must already exist."
required: true
concurrency:
group: release
cancel-in-progress: false
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
verify:
if: github.repository == 'tableau/hyper-api-rust'
name: verify
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.inputs.tag || github.event.release.tag_name || github.ref }}
- name: Install system libraries
run: sudo apt-get update -q && sudo apt-get install -y libfontconfig1-dev mold protobuf-compiler
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
cache-key: release-verify
rustflags: ""
- name: Cache hyperd binary
id: hyperd-cache
uses: actions/cache@v5
with:
path: .hyperd
key: hyperd-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('hyperdb-bootstrap/hyperd-version.toml') }}
- name: Download hyperd
if: steps.hyperd-cache.outputs.cache-hit != 'true'
run: cargo run --release -p hyperdb-bootstrap --bin hyperdb-bootstrap -- download
- name: Workspace tests
env:
HYPERD_PATH: ${{ github.workspace }}/.hyperd/current
run: |
cargo test --workspace \
--exclude hyperdb-api-node \
--exclude hyperdb-bootstrap
- name: hyperdb-bootstrap tests
run: cargo test -p hyperdb-bootstrap
- name: Verify pinned hyperd release URLs still resolve
run: cargo run --release -p hyperdb-bootstrap --bin hyperdb-bootstrap -- verify
publish:
name: publish to crates.io
needs: verify
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.inputs.tag || github.event.release.tag_name || github.ref }}
- name: Install system libraries
run: sudo apt-get update -q && sudo apt-get install -y libfontconfig1-dev mold protobuf-compiler
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
cache-key: release-publish
rustflags: ""
- name: Resolve tag name
id: tag
env:
REF_NAME: ${{ github.ref_name }}
INPUT_TAG: ${{ github.event.inputs.tag }}
RELEASE_TAG: ${{ github.event.release.tag_name }}
run: |
set -euo pipefail
TAG="${INPUT_TAG:-${RELEASE_TAG:-$REF_NAME}}"
# Defense in depth: tags coming from workflow_dispatch are
# user-supplied. Enforce a strict `vX.Y.Z` / `vX.Y.Z-rc.N`
# shape before letting the name flow into cargo/git commands.
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-(rc|alpha|beta)\.[0-9]+)?$ ]]; then
echo "::error::Invalid tag name: $TAG (expected vX.Y.Z or vX.Y.Z-rc.N)" >&2
exit 1
fi
echo "name=$TAG" >> "$GITHUB_OUTPUT"
echo "version=${TAG#v}" >> "$GITHUB_OUTPUT"
- name: Confirm tag matches workspace version
# All publishable crates are in lockstep. Use hyperdb-api-core as
# the bellwether (it's the foundation every other crate depends on).
env:
EXPECTED: ${{ steps.tag.outputs.version }}
run: |
set -euo pipefail
ACTUAL=$(cargo metadata --no-deps --format-version 1 \
| jq -r '.packages[] | select(.name=="hyperdb-api-core") | .version')
if [[ "$EXPECTED" != "$ACTUAL" ]]; then
echo "::error::Tag version ($EXPECTED) does not match hyperdb-api-core Cargo.toml ($ACTUAL). Bump all workspace Cargo.tomls to match the tag before releasing." >&2
exit 1
fi
- name: Publish in dependency order
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
set -euo pipefail
publish() {
local crate="$1"
echo "::group::Publishing $crate"
if ! cargo publish -p "$crate" 2>&1 | tee /tmp/publish_out; then
if grep -q "already exists on" /tmp/publish_out; then
echo "::warning::$crate already published — skipping"
else
echo "::endgroup::"
return 1
fi
fi
echo "::endgroup::"
# crates.io index propagation: downstream crates' own
# `cargo publish` verification step resolves their deps
# against the live index. 45s is the empirically-safe
# window for small crates.
sleep 45
}
publish hyperdb-api-salesforce
publish hyperdb-api-core
publish hyperdb-api
publish hyperdb-mcp
publish hyperdb-bootstrap
publish sea-query-hyperdb
- name: Create GitHub release
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ steps.tag.outputs.name }}
prerelease: ${{ contains(steps.tag.outputs.name, '-rc.') || contains(steps.tag.outputs.name, '-alpha.') || contains(steps.tag.outputs.name, '-beta.') }}
generate_release_notes: true