Skip to content

Bypass actors with actor_id: null are invisible to ruleset diffs; actor_id: 1 re-applies forever #1034

Description

@tdabasinskas

For ruleset bypass_actors, GitHub's API ignores actor_id when actor_type is OrganizationAdmin (or DeployKey) and always returns actor_id: null for those entries. MergeDeep cannot handle that shape, in either direction:

Configured as actor_id: null (matching what the API returns): the entry never deploys. NAME_USERNAME_PROPERTY picks actor_id as the object's identity field because the key exists, GET_NAME_USERNAME_PROPERTY returns the null, and processArrays skips entries with a falsy id (if (id) visited[id] = a). An OrganizationAdmin actor present in config but missing from the live ruleset produces no addition, no modification, and a "no changes" plan. The sync silently does nothing.

Configured as actor_id: 1 (what docs/sample-settings/settings.yml shows): the entry deploys, but on the next sync the config entry (id 1) cannot match the live entry (id null), so the same change is detected and re-applied on every run, forever. In our org this flapped 15 repos on an hourly schedule until we noticed.

So there is no actor_id value for an OrganizationAdmin bypass actor that both deploys and converges.

Reproduction with compareDeep directly:

const md = new MergeDeep(log, github, [])
const orgAdmin = { actor_id: null, actor_type: 'OrganizationAdmin', bypass_mode: 'pull_request' }
md.compareDeep({ bypass_actors: [] }, { bypass_actors: [orgAdmin] }, {}, {}, {})
// => hasChanges: false  (expected: an addition)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions