Skip to content

Fix: skip unchanged GitHub team memberships in provisioner#86

Merged
Alexanderamiri merged 2 commits into
mainfrom
fix/provisioner-skip-unchanged-roles
Mar 17, 2026
Merged

Fix: skip unchanged GitHub team memberships in provisioner#86
Alexanderamiri merged 2 commits into
mainfrom
fix/provisioner-skip-unchanged-roles

Conversation

@Alexanderamiri
Copy link
Copy Markdown
Member

Summary

Root cause fix for the CODEOWNER self-merge regression.

The provisioner was calling PUT /teams/{slug}/memberships/{user} on every run for every member, even when the role was already correct. This re-added members via the API, changing their membership state from "org-owner implicit" to "explicit API-added", which caused GitHub to block self-merge on CODEOWNER-required PRs.

Now fetches current member roles first and only calls PUT when a role change is actually needed.

What happened

  1. PR Default GitHub team members to member role, not maintainer #80 changed provisioner to default role: member
  2. Registry Fix budget IAM permissions and remove CloudTrail from monitoring #16 merged → provisioner ran for first time with new code
  3. Provisioner called PUT memberships/alexanderamiri {"role": "maintainer"} — role was already maintainer, but the API call changed the membership source
  4. GitHub stopped allowing self-merge on CODEOWNER PRs

Also reverted

Removed the org-admin bypass actor from the ruleset (was a band-aid, not the fix).

Test plan

  • Merge this PR (should be self-mergeable — provisioner hasn't run again)
  • Trigger provisioner via registry merge
  • Verify team membership unchanged (check GitHub API)
  • Create a test PR → verify self-merge still works

- Naming table: team-prefixed convention for app vs platform resources
- Working rules: 5 static + 2 dynamic tags, boundary is human-applied
- Org file listing: add boundary.tf
- Task status: add tags/naming/ABAC task as done
- Known issues: cost allocation tags pending, test app naming migration
The provisioner was unconditionally calling PUT memberships for every
member on every run, even when the role was already correct. This
re-added members via the API, changing their membership state from
org-owner-implicit to explicit-API-added, which broke CODEOWNER
self-merge for org admins.

Now fetches current member roles and only calls PUT when a role change
is actually needed.
@Alexanderamiri Alexanderamiri requested a review from a team as a code owner March 17, 2026 22:21
@Alexanderamiri Alexanderamiri enabled auto-merge (squash) March 17, 2026 22:21
@github-actions
Copy link
Copy Markdown

Terraform Plan

🚧 Changes detected — Plan: 0 to add, 1 to change, 0 to destroy.

Plan output
Acquiring state lock. This may take a few moments...

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # module.lambdas.aws_lambda_function.team_provisioner will be updated in-place
  ~ resource "aws_lambda_function" "team_provisioner" {
        id                             = "javabin-team-provisioner"
      ~ last_modified                  = "2026-03-17T20:44:40.000+0000" -> (known after apply)
      ~ source_code_hash               = "wX2pv1QxWt5RN/akAYhiGmQHMGivVw80weFw6a1vHPQ=" -> "gI0WsTGi0c1NMeuTU0YPuv8bHC8cfy0NtMHMdsyb2wA="
        tags                           = {}
        # (21 unchanged attributes hidden)

        # (4 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────

Saved the plan to: tfplan

To perform exactly these actions, run the following command to apply:
    terraform apply "tfplan"

LLM Review

Risk: 🟢 LOW

Routine Lambda function code update for team_provisioner with source code hash change.

  • [routine] Lambda function team_provisioner source code updated (hash change from wX2pv1QxWt5RN/akAYhiGmQHMGivVw80weFw6a1vHPQ= to gI0WsTGi0c1NMeuTU0YPuv8bHC8cfy0NtMHMdsyb2wA=). This is an in-place update with no infrastructure changes.
  • [routine] No resources are being created or destroyed. Only metadata (last_modified timestamp) will be updated alongside the code hash.
  • [routine] No security group, IAM policy, or permission changes detected. All 21 other Lambda attributes remain unchanged.
  • [routine] No cost implications. This is a code deployment to an existing Lambda function with no resource scaling or new billable resources.
  • [routine] No data loss risk. This is a stateless Lambda function update with no database or persistent storage modifications.

@Alexanderamiri Alexanderamiri merged commit 4ff0b55 into main Mar 17, 2026
3 checks passed
@Alexanderamiri Alexanderamiri deleted the fix/provisioner-skip-unchanged-roles branch March 17, 2026 22:33
Alexanderamiri added a commit that referenced this pull request May 9, 2026
## Summary

Root cause fix for the CODEOWNER self-merge regression.

The provisioner was calling `PUT /teams/{slug}/memberships/{user}` on
every run for every member, even when the role was already correct. This
re-added members via the API, changing their membership state from
"org-owner implicit" to "explicit API-added", which caused GitHub to
block self-merge on CODEOWNER-required PRs.

Now fetches current member roles first and only calls PUT when a role
change is actually needed.

## What happened
1. PR #80 changed provisioner to default `role: member`
2. Registry #16 merged → provisioner ran for first time with new code
3. Provisioner called `PUT memberships/alexanderamiri {"role":
"maintainer"}` — role was already maintainer, but the API call changed
the membership source
4. GitHub stopped allowing self-merge on CODEOWNER PRs

## Also reverted
Removed the org-admin bypass actor from the ruleset (was a band-aid, not
the fix).

## Test plan
- [ ] Merge this PR (should be self-mergeable — provisioner hasn't run
again)
- [ ] Trigger provisioner via registry merge
- [ ] Verify team membership unchanged (check GitHub API)
- [ ] Create a test PR → verify self-merge still works
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant