Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bumps
[taiki-e/install-action](https://github.com/taiki-e/install-action) from
2.85.10 to 2.86.5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/taiki-e/install-action/releases">taiki-e/install-action's
releases</a>.</em></p>
<blockquote>
<h2>2.86.5</h2>
<ul>
<li>
<p>Update <code>zola@latest</code> to 0.23.4.</p>
</li>
<li>
<p>Update <code>wasm-tools@latest</code> to 1.257.1.</p>
</li>
<li>
<p>Update <code>protoc@latest</code> to 3.36.0.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.8.10.</p>
</li>
<li>
<p>Update <code>cargo-dinghy@latest</code> to 0.8.6.</p>
</li>
<li>
<p>Update <code>wasmtime@latest</code> to 48.0.0.</p>
</li>
</ul>
<h2>2.86.4</h2>
<ul>
<li>
<p>Update <code>oxfmt@latest</code> to 1.79.0.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.8.8.</p>
</li>
<li>
<p>Update <code>martin@latest</code> to 1.14.0.</p>
</li>
<li>
<p>Update <code>dprint@latest</code> to 0.56.0.</p>
</li>
<li>
<p>Update <code>cargo-about@latest</code> to 0.9.2.</p>
</li>
<li>
<p>Update <code>biome@latest</code> to 2.5.9.</p>
</li>
</ul>
<h2>2.86.3</h2>
<ul>
<li>
<p>Update <code>prek@latest</code> to 0.4.14.</p>
</li>
<li>
<p>Update <code>osv-scanner@latest</code> to 2.5.1.</p>
</li>
<li>
<p>Update <code>cargo-llvm-cov@latest</code> to 0.9.0.</p>
</li>
</ul>
<h2>2.86.2</h2>
<ul>
<li>
<p>Update <code>uv@latest</code> to 0.12.5.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.8.6.</p>
</li>
<li>
<p>Update <code>cargo-tarpaulin@latest</code> to 0.37.2.</p>
</li>
</ul>
<h2>2.86.1</h2>
<ul>
<li>Fix an issue where <code>oxfmt</code> was accidentally installed as
<code>oxfmt-{target}{exe}</code>. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/1969">#1969</a>)</li>
</ul>
<h2>2.86.0</h2>
<ul>
<li>Support <code>oxfmt</code>. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/1967">#1967</a>,
thanks <a
href="https://github.com/rami3l"><code>@rami3l</code></a>)</li>
</ul>
<h2>2.85.14</h2>
<ul>
<li>
<p>Update <code>uv@latest</code> to 0.12.4.</p>
</li>
<li>
<p>Update <code>trivy@latest</code> to 0.74.0.</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md">taiki-e/install-action's
changelog</a>.</em></p>
<blockquote>
<h2>[2.86.5] - 2026-08-21</h2>
<ul>
<li>
<p>Update <code>zola@latest</code> to 0.23.4.</p>
</li>
<li>
<p>Update <code>wasm-tools@latest</code> to 1.257.1.</p>
</li>
<li>
<p>Update <code>protoc@latest</code> to 3.36.0.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.8.10.</p>
</li>
<li>
<p>Update <code>cargo-dinghy@latest</code> to 0.8.6.</p>
</li>
<li>
<p>Update <code>wasmtime@latest</code> to 48.0.0.</p>
</li>
</ul>
<h2>[2.86.4] - 2026-08-20</h2>
<ul>
<li>
<p>Update <code>oxfmt@latest</code> to 1.79.0.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.8.8.</p>
</li>
<li>
<p>Update <code>martin@latest</code> to 1.14.0.</p>
</li>
<li>
<p>Update <code>dprint@latest</code> to 0.56.0.</p>
</li>
<li>
<p>Update <code>cargo-about@latest</code> to 0.9.2.</p>
</li>
<li>
<p>Update <code>biome@latest</code> to 2.5.9.</p>
</li>
</ul>
<h2>[2.86.3] - 2026-08-18</h2>
<ul>
<li>
<p>Update <code>prek@latest</code> to 0.4.14.</p>
</li>
<li>
<p>Update <code>osv-scanner@latest</code> to 2.5.1.</p>
</li>
<li>
<p>Update <code>cargo-llvm-cov@latest</code> to 0.9.0.</p>
</li>
</ul>
<h2>[2.86.2] - 2026-08-17</h2>
<ul>
<li>
<p>Update <code>uv@latest</code> to 0.12.5.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.8.6.</p>
</li>
<li>
<p>Update <code>cargo-tarpaulin@latest</code> to 0.37.2.</p>
</li>
</ul>
<h2>[2.86.1] - 2026-08-15</h2>
<ul>
<li>Fix an issue where <code>oxfmt</code> was accidentally installed as
<code>oxfmt-{target}{exe}</code>. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/1969">#1969</a>)</li>
</ul>
<h2>[2.86.0] - 2026-08-15</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/taiki-e/install-action/commit/ba47c86ac325773530516bb756137ac718732518"><code>ba47c86</code></a>
Release 2.86.5</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/5e0b59bc928f672ccd1072a19b6815d0cf5b21cb"><code>5e0b59b</code></a>
Update <code>zola@latest</code> to 0.23.4</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/60dfdd7edfbb113f6254c9b3889a61fb3e20baf4"><code>60dfdd7</code></a>
Update <code>wasm-tools@latest</code> to 1.257.1</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/c262502059d0289897f7720971cb62c8b83217f1"><code>c262502</code></a>
Update <code>protoc@latest</code> to 3.36.0</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/4985cbc05f60164fac55ad0f7e788c0a97fd2aed"><code>4985cbc</code></a>
Update <code>mise@latest</code> to 2026.8.10</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/e782b6cb9189134d57cdae9cdf8ac0ae4c62384c"><code>e782b6c</code></a>
Update <code>cargo-dinghy@latest</code> to 0.8.6</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/e891b49f0d0c25fc74d5bf0f29a720e43c063750"><code>e891b49</code></a>
Update biome manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/394bb5ddf8b2bba382638dadf8c93ff59b9b3fb5"><code>394bb5d</code></a>
Update wasmtime manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/a2a5f6e99e1a31540baa0468acfa302cff0f359f"><code>a2a5f6e</code></a>
Release 2.86.4</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/5afbb1a197d47fef2a5793727b494b64e09ac265"><code>5afbb1a</code></a>
Update wasm-tools manifest</li>
<li>Additional commits viewable in <a
href="https://github.com/taiki-e/install-action/compare/v2.85.10...v2.86.5">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com>
## What
- **CLAUDE.md** (new, tracked): project-level rules for AI coding
sessions — build/workflow basics, Rust code organization (item order
`mod → use → const/static → types → impls → fns`, pub/private function
grouping, `#[cfg(test)] mod tests` always last, structural thresholds
are ratchet-only), comment discipline (one line, only for non-obvious
constraints), PR conventions, and enterprise-gated code verification
(including keeping `Cargo.toml.openobserve` in the o2-enterprise repo in
sync with this repo's root `Cargo.toml`). Replaces `.claude/.clauderc`,
which is not a file Claude Code reads.
- **Structural clippy ratchets in CI**: the clippy step now also enables
`too_many_lines`, `cognitive_complexity`, and `excessive_nesting`, with
clippy.toml thresholds set just above today's worst offenders (1024
lines / complexity 100 / nesting 10), so the current tree passes clean.
Measured across the workspace with `--all-targets`: max function 1019
lines, max complexity 94, max nesting 10. The thresholds only ratchet
down as code is cleaned up — CI failing on one of these means split the
function, not raise the number.
- **clippy.toml**: add `source-item-ordering = ["module"]` so the opt-in
`clippy::arbitrary_source_item_ordering` lint checks module-level item
order only (its default also forces alphabetical struct fields/enum
variants).
- **.gitignore**: reorganized into commented sections and slimmed from
116 to 75 lines — removed duplicate entries, patterns shadowed by other
patterns, one dead rule, and 14 stale one-off entries with no matching
files; simplified the `.vscode`/`.opencode`/`.claude` blocks.
## Why
Coding sessions kept placing functions in arbitrary positions (above
constants, mixed into the wrong visibility group, tests at the top of
files) and writing multi-line comment essays, and nothing bounded
function size/complexity growth. CLAUDE.md states the conventions once
for every contributor's sessions; enforcement stays with the standard
Rust toolchain (rustfmt, clippy thresholds, CI's `-D warnings`).
## Notes for reviewers
- The enterprise CI clippy step runs its own command without these `-W`
flags, so it is unaffected.
- An earlier revision of this branch added a PostToolUse hook script for
style checking; it was dropped in favor of toolchain + prompt rules
only, and `.claude/settings.json` stays gitignored.
- The gitignore rewrite was verified behavior-preserving at each step:
the untracked-file list and an 86-path rule battery were compared
before/after every change; the only intentional semantic changes are the
removals listed above.
## What this PR adds
end-to-end test suite for the **Mobile RUM SDK** under
`tests/mobile-testing/`, plus a **self-contained CI workflow** that runs
it on real emulators/simulators against an OpenObserve **built from this
PR's source**. Test / fixture / CI only — no product-code/existing test
changes
## How each test works (3 layers)
Every scenario is a real end-to-end journey, so a failure points at the
actual broken layer:
1. **Drive** — a Maestro flow taps through the app like a user
(`maestro/<track>/*.yaml`).
2. **API** — query the `_rumdata` stream and assert the telemetry is
correct (`utils/ooClient.js`, poll-and-retry for async ingestion).
3. **UI** — open the RUM dashboard and assert the sessions
## Coverage (42 tests across 4 platforms)
The **native platforms (android-native, ios-native) are now at parity
with React Native** — each new
native test (masking, network, bg/fg, user-identity, no-phone-home) was
built + validated on a real
emulator/simulator before landing.
| Capability | Layer | RN-Android | Android-native | RN-iOS | iOS-native
|
|---|---|:-:|:-:|:-:|:-:|
| Core telemetry (views/actions/handled-error/crash → `_rumdata`) | API
| ✅ | ✅ | ✅ | ✅ |
| Crash session viewable in dashboard | UI | ✅ | ✅ | ✅ | ✅ |
| Attributes: env / service / version tagging | API | ✅ | ✅ | ✅ | ✅ |
| User identity (`setUser`) | API | ✅ | ✅ | ✅ | ✅ |
| Network: fetch → resource + 4xx/5xx | API | ✅ | ✅ | ✅ | ✅ |
| Session-replay PII masking | UI | ✅ | ✅ | ✅ | ✅ |
| Background / foreground view transitions | API | ✅ | ✅ | — | ✅ |
| No-phone-home (no egress to Datadog hosts) | security | ✅ | ✅ | — | ✅
|
- Shared per-capability factories keep the specs DRY
(`utils/rumChecks.js`, `utils/coreRumSpec.js`).
- Negatives are covered: 4xx capture, PII-must-not-leak (masking), no
phone-home, handled-error ≠ crash.
- `o2-enterprise#2289` dashboard bugs are kept as inline skips that flip
green once fixed.
- Full capability × platform detail + on-device status:
`docs/COVERAGE-MATRIX.md`.
## Fixture apps + build-time config
- Four vendored apps under `apps/`: `o2-rum-tester` (React Native —
drives both RN platforms), `o2-native-android` (Kotlin), `o2-native-ios`
(Swift / xcodegen).
- Each reads its RUM target (endpoint / org / token) and SDK version
from a **build-time-overridable** config. The committed default is the
current pin, so local dev is unchanged; CI regenerates it to point at
the runner's OpenObserve and can pin the latest SDK on release.
## CI — `.github/workflows/mobile-sdk-e2e.yml` (self-contained, no
secrets)
- **Build once per OS from source.** `build_oo_linux` / `build_oo_macos`
compile OpenObserve (binary + embedded web UI) from this PR's code and
cache it. Device jobs download and run it **natively**, and the app
posts real RUM to it (Android reaches the host at `10.0.2.2`, the iOS
simulator via `localhost`). No Docker, no shared cluster, no secrets.
- **Device jobs run in parallel.** `android` (Linux + KVM emulator →
rn-android + android-native) and `ios` (macOS simulator, pinned Xcode
16.4 → rn-ios + ios-native).
- **`merge_reports`** combines both platforms into one browsable HTML
report — even when a device job fails.
- **`decide` picks which platform runs, to keep scarce macOS runners in
check:**
- PR touching Android or shared mobile-RUM code → **Android auto-runs**;
iOS is gated behind the `mobile-e2e` label.
- `mobile-e2e` label → both platforms (full pre-merge gate).
- `repository_dispatch(mobile-sdk-release)` from an SDK repo → runs that
SDK's platform (companion PRs wire this up:
openobserve-react-native-rum#3, openobserve-sdk-android#1,
openobserve-sdk-ios#1).
- `workflow_dispatch` → manual, choose platforms.
*Separate workflow :* it needs macOS **and** Android emulators, builds 4
phone apps, and is dispatch-driven — matching the repo's existing
per-suite split
## Status
Green end-to-end on GitHub runners (Android + iOS device jobs + merge) :
https://github.com/openobserve/openobserve/actions/runs/31733717758/job/94565520891
---------
Co-authored-by: Shrinath Rao <shnath@openobserve.ai>
Automated coverage for **email alert destinations and distribution
lists**, and unblocks the email tests that have been skipped since they
were written. **32 cases** — 27 active, 5 skipped regressions tracking
open defects (openobserve/o2-enterprise#2471).
**The unblocking.** The two skipped tests said *"the test environment
does not have email infrastructure set up"*. That over-stated it:
creating, editing, validating and deleting an email destination needs
SMTP switched **on**, and never reads a mailbox. Only delivery
assertions do. The suite is tiered on that:
| Tier | Needs | Cases |
|---|---|---|
| A | SMTP enabled | 24 |
| B | a readable sink | 2 |
| C | an alias that fans out | 1 |
**Tests**
- `Alerts/dl-email-destinations.spec.js` (32) — the DL half (alias
accepted, addressed, fanned out) and the recipient-list half, where our
code actually runs: splitting/trimming/lowercasing, the org-membership
gate, edit round-trips, add/remove/delete, both form paradigms (prebuilt
free-text vs the custom path's org-user picker), template auto-attach,
duplicate names, cancel, type-switching, keyboard, dark mode at 420px.
- `utils/mail-sink.js` — pluggable sink: Mailpit, a Mailinator inbox, or
a clean skip with a stated reason.
- `utils/o2-api.js` — storage is asserted from the API, never the form
field: an input can echo what you typed while the stored value differs.
- `scripts/dl-relay.js` — SMTP relay that expands one alias into
per-member deliveries, so fan-out runs with no external provider. Same
pattern as the in-test HTTP receiver in
`alerts-content-templates.spec.js`.
- `alertDestinationsPage.js` — +17 methods; the spec carries zero raw
locators.
**Replaces, without losing coverage.** The two skipped tests in
`alerts-destinations-prebuilt.spec.js` are removed for a pointer mapping
their intent to its new home: create (`D-01`), edit-add (`D-07`),
edit-remove (`ML-08`), delete (`UI-12`), format validation (`UI-02`).
Three of those did not exist before. That file now has no skips.
**CI.** `ZO_SMTP_ENABLED: true` was already set in `playwright.yml` but
had no host or port, so it fell back to `localhost:25` where nothing
listens — destinations could be **saved** while every **send** failed
silently. The workflow now starts Mailpit and a DL relay as static
binaries before the app (no Docker-in-Docker on these runners) and
points `ZO_SMTP_*` at them.
All three tiers run with no secrets and no egress. Verified in the CI
topology: **27 passed, 5 skipped**, `D-02` confirmed reaching all three
member mailboxes.
**Behaviour.** Self-cleaning via the `auto_dest_dl_*` prefix
`cleanup.spec.js` already sweeps, plus an API `afterAll`. `mode:
'parallel'` — each test owns its fixtures.
**Findings** are filed in openobserve/o2-enterprise#2471, not fixed
here. Two P1s: the *"Show matching rows"* toggle is ignored so log rows
are always embedded, and a user removed from the org keeps receiving
alerts while the destination can no longer be saved. The regression
tests for each are in this PR, skipped until the fix lands.
**Paired ENT PR: openobserve/o2-enterprise#2472.** ENT's workflow sets
`ZO_SMTP_ENABLED: false`, so without it the suite skips all 27 cases
there. The shard matrix needs no ENT change — ENT builds it from this
repo's `ci_matrix.json` plus its overlay, so the new spec is picked up
automatically. Merge the two together: this one alone leaves enterprise
with no email coverage.
## What
Adds `.github/workflows/merge-queue-auto-requeue.yml` — **Auto Merge
Queuer**.
When a PR is kicked **out of the merge queue because its required checks
failed** (`reason == CI_FAILURE`) or **timed out** (`reason ==
CI_TIMEOUT`), the workflow adds it straight back to the queue — **up to
twice**.
## Behavior
- **Trigger:** `pull_request: [dequeued]`, gated at the job `if` to
`CI_FAILURE` / `CI_TIMEOUT` only.
- **Manual removals** (`reason == MANUAL`) and every other reason
(`MERGE_CONFLICT`, `QUEUE_CLEARED`, `BRANCH_PROTECTIONS`, …) are
**ignored** — the job never runs for them.
- **Limit:** attempt count tracked via labels `auto-requeue-1` /
`auto-requeue-2` (max 2 re-adds).
- **Re-queue:** GraphQL `enqueuePullRequest` mutation, authenticated
with `secrets.ORG_ADMIN_TOKEN` (a `GITHUB_TOKEN` enqueue would not
re-trigger the `merge_group` check workflows).
- **One sticky comment, edited in place** (found by a hidden marker):
- 1st kick → "added back (attempt 1 of 2)"
- 2nd kick → same comment edited → "re-added a second time (2 of 2) —
last automatic retry"
- 3rd kick → same comment edited → "🛑 no-go for auto re-add" and it does
**not** re-queue.
All `gh` calls run under the PAT, so the comment, labels and enqueue are
authored by the token owner (not `github-actions[bot]`).
## Notes for reviewers
- Requires repo secret `ORG_ADMIN_TOKEN` with merge-queue write (already
used by 26 workflows in this repo).
- `github.event.reason` on the `dequeued` payload drives the gate; worth
confirming on the first real CI-caused dequeue. Safe failure mode if
absent: the job no-ops.