Skip to content

chore(serverless): publish web request-start event - #19898

Open
litianningdatadog wants to merge 1 commit into
mainfrom
tianning.li/2-wsgi-asgi-integration
Open

litianningdatadog wants to merge 1 commit into
mainfrom
tianning.li/2-wsgi-asgi-integration

Conversation

@litianningdatadog

@litianningdatadog litianningdatadog commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

Stacked PRs:

Description

This PR provides the framework side of the MicroVM identity-refresh flow. WSGI,
ASGI, and Django publish web.request.starting before they create a root span,
passing the request method and normalized path.

The publisher is deliberately product-neutral: it does not import MicroVM
helpers, recognize the MicroVM /run endpoint, or decide whether to refresh a
runtime ID. PR #19939 registers the MicroVM-only listener and owns that policy.
When no product listens for the event, the publisher returns after a single
listener check, before reading the request or normalizing the path.

Two helpers in trace_utils own the publishing:

  • dispatch_wsgi_web_request_starting(environ) is used by DDWSGIMiddleware
    and Django's get_response hook. WSGI and Django share an environ marker so
    nested layers publish one event. The Django hook also covers Django 3.0 ASGI
    requests, which reach the sync get_response because get_asgi_application
    is only wrapped on Django 3.1+.
  • dispatch_asgi_web_request_starting(scope) publishes only from the outer ASGI
    application. It accepts scopes whether or not path already includes
    root_path, so mounted or server-prefixed apps do not produce a duplicated
    prefix.

Scope: the event is published for the generic WSGI/ASGI middleware and Django.
Frameworks whose automatic instrumentation creates the root span without
DDWSGIMiddleware (Falcon, Bottle, Pyramid, CherryPy, Molten) are out of scope
for this PR and will follow separately.

This implements the requested split in review comment r4146791727.

Reference

Testing

  • scripts/lint fmt and scripts/lint typing on the changed files
  • focused WSGI request-start tests (py3.13): 7 passed
  • focused ASGI request-start tests (py3.13): 48 passed
  • focused Django request-start tests: 3 passed on Django 3.0 (py3.9) and on
    Django 5.1 (py3.13), including a real ASGIRequest reaching get_response

Risks

There is no public API change. The only production listener in this stack is
registered by PR #19939 in MicroVM processes, so non-MicroVM requests do not
dispatch this event.

🤖 Generated with Claude Code

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 27, 2026 •

Copy link
Copy Markdown

Codeowners resolved as

Resolved from the full PR diff against main using the target branch CODEOWNERS file.
CODEOWNERS team requests not listed below are not required by the current file set.

ddtrace/contrib/_events/web_framework.py                                @DataDog/python-guild @DataDog/apm-idm-python
ddtrace/contrib/internal/asgi/middleware.py                             @DataDog/python-guild @DataDog/apm-idm-python
ddtrace/contrib/internal/django/response.py                             @DataDog/python-guild @DataDog/apm-idm-python
ddtrace/contrib/internal/trace_utils.py                                 @DataDog/python-guild @DataDog/apm-idm-python
ddtrace/contrib/internal/wsgi/wsgi.py                                   @DataDog/python-guild @DataDog/apm-idm-python
ddtrace/internal/constants.py                                           @DataDog/apm-core-python
ddtrace/internal/serverless/__init__.py                                 @DataDog/apm-core-python
tests/contrib/asgi/test_asgi.py                                         @DataDog/python-guild @DataDog/apm-idm-python
tests/contrib/django/test_django.py                                     @DataDog/python-guild @DataDog/apm-idm-python
tests/contrib/wsgi/test_wsgi.py                                         @DataDog/python-guild @DataDog/apm-idm-python
tests/internal/test_serverless.py                                       @DataDog/apm-serverless @DataDog/asm-python @DataDog/serverless-aws @DataDog/serverless-azure-and-gcp

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 27, 2026 •

Copy link
Copy Markdown

Circular import analysis

⚠️ Existing circular imports

There are 1 circular imports that already exist on the base branch and have not been changed by this PR.

ddtrace.errortracking._handled_exceptions.bytecode_injector -> ddtrace.errortracking._handled_exceptions.callbacks -> ddtrace.errortracking._handled_exceptions.collector -> ddtrace.errortracking._handled_exceptions.bytecode_reporting -> ddtrace.errortracking._handled_exceptions.bytecode_injector

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 27, 2026 •

Copy link
Copy Markdown

Dependency direction analysis

⚠️ Existing dependency direction violations

There are 201 dependency direction violations that already exist on the base branch and have not been changed by this PR.

Show existing violations (showing 5 of 201 highest severity)
ddtrace.internal.tracemethods -×-> ddtrace.trace  (internal-core -> product:tracing, score=132)
ddtrace.llmobs._integrations.anthropic -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=130)
ddtrace.internal.openfeature._span_enrichment -×-> ddtrace.trace  (product:openfeature -> product:tracing, score=130)
ddtrace.llmobs._integrations.openai -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=130)
ddtrace.internal.test_visibility.api -×-> ddtrace.trace  (product:ci_visibility -> product:tracing, score=130)

To see all violations, download the layers-base.json and layers-pr.json artifacts from this CI job and run:

uv run --script scripts/import-analysis/layers.py compare layers-base.json layers-pr.json

@datadog-datadog-us1-prod

datadog-datadog-us1-prod Bot commented Aug 27, 2026 •

Copy link
Copy Markdown

Pipelines  Tests

✨ Unblock PR with BitsAI

❌ Errors

Your PR has failed checks. Please review the issues below and take necessary action before merging.

🚦 1 Pipeline job failed

DataDog/apm-reliability/dd-trace-py | contrib/rq 1/2 — 🔧 Needs a code fix, caused by this PR

View more details · View in GitLab

ℹ️ Info

No other issues found (see more)

🧪 All tests passed
❄️ No new flaky tests detected

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 1e76b73 | Docs | View more details | Give us feedback!

@litianningdatadog litianningdatadog changed the title feat(serverless): emit MicroVM request start feat(serverless): emit MicroVM request start for WSGI & ASGI-based applications Aug 27, 2026
@litianningdatadog litianningdatadog added the aws-microvm Work related to AWS MicroVM onboarding label Aug 31, 2026
@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch 2 times, most recently from 4aebb33 to 206cd22 Compare September 3, 2026 20:32
@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch from 206cd22 to f3ea773 Compare September 3, 2026 20:47
@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch from f3ea773 to 68bf61e Compare September 4, 2026 15:37
@litianningdatadog
litianningdatadog requested a balanced review from Copilot September 4, 2026 16:23
@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch from 68bf61e to 8e26c22 Compare September 4, 2026 16:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The environment detector lacks direct coverage, and the release note announces behavior completed only by a follow-up PR.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds pre-span MicroVM request detection to WSGI and ASGI instrumentation, supporting the runtime identity refresh stack.

Changes:

  • Dispatches web.request.starting for matching MicroVM requests.
  • Adds explicit runtime identity refresh callbacks while preserving fork lineage.
  • Adds focused integration/runtime tests and a release note.
File summaries
File Description
ddtrace/contrib/_events/web_framework.py Defines the request-start event.
ddtrace/contrib/internal/web.py Matches and dispatches MicroVM requests.
ddtrace/contrib/internal/asgi/middleware.py Dispatches before ASGI span creation.
ddtrace/contrib/internal/wsgi/wsgi.py Dispatches before WSGI span creation.
ddtrace/internal/serverless/__init__.py Detects the MicroVM environment.
ddtrace/internal/runtime/__init__.py Adds explicit identity refresh support.
tests/contrib/asgi/test_asgi.py Tests ASGI matching and ordering.
tests/contrib/wsgi/test_wsgi.py Tests WSGI request matching.
tests/tracer/runtime/test_runtime_id.py Tests refresh and fork semantics.
releasenotes/notes/add-lambda-microvm-web-request-starting-ffa6841a15e3c57c.yaml Announces MicroVM request detection.
Review details
  • Files reviewed: 8/8 changed files
  • Comments generated: 2
  • Review effort level: Balanced

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread ddtrace/internal/serverless/__init__.py Outdated
Comment thread releasenotes/notes/add-lambda-microvm-web-request-starting-ffa6841a15e3c57c.yaml Outdated
@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch from 8e26c22 to cdc53d4 Compare September 4, 2026 16:39
@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch 2 times, most recently from d28bc4e to 0d5cf10 Compare September 21, 2026 20:46
@litianningdatadog litianningdatadog added the changelog/no-changelog A changelog entry is not required for this PR. label Sep 23, 2026
@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch from 0d5cf10 to 4654514 Compare September 23, 2026 14:38

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 24e4d34d84

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ddtrace/contrib/internal/wsgi/wsgi.py Outdated
Comment thread ddtrace/contrib/internal/wsgi/wsgi.py Outdated
@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch from 24e4d34 to 2d71731 Compare September 24, 2026 16:18

@jcstorms1 jcstorms1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just looked at the files we own. LGTM

@litianningdatadog
litianningdatadog requested review from a team and mabdinur and removed request for a team September 24, 2026 19:45
@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch from 2d71731 to bfe3d91 Compare September 25, 2026 15:50
@litianningdatadog
litianningdatadog added this pull request to stack #20582 September 25, 2026 15:50
@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch from bfe3d91 to a44c5ce Compare September 25, 2026 15:50
@litianningdatadog
litianningdatadog requested a review from a team as a code owner September 25, 2026 21:37
@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch from a44c5ce to 7398b18 Compare September 25, 2026 21:40
Base automatically changed from tianning.li/1-runtime-identity-refresh to main September 28, 2026 15:37
gh-worker-dd-mergequeue-cf854d Bot pushed a commit that referenced this pull request Sep 28, 2026
Stacked PRs:
- 👉 This #19778 — runtime identity foundation
  - #19898 — WSGI/ASGI request-start hook
    - #19939 — central MicroVM /run identity refresh
      - #19820 — tracer/native writer exporter refresh
        - #19821 — telemetry worker refresh
          - #19822 — runtime metrics runtime-id tags

## Description

Adds `ddtrace.internal.runtime.refresh_identity()` for runtimes that need a fresh runtime ID without going through an OS fork.

This introduces `on_runtime_identity_refresh()`, a dedicated callback registry for consumers that should react only to explicit identity refreshes. Existing `on_runtime_id_change()` behavior remains available for fork-related and general runtime-ID change handling.

`refresh_identity()` rotates the runtime ID without recording parent or ancestor lineage because a resumed MicroVM run is not a real fork. Existing fork behavior and lineage tracking remain unchanged.

Refresh callbacks are isolated by default so one failed consumer does not block others. Callers coordinating a refresh transaction can opt into error propagation with `raise_on_error=True` and retry the same identity refresh when a rebuild fails.

## Reference

- [RFC](https://docs.google.com/document/d/17lde4Zak2YRBuDvf32KFanXj9TdpOv24GYaEY8swA1w/edit?tab=t.0#heading=h.wwu37decnk8j)

## Testing

Added coverage for:

- runtime ID rotation through `refresh_identity()`
- preservation of parent and ancestor fork lineage
- explicit refresh subscriber notification
- refresh subscribers not being invoked by fork handling
- callback failure isolation by default
- optional refresh callback failure propagation
- successful callbacks under `raise_on_error=True`

Validation:

- `scripts/run-tests -s --venv 190fcc7 -- -q tests/tracer/runtime/test_runtime_id.py` — 21 passed
- `scripts/lint checks` — passed

## Risks

Low. The new path is opt-in and is not wired to traffic in this PR. Existing fork behavior is preserved.


Co-authored-by: tianning.li <tianning.li@datadoghq.com>

@lym953 lym953 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving blindly as I don't have knowledge on any of the files, and since apm-serverless has approved it.
Will discuss whether we should remove serverless-aws as owner.

@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch from 7398b18 to 6e98bbd Compare September 29, 2026 18:06
Comment thread tests/contrib/asgi/test_asgi.py Outdated

@quinna-h quinna-h left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM overall for the test files that IDM owns; left one comment about a test that was supposed to prove the request-start event happens before the request span is created, but instead the span marker records when the middleware retrieves the span

@avara1986 avara1986 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch from 6e98bbd to a251b4d Compare September 30, 2026 14:07
request.META.get("SCRIPT_NAME") or "",
request.META.get("PATH_INFO") or "",
):
request.META[_WEB_REQUEST_STARTING_DISPATCHED] = True

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handling for sub-apps?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment could be nice here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acked

Comment thread ddtrace/contrib/internal/wsgi/wsgi.py Outdated
environ.get("SCRIPT_NAME") or "",
environ.get("PATH_INFO") or "",
):
environ[_WEB_REQUEST_STARTING_DISPATCHED] = True

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, comment with reasoning would be good.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acked

Comment thread ddtrace/contrib/internal/web.py Outdated

path = path_prefix.rstrip("/") + path
if path != _LAMBDA_MICROVM_RUN_PATH:
return False

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic should be moved to the microvm listener/runtime id specific listener of the event.

doing the method and path checking for microvm run path in the event dispatcher isn't really any different/better than just hard coding it into each integration, we want to remove product specific behaviors/code from the integrations and dispatch them through the event hub.

so this should be something more like:

def dispatch_web_request_starting(method: Optional[str], path_prefix: str, path: str) -> None:
    core.dispatch(WebFrameworkEvents.WEB_REQUEST_STARTING.value, (method, path))



def check_microvm_run(method: Optional[str], path_prefix: str):
    if method != "POST":
        return
    path = path_prefix.rstrip("/") + path
    if path != _LAMBDA_MICROVM_RUN_PATH:
        return

    # trigger behaviors we want when this endpoint is called by microvm


if in_aws_lambda_microvm():
    core.on(WebFrameworkEvents.WEB_REQUEST_STARTING.value, check_microvm_run)

what we are deciding is that ASGI/WSGI integrations should emit an event when the web request is starting, and then allowing different products/code to then use those events to perform different actions (in our case, when in a microvm we should refresh identity information)

@litianningdatadog litianningdatadog Sep 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I will revise PR #19898 & #19939 as #19898 now publishes only the generic web.request.starting event with the request method and normalized path. It no longer contains MicroVM environment, method, or path checks.
#19939 registers the runtime-ID listener only in MicroVM processes and owns the exact POST /aws/lambda-microvms/runtime/v1/run match and identity refresh. This keeps product behavior out of the WSGI/ASGI integrations. Let me know whether that makes sense.

@litianningdatadog
litianningdatadog force-pushed the tianning.li/2-wsgi-asgi-integration branch from a251b4d to 3d8d4ca Compare September 30, 2026 18:23
@litianningdatadog litianningdatadog changed the title chore(serverless): emit MicroVM request start for WSGI & ASGI-based applications feat(serverless): publish web request-start event Sep 30, 2026

@dubloom dubloom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small comments but overall LGTM

Comment thread ddtrace/contrib/_events/web_framework.py Outdated
Comment thread ddtrace/contrib/internal/web.py Outdated
Comment thread ddtrace/contrib/internal/web.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 11ab2d5fe7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ddtrace/contrib/internal/wsgi/wsgi.py Outdated
Comment on lines +110 to +111
if not environ.get(_WEB_REQUEST_STARTING_DISPATCHED):
if trace_utils.dispatch_web_request_starting(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Publish starts from automatically patched WSGI integrations

In an AWS Lambda MicroVM running an automatically instrumented Falcon app without manually adding DDWSGIMiddleware, this code is never reached: a repo-wide search shows that ddtrace/contrib/internal/falcon/patch.py:40-48 installs Falcon's separate falcon.middleware.TraceMiddleware, whose process_request creates the root request context directly at ddtrace/contrib/internal/falcon/middleware.py:34-56. The new Django-specific hook resolves the earlier Django case, but Falcon—and similarly structured WSGI integrations—still emits no start event, so the first request span after a MicroVM resume retains the previous runtime identity. Publish the event from these automatically installed WSGI instrumentation paths or introduce a shared hook they invoke.

AGENTS.md reference: AGENTS.md:L60-L63

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scoping this PR to the generic WSGI/ASGI middleware and Django. Falcon, along with Bottle, Pyramid, CherryPy, and Molten (which also create the root span without going through DDWSGIMiddleware), will get request-start coverage in a follow-up PR. The scope is stated above the helpers in trace_utils.py and in the PR description.

Comment on lines +279 to +283
trace_utils.dispatch_web_request_starting(
method,
scope.get("root_path") or "",
scope.get("path") or "",
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid duplicating root_path in ASGI event paths

For ASGI scopes where path already contains root_path, as occurs with mounted or server-prefixed applications, this unconditionally constructs a duplicated path such as /aws/lambda-microvms/runtime/v1/aws/lambda-microvms/runtime/v1/run. The same middleware later treats scope["path"] as full_path and uses it directly when constructing the request URL at lines 323-337, so callers cannot be assumed always to provide only the post-prefix remainder used by the new test. Because the MicroVM listener matches the runtime /run endpoint, these requests silently miss the refresh event; normalize based on whether path already includes the prefix before concatenating.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 1e76b73. dispatch_asgi_web_request_starting now prepends root_path only when path does not already start with it on a path-segment boundary (ignoring a trailing slash on root_path), the same rule as Starlette's get_route_path. Added a test case where path already includes root_path.

# Django's automatic WSGI instrumentation bypasses DDWSGIMiddleware, but an
# application can still wrap it. The shared environ marker lets the first
# layer publish the request-start event before either layer creates a span.
if request.META.get("wsgi.version") is not None and not request.META.get(_WEB_REQUEST_STARTING_DISPATCHED):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Dispatch for Django 3.0 ASGI requests

In the supported Django 3.0 ASGI configuration, requests reach the synchronous traced_get_response path but their META is built from an ASGI scope and has no wsgi.version, so this condition suppresses the event. The fallback ASGI middleware does not cover this version: ddtrace/contrib/internal/django/patch.py:471-477 deliberately wraps get_asgi_application only for Django 3.1+, while the test matrix and test_asgi_200 explicitly exercise Django 3.0 ASGI. Consequently a Django 3.0 application served through Daphne in a MicroVM creates its request span without refreshing runtime identity; add an ASGI-aware dispatch path for the pre-3.1 handler.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 1e76b73. Dropped the wsgi.version guard: the hook now calls dispatch_wsgi_web_request_starting(request.META) for every request. Django 3.0's ASGIRequest.META carries SCRIPT_NAME/PATH_INFO with root_path already stripped, so the path comes out right. Django 3.1+ ASGI requests go through get_response_async and the ASGI middleware instead, so there is no double dispatch. Added a test that builds a real ASGIRequest; it passes on Django 3.0 and 5.1.

…plications

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

aws-microvm Work related to AWS MicroVM onboarding changelog/no-changelog A changelog entry is not required for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants