-
Notifications
You must be signed in to change notification settings - Fork 12
[APPS-2792] Add: v3 to v4 migration guide entry #511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,12 @@ | |
| Everything you need to know about breaking changes and major version bumps. | ||
|
|
||
| <!-- #toc --> | ||
| - [v3 to v4](#v3-to-v4) | ||
| - [`npm run dev` now executes backend functions in-process instead of via a cloud round trip](#npm-run-dev-now-executes-backend-functions-in-process-instead-of-via-a-cloud-round-trip) | ||
| - [Run `npm run dev:verify` to check cloud parity before publishing](#run-npm-run-devverify-to-check-cloud-parity-before-publishing) | ||
| - [`process.env` is now allowlisted during local execution](#processenv-is-now-allowlisted-during-local-execution) | ||
| - [Custom Credentials resolve locally via `datadog-app.local.json`](#custom-credentials-resolve-locally-via-datadog-applocaljson) | ||
| - [`getInitiatingUser()` and `getExecutionUser()` continue to return your real identity locally](#getinitiatinguser-and-getexecutionuser-continue-to-return-your-real-identity-locally) | ||
| - [v2 to v3](#v2-to-v3) | ||
| - [Renamed `disabled` to `enable`](#renamed-disabled-to-enable) | ||
| - [Removed `options.errorTracking.sourcemaps.disableGit`](#removed-optionserrortrackingsourcemapsdisablegit) | ||
|
|
@@ -17,6 +23,80 @@ Everything you need to know about breaking changes and major version bumps. | |
| - [Log Level](#log-level) | ||
| <!-- #toc --> | ||
|
|
||
| ## v3 to v4 | ||
|
tyffical marked this conversation as resolved.
|
||
|
|
||
| This release changes how `npm run dev` runs an app's backend functions (`*.backend.ts`). Apps that don't define any backend functions are unaffected. | ||
|
|
||
| ### `npm run dev` now executes backend functions in-process instead of via a cloud round trip | ||
|
|
||
| Previously, `npm run dev` bundled a backend function's file and sent it to Datadog's API on every call, executing it in the cloud and returning the result over the network. | ||
|
|
||
| `npm run dev` now loads the function's file directly into the local Vite dev server and executes it there, instead of bundling it and sending it to the cloud on every call. `$.Actions` calls still reach Datadog's API exactly as they do in production, and connection scoping and input/output validation behave the same as before — a function that only reads its arguments and calls `$.Actions` needs no changes. | ||
|
|
||
| Static imports of Node built-ins (`fs`, `child_process`, `net`, etc.), dynamic imports of one using a literal string specifier (e.g. `import('fs')`), and raw network globals (`fetch`, `XMLHttpRequest`, `WebSocket`, `EventSource`) in a backend file are rejected at build time — this check covers every app-local module resolved into the backend bundle, not just the entry file itself, so an app-local helper module is checked too. A dynamic import using a runtime-computed specifier (e.g. `import(moduleName)`) isn't caught by this check. Backend functions have never had access to these in production, and `npm run dev` ran a function through that same restricted production environment before this release too (see above) — so code relying on one of these already failed under `npm run dev`, just later than it does now, and with a runtime error instead of this build-time one. | ||
|
|
||
| A separate runtime guard also blocks network and subprocess access (`net`, `dns`, `child_process`, `worker_threads`, etc.) while a function body executes. It exists for what the build-time check above can't see: a `node_modules` dependency that reaches the network or spawns a process directly — bypassing `$.Actions` — fails at call time under `npm run dev` instead of at build time. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a Useful? React with 👍 / 👎. |
||
|
|
||
| ### Run `npm run dev:verify` to check cloud parity before publishing | ||
|
|
||
| Because a function's own code now runs locally instead of in Datadog's cloud, local execution can no longer catch every difference between local and production behavior on its own (see the `process.env` allowlist below, for example). | ||
|
|
||
| `npm run dev:verify` still executes backend functions through the full cloud round trip, the same way `npm run dev` used to. Run it before publishing an app to confirm a function's real dependencies (environment variables, connections) behave the same way in the cloud as they did locally. | ||
|
|
||
| ```bash | ||
| npm run dev:verify | ||
|
tyffical marked this conversation as resolved.
|
||
| ``` | ||
|
tyffical marked this conversation as resolved.
|
||
|
|
||
| If your `package.json` doesn't have a `dev:verify` script yet, `dev:verify` is just your existing dev command with Vite's `--mode dev-verify` flag appended (e.g. `vite --mode dev-verify`) — add the script, or run the equivalent command directly. | ||
|
|
||
| ### `process.env` is now allowlisted during local execution | ||
|
|
||
| A backend function running under `npm run dev` no longer has unscoped access to `process.env`. It's scoped to a small, fixed set of safe variables during local execution: `PATH`, `HOME`, `NODE_ENV`, and `TMPDIR`. | ||
|
|
||
| Reading any other variable — including one a secret-backed connection would resolve to in production — returns `undefined` locally, even though the equivalent read against the deployed function succeeds in production. The one exception is a Custom Credentials-backed variable declared in `datadog-app.local.json` (see below). | ||
|
|
||
| ```diff | ||
| export function myBackendFunction() { | ||
| - const region = process.env.AWS_REGION; // resolved in production | ||
| + const region = process.env.AWS_REGION; // undefined under `npm run dev` — not in the local allowlist | ||
| } | ||
| ``` | ||
|
|
||
| If a backend function depends on a variable like this, verify it with `npm run dev:verify` (see above) before publishing, since that path still runs against the real cloud environment. | ||
|
|
||
| ### Custom Credentials resolve locally via `datadog-app.local.json` | ||
|
|
||
| Previously, a backend function's Custom Credentials-backed connection resolved to its real value under `npm run dev`, because the function ran through the cloud round trip described above. Now that the function runs locally, that same variable would otherwise fall under the allowlist above and read as `undefined`. | ||
|
|
||
| `npm run dev` closes that gap by resolving Custom Credentials from a `datadog-app.local.json` file in your project root, if you create one. Add it to `.gitignore` and map each credential's env var name to its real value: | ||
|
tyffical marked this conversation as resolved.
tyffical marked this conversation as resolved.
tyffical marked this conversation as resolved.
|
||
|
|
||
| ```json | ||
| { | ||
| "STRIPE_API_KEY": "sk_test_..." | ||
| } | ||
| ``` | ||
|
|
||
| A missing file resolves to no extra variables — most projects won't have one, and the variable then reads as `undefined` locally until you add it. A present-but-malformed file (invalid JSON, or a value that isn't a string) throws instead of silently resolving to `undefined`, so a typo doesn't look identical to an undeclared secret. | ||
|
|
||
| A `datadog-app.local.json` entry is only resolved for code that runs inside the function body — code at the module's top level (e.g. a client constructed at import time) still sees the variable as `undefined`, since credentials aren't resolved until the function is actually invoked. Move the read, and anything constructed from it, inside the function body: | ||
|
|
||
| ```diff | ||
| -const client = new StripeClient(process.env.STRIPE_API_KEY); // undefined — evaluated at module load, before credentials resolve | ||
| - | ||
| export function myBackendFunction() { | ||
| - // ... | ||
| + const client = new StripeClient(process.env.STRIPE_API_KEY); // real value, once declared in datadog-app.local.json | ||
| } | ||
| ``` | ||
|
|
||
| ### `getInitiatingUser()` and `getExecutionUser()` continue to return your real identity locally | ||
|
|
||
| Previously, `getInitiatingUser()` and `getExecutionUser()` (from `@datadog/apps-backend/user`) returned your real identity under `npm run dev`, because the function ran through the cloud round trip described above and `$.Source` came from that same authenticated session. | ||
|
|
||
| Now that the function runs locally, `npm run dev` fetches your real, authenticated identity from a preview call before running any backend code, so `getInitiatingUser()` and `getExecutionUser()` keep returning that real identity (`id`, `orgId`, and optionally `email` and `name`) instead of falling back to a placeholder. | ||
|
tyffical marked this conversation as resolved.
|
||
|
|
||
| Both calls return the identity of that preview invocation, i.e. your own account — not necessarily the identity a real deployed trigger would pass to `getExecutionUser()` (a scheduled run or a different end user's action, for example). `npm run dev:verify` doesn't help here either — it's also a manual preview under your own credentials, with no way to simulate another trigger's identity. Confirm behavior against an execution's real identity by publishing the app and running it through an actual deployed trigger instead. | ||
|
|
||
| ## v2 to v3 | ||
|
|
||
| To sum up, here's the complete migration (to adapt for other bundlers) : | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.