[APPS-2784] feat(apps): add description, selfService, permissions to manifest and config by tyffical · Pull Request #446 · DataDog/build-plugins · GitHub
Skip to content

[APPS-2784] feat(apps): add description, selfService, permissions to manifest and config#446

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 6 commits into
masterfrom
tiffany.trinh/apps-2784-manifest-app-properties
Jul 2, 2026
Merged

[APPS-2784] feat(apps): add description, selfService, permissions to manifest and config#446
gh-worker-dd-mergequeue-cf854d[bot] merged 6 commits into
masterfrom
tiffany.trinh/apps-2784-manifest-app-properties

Conversation

@tyffical

@tyffical tyffical commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Motivation

  • APPS-2784
  • The app-builder-code service (ddoghq/dd-source#8713) now accepts description, selfService, permissions.protectionLevel, and permissions.runAs in the uploaded manifest.json. Previously there was no way to set these from the build plugin — developers had to configure them manually in the App Builder UI after each deploy.

Changes

What changed File
Add AppsProtectionLevel type and description, selfService, permissions fields to AppsOptions and AppsManifest src/types.ts
Conditionally pass new optional fields into AppsOptionsWithDefaults; omit entirely when unset so callers using in/hasOwnProperty see a stable shape src/validate.ts
Write description, selfService, permissions into manifest.json only when configured; reconstruct permissions from non-null subfields only to prevent null values or empty objects reaching the server src/vite/handle-upload.ts
Tests: new fields appear in manifest when configured, absent when not, selfService:false preserved, runAs included, empty permissions:{} omitted, null subfields stripped src/index.test.ts
Tests: new fields flow through validateOptions; keys absent entirely (not undefined) when not configured src/validate.test.ts
Document description, selfService, permissions.protectionLevel, permissions.runAs config options with defaults and behaviour README.md

Architecture

Fields configured in vite.config.ts flow into the generated manifest.json bundle, which app-builder-code reads on upload and applies via the appropriate app-builder-api endpoints. Omitting any field leaves the existing server-side value unchanged.

vite.config.ts (AppsOptions)
  → validate.ts (AppsOptionsWithDefaults)
    → handle-upload.ts buildManifest()
      → manifest.json in bundle
        → app-builder-code (ddoghq/dd-source#8713)
          → app-builder-api /self-service, /protection-level, /identity

Example vite.config.ts:

datadogVite({
  apps: {
    description: 'My high-code app',
    selfService: true,
    permissions: {
      protectionLevel: 'approval_required',
      runAs: '<service-account-uuid>',   // optional
    },
  },
})

QA Instructions

Test URL: local Vite build — no service required for manifest verification.

1. Build and test

yarn
yarn workspace @dd/tests test:unit
# Expected: all tests pass, including two new apps manifest tests ✅ VERIFIED

yarn workspace @dd/apps-plugin typecheck
# Expected: no type errors ✅ VERIFIED

2. Local manifest verification

In any Vite app using @datadog/vite-plugin:

# Add new fields to vite.config.ts, then build with dryRun (no upload):
DD_APPS_UPLOAD_ASSETS=1 vite build
# Inspect the generated manifest.json inside the archive to confirm new fields appear ✅ VERIFIED

3. Staging end-to-end

Using the apps-2780-qa TD (still live from ddoghq/dd-source#8713) with dd-auth --actions-api --domain dd.datad0g.com:

# Upload bundle with description, selfService:true, protectionLevel:approval_required in manifest.json
curl -s -X POST "https://dd.datad0g.com/api/unstable/app-builder-code/apps/bp-pr446-qa2/upload" \
    -H "test-drive-apps-2780-qa: 1" \
    -F "bundle=@bundle-with-new-fields.zip" \
    -F "name=build-plugins-pr446-qa2"
# Expected: {"application_id":"bp-pr446-qa2","version_id":"439e1dc156164851","app_builder_id":"446f7de3-f4cf-4e1f-9b97-bd8fb35ba653","created":true} ✅ VERIFIED

# Verify properties applied in app-builder-api
curl -s "https://dd.datad0g.com/api/v2/app-builder/apps/446f7de3-f4cf-4e1f-9b97-bd8fb35ba653" \
    -H "test-drive-apps-2780-qa: 1" | jq '{description,selfService,protectionLevel}'
# Expected: {"description":"QA rerun — build-plugins PR #446 post-null-fix","selfService":true,"protectionLevel":"approval_required"} ✅ VERIFIED

# Re-upload bare manifest (no new fields) — existing properties must be preserved
curl -s -X POST "https://dd.datad0g.com/api/unstable/app-builder-code/apps/bp-pr446-qa2/upload" \
    -H "test-drive-apps-2780-qa: 1" -F "bundle=@bare-manifest-bundle.zip"
curl -s "https://dd.datad0g.com/api/v2/app-builder/apps/446f7de3-f4cf-4e1f-9b97-bd8fb35ba653" \
    -H "test-drive-apps-2780-qa: 1" | jq '{description,selfService,protectionLevel}'
# Expected: same values unchanged (backwards compat) ✅ VERIFIED

Blast Radius

  • Additive only — new optional fields, no existing behaviour changed
  • Omitting any field produces the same manifest as before (backwards compatible)
  • Risk: low

Documentation

… config

Exposes the three new fields that app-builder-code (ddoghq/dd-source#8713)
added support for server-side:
- description: human-readable app description
- selfService: whether the app appears in the self-service catalog
- permissions.protectionLevel: direct_publish | approval_required
- permissions.runAs: service account UUID for backend function execution

Fields flow from AppsOptions (vite.config.ts) into the generated
manifest.json bundle, which app-builder-code reads on upload and applies
via the appropriate app-builder-api endpoints.

Omitting any field leaves the existing value unchanged on the server.

Refs: APPS-2784
@tyffical

tyffical commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@tyffical tyffical requested a review from Copilot July 2, 2026 17:16
@tyffical

tyffical commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

@cursor review

Copilot AI 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.

Pull request overview

Adds support in the Apps build plugin for configuring additional app metadata and deployment/identity settings (description, selfService, permissions.protectionLevel, permissions.runAs) so they can be emitted into the generated manifest.json and applied by the upload pipeline.

Changes:

  • Extend AppsOptions / AppsManifest types with description, selfService, and permissions (including AppsProtectionLevel).
  • Plumb the new options through validation/default-resolution and into manifest.json generation.
  • Add unit tests and README documentation for the new configuration fields.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/plugins/apps/src/vite/handle-upload.ts Build manifest.json with optional description/selfService/permissions and pass options into manifest generation.
packages/plugins/apps/src/validate.ts Pass through the new resolved app options into AppsOptionsWithDefaults.
packages/plugins/apps/src/types.ts Add AppsProtectionLevel and extend options/manifest typings for the new fields.
packages/plugins/apps/src/index.test.ts Add tests ensuring new fields appear when configured and are omitted when absent.
packages/plugins/apps/README.md Document the new configuration options and update TOC/config snippet.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/plugins/apps/src/vite/handle-upload.ts Outdated
Comment thread packages/plugins/apps/src/index.test.ts

@sdkennedy2 sdkennedy2 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks great!

This comment was marked as resolved.

Previously description, selfService, and permissions were always present
in the returned object (with undefined values) even when the caller did
not configure them. This changed the observable shape of
AppsOptionsWithDefaults and could pass null values through to the
manifest builder if a caller explicitly passed null.

Use conditional spreading so the keys are absent entirely when the option
is not provided, and guard against null via != null. Update the test to
assert key absence with not.toHaveProperty() rather than toBeUndefined().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

This comment was marked as resolved.

Assigning options.permissions directly to manifest.permissions would
pass through null subfield values (e.g. { protectionLevel: null }) since
they satisfy the !== undefined guard. The server does not accept null as
a valid permissions value and null subfields are observably different
from absent keys.

Reconstruct the permissions object from only non-null subfields, and
align description/selfService guards to use != null consistently with
validate.ts. Add a test covering the null-subfield case.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread packages/plugins/apps/src/validate.test.ts
buildManifest now uses != null throughout; update the test comment to
match so the documentation stays accurate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tyffical tyffical marked this pull request as ready for review July 2, 2026 18:28
@tyffical tyffical requested review from a team as code owners July 2, 2026 18:28
@tyffical tyffical requested review from JohanDelao and sdkennedy2 and removed request for a team and JohanDelao July 2, 2026 18:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants