Skip to content

Refactor app-installations override to patch anyOf in-place#531

Open
salmanmkc wants to merge 6 commits intooctokit:mainfrom
salmanmkc:fix/app-installations-anyof-refactor
Open

Refactor app-installations override to patch anyOf in-place#531
salmanmkc wants to merge 6 commits intooctokit:mainfrom
salmanmkc:fix/app-installations-anyof-refactor

Conversation

@salmanmkc
Copy link
Copy Markdown

Problem

The override files for /app/installations replace the entire operation using replaceOperation(), which causes the permissions block to drift out of sync every time GitHub adds a new permission scope upstream. This led to #528 where 20 permissions were missing and team_discussions was stale.

Solution

Replace the full-operation override with a targeted in-place patch that only fixes the specific anyOf issues (openapi-types.ts#305):

  • items.properties.account — flatten anyOf to allOf (deref)
  • components.schemas.installation.properties.account — flatten anyOf to allOf (non-deref)

This allows all other fields (including permissions) to flow through from the upstream schema automatically.

Also adds a null guard for requestBody schemas that lack an application/json schema property, fixing a pre-existing issue with newer upstream specs.

Stacked on

This PR depends on #529 and should be merged after it. The diff includes commits from #529 — the net-new changes in this PR are only in the last commit.

Once #529 merges, this PR can be rebased onto main for a clean diff.

Impact

No behavioral change — the output schema is identical. The difference is that permissions will now stay in sync with upstream automatically.

The override files for /app/installations contained a stale copy
of the app-permissions schema that used team_discussions instead of
discussions. The upstream schema (rest-api-description) was updated
from team_discussions to discussions, but these hardcoded overrides
were never updated to match.

This caused @octokit/openapi consumers to see team_discussions
instead of discussions in the app-permissions schema.
Update the frozen permission snapshots in override files to include
all current GitHub API permissions. Beyond the team_discussions to
discussions rename, this adds 20 missing permissions including:
artifact_metadata, attestations, codespaces, merge_queues,
dependabot_secrets, interaction_limits, email_addresses,
organization_copilot_agent_settings, organization_copilot_seat_management,
organization_custom_org_roles, organization_custom_properties,
organization_events, enterprise_custom_properties_for_organizations,
custom_properties_for_organizations, repository_custom_properties,
followers, git_ssh_keys, gpg_keys, profile, and starring.
Replace the full-operation override for /app/installations with a
targeted in-place patch that only fixes the anyOf issues in the
account field. This allows the permissions block to flow through
from the upstream schema automatically, preventing drift when new
permission scopes are added.

Also adds a null guard for requestBody schemas that lack an
application/json schema property, fixing a pre-existing issue with
newer upstream specs.
@octokit
Copy link
Copy Markdown
Contributor

octokit Bot commented Apr 11, 2026

👋 Hi! Thank you for this contribution! Just to let you know, our GitHub SDK team does a round of issue and PR reviews twice a week, every Monday and Friday! We have a process in place for prioritizing and responding to your input. Because you are a part of this community please feel free to comment, add to, or pick up any issues/PRs that are labeled with Status: Up for grabs. You & others like you are the reason all of this works! So thank you & happy coding! 🚀

The previous implementation only converted account's anyOf to allOf but
missed two things:

1. account: add nullable:true and remove type:[null,object] array to
   match OpenAPI 3.0 nullable pattern
2. suspended_by: convert anyOf [{type:null}, SimpleUser] to the
   SimpleUser entry with nullable:true

Also adds a reusable anyOfToNullable() helper for the null-union pattern.
Tests validate the generated output after overrides are applied:
- account: must be allOf (not anyOf) with nullable:true
- suspended_by: must be flat nullable object (not anyOf)
- permissions: must have known keys with valid enum values
- Cross-file check: no residual anyOf on patched fields
- Request body anyOf filtering: no non-object types

Runs 219 assertions across all generated schemas.
Wired into npm test so CI catches regressions.
wolfy1339
wolfy1339 previously approved these changes Apr 11, 2026
@wolfy1339 wolfy1339 linked an issue Apr 11, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🆕 Triage

Development

Successfully merging this pull request may close these issues.

Refactor app-installations override to prevent permissions drift

2 participants