Skip to content

Commit 3dea32c

Browse files
kentkwuclaude
andauthored
feat(javascript): add npm publishing workflow and release scripts (#4076)
This PR implements the npm publishing and release scripts for the Node.js Driver Manager. - ci/scripts/node_npm_upload.sh — publishes platform + main packages to an npm registry - packaging.yml — upload-npm job publishes to npm with --tag next on schedule or manual dispatch - dev/release/post-09-npm.sh — release manager script to publish official releases - dev/release/02-sign.sh — GPG signing for npm tarballs - dev/release/utils-prepare.sh — JavaScript version bumping added to release preparation - Package renamed to `apache-arrow/adbc-driver-manager` with proper versioning (0.23.0) **Test Plan** Tested packaging and npm publishing against a local proxy registry from my fork - [Action Run: 22973831085](https://github.com/kentkwu/arrow-adbc/actions/runs/22973831085/job/66698340917) ```sh # Start a local Verdaccio registry docker run -d --name verdaccio-adbc-test -p 4873:4873 verdaccio/verdaccio sleep 3 # Create a test user and capture the auth token TOKEN=$(curl -s -X PUT http://localhost:4873/-/user/org.couchdb.user:testuser \ -H "Content-Type: application/json" \ -d '{"name":"testuser","password":"testpass","type":"user"}' \ | jq -r '.token') # Download CI-built packages from a workflow run gh run download 22973831085 --repo kentkwu/arrow-adbc --name node-packages --dir /tmp/node-packages # Publish to local registry NPM_TOKEN="${TOKEN}" \ NPM_REGISTRY=http://localhost:4873 \ ./ci/scripts/node_npm_upload.sh /tmp/node-packages/ # Verify - note: needs at symbol before apache-arrow npm view apache-arrow/adbc-driver-manager optionalDependencies --registry http://localhost:4873 # Clean up docker rm -f verdaccio-adbc-test ``` <img width="1234" height="1095" alt="Screenshot 2026-03-11 at 5 02 26 PM" src="https://github.com/user-attachments/assets/072635ea-285e-468e-9a6c-008c7018b174" /> Tested `utils-prepare.sh` increments version ```sh SOURCE_DIR=./dev/release source "$SOURCE_DIR/utils-common.sh" source "$SOURCE_DIR/utils-prepare.sh" VERSION_JS="0.99.0" update_versions "release" ``` Verified the following files updated to `0.99.0`: - `javascript/package.json` — main version and all `optionalDependencies` - `javascript/npm/*/package.json` — all 5 platform packages - `javascript/Cargo.toml` Closes #4051 --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 59ccc45 commit 3dea32c

22 files changed

Lines changed: 206 additions & 626 deletions

File tree

.github/workflows/javascript.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,7 @@ jobs:
111111
- name: Build
112112
working-directory: javascript
113113
shell: bash
114-
run: |
115-
npx napi build --platform --release --target ${{ matrix.settings.target }}
116-
mv index.js binding.js
117-
mv index.d.ts binding.d.ts
118-
npx tsc
114+
run: npm run build:ci -- --target ${{ matrix.settings.target }} && npm run build:ts
119115
- name: Ad-hoc sign binary (macOS)
120116
if: runner.os == 'macOS'
121117
working-directory: javascript

.github/workflows/packaging.yml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ on:
4747
required: true
4848
type: boolean
4949
default: false
50-
5150
concurrency:
5251
group: ${{ github.repository }}-${{ github.ref }}-${{ github.workflow }}
5352
cancel-in-progress: true
@@ -1190,13 +1189,18 @@ jobs:
11901189
cache: 'npm'
11911190
cache-dependency-path: adbc/javascript/package-lock.json
11921191

1192+
- name: Setup Rust
1193+
run: |
1194+
rustup toolchain install stable --no-self-update
1195+
rustup default stable
1196+
11931197
- name: Install Node dependencies
11941198
working-directory: adbc/javascript
11951199
run: npm ci
11961200

1197-
- name: Build Node.js JS
1201+
- name: Build Node.js
11981202
working-directory: adbc/javascript
1199-
run: npm run build:ts
1203+
run: npm run build:ci && npm run build:ts
12001204

12011205
- name: Download Node.js binaries
12021206
uses: actions/download-artifact@v8
@@ -1226,6 +1230,7 @@ jobs:
12261230
path: |
12271231
adbc/javascript/*.tgz
12281232
1233+
12291234
release:
12301235
name: "Create release"
12311236
runs-on: ubuntu-latest
@@ -1272,7 +1277,7 @@ jobs:
12721277
-exec mv '{}' upload-staging \;
12731278
12741279
# Handle Node.js packages (in tarball form)
1275-
find ./release-artifacts/ -name 'adbc-driver-manager-*.tgz' -exec mv '{}' upload-staging \;
1280+
find ./release-artifacts/ -name 'apache-arrow-adbc-driver-manager-*.tgz' -exec mv '{}' upload-staging \;
12761281
12771282
UPLOAD=$(find upload-staging -type f | sort | uniq)
12781283
@@ -1357,6 +1362,7 @@ jobs:
13571362
needs:
13581363
- clean-gemfury
13591364
- java
1365+
- node-dist
13601366
- python-manylinux
13611367
- python-macos
13621368
- python-windows
@@ -1380,13 +1386,18 @@ jobs:
13801386
-name '*.jar' -or \
13811387
-name '*.pom' -or \
13821388
-name '*.whl' -or \
1383-
-name 'adbc_*.tar.gz' \
1389+
-name 'adbc_*.tar.gz' -or \
1390+
-name 'apache-arrow-adbc-driver-manager-*.tgz' \
13841391
')' \
13851392
-exec mv '{}' upload-staging \;
13861393
13871394
# Java
13881395
./ci/scripts/java_jar_upload.sh upload-staging/*.pom
13891396
# Python
13901397
./ci/scripts/python_wheel_upload.sh upload-staging/adbc_*.tar.gz upload-staging/*.whl
1398+
# Node.js
1399+
./ci/scripts/node_npm_upload.sh upload-staging
13911400
env:
13921401
GEMFURY_PUSH_TOKEN: ${{ secrets.GEMFURY_PUSH_TOKEN }}
1402+
NPM_REGISTRY: https://npm.fury.io/arrow-adbc-nightlies/
1403+
NPM_TOKEN: ${{ secrets.GEMFURY_PUSH_TOKEN }}

ci/scripts/node_npm_upload.sh

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/usr/bin/env bash
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
19+
# Publish Node.js packages to an npm registry.
20+
#
21+
# Usage: ./ci/scripts/node_npm_upload.sh <packages_dir>
22+
#
23+
# Environment variables:
24+
# NPM_TOKEN npm authentication token (required)
25+
# NPM_REGISTRY registry URL (default: https://registry.npmjs.org)
26+
# NPM_TAG dist-tag to publish under (default: latest)
27+
# DRY_RUN set to 1 to pass --dry-run to npm publish
28+
29+
set -euo pipefail
30+
31+
main() {
32+
local packages_dir
33+
packages_dir="$(realpath "$1")"
34+
local registry="${NPM_REGISTRY:-https://registry.npmjs.org}"
35+
local dry_run_flag=""
36+
if [[ "${DRY_RUN:-0}" == "1" ]]; then
37+
dry_run_flag="--dry-run"
38+
fi
39+
local tag_flag=""
40+
if [[ -n "${NPM_TAG:-}" ]]; then
41+
tag_flag="--tag ${NPM_TAG}"
42+
fi
43+
44+
# Write a temp .npmrc with the auth token for the target registry
45+
local npmrc
46+
npmrc=$(mktemp)
47+
trap "rm -f ${npmrc}" EXIT
48+
echo "//${registry#*://}/:_authToken=${NPM_TOKEN:-}" > "${npmrc}"
49+
export NPM_CONFIG_USERCONFIG="${npmrc}"
50+
51+
# Publish platform-specific packages first, then the main package
52+
for pkg in "${packages_dir}"/apache-arrow-adbc-driver-manager-*-*.tgz; do
53+
echo "==== Publishing ${pkg}"
54+
npm publish "${pkg}" --access public --registry "${registry}" ${tag_flag} ${dry_run_flag}
55+
done
56+
57+
echo "==== Publishing main package"
58+
npm publish "${packages_dir}"/apache-arrow-adbc-driver-manager-[0-9]*.tgz \
59+
--access public --registry "${registry}" ${tag_flag} ${dry_run_flag}
60+
}
61+
62+
main "$@"

dev/release/02-sign.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ main() {
8080
header "Upload signatures for Python"
8181
upload_asset_signatures "${tag}" $(find "${download_dir}" -type f \( -name '*.whl' -or -name 'adbc_*.tar.gz' \))
8282

83+
header "Upload signatures for Node.js"
84+
upload_asset_signatures "${tag}" $(find "${download_dir}" -type f -name 'apache-arrow-adbc-driver-manager-*.tgz')
85+
8386
header "Upload signatures for docs"
8487
upload_asset_signatures "${tag}" "${download_dir}/docs.tgz"
8588

dev/release/post-09-npm.sh

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env bash
2+
# -*- indent-tabs-mode: nil; sh-indentation: 2; sh-basic-offset: 2 -*-
3+
#
4+
# Licensed to the Apache Software Foundation (ASF) under one
5+
# or more contributor license agreements. See the NOTICE file
6+
# distributed with this work for additional information
7+
# regarding copyright ownership. The ASF licenses this file
8+
# to you under the Apache License, Version 2.0 (the
9+
# "License"); you may not use this file except in compliance
10+
# with the License. You may obtain a copy of the License at
11+
#
12+
# http://www.apache.org/licenses/LICENSE-2.0
13+
#
14+
# Unless required by applicable law or agreed to in writing,
15+
# software distributed under the License is distributed on an
16+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
# KIND, either express or implied. See the License for the
18+
# specific language governing permissions and limitations
19+
# under the License.
20+
#
21+
22+
set -e
23+
set -u
24+
set -o pipefail
25+
26+
SOURCE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
27+
source "${SOURCE_DIR}/utils-common.sh"
28+
source "${SOURCE_DIR}/utils-prepare.sh"
29+
30+
main() {
31+
if [ "$#" -ne 0 ]; then
32+
echo "Usage: $0"
33+
exit
34+
fi
35+
36+
local -r tag="apache-arrow-adbc-${RELEASE}"
37+
local -r tmp=$(mktemp -d -t "arrow-post-npm.XXXXX")
38+
39+
header "Downloading Node.js packages for ${RELEASE}"
40+
41+
gh release download \
42+
--repo "${REPOSITORY}" \
43+
"${tag}" \
44+
--dir "${tmp}" \
45+
--pattern "apache-arrow-adbc-driver-manager-*.tgz"
46+
47+
header "Uploading Node.js packages for ${RELEASE}"
48+
49+
DRY_RUN="${DRY_RUN:-0}" "${SOURCE_TOP_DIR}/ci/scripts/node_npm_upload.sh" "${tmp}"
50+
51+
rm -rf "${tmp}"
52+
53+
echo "Success! The released npm package is available here:"
54+
echo " https://www.npmjs.com/package/@apache-arrow/adbc-driver-manager"
55+
}
56+
57+
main "$@"
File renamed without changes.

dev/release/utils-prepare.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ update_versions() {
2323

2424
local conda_version="${VERSION_NATIVE}"
2525
local csharp_version="${VERSION_CSHARP}"
26+
local js_version="${VERSION_JS}"
2627
local linux_version="${RELEASE}"
2728
local rust_version="${VERSION_CSHARP}"
2829
case ${type} in
@@ -67,6 +68,7 @@ update_versions() {
6768
echo "GLib/Ruby: ${glib_version}"
6869
echo "Java: ${java_version}"
6970
echo "Linux: ${linux_version}"
71+
echo "JavaScript: ${js_version}"
7072
echo "Python: ${py_version}"
7173
echo "R: ${r_version}"
7274
echo "Rust: ${rust_version}"
@@ -153,6 +155,18 @@ update_versions() {
153155
cargo check --manifest-path "${ADBC_DIR}/rust/Cargo.toml"
154156
git add "${ADBC_DIR}/rust/Cargo.lock"
155157

158+
pushd "${ADBC_DIR}/javascript"
159+
sed -i.bak -E \
160+
-e "s/^ \"version\": \".+\"/ \"version\": \"${js_version}\"/" \
161+
-e "s/(\"@apache-arrow\/adbc-driver-manager[^\"]*\"): \".+\"/\1: \"${js_version}\"/g" \
162+
package.json
163+
rm package.json.bak
164+
npx --yes napi version
165+
sed -i.bak -E "s/^version = \".+\"/version = \"${js_version}\"/" Cargo.toml
166+
rm Cargo.toml.bak
167+
git add package.json package-lock.json Cargo.toml npm/*/package.json
168+
popd
169+
156170
if [ ${type} = "release" ]; then
157171
pushd "${ADBC_DIR}/ci/linux-packages"
158172
rake version:update VERSION=${linux_version}

0 commit comments

Comments
 (0)