Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2145aa7
Merge pull request #41 from glassnode:main
planadecu Sep 29, 2026
9f45655
Remove the deprecated MetricTier, MetricDataType and FetchFn exports
planadecu Sep 29, 2026
e82ad1e
Merge pull request #45 from glassnode/feat/1.0-remove-deprecated
planadecu Sep 29, 2026
080f952
Make MetricMetadata refs, queried and parameters optional
planadecu Sep 29, 2026
c6e9999
Merge pull request #47 from glassnode/feat/1.0-lenient-metadata
planadecu Sep 29, 2026
3ca18fc
Keep MetricMetadata.modified as unix seconds (number)
planadecu Sep 29, 2026
ca507f2
Merge pull request #46 from glassnode/feat/1.0-modified-unix-seconds
planadecu Sep 29, 2026
d0a7e04
Merge main (0.29.5–0.30.1) into release/1.0
planadecu Sep 29, 2026
8a09be3
Merge pull request #52 from glassnode/sync/main-into-1.0
planadecu Sep 29, 2026
db0ba0d
Declare the CDN entry with unpkg/jsdelivr; move browser build to bund…
planadecu Sep 29, 2026
1a98f0d
Correct the CDN, affected-tools and browser-field claims (#37)
planadecu Sep 29, 2026
ab074d8
Merge pull request #53 from glassnode/feat/1.0-browser-entry
planadecu Sep 29, 2026
ed7a604
Default maxRetries to 2 (0 in x402 mode) (#49)
planadecu Sep 29, 2026
23d4e5c
Keep GlassnodeConfigSchema an object schema; resolve maxRetries in th…
planadecu Sep 29, 2026
6ac2f52
Say that GlassnodeConfigSchema no longer fills in maxRetries
planadecu Sep 29, 2026
3a21a16
Merge pull request #54 from glassnode/feat/1.0-default-retries
planadecu Sep 29, 2026
ea068c4
Refresh the dev toolchain and pin GitHub Actions by SHA (#50)
planadecu Sep 29, 2026
1b4b16f
Raise the minimum Node.js version to 22 (#48)
planadecu Sep 29, 2026
690ebe9
Merge pull request #55 from glassnode/feat/1.0-toolchain-node22
planadecu Sep 29, 2026
9e4583c
Guard npm latest and detect skipped releases in publish.yml (#33)
planadecu Sep 29, 2026
ed2552a
Harden the publish guards: validate the dist-tag, assert npm args, dr…
planadecu Sep 29, 2026
5bcbabd
Merge pull request #56 from glassnode/feat/1.0-publish-guards
planadecu Sep 29, 2026
fb21625
Prepare the 1.0.0 release
planadecu Sep 29, 2026
966ba15
Tighten the 1.0 stability policy and release-branch docs
planadecu Sep 29, 2026
7975bf2
Merge pull request #57 from glassnode/chore/prep-1.0.0
planadecu Sep 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 27 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,30 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
with:
standalone: true
env:
# The repo .npmrc sets ignore-scripts=true (supply-chain hardening), but the
# standalone pnpm (@pnpm/exe) needs its preinstall (setup.js picks the platform
# binary) or the pnpm bin is a stub that fails with "This: not found". Re-enable
# scripts for this bootstrap only; the project installs below still honor .npmrc.
# The standalone pnpm (@pnpm/exe) needs its preinstall (setup.js picks the platform
# binary) or the pnpm bin is a stub that fails with "This: not found". The action
# installs it with `npm ci` in its own directory and lockfile, where the repo .npmrc
# (ignore-scripts=true) is probably not read; this step-level override makes sure
# scripts run for that bootstrap whatever npm config applies. It is scoped to this
# step: the project installs below still honor the repo .npmrc.
npm_config_ignore_scripts: 'false'
- uses: actions/setup-node@v4
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
cache: 'pnpm'
# The top CHANGELOG.md heading must be exactly `## <package.json version>` (publish.yml takes
# the GitHub Release notes from that line). Into release/** a `## <x.y.z> (unreleased)`
# heading is accepted too, so a heading still marked "(unreleased)" can never reach main.
# The target is the PR's base branch, or the pushed branch (main) when publish.yml calls this.
- name: Check the CHANGELOG.md heading
env:
TARGET_BRANCH: ${{ github.base_ref || github.ref_name }}
run: node scripts/check-changelog-heading.mjs
- run: pnpm install --frozen-lockfile
- run: pnpm run lint
# Enforce the coverage thresholds (vitest.config.ts), not just that tests pass.
Expand Down Expand Up @@ -76,21 +86,23 @@ jobs:
- run: pnpm dlx publint
- run: pnpm dlx @arethetypeswrong/cli --pack .

# Prove the package's advertised floor (engines: ">=18"). Vitest 5 needs Node >=22.12, so this
# job does not run the suite — it builds, smoke-imports the CJS entry and runs a plain-Node
# runtime smoke (a real AbortSignal.timeout() abort -> GlassnodeNetworkError timedOut) on Node 18.
compat-node18:
# Prove the package's advertised floor (engines: ">=22.0.0"). The main job runs on Node 24, and
# Vitest 5 needs Node >=22.12, so this job does not run the suite — it builds, smoke-imports the
# CJS entry and runs a plain-Node runtime smoke (a real AbortSignal.timeout() abort ->
# GlassnodeNetworkError timedOut) on the floor major. The job name is version-neutral so the
# rulesets' required check survives the next floor bump; only node-version changes then.
compat-node-floor:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
with:
standalone: true
env:
npm_config_ignore_scripts: 'false'
- uses: actions/setup-node@v4
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 18
node-version: 22
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm run build
Expand Down
22 changes: 12 additions & 10 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,26 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
with:
standalone: true
env:
# The repo .npmrc sets ignore-scripts=true (supply-chain hardening), but the
# standalone pnpm (@pnpm/exe) needs its preinstall (setup.js picks the platform
# binary) or the pnpm bin is a stub that fails with "This: not found". Re-enable
# scripts for this bootstrap only; the project installs below still honor .npmrc.
# The standalone pnpm (@pnpm/exe) needs its preinstall (setup.js picks the platform
# binary) or the pnpm bin is a stub that fails with "This: not found". The action
# installs it with `npm ci` in its own directory and lockfile, where the repo .npmrc
# (ignore-scripts=true) is probably not read; this step-level override makes sure
# scripts run for that bootstrap whatever npm config applies. It is scoped to this
# step: the project installs below still honor the repo .npmrc.
npm_config_ignore_scripts: 'false'
- uses: actions/setup-node@v4
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm run docs
- uses: actions/configure-pages@v6
- uses: actions/upload-pages-artifact@v5
- uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
- uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: api-docs

Expand All @@ -51,4 +53,4 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v5
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
81 changes: 55 additions & 26 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ name: Publish Package
# GitHub Release from the CHANGELOG section
# A merge that does not bump `version`, or a re-run after a successful release, skips the
# publish (and the approval) with a notice in the job summary.
#
# Concurrency (the `npm-publish` group on the publish job): an in-progress publish is never
# cancelled, but GitHub keeps at most ONE pending run per group. A newer merge's publish job
# replaces (cancels) an older one still waiting in the queue or for its approval, so that older
# version is never published. This happened on 2026-09-29 to 0.29.5 and 0.30.0 (#33). Hence:
# - Merge release PRs one at a time: wait for each publish to finish before the next merge.
# - The `release` job warns in the summary about any CHANGELOG version between the last
# published one and this one that is missing on npm (scripts/release-plan.mjs).
# - To recover, re-run the cancelled version's workflow run (its commit still carries that
# version). If a higher version is already `latest`, it is published under the
# `backport-<major>.<minor>` dist-tag instead, so `latest` never moves backwards; a
# prerelease goes out under `next`. Its GitHub Release is then not marked "Latest".
# A re-run uses the workflow of its own commit: one older than this guard publishes with npm's
# default tag, so check `npm dist-tag ls` afterwards (CONTRIBUTING.md "Releases").
on:
push:
branches:
Expand All @@ -31,12 +45,13 @@ jobs:
action: ${{ steps.state.outputs.action }}
version: ${{ steps.state.outputs.version }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
# Fails the job (rather than publishing) if npm cannot be queried; only a 404 means
# "not published".
# "not published". Also picks the dist-tag and warns about skipped (never published)
# CHANGELOG versions in the job summary.
- id: state
run: scripts/release-state.sh

Expand All @@ -57,37 +72,39 @@ jobs:
contents: write # push the v<version> tag and create the GitHub Release
id-token: write # npm Trusted Publishing (OIDC) and provenance
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
with:
standalone: true
env:
# The repo .npmrc sets ignore-scripts=true (supply-chain hardening), but the
# standalone pnpm (@pnpm/exe) needs its preinstall (setup.js picks the platform
# binary) or the pnpm bin is a stub that fails with "This: not found". Re-enable
# scripts for this bootstrap only; the project installs below still honor .npmrc.
# The standalone pnpm (@pnpm/exe) needs its preinstall (setup.js picks the platform
# binary) or the pnpm bin is a stub that fails with "This: not found". The action
# installs it with `npm ci` in its own directory and lockfile, where the repo .npmrc
# (ignore-scripts=true) is probably not read; this step-level override makes sure
# scripts run for that bootstrap whatever npm config applies. It is scoped to this
# step: the project installs below still honor the repo .npmrc.
npm_config_ignore_scripts: 'false'
- uses: actions/setup-node@v4
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
# registry-url is required so npm knows the registry for the OIDC exchange.
# npm CLI (>= 11.5.1) detects the OIDC environment and authenticates with it
# BEFORE falling back to the setup-node placeholder token, so no NODE_AUTH_TOKEN
# is set on the publish step. (pnpm publish does NOT do this — it uses the
# placeholder and 404s — which is why we publish with npm below.)
# registry-url is required so npm knows the registry for the OIDC exchange. No cache
# here: this job holds id-token: write and contents: write, and setup-node's docs advise
# against restoring a cache in privileged release jobs (cache poisoning).
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
# setup-node's registry-url writes an .npmrc with `always-auth=true` and a placeholder
# `_authToken`, which forces npm to send the fake token instead of doing the OIDC
# exchange (→ E404). Overwrite it with just the registry so npm has no token and must
# authenticate via OIDC trusted publishing.
- name: Clean npmrc so npm uses OIDC (not the placeholder token)
# With registry-url, setup-node v7 writes a user .npmrc (NPM_CONFIG_USERCONFIG) containing
# `//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}` and `registry=…`, and no longer
# exports a placeholder NODE_AUTH_TOKEN (v4–v6 did). We set no NODE_AUTH_TOKEN: npm must
# authenticate via OIDC trusted publishing, not a configured token. The `_authToken` line
# still names a token (an unset variable) for the registry, which can pre-empt or break the
# OIDC path, so overwrite the file with just the registry. We publish with npm (>= 11.5.1
# does the OIDC exchange), not pnpm publish, which does not and 404s.
- name: Clean npmrc so npm uses OIDC (no configured token)
run: printf 'registry=https://registry.npmjs.org/\n' > "$NPM_CONFIG_USERCONFIG"
# npm >= 11.5.1 performs the OIDC exchange.
- run: npm install -g npm@latest
- run: npm --version
# Re-check right before publishing: the approval may have waited while another run
# published this version.
# published this version, or moved `latest` (which decides the dist-tag).
- id: state
run: scripts/release-state.sh
- if: steps.state.outputs.action == 'publish'
Expand All @@ -103,12 +120,18 @@ jobs:
# provenance (publishConfig.provenance). Requires a Trusted Publisher configured for this
# package on npmjs.com: repo glassnode/glassnode-api-ts-client, workflow publish.yml,
# environment npm.
# The dist-tag is always explicit: `latest`, or `backport-<major>.<minor>` for a version
# lower than the current `latest` (a re-run of a cancelled older release) and `next` for a
# prerelease, so `latest` never moves backwards (scripts/release-plan.mjs).
- if: steps.state.outputs.action == 'publish'
run: npm publish
env:
DIST_TAG: ${{ steps.state.outputs.dist_tag }}
run: npm publish --tag "$DIST_TAG"
- if: steps.state.outputs.action == 'publish'
env:
VERSION: ${{ steps.state.outputs.version }}
run: echo "Published \`glassnode-api@$VERSION\` to npm." >> "$GITHUB_STEP_SUMMARY"
DIST_TAG: ${{ steps.state.outputs.dist_tag }}
run: echo "Published \`glassnode-api@$VERSION\` to npm under the \`$DIST_TAG\` dist-tag." >> "$GITHUB_STEP_SUMMARY"
# Tag the published commit. An existing tag on this commit is fine (re-run); one on another
# commit is left alone with a warning, and the GitHub Release is then skipped.
- name: Push the v<version> tag
Expand Down Expand Up @@ -145,13 +168,16 @@ jobs:
exit 1
fi
# The release notes are the package.json version's section of CHANGELOG.md (from its
# `## <version>` heading to the next `## ` heading).
# `## <version>` heading to the next `## ` heading). Only a version published as npm
# `latest` becomes the repository's "Latest" GitHub Release; a backport does not, and a
# prerelease is marked as one.
- name: Create the GitHub Release
if: steps.tag.outputs.release == 'true'
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ steps.state.outputs.tag }}
VERSION: ${{ steps.state.outputs.version }}
DIST_TAG: ${{ steps.state.outputs.dist_tag }}
run: |
if gh release view "$TAG" > /dev/null 2> view.err; then
echo "GitHub Release \`$TAG\` already exists." >> "$GITHUB_STEP_SUMMARY"
Expand All @@ -170,5 +196,8 @@ jobs:
echo "::warning::CHANGELOG.md has no '## $VERSION' section; the release links to it instead."
echo "See [CHANGELOG.md](https://github.com/$GITHUB_REPOSITORY/blob/$TAG/CHANGELOG.md)." > notes.md
fi
gh release create "$TAG" --verify-tag --title "$TAG" --notes-file notes.md
flags=()
if [ "$DIST_TAG" != latest ]; then flags+=(--latest=false); fi
case "${VERSION%%+*}" in *-*) flags+=(--prerelease) ;; esac
gh release create "$TAG" --verify-tag --title "$TAG" --notes-file notes.md "${flags[@]}"
echo "Created GitHub Release \`$TAG\`." >> "$GITHUB_STEP_SUMMARY"
Loading
Loading