Repository navigation
Fix extension usage reporting gaps - #6224
Merged
Merged
Conversation
inancgumus
requested review from
ankur22 and
janHildebrandt98
and removed request for
a team
July 28, 2026 17:07
inancgumus
temporarily deployed
to
azure-trusted-signing
July 28, 2026 17:13 — with
GitHub Actions
Inactive
inancgumus
temporarily deployed
to
azure-trusted-signing
July 28, 2026 17:17 — with
GitHub Actions
Inactive
4 tasks done
inancgumus
temporarily deployed
to
azure-trusted-signing
July 28, 2026 22:11 — with
GitHub Actions
Inactive
inancgumus
force-pushed
the
fix/ext-telemetry-reporting-gaps
branch
from
July 28, 2026 22:13
02a493c to
5916301
Compare
inancgumus
temporarily deployed
to
azure-trusted-signing
July 28, 2026 22:19 — with
GitHub Actions
Inactive
inancgumus
temporarily deployed
to
azure-trusted-signing
July 28, 2026 22:21 — with
GitHub Actions
Inactive
Every reported run consulted the extension catalog, fetching it on a cold or stale cache even when the script used no extensions, which is most runs. The fetch also spent part of the bounded report window with nothing to filter. The report step now resolves the catalog lazily, only after finding recorded extension usage, so an extension-less run sends its report without touching the registry.
The subcommand report matched the executed command's bare name against the extension registry. cobra returns the deepest command it ran, so an extension invoked through a nested subcommand (k6 x docs search) was never reported, while a builtin sharing a registered extension's name (k6 version) was reported without the extension running. Two of the four catalogued subcommand extensions already nest, so their real usage went uncounted. The report now resolves the extension from the direct child of the root-level x command on the executed command's parent chain: nested invocations count toward their extension, builtins stay unreported, and the catch-all x help and provisioning stubs stay excluded.
The subcommand report checked only K6_NO_USAGE_REPORT, while the run report also honors the config file's noUsageReport option. The public usage-collection docs list the config file as a supported opt-out, so a user who disabled reporting there still sent a report on every k6 x extension run. The subcommand gate now reads the config file too, with the env var winning like on the run path, and fails closed by skipping the send when either source is unreadable, logging the skip at debug. Ordinary commands never pay for the file read: the extension match returns first.
createReport's catalog parameter became a func, and the unit tests passed a bare nil. That was safe only because no case records an extension: the old nil map filtered everything out when consulted, but calling a nil func panics. The tests now pass a func returning a nil catalog, so a future case that records an extension filters against an empty catalog instead of panicking.
K6_NO_USAGE_REPORT is documented to win over the config file's noUsageReport, but no test set both sources at once, so inverting the Apply order in reportSubcommandUsage passed the whole telemetry suite. The config-file opt-out test now tables the env variant: with K6_NO_USAGE_REPORT=false against the file's noUsageReport: true, one report must go out on both the run and subcommand paths. The inverted-precedence mutant now fails it.
The walk's root-level check in subcommandExtension had no covering test: simplifying its condition to a bare name match passed the whole suite while an invocation under an extension's own x-named subcommand went unreported. Rows for a grandchild and an x-named nested subcommand now pin the attribution; the weakened guard fails them.
Only the negative half of the builtin-name collision was pinned: running the builtin sends nothing. A walk that additionally blacklisted builtin names would have passed the suite while a builtin-named extension invoked under x silently went unreported. The positive case pins that k6 x version reports the extension.
reportSubcommandUsage skips the send when the config file is unreadable, but no test covered that branch: swallowing the read error and reporting anyway would have passed the suite. The new case pins that a malformed config file suppresses the report even when the env re-enables it, while the subcommand still runs.
The hardcoded module path never matched the registered extension: a func module resolves to its constructor's symbol name, so the catalog fixture filtered every extension out and the count-only assertions hid it. Deriving the path via ext.Get keeps the fixture real, like the sibling report tests.
inancgumus
temporarily deployed
to
azure-trusted-signing
July 28, 2026 23:34 — with
GitHub Actions
Inactive
inancgumus
temporarily deployed
to
azure-trusted-signing
July 28, 2026 23:36 — with
GitHub Actions
Inactive
inancgumus
force-pushed
the
fix/ext-telemetry-reporting-gaps
branch
from
July 28, 2026 23:40
79e80f4 to
2b1399e
Compare
inancgumus
temporarily deployed
to
azure-trusted-signing
July 28, 2026 23:45 — with
GitHub Actions
Inactive
inancgumus
temporarily deployed
to
azure-trusted-signing
July 28, 2026 23:48 — with
GitHub Actions
Inactive
k6 x <name> --help reported the extension, but k6 help x <name>, which displays the same help, did not, undercounting extension usage. Resolve the root help command to the command whose help it displayed before matching it to an extension, so both help forms count. k6 help x and k6 x help <name> describe the x namespace rather than an extension and stay unreported.
inancgumus
temporarily deployed
to
azure-trusted-signing
July 29, 2026 01:20 — with
GitHub Actions
Inactive
inancgumus
temporarily deployed
to
azure-trusted-signing
July 29, 2026 01:22 — with
GitHub Actions
Inactive
janHildebrandt98
approved these changes
Jul 30, 2026
stacked auto-merge was automatically disabled
July 30, 2026 13:51
Pull Request is not mergeable
stacked auto-merge was automatically disabled
July 30, 2026 13:55
Pull Request is not mergeable
social4hyq
pushed a commit
to social4hyq/homebrew-core
that referenced
this pull request
Sep 20, 2026
k6 2.2.0 Created-by: HarmonybrewBot Commit-by: HarmonybrewBot Merged-by: HarmonybrewBot Description: Created by `brew bump` --- Created with `brew bump-formula-pr`.<details> <summary>release notes</summary> <pre>k6 `v2.2.0` is here 🎉! This release includes: - `k6 cloud run --local-execution` now streams k6's logs to Grafana Cloud, so the test run's log view works for local execution too. - `chromium.connectOverCDP()`, which connects browser tests to an already-running Chromium instance. - `TextEncoder` and `TextDecoder` available as globals, and `WritableStream` support in `k6/experimental/streams`. - A `k6 cloud load-zone list` command. - Two new experimental feature flags: `merge-run-tags` and `freeze-env`. ## Breaking changes There are no breaking changes in this release. ## New features ### `k6 cloud run --local-execution` streams logs to Grafana Cloud [#6171](grafana/k6#6171) When a cloud test runs locally with `k6 cloud run --local-execution`, k6's logs now stream to the Grafana Cloud test run, so the run's log view is populated the same way it is for cloud execution. Previously, local-execution logs stayed on the machine running k6 and never reached the cloud. Work with Grafana's secrets management to safely work with secrets and redact them if they're accidentally leaked into logs are pushed. Use the new `--no-cloud-logs` flag opts out to opt out of streaming of logs when working with `--local-execution`: ```shell k6 cloud run --local-execution script.js k6 cloud run --local-execution --no-cloud-logs script.js ``` ### Connect to a running browser with `chromium.connectOverCDP()` [#6165](grafana/k6#6165) The browser module can now attach to an existing Chromium-based browser over the Chrome DevTools Protocol, mirroring Playwright's `browserType.connectOverCDP()`. Pass the browser's WebSocket endpoint and k6 manages the returned browser's connection — it's auto-closed at the end of the iteration, though you can call `close()` earlier to release the connection on demand. ```js import { chromium } from 'k6/browser'; export default async function () { const browser = await chromium.connectOverCDP('ws://localhost:9222/devtools/browser/<id>'); const page = await browser.newPage(); try { await page.goto('https://quickpizza.grafana.com/'); } finally { await page.close(); await browser.close(); } } ``` Unlike the `K6_BROWSER_WS_URL` environment variable, the endpoint is a runtime value — you can, for example, request a fresh session URL from a browser provider's API in `setup()` and connect to it from the iterations. ### `TextEncoder` and `TextDecoder` globals [#6182](grafana/k6#6182) `TextEncoder` and `TextDecoder` are now available as standard globals in both the init and VU contexts, no import required — matching how they are exposed in browsers and other JavaScript runtimes. ```js const encoded = new TextEncoder().encode('Hello, world!'); const decoded = new TextDecoder().decode(encoded); ``` ### `WritableStream` in `k6/experimental/streams` [#6132](grafana/k6#6132) The experimental streams module now implements `WritableStream` and `WritableStreamDefaultWriter` following the WHATWG Streams specification, complementing the existing `ReadableStream` and paving the way for a future `TransformStream` implementation. ```js import { WritableStream } from 'k6/experimental/streams'; export default async function () { const stream = new WritableStream({ write(chunk) { console.log(`wrote ${chunk}`); }, }); const writer = stream.getWriter(); await writer.write('hello'); await writer.close(); } ``` ### `k6 cloud load-zone list` command [#6142](grafana/k6#6142) A new `k6 cloud load-zone list` subcommand lists the load zones — public and private — available in the configured Grafana Cloud k6 stack, mirroring the existing `k6 cloud project list` command. Output defaults to a human-readable table; pass `--json` to emit a JSON array instead. ```console $ k6 cloud load-zone list Load zones for https://example.grafana.net: ID NAME TYPE AVAILABLE amazon:us:ashburn Ashburn, US (Amazon) public yes amazon:sa:cape town Cape Town, SA (Amazon) public yes ``` ### Configurable `handleSummary()` timeout [#5854](grafana/k6#5854) The time budget for the `handleSummary()` callback — previously hardcoded to 120 seconds — is now configurable through the `handleSummaryTimeout` option or the `K6_HANDLE_SUMMARY_TIMEOUT` environment variable, so long-running tests with heavy summaries no longer fail with `handleSummary() execution timed out`. Thanks, @LBaronceli! ```js export const options = { handleSummaryTimeout: '5m', }; ``` ### New experimental feature flags: `merge-run-tags` and `freeze-env` Two new experimental flags join the feature-flag system introduced in v2.1.0: - [#5714](grafana/k6#5714) `merge-run-tags` merges run tags per key across config layers, so `options.tags` in a script is no longer silently discarded when `--tag` or `K6_TAGS` is also used — higher-priority layers win on conflicting keys instead of replacing the whole map. Thanks, @yordis! - [#6032](grafana/k6#6032) `freeze-env` freezes the `__ENV` object, so modifications from script code throw a `TypeError` (in strict mode) instead of silently persisting across iterations and scenarios. Thanks, @lohitkolluri! ```shell k6 run --features merge-run-tags,freeze-env script.js ``` ## UX improvements and enhancements - [#5631](grafana/k6#5631) Makes the browser module's header accessors — `response.allHeaders()`, `headerValue()`, `headerValues()`, and `headersArray()` — return the raw wire headers (including `Set-Cookie` and security-related headers), correctly paired with each hop of a redirect chain instead of Chrome's provisional headers. As part of this, `headerValues()` now matches header names case-insensitively and splits repeated values on newlines rather than commas, and the `browser_data_sent`/`browser_data_received` metrics now include the raw header bytes and no longer vary run-to-run with CDP event ordering. - [#6208](grafana/k6#6208) Makes `k6 cloud` reject the run flags (for example, `--vus`) with an `unknown flag` error and a non-zero exit code. Previously `k6 cloud --vus 10 script.js` accepted the flags, printed the help text, and exited 0 — running tests with `k6 cloud` directly was deprecated in v2.0.0 in favor of `k6 cloud run`. - [#6096](grafana/k6#6096) Points the cloud secrets error at `K6_CLOUD_SECRETS_TOKEN` and `K6_CLOUD_SECRETS_ENDPOINT` when a test run is reused via `K6_CLOUD_PUSH_REF_ID` under `--local-execution`, instead of suggesting the `--local-execution` flag the user is already using. - [#6196](grafana/k6#6196) Adds `catch` blocks to the browser examples so a failing iteration reports the original error instead of a subsequent `page.close()` failure. Thanks, @locker95! ## Bug fixes - [#6234](grafana/k6#6234) Classifies HTTP/2 errors by message so the `error_code` metric tag stays correct when k6 is built with Go 1.27 (whose `x/net/http2` delegates to the standard library), and explicitly enables HTTP/2 negotiation on VU transports. - [#6232](grafana/k6#6232) Drains queued log entries in the Loki hook at shutdown so `--out loki` and cloud log streaming no longer lose the final batch, and emits a `k6 dropped N log messages` warning when the cloud log buffer overflows instead of dropping logs silently. - [#6125](grafana/k6#6125) Serializes the first concurrent open of a file in the caching filesystem so parallel `fs.open()` calls on the same file no longer read zero or truncated bytes. - [#6147](grafana/k6#6147) Fixes a data race and inconsistent request-interception state when browser routes are added or removed concurrently. Thanks, @somak2kai! - [#6070](grafana/k6#6070) Flushes buffered file log output once per second so recent logs aren't lost when k6 is killed before shutdown. Thanks, @rohan-patnaik! - [#6205](grafana/k6#6205) Stops sending an invalid `Sec-WebSocket-Protocol` header when tailing Grafana Cloud logs; spec-strict servers rejected the handshake with `websocket: bad handshake`. - [#6200](grafana/k6#6200) Leaves a counter's `rate` unset when the observed duration is zero, instead of computing `+Inf` and spuriously failing `rate` thresholds. Thanks, @samarth70! - [#6195](grafana/k6#6195) Initializes a gauge's maximum from the first sample so all-negative gauge series no longer report `max=0`. Thanks, @Solaris-star! - [#6145](grafana/k6#6145) Prevents the OpenTelemetry output from panicking at startup when basic auth is configured without `K6_OTEL_HEADERS`. Thanks, @lukdz! - [#6140](grafana/k6#6140) Stops `SharedArray` deep-freezing JS primitives, which needlessly wrapped large strings in `String` objects — cutting memory usage in the reported reproduction from roughly 1 GB to 100 MB. ## Maintenance and internal improvements - [#6126](grafana/k6#6126), [#6224](grafana/k6#6224), [#6229](grafana/k6#6229) Adds anonymous extension usage to the k6 usage report: a run reports the Go module path, version, and type of registry-cataloged extensions it actually uses (imported `k6/x/` modules, output extensions selected with `--out`, and `k6 x` subcommands). Private and unlisted extensions are never reported, and the existing `--no-usage-report` opt-out covers it. - [#6183](grafana/k6#6183), [#6218](grafana/k6#6218) Updates Sobek and regexp2, making `W See merge request: Harmonybrew/homebrew-core!16299
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
Fixes three reporting gaps in extension usage telemetry:
k6 x docs search) is reported. A builtin sharing an extension's name is not.noUsageReportsuppresses the subcommand report, matching the run report; the env var keeps precedence.Why?
Extension telemetry should count what users actually run and respect opt-outs.