Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
86 changes: 86 additions & 0 deletions .github/scripts/verify-npm-hyperd-pin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env python3
"""Guard: keep the npm release workflow's hyperd pin in sync with the toml.

`.github/workflows/npm-build-publish.yml` bundles `hyperd` into the npm
packages using its OWN hardcoded `HYPERD_VERSION` / `HYPERD_BUILD_ID` /
per-platform matrix `hyperd-sha256`s. Those are decoupled from
`hyperdb-bootstrap/hyperd-version.toml`, which is what `make download-hyperd`
and the crates.io path use.

When only the toml was bumped (as in PR #237), npm silently kept shipping the
old engine: 0.7.1 bundled hyperd 0.0.25080 while crates.io shipped 0.0.26359.
This script fails CI whenever the two drift, so that can't recur silently.

The platform slug (`macos-arm64`, `linux-x86_64`, `windows-x86_64`) is the join
key: it is identical between the toml's `[sha256]` table and the workflow's
`hyperd-slug` matrix field. Only slugs the workflow actually builds are checked,
so a commented-out matrix entry (invisible to the YAML parser) and any unused
extra toml sha are both fine.
"""

from __future__ import annotations

import sys
import tomllib
from pathlib import Path

import yaml

ROOT = Path(__file__).resolve().parents[2]
TOML = ROOT / "hyperdb-bootstrap" / "hyperd-version.toml"
WORKFLOW = ROOT / ".github" / "workflows" / "npm-build-publish.yml"


def main() -> int:
toml_data = tomllib.loads(TOML.read_text())
workflow = yaml.safe_load(WORKFLOW.read_text())

env = workflow.get("env", {})
toml_sha = toml_data.get("sha256", {})

# (label, expected-from-toml, actual-from-workflow)
checks: list[tuple[str, str, str | None]] = [
("HYPERD_VERSION", str(toml_data["version"]), env.get("HYPERD_VERSION")),
("HYPERD_BUILD_ID", str(toml_data["build_id"]), env.get("HYPERD_BUILD_ID")),
]

errors: list[str] = []

include = workflow["jobs"]["build-npm"]["strategy"]["matrix"]["include"]
for entry in include:
slug = entry.get("hyperd-slug")
if slug is None:
continue
expected = toml_sha.get(slug)
if expected is None:
errors.append(
f'matrix slug "{slug}" has no [sha256]."{slug}" entry in {TOML.name}'
)
continue
checks.append((f"sha256[{slug}]", expected, entry.get("hyperd-sha256")))

for label, expected, actual in checks:
if actual == expected:
print(f"ok: {label} = {expected}")
else:
errors.append(f"{label}: workflow has {actual!r}, toml has {expected!r}")

if errors:
print()
for err in errors:
print(f"::error::hyperd pin drift — {err}")
sys.stdout.flush()
print(
f"\n{WORKFLOW.name} is out of sync with {TOML.name}. "
"Update the workflow's env vars and matrix sha256s to match the toml "
"(or vice versa) so npm bundles the same hyperd as crates.io.",
file=sys.stderr,
)
return 1

print(f"\n{WORKFLOW.name} hyperd pin matches {TOML.name}.")
return 0


if __name__ == "__main__":
sys.exit(main())
10 changes: 5 additions & 5 deletions .github/workflows/npm-build-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ permissions:

env:
CARGO_TERM_COLOR: always
HYPERD_VERSION: "0.0.25080"
HYPERD_BUILD_ID: "r2bfd835b"
HYPERD_VERSION: "0.0.26359"
HYPERD_BUILD_ID: "r07abb490"

jobs:
verify-ci:
Expand Down Expand Up @@ -96,7 +96,7 @@ jobs:
os: macos-14
target: aarch64-apple-darwin
hyperd-slug: macos-arm64
hyperd-sha256: "2b0fa3fefcf4eba60f052e1cb51abfc32d8c84354274513763760f9549b45991"
hyperd-sha256: "434a5e7f95d914a7b328ac333b872fa044fabc6e23ad2aac9d0c9b762032b5ab"
# TODO: re-enable when macos-13 runners are more available
# - platform: darwin-x64
# os: macos-13
Expand All @@ -107,12 +107,12 @@ jobs:
os: ubuntu-latest
target: x86_64-unknown-linux-gnu
hyperd-slug: linux-x86_64
hyperd-sha256: "3d3fd2104f55f7fad832470592394dc78f350a03d52e89d36c5288b202dd0bc0"
hyperd-sha256: "40e488c01ddc1ecaa53123a88fcf4150161a5828e1c22b475dd73e1cd9cbbbed"
- platform: win32-x64-msvc
os: windows-latest
target: x86_64-pc-windows-msvc
hyperd-slug: windows-x86_64
hyperd-sha256: "9dc4851d416e0e6e00f0367ee6b45fcd676e7ba3a110d4644e3bec871b9aa1de"
hyperd-sha256: "8546e67501ed3f15e97c9a0ed6a0dfc56fa9f070878bac435a7e5f7d1bfb6c99"
runs-on: ${{ matrix.os }}
defaults:
run:
Expand Down
15 changes: 13 additions & 2 deletions .github/workflows/verify-hyperd-pin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ on:
- "hyperdb-bootstrap/hyperd-version.toml"
- "hyperdb-bootstrap/src/**"
- ".github/workflows/verify-hyperd-pin.yml"
- ".github/workflows/npm-build-publish.yml"
- ".github/scripts/verify-npm-hyperd-pin.py"
pull_request:
paths:
- "hyperdb-bootstrap/hyperd-version.toml"
- "hyperdb-bootstrap/src/**"
- ".github/workflows/verify-hyperd-pin.yml"
- ".github/workflows/npm-build-publish.yml"
- ".github/scripts/verify-npm-hyperd-pin.py"
schedule:
# Weekly sanity check — independent of PR traffic.
- cron: "0 12 * * 1"
Expand All @@ -30,12 +34,19 @@ jobs:
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- name: Install mold linker
run: sudo apt-get update -q && sudo apt-get install -y mold
- name: Install build + guard dependencies (mold, python3-yaml)
run: sudo apt-get update -q && sudo apt-get install -y mold python3-yaml
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
cache-key: verify-hyperd-pin
rustflags: ""
- name: Verify pinned release URLs are reachable
run: cargo run --release -p hyperdb-bootstrap --bin hyperdb-bootstrap -- verify

- name: Verify npm-build-publish.yml hyperd pin matches the toml
# The release workflow bundles hyperd into the npm packages from its
# OWN hardcoded version/build_id/sha256s, decoupled from the toml.
# 0.7.1 shipped npm with the stale 0.0.25080 engine because only the
# toml was bumped. This guard fails the build if they ever drift again.
run: python3 .github/scripts/verify-npm-hyperd-pin.py
Loading