Skip to content

Deploy August 10, 2026 - #6255

Merged
canova merged 59 commits into
productionfrom
main
Aug 10, 2026
Merged

Deploy August 10, 2026#6255
canova merged 59 commits into
productionfrom
main

Conversation

@canova

@canova canova commented Aug 10, 2026

Copy link
Copy Markdown
Member

Changes:

[fatadel] Create the Network track from the timeline-network schema display location (#6224)
[Markus Stange] Only call getRawFrameTableBuilderWithExistingContents once per symbolication batch. (#6233)
[fatadel] Improve discoverability of downloading a local profile (#6216)
[Nazım Can Altınova] Handle the cli daemon startup failures more gracefully with better errors (#6241)
[Nazım Can Altınova] Add the ability to apply source maps from the CLI (#6229)
[Nazım Can Altınova] Handle Text and Log marker payloads with their marker schema (#6247)
[Nazım Can Altınova] Bump the Gecko profile version to make sure that the Text and Log marker changes are picked up in the frontends (#6252)
[fatadel] Deactivate a menu button as soon as its panel is dismissed (#6251)
[Nazım Can Altınova] 🔃 Sync: l10n -> main (August 10, 2026) (#6253)
[Nazım Can Altınova] Bump profiler-cli version to 0.8.0 (#6254)

And special thanks to our localizers:

de: Ger
de: Michael Köhler
el: George kitsoukakis
en-CA: chutten
en-CA: Saurabh
en-GB: Ian Neal
es-CL: ravmn
fy-NL, nl: Fjoerfoks
fr: Théo Chevalier
fy-NL: Fjoerfoks
ia: Melo46
it: Francesco Lodolo [:flod]
nl: Fjoerfoks
ru: michellemelsspam
ru: Valery Ledovskoy
tr: giray
tr: Selim Şumlu
zh-TW: Pin-guang Chen

mstange and others added 30 commits August 3, 2026 09:20
…olication batch.

Fixes #6232.

Before: https://share.firefox.dev/3UaE2Pt
After: https://share.firefox.dev/4fNirnE

Create the mutable tables once per batch and let each step mutate them in
place. This avoids cloning tables unnecessarily.

Unrelated to the main change in this patch, this also replaces the linear
scan of the sources table, which ran once per newly created func, with a
filename-to-source-index map built once per batch.
Co-authored-by: Francesco Lodolo [:flod] <flod+pontoon@mozilla.com> (it)
Co-authored-by: Pin-guang Chen <petercpg@mail.moztw.org> (zh-TW)
Co-authored-by: Michael Köhler <michael.koehler1@gmx.de> (de)
Co-authored-by: Ian Neal <iann_bugzilla@blueyonder.co.uk> (en-GB)
Co-authored-by: Valery Ledovskoy <valery@ledovskoy.com> (ru)
Co-authored-by: ravmn <ravmn@ravmn.cl> (es-CL)
Co-authored-by: Melo46 <melo@carmu.com> (ia)
…ation (#6224)

The Network track was added whenever a thread had a marker with
data.type === 'Network'. Add a timeline-network marker-schema display
location, declare it on the Network schema, and drive track creation
from that location so Network handling no longer hardcodes the payload
type.

The combined (front-end + Gecko) schema list is used so the front-end
Network schema override always contributes its timeline-network
location.

Bump the processed profile format version to 69 for the new display
location.

Part of #6194
Co-authored-by: Fjoerfoks <fryskefirefox@gmail.com> (nl)
Co-authored-by: Théo Chevalier <theo@theochevalier.org> (fr)
Co-authored-by: George kitsoukakis <norhorn@gmail.com> (el)
Co-authored-by: Fjoerfoks <fryskefirefox@gmail.com> (fy-NL, nl)
…olication batch. (#6233)

<!-- profiler-preview-links:start -->

[Main](https://main--perf-html.netlify.app/public/ksp1w4z1tgpkt16m6mxmabbvdevf118v41fvvjg/calltree/?globalTrackOrder=0&symbolServer=https://mozilla.symbols.samplyprofiler.com&thread=0&v=17)
| [Deploy
preview](https://deploy-preview-6233--perf-html.netlify.app/public/ksp1w4z1tgpkt16m6mxmabbvdevf118v41fvvjg/calltree/?globalTrackOrder=0&symbolServer=https://mozilla.symbols.samplyprofiler.com&thread=0&v=17)
<!-- profiler-preview-links:end -->

Fixes #6232.

Before: https://share.firefox.dev/3UaE2Pt (35s jank)
After: https://share.firefox.dev/4fNirnE (8.8s jank, 4x faster)

Create the mutable tables once per batch and let each step mutate them
in place. This avoids cloning tables unnecessarily.

Unrelated to the main change in this patch, this also replaces the
linear scan of the sources table, which ran once per newly created func,
with a filename-to-source-index map built once per batch.
Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
Bumps [fast-uri](https://github.com/fastify/fast-uri) from 3.1.4 to 3.1.5.
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](fastify/fast-uri@v3.1.4...v3.1.5)

---
updated-dependencies:
- dependency-name: fast-uri
  dependency-version: 3.1.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Downloading a profile was only reachable from inside the single
"Upload Local Profile" menu, so users looking to save a profile to
disk had no way to discover it from the toolbar.

Replace that single menu with two buttons, "Download…" and "Share…",
each with its own icon. Both open the same options panel; only the
heading and the action button differ, so Download saves the profile to
a file and Share uploads it for a shareable link.

Closes #3620
We spawn the daemon detached with its stdio discarded, so a fatal
startup error was just an exit code. A denied listen() even exited 0,
since the server error handler routed through shutdown().

This commit adds a reportFatalError() that writes the reason to a
<sessionId>.error file, appends it to the log, and exits 3, plus a
diagnostics.ts that turns the errnos behind these failures into
explanations. The following commits are going to read this file.

Also it fixes the log stream being created before the session directory
exists.
Previously we only output "Daemon process exited unexpectedly during
startup" on daemon startup failure. Now we report the reason the daemon
records, which is the startup error file first, then the tail of its
log.

When neither exists, report what is known instead of guessing. If the
daemon exited, print the command to rerun the spawn in the foreground.
If it is still running and simply has not published its metadata, say
that and name the pid, rather than declaring it dead and blaming the
sandbox.
An unusable session directory is the one failure the daemon cannot
report, since the error file it would report through lives in that
directory. Check it in the client instead: stat, mkdir, and a write
probe, because mkdirSync() succeeds on an existing directory that cannot
be written to.

Check the socket path length there too. The kernel rejects an over-long
sockaddr_un with a bare EINVAL that names neither the limit nor the
path.

Also stop "session list" from creating the session directory just to find no
sessions in it.
A dead daemon and a sandbox that forbids connect() look the same to
validateSession(), and both ended in cleanupSession(). Deleting the socket file
of a live daemon makes it unreachable for good, and deleting the metadata hides
it from "session list" and "stop --all", leaving a process holding a profile that
no command can find or stop.

This patch gates cleanup on the errnos that prove nothing is listening:
ENOENT, ECONNREFUSED, and ENOTSOCK. On EACCES, EPERM or ETIMEDOUT, keep
the files and report the session as unreachable with its pid.
…rors (#6241)

Fixes #6230.

The scope of this PR was smaller but I went into this rabbit hole of
improving this code and it turned out a lot bigger than I initially
intended. But I think this improves the whole daemon startup path
drastically. See the individual commits for more info. Now, the cli
returns error messages like this:

When the session directory is not writable:
```
Error: Cannot write to the profiler-cli session directory ~/.profiler-cli.
Permission denied. Sandboxes (agent sandboxes, containers, restricted CI runners) commonly deny access outside the workspace, including the home directory.
Underlying error: EACCES: permission denied, open '~/.profiler-cli/.write-probe-28702'
This is the default session directory (PROFILER_CLI_SESSION_DIR is not set).
Point profiler-cli somewhere writable, for example:
  PROFILER_CLI_SESSION_DIR=/var/folders/.../T/profiler-cli profiler-cli load <PATH>
A directory inside your workspace also works, as long as the socket path stays short.
```

When the unix sockets are not allowed:
```
Error: The profiler-cli daemon exited during startup (exit code 3):
    Not allowed to create the Unix domain socket at ~/.profiler-cli/ewzneg2rzye.sock.
    profiler-cli needs a Unix domain socket to talk to its daemon. If you are inside a sandbox, allow Unix domain sockets in the sandbox policy, point PROFILER_CLI_SESSION_DIR at a directory the sandbox can write to, or run profiler-cli outside the sandbox.
    Underlying error: listen EPERM: operation not permitted ~/.profiler-cli/ewzneg2rzye.sock
```

And there are a few more other combinations in case socket path is too
long, the socket path is already occupied, a session can't be reached,
when the `connect()` is denied, etc.
Co-authored-by: ravmn <ravmn@ravmn.cl> (es-CL)
Co-authored-by: Fjoerfoks <fryskefirefox@gmail.com> (nl)
Co-authored-by: Francesco Lodolo [:flod] <flod+pontoon@mozilla.com> (it)
depfu Bot and others added 26 commits August 7, 2026 14:58
Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
Co-authored-by: Valery Ledovskoy <valery@ledovskoy.com> (ru)
Co-authored-by: michellemelsspam <michellemelsspam@gmail.com> (ru)
Co-authored-by: Saurabh <connect@saurabhpro.com> (en-CA)
Co-authored-by: chutten <chutten@mozilla.com> (en-CA)
Co-authored-by: Ian Neal <iann_bugzilla@blueyonder.co.uk> (en-GB)
Co-authored-by: Théo Chevalier <theo@theochevalier.org> (fr)
Co-authored-by: giray <giray@nightlylab.com> (tr)
Co-authored-by: Melo46 <melo@carmu.com> (ia)
Co-authored-by: Melo46 <melo@carmu.com> (ia)
Co-authored-by: George kitsoukakis <norhorn@gmail.com> (el)
Firefox now outputs the Text marker's `name` and the Log marker's
`message` as unique strings, so the payload holds a string table index
instead of the text itself. The two Text marker PII sanitizers and the
MOZ_LOG formatting read those fields directly and threw an error.

This patch fixes these issues by always looking at the marker schema and
not having any arbitrary assumptions about some certain marker types. It
was a bad idea to have these custom handlings in the past instead of
relying on the marker schema in the first place.
Added a SourceMapRunner type and an optional `run` argument to
doSourceMapSymbolication through applySourceMapFile, to make the source
map symbolication runner injectable. The default behavior stays as the
Web Worker runner, but let's the non-browser callers inject a runner
that calls the core logic directly, since the profiler-cli Node daemon
has no Workers.
`ApplySourceMapFileResult` only carried the resolved bundle source's
filename, which is all the web UI needs. Add the source table index
alongside it, so callers that identify sources by index rather than by
name can report which source the map landed on. A follow-up uses this to
add "sourcemap" commands to profiler-cli, which refers to sources by
"src-N" handles.
Lists the bundle sources that carry a `sourceMapURL` and are therefore
eligible to have a `.map` applied to them -- the same set the web app's
"Apply source map…" picker offers. Each gets a `src-N` handle, which is a
direct index into `profile.shared.sources` and so is stable across
sessions for the same profile, like `f-N`.

Firefox stores an inline map's entire `data:` URL in the source table, so
a "URL" can be megabytes of base64. Those are reported by media type and
size instead, which keeps the payload out of both the text and `--json`
output.

The integration fixtures are pre-generated and committed because the
profile builders are DOM-coupled and can't run in the node-env test
process, so sourcemap-generator.ts regenerates them via a browser-env
test.

A follow-up adds "sourcemap apply", which consumes these handles.
Brings the web app's "Apply source map…" feature to profiler-cli, reusing
the shared `applySourceMapFile` thunk. Since the CLI is one-shot, the web
picker becomes a two-step flow: "sourcemap sources" lists the candidates,
then "sourcemap apply <path> [--to src-N]" reads the .map on the daemon,
auto-matches it to a source (or applies to the source given by --to) and
re-symbolicates in place. Ambiguous matches and errors exit non-zero so
scripts can branch on them.

The daemon has no Web Worker, so it injects a runner that calls the
symbolication core directly on the current thread. That core's `source-map`
dependency reads its WASM parser from `path.join(__dirname,
'mappings.wasm')` at runtime, and esbuild does not bundle that file, so the
build copies it next to the bundle and the publish check now fails if it is
missing -- without it, "sourcemap apply" silently applies nothing.

`--to` only accepts sources that carry a `sourceMapURL`, the same set the
web picker offers. Applying a map to any other source would skip the
auto-match step's `no-eligible-sources` guard and then de-minify nothing,
which reads as a successful apply.
Adds a SOURCE MAPS section covering the sources -> apply flow and the
--to disambiguation step, and lists src-N in the handle reference tables
alongside t-N / f-N / c-N / ts-N.
This fixes #6196.

This PR adds 2 commands to the CLI so we can apply source maps from
local files later:
- `pq sourcemap sources`
- `pq sourcemap apply`

`sourcemap sources` is used for determining which sources we can apply
the source maps onto. and `sourcemap apply` is to apply that source map
that we provide as an argument.

For example the output of `sourcemap sources`:

```
[Thread: t-20 (GeckoMain) | View: Full profile | Full: 6.572s]

Sources with source maps (4):
  src-61  https://profiler.firefox.com/index-XVVABR7J.js  (sourceMapURL: /index-XVVABR7J.js.map)
  src-65  https://profiler.firefox.com/chunk-JI4GYAEJ.js  (sourceMapURL: /chunk-JI4GYAEJ.js.map)
  src-66  https://profiler.firefox.com/chunk-FQS6JYWD.js  (sourceMapURL: /chunk-FQS6JYWD.js.map)
  src-70  https://profiler.firefox.com/chunk-FFESA2B5.js  (sourceMapURL: /chunk-FFESA2B5.js.map)
```

Then `pq sourcemap apply <sourcemap-path>` could optionally take `--to
<src-N>` argument.
If it's not provided, we try to match the source map given to an
existing source, if it matches, great, it's done. If it doesn't match,
we show an error saying that the user has to provide the `--to <src-N>`
by looking at the output of `sourcemap sources`. If that argument is
provided, we automatically apply to that only.

For example:
```
$ pq sourcemap apply ./dist/index.js.map
The source map matches more than one source. Re-run with --to <src-N> to pick one:
  src-61  https://profiler.firefox.com/index-XVVABR7J.js  (sourceMapURL: /index-XVVABR7J.js.map)
  src-65  https://profiler.firefox.com/chunk-JI4GYAEJ.js  (sourceMapURL: /chunk-JI4GYAEJ.js.map)
  src-66  https://profiler.firefox.com/chunk-FQS6JYWD.js  (sourceMapURL: /chunk-FQS6JYWD.js.map)
  src-70  https://profiler.firefox.com/chunk-FFESA2B5.js  (sourceMapURL: /chunk-FFESA2B5.js.map)
```
And then:
```
$ pq sourcemap apply ./dist/index.js.map --to src-61
Applied source map to https://profiler.firefox.com/index-XVVABR7J.js (src-61). Re-run thread commands to see de-minified names.
```
Fixes #6245 

Firefox now outputs the Text marker's `name` and the Log marker's
`message` as unique strings, so the payload holds a string table index
instead of the text itself. The two Text marker PII sanitizers and the
MOZ_LOG formatting read those fields directly and threw an error.

This patch fixes these issues by always looking at the marker schema and
not having any arbitrary assumptions about some certain marker types. It
was a bad idea to have these custom handlings in the past instead of
relying on the marker schema in the first place.
Co-authored-by: giray (tr) <giray@nightlylab.com>
Co-authored-by: Selim Şumlu (tr) <selim@sum.lu>
…ker changes are picked up in the frontends (#6252)

The Text marker's `name` and the Log marker's `message` are unique
strings now, so their payloads hold a string table index instead of the
text.

But we realized that the frontend had some hardcoded assumptions about
these marker types, and they weren't looking at the schema at all.
That's fixed in #6247.

There is nothing to upgrade because the frontend reads the field format
from the marker schema. But since older frontends read these two fields
directly, this bump makes sure that they get updated.

Bugzilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=2054010
The dismissed button kept its active background until ArrowPanel's
400ms closing timeout had run, so two buttons looked active at once.
closePanel now clears the open state when the close starts, leaving
the animation to ArrowPanel.

Closes #6243
Updated locales: be, de, el, en-CA, en-GB, es-CL, fr, fur, fy-NL, ia,
it, kab, nl, pt-BR, ru, sr, sv-SE, tr, uk, zh-CN, zh-TW.
@canova
canova requested review from a team and fatadel as code owners August 10, 2026 17:02
@canova
canova merged commit a04f7ea into production Aug 10, 2026
38 checks passed
@canova canova changed the title Deloy August 10, 2026 Deploy August 10, 2026 Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants