Skip to content

[pull] main from jsr-io:main#91

Merged
pull[bot] merged 9 commits into
code:mainfrom
jsr-io:main
Jun 5, 2026
Merged

[pull] main from jsr-io:main#91
pull[bot] merged 9 commits into
code:mainfrom
jsr-io:main

Conversation

@pull

@pull pull Bot commented Jun 5, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

crowlKats and others added 9 commits June 5, 2026 01:12
)

## Summary

Extracts the OpenTelemetry changes from #1406 into a standalone PR so
they can land independently of the Cloudflare Container migration.

Switches the trace exporter from **OTLP/gRPC (tonic)** and **Google
Cloud Trace** to **OTLP/HTTP (protobuf) over reqwest**, the same HTTP
stack the rest of the crate already uses. This is what the managed
Grafana Cloud OTLP gateway speaks.

## Changes

- **`api/src/tracing.rs`**
- `TracingExportTarget::Otlp` now carries `{ endpoint, headers }`; the
gRPC exporter is replaced with the HTTP/protobuf exporter (`.http()` +
`Protocol::HttpBinary` + `.with_headers(...)`).
- `otlp_signal_endpoint()` appends the per-signal path (`/v1/traces`) to
a base endpoint, OTEL `OTEL_EXPORTER_OTLP_ENDPOINT` style (the 0.12 HTTP
exporter doesn't do this itself). Tolerates a trailing slash / an
endpoint that already carries the path.
- `parse_otlp_headers()` parses the `OTEL_EXPORTER_OTLP_HEADERS`
`key=value,...` format, splitting on the first `=` only so base64
padding in a `Basic` auth header survives.
- Removes the `CloudTrace` export target. Adds unit tests for both
helpers.
- **`api/src/config.rs`**
- `otlp_endpoint` is now the base OTLP/HTTP endpoint; new `otlp_headers`
(`OTLP_HEADERS`) carries backend auth. Removes `--cloud_trace` and the
now-unused `gcp_project_id`.
- **`api/src/main.rs`**: build the `Otlp { endpoint, headers }` target
from config; drop the `cloud_trace` branch.
- **`api/Cargo.toml`**: `opentelemetry-otlp` now uses `default-features
= false` + `http-proto` + `reqwest-client` (no `grpc-tonic`); removes
`opentelemetry-gcloud-trace`.
- **`Cargo.lock`**: drops the tonic/prost/gcloud-trace dependency tree.

## Not included from #1406

Everything else — the Cloudflare Container migration, DB mTLS, the GCP
service-account-key metadata strategy, the `rustls` pin, LB worker,
Terraform, and CI changes — stays in #1406.

## Testing

- `cargo build` ✅
- `cargo test --bin registry_api tracing::` — 5/5 pass ✅
- `cargo fmt --check` ✅
…ty (#1424)

## Summary

Exports the Cloudflare Workers' **traces and logs** to an external OTLP
backend (e.g. Grafana Cloud) using Cloudflare's **native Workers
Observability** export — not a custom in-Worker OTLP exporter.

Cloudflare exports both automatic request **traces** and **logs**
(console output + invocation logs) to a "destination" you configure with
an OTLP endpoint + auth headers. The Worker config just references that
destination by name; no exporter code runs in the Worker.

## Changes

- **`terraform/variables.tf`**: add `otlp_traces_destination` and
`otlp_logs_destination` — the names of the dashboard-managed
destinations. Empty (default) keeps export disabled, with Cloudflare
still storing traces/logs in its own dashboard.
- **`terraform/cloudflare_frontend.tf`** and **`terraform/lb.tf`**: add
a `traces` block and `logs.destinations` to each worker's
`observability` block, pointing at the named destinations when the vars
are set.
- **`.github/workflows/ci.yml`**: pass `TF_VAR_otlp_traces_destination`
/ `TF_VAR_otlp_logs_destination` (from non-secret GitHub Actions `vars`)
on both staging and prod applies.

Covers **both** workers (frontend + lb) — native tracing needs no
per-worker code.

## Required setup (one-time, per Cloudflare account)

The OTLP endpoint + auth headers ("the provided values") live in a
**dashboard destination**, because the
`cloudflare_workers_observability_destination` terraform resource is
advertised but **not yet implemented** in the pinned provider (5.19.1) —
see
[cloudflare/terraform-provider-cloudflare#7127](cloudflare/terraform-provider-cloudflare#7127).

1. In the Cloudflare dashboard → Workers & Pages → Observability →
Telemetry, **add a destination** (type Traces, and one for Logs) with
the OTLP endpoint URL and auth header(s) (e.g. `Authorization: Basic
<base64>` for Grafana Cloud).
2. Set the GitHub Actions repo/environment **variables**
`OTLP_TRACES_DESTINATION` and `OTLP_LOGS_DESTINATION` to those
destination names.

Until both are done, behaviour is unchanged (Cloudflare dashboard
storage only).

## Notes

- The frontend's existing hand-rolled tracer
(`frontend/utils/tracing.ts`) is left as-is and stays dormant (it only
exports if `OTLP_ENDPOINT` is set, which it isn't). With native export
now handling traces, that module is a candidate for removal in a
follow-up.

## Testing

- `terraform validate` + `terraform fmt` ✅ (provider 5.19.1 accepts the
`observability.traces` / `destinations` schema on both
`cloudflare_worker` and `cloudflare_workers_script`)
… runtime (#1425)

## Problem

Fixes #1390.

When `localStorage` holds a `preferredUsage` for a runtime that the
**current** package does not support (e.g. a stored `"Bun"` preference
visiting `@fresh/core`, or any package whose usage list changed), the
package page's JS crashes and the whole page loses interactivity:

- search input becomes invisible
- login does not work
- download graph shows no labels

The console shows:

```
Uncaught TypeError: can't access property "name", r.value is undefined
Uncaught (in promise) TypeError: can't access property "icon", r.value is undefined
```

## Root cause

In `frontend/islands/DocUsages.tsx`, the stored preference is applied
with:

```ts
activeUsageIdx.value = usages.findIndex((usage) => usage.name === preferredUsage);
```

`findIndex` returns `-1` when the preferred runtime isn't in this
package's `usages`, so `activeUsage` becomes `usages[-1]` → `undefined`.
Every subsequent `activeUsage.value.name` / `.icon` / `.content` access
throws, which aborts hydration for the island (and cascades to other
islands on the page).

## Fix

Only apply the stored preference when a matching usage actually exists;
otherwise keep the default first usage:

```ts
const idx = usages.findIndex((usage) => usage.name === preferredUsage);
if (idx !== -1) {
  activeUsageIdx.value = idx;
}
```

The existing signal effect then rewrites `preferredUsage` in
`localStorage` to the now-active (supported) value, so the stale
preference self-heals on next visit.

## Verification

- Logic check: with a supported preference (`"npm"`) behaviour is
unchanged; with an unsupported preference (`"Bun"`) it now falls back to
the first usage instead of producing `undefined`.
- `deno fmt --check`, `deno lint`, and `deno check
islands/DocUsages.tsx` pass.

Minimal change, no visual/layout changes.
…#1422)

## Summary

On the package version-diff page (`/@scope/pkg/diff/<old>...<new>`), the
two
version dropdowns and the swap-direction link had no accessible names:

- The two `<select>` elements (choose the old/base version and the
new/target
version) had no `<label>` or `aria-label`, so assistive technology
announced
each as a bare "combobox" with no indication of which side it controls.
- The swap link (the `TbArrowRight` icon between the dropdowns, which
reverses
the comparison direction) is icon-only and had no accessible name at
all.

This adds accessible names so all three controls are announced
meaningfully. The
sibling "show all / changed only" toggle already had a `title` and is
unchanged.

## Changes

- `frontend/routes/package/(_islands)/DiffVersionSelector.tsx`:
  - `aria-label="Old version"` on the first (base) version `<select>`.
- `aria-label="New version"` on the second (target) version `<select>`.
- `aria-label="Swap versions"` + `title="Swap versions"` on the swap
link.

No layout, styling, or behavior changes.

## Validation

- `deno fmt --check` and `deno lint` on the touched file — clean.
- `deno test` (frontend) — 3 passed, 0 failed.
- Rendered the island with `preact-render-to-string`:
  - Before: both `<select>` and the swap `<a>` had no `aria-label`.
- After: both selects carry their `aria-label`, and the swap link
carries
    `aria-label`/`title`; the eye-toggle link is unchanged.
- Attribute-only additions — light/dark and responsive states are
unaffected.
(Screenshots couldn't be captured in this environment — no Chromium
available.)

## PR Checklist

- [x] The PR title follows [conventional
commits](https://www.conventionalcommits.org/en/v1.0.0/)
- [x] Is this closing an open issue? If so, link it, else include a
proper description of the changes and reason behind them.
- [x] Does the PR have changes to the frontend? If so, include
screenshots or a recording of the changes.
<br/>If it affect colors, please include screenshots/recording in both
light and dark mode.
- [ ] Does the PR have changes to the backend? If so, make sure tests
are added.
<br/>And if changing dababase queries, be sure you have ran `sqlx
prepare` and committed the changes in the `.sqlx` directory.
)

## Summary

The GitHub and GitLab logo images in the sign-in flows are
**decorative** — each
one sits immediately next to a visible "Sign in with GitHub" / "Sign in
with
GitLab" text label, so the image conveys no information the link text
doesn't
already provide. They had no `alt` attribute, which means assistive
technology
falls back to announcing the image's filename (e.g. "github.svg") as
redundant
noise alongside the link text.

This marks them as decorative with `alt=""`, so screen readers skip the
image
and announce only the meaningful link text. This matches the convention
already
used in the codebase for the decorative Orama logos in
`GlobalSearch.tsx`.

## Changes

- `frontend/islands/SignInMenu.tsx` — header sign-in dropdown (GitHub +
GitLab).
- `frontend/routes/login.tsx` — `/login` page (GitHub + GitLab).
- `frontend/routes/new.tsx` — `/new` publish page, logged-out state
(GitHub + GitLab).

Each change adds `alt=""` to the provider `<img>`. No layout, styling,
or
behavior changes. (`deno fmt` reflowed the two `new.tsx` images onto
multiple
lines; the only semantic change there is the added `alt=""`.)

## Validation

- `deno fmt --check` and `deno lint` on the touched files — clean.
- `deno test` (frontend) — 3 passed, 0 failed.
- Audited every `<img>` under `frontend/` — these six provider logos
were the only
  images missing an `alt` attribute; all others already set one.
- Rendered `SignInMenu` with `preact-render-to-string` and confirmed the
provider
  `<img>` elements now carry an (empty) `alt` attribute.
- Attribute-only change to decorative images — light/dark and responsive
states
are unaffected. (Screenshots couldn't be captured in this environment —
no
  Chromium available.)

## PR Checklist

- [x] The PR title follows [conventional
commits](https://www.conventionalcommits.org/en/v1.0.0/)
- [x] Is this closing an open issue? If so, link it, else include a
proper description of the changes and reason behind them.
- [x] Does the PR have changes to the frontend? If so, include
screenshots or a recording of the changes.
<br/>If it affect colors, please include screenshots/recording in both
light and dark mode.
- [ ] Does the PR have changes to the backend? If so, make sure tests
are added.
<br/>And if changing dababase queries, be sure you have ran `sqlx
prepare` and committed the changes in the `.sqlx` directory.
…1420)

## Problem

A README relative link starting with a single `/`, e.g.

```markdown
[Documentation](/docs/getting-started.md)
```

renders on jsr.io as a link to `https://jsr.io/docs/getting-started.md`,
which 404s. Both GitHub and npm treat such links as relative to the
repository root. (Example: the "MIT License" `/LICENSE` link on
https://jsr.io/@dbushell/http-tunnel.)

## Root cause

In `api/src/docs.rs`, `get_url_rewriter` returned any URL starting with
`/` unchanged:

```rust
if url.starts_with('#') || url.starts_with('/') {
  return url.to_string();
}
```

So root-relative links were never rewritten to the linked GitHub
repository and were served relative to jsr.io.

## Fix

Only leave anchors (`#…`) and protocol-relative URLs (`//host/…`)
untouched. Resolve single-`/` root-relative URLs against the repository
root — the GitHub repo root (`blob/HEAD` or `raw.githubusercontent.com`
for images) when the package has a linked repository, or the package
root otherwise, consistent with how ordinary relative links are already
handled.

## Test

Extended `test_url_rewriter` with assertions that `/LICENSE` and
`/assets/logo.svg` resolve against the repo root (and package root in
the no-repo case), and that protocol-relative URLs remain untouched.
These fail before the change and pass after.

Closes #768
## Summary

The navigation overflow menu (the "…" button rendered by `NavOverflow`,
used by
`Nav` when the tab items don't all fit — e.g. the package/scope nav on
narrow
and mobile viewports) is an icon-only button. Its only child is the
decorative
`TbDots` icon, and it had no text, `aria-label`, or `title`, so it
exposed **no
accessible name**. Assistive technology announced it as an unlabeled
"button, collapsed", and it had no hover tooltip for sighted mouse
users.

This adds an accessible name to the control, following the same
convention used
by the other icon-only header control, `DarkModeToggle`, which sets both
`aria-label` and `title`.

## Changes

- `frontend/components/NavOverflow.tsx`: add `aria-label="More
navigation items"`
and `title="More navigation items"` to the toggle `<button>`. Two
attributes;
no markup, styling, or behavior changes — the toggle script still keys
off the
  `#nav-menu` element and `aria-expanded`.

## Validation

- `deno fmt --check` and `deno lint` on the touched file — clean.
- `deno check frontend/components/NavOverflow.tsx` (source module graph)
— clean.
- `deno test` (frontend) — 3 passed, 0 failed.
- Rendered `NavOverflow` with `preact-render-to-string` and inspected
the
  emitted button tag:
- Before: `<button type="button" class="…" aria-expanded="false">` — no
accessible name.
- After: `<button type="button" class="…" aria-label="More navigation
items" title="More navigation items" aria-expanded="false">`.
- This is an attribute-only addition to a server-rendered control, so
light/dark
and responsive states are unaffected. (Screenshots couldn't be captured
in this
  environment — no Chromium available.)

## PR Checklist

- [x] The PR title follows [conventional
commits](https://www.conventionalcommits.org/en/v1.0.0/)
- [x] Is this closing an open issue? If so, link it, else include a
proper description of the changes and reason behind them.
- [x] Does the PR have changes to the frontend? If so, include
screenshots or a recording of the changes.
<br/>If it affect colors, please include screenshots/recording in both
light and dark mode.
- [ ] Does the PR have changes to the backend? If so, make sure tests
are added.
<br/>And if changing dababase queries, be sure you have ran `sqlx
prepare` and committed the changes in the `.sqlx` directory.
## Problem

Submitting provenance for some packages fails with a cryptic error:

```
Caused by:
    Invalid symbol 45, offset 1238.
```

Byte `45` is `-`, which belongs to the URL-safe base64 alphabet but not
the standard one. The provenance handler decodes the DSSE envelope
`payload` with `BASE64_STANDARD`, so a payload encoded with the URL-safe
alphabet (`-`/`_` instead of `+`/`/`) is rejected and provenance
submission fails.

## Fix

Fall back to URL-safe base64 decoding when standard decoding fails. This
step only reads the attestation subject out of the payload (the DSSE
signature itself is not verified here), so accepting the URL-safe
alphabet decodes the same bytes without weakening any verification — the
subject-name check and certificate-chain verification are unchanged.

## Test

Added a unit test in `api/src/provenance.rs` asserting the payload
decoder accepts both standard (`+/8=`) and URL-safe (`-_8=`) encodings
of the same bytes. It fails before this change (the standard decoder
rejects `-`) and passes after.

Closes #1312
@pull pull Bot locked and limited conversation to collaborators Jun 5, 2026
@pull pull Bot added the ⤵️ pull label Jun 5, 2026
@pull pull Bot merged commit f15d566 into code:main Jun 5, 2026
1 check failed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants