-
Notifications
You must be signed in to change notification settings - Fork 65
191 lines (174 loc) · 7.69 KB
/
Copy pathpublish-datatype-parser.yml
File metadata and controls
191 lines (174 loc) · 7.69 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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
name: "publish: datatype parser"
# Independent publish + release for the standalone @clickhouse/datatype-parser
# package (the data-type string parser). Like the per-package client publish
# workflows (publish-client*.yml), it carries its own version in
# packages/datatype-parser/package.json and ships on its own cadence. Triggered
# manually, and — like those workflows — must be dispatched from the `release`
# branch: the npm-publish environment is protected so only that branch may
# deploy (the repo's human-in-the-loop release gate). Dispatches from any other
# ref are skipped by the job-level `if` guard below.
#
# The release branch is itself protected, so the unit suite is not re-run here.
# The `publish` job instead builds, packs the tarball, installs that exact
# tarball into a throwaway project and smoke-tests its imports, and only then
# publishes the same tarball with the "latest" tag (npm OIDC + provenance) and
# pushes a matching git tag. The `e2e` job then repeats the smoke test against
# the freshly published version on the registry across the supported Node
# versions.
permissions:
contents: read
id-token: write # Required for npm OIDC authentication and provenance
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
on:
workflow_dispatch:
env:
# Network resilience: npm's default of 2 fetch retries is not enough for
# the transient registry errors (ECONNRESET) we regularly hit in CI.
NPM_CONFIG_FETCH_RETRIES: "5"
NPM_CONFIG_FETCH_RETRY_MINTIMEOUT: "10000"
NPM_CONFIG_FETCH_RETRY_MAXTIMEOUT: "60000"
NPM_CONFIG_FETCH_TIMEOUT: "600000"
jobs:
publish:
# The npm-publish environment only permits the release branch to deploy;
# skip cleanly on any other ref instead of failing the protection check.
if: github.ref == 'refs/heads/release'
runs-on: ubuntu-latest
timeout-minutes: 10
environment: npm-publish
permissions:
contents: write # Required to push the release git tag
id-token: write # Required for npm OIDC authentication and provenance
defaults:
run:
working-directory: packages/datatype-parser
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 24
registry-url: "https://registry.npmjs.org"
- name: Install dependencies
# datatype-parser is an npm workspace package, so install the whole
# workspace from the repo root (overriding this job's package-dir
# default). A scoped `npm ci` from the package dir still fires the root
# lifecycle scripts (postinstall/parquet-wasm, prepare/husky) but
# without their dev-only devDependencies, which breaks the install. The
# remaining steps run from packages/datatype-parser as usual.
working-directory: ${{ github.workspace }}
run: npm ci
- name: Build
run: npm run build
- name: Get the release version
id: version
run: |
VERSION=$(node -p "require('./package.json').version")
echo "Publishing @clickhouse/datatype-parser@$VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Pack the tarball
id: pack
# prepack rebuilds dist before packing.
run: |
set -euo pipefail
TARBALL=$(npm pack --pack-destination "$RUNNER_TEMP" | tail -1)
echo "Packed: $TARBALL"
echo "tarball=$RUNNER_TEMP/$TARBALL" >> "$GITHUB_OUTPUT"
- name: Pre-publish smoke test (install the packed tarball)
env:
TARBALL: ${{ steps.pack.outputs.tarball }}
run: |
set -euo pipefail
work="$(mktemp -d)"
cd "$work"
npm init -y >/dev/null 2>&1
npm install "$TARBALL"
# Verify the main barrel entry resolves and exposes the parser, from
# the exact artifact we are about to publish.
node --input-type=module -e "
import * as dt from '@clickhouse/datatype-parser';
if (typeof dt.parseDataType !== 'function') throw new Error('parseDataType missing from main export');
console.log('OK: packed tarball imports cleanly');
"
- name: Publish to npm
# Publish the exact tarball that passed the pre-publish smoke test.
env:
TARBALL: ${{ steps.pack.outputs.tarball }}
run: npm publish "$TARBALL" --access public --provenance
- name: Create and push release git tag
env:
RELEASE_TAG: datatype-parser-v${{ steps.version.outputs.version }}
RELEASE_VERSION: ${{ steps.version.outputs.version }}
run: |
if git ls-remote --exit-code --tags origin "refs/tags/${RELEASE_TAG}" >/dev/null 2>&1; then
echo "Tag ${RELEASE_TAG} already exists on origin; skipping."
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag -a "${RELEASE_TAG}" -m "Release @clickhouse/datatype-parser ${RELEASE_VERSION}"
git push origin "refs/tags/${RELEASE_TAG}"
e2e:
name: e2e (node ${{ matrix.node }})
needs: publish
if: needs.publish.result == 'success'
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: true
matrix:
node: [20, 22, 24, 26]
env:
PUBLISHED_VERSION: ${{ needs.publish.outputs.version }}
steps:
- name: Setup NodeJS ${{ matrix.node }}
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: ${{ matrix.node }}
registry-url: "https://registry.npmjs.org"
- name: Wait for @clickhouse/datatype-parser@${{ needs.publish.outputs.version }} on npm
run: |
set -euo pipefail
if [ -z "${PUBLISHED_VERSION}" ]; then
echo "PUBLISHED_VERSION is empty; cannot wait for npm publication." >&2
exit 1
fi
pkg="@clickhouse/datatype-parser"
# Poll the registry for up to ~5 minutes. New versions usually surface
# in seconds, but the registry CDN can lag.
max_attempts=60
sleep_seconds=5
attempt=1
echo "Waiting for ${pkg}@${PUBLISHED_VERSION} to be available on npm..."
while true; do
if npm view "${pkg}@${PUBLISHED_VERSION}" version >/dev/null 2>&1; then
echo " ${pkg}@${PUBLISHED_VERSION} is available."
break
fi
if [ "$attempt" -ge "$max_attempts" ]; then
echo "Timed out waiting for ${pkg}@${PUBLISHED_VERSION} on npm" >&2
exit 1
fi
echo " attempt ${attempt}/${max_attempts}: not available yet, sleeping ${sleep_seconds}s..."
attempt=$((attempt + 1))
sleep "$sleep_seconds"
done
- name: Install and import the published package
run: |
set -euo pipefail
work="$(mktemp -d)"
cd "$work"
npm init -y >/dev/null 2>&1
npm install "@clickhouse/datatype-parser@${PUBLISHED_VERSION}"
# Verify the main barrel entry resolves and exposes the parser to a
# downstream consumer.
node --input-type=module -e "
import * as dt from '@clickhouse/datatype-parser';
if (typeof dt.parseDataType !== 'function') throw new Error('parseDataType missing from main export');
console.log('OK: @clickhouse/datatype-parser@${PUBLISHED_VERSION} imports cleanly');
"