-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat: add github_repo_permission module and test #10767
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
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Daniele Marcocci <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces a new Ansible module github_repo_permission
for managing team and user permissions on GitHub repositories, providing Terraform-like capabilities within Ansible to grant/revoke repository access.
- Adds comprehensive GitHub API integration with support for both built-in permissions and custom roles
- Implements idempotent operations with proper verification and retry logic for eventual consistency
- Includes full test coverage for teams, users, built-in permissions, and custom roles
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
File | Description |
---|---|
plugins/modules/github_repo_permission.py | Main module implementation with GitHub API wrapper, permission management logic, and support for both teams and users |
tests/unit/plugins/modules/test_github_repo_permission.py | Comprehensive unit tests covering idempotency, updates, custom roles, and user/team scenarios |
changelogs/fragments/gh-repo-permission-module.yml | Changelog entry documenting the new module |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
permission: | ||
description: | ||
- Permission to grant when O(state=present). | ||
- Supports built-ins C(pull), C(triage), C(push), C(maintain), C(admin) and custom repository roles (GitHub Enterprise). | ||
- Synonyms C(read) -> C(pull) and C(write) -> C(push) are accepted. | ||
type: str |
Copilot
AI
Aug 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The indentation for the 'permission' option is incorrect. It should be at the same level as other top-level options like 'team_slug' and 'username'.
permission: | |
description: | |
- Permission to grant when O(state=present). | |
- Supports built-ins C(pull), C(triage), C(push), C(maintain), C(admin) and custom repository roles (GitHub Enterprise). | |
- Synonyms C(read) -> C(pull) and C(write) -> C(push) are accepted. | |
type: str | |
permission: | |
description: | |
- Permission to grant when O(state=present). | |
- Supports built-ins C(pull), C(triage), C(push), C(maintain), C(admin) and custom repository roles (GitHub Enterprise). | |
- Synonyms C(read) -> C(pull) and C(write) -> C(push) are accepted. | |
type: str |
Copilot uses AI. Check for mistakes.
|
||
def ensure_team_permission(module, session, owner, repo, team_slug, desired_permission, state): | ||
# Get current teams on repo and find team's current permission | ||
role_name, current_builtin = get_team_repo_permission(session, owner, team_slug, owner, repo) |
Copilot
AI
Aug 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameters are incorrect - 'owner' is passed twice. The first parameter should be 'org' (organization), not 'owner'. This should be: get_team_repo_permission(session, owner, team_slug, owner, repo)
Copilot uses AI. Check for mistakes.
The test
The test
The test
The test
The test
The test
The test
The test
The test
The test
The test
The test
The test
The test
The test
The test
|
Signed-off-by: Daniele Marcocci <[email protected]>
Signed-off-by: Daniele Marcocci <[email protected]>
Signed-off-by: Daniele Marcocci <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @danielino Thanks for your contribution.
This PR seems to have been vibe-coded. Sigh. The code is super bloated, confused, and it looks like something that will be a nightmare to maintain - one year from now, no one will have any idea what was in there. Even now, this over-verbose code is hard to read and make sense of. After a couple of interactions, Copilot (or any other LLM) will lose track of the objectives.
I strongly suggest you perform a thorough review of this module and improve its quality. There are many redundancies, and things being done in over-engineered ways. There are (possibly, probably) parts that could be refactored to make it better.
I have pointed some things that popped up immediately, but not everything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changelog fragments are not used when adding new modules, please remove this file.
- Supports built-ins C(pull), C(triage), C(push), C(maintain), C(admin) and custom repository roles (GitHub Enterprise). | ||
- Synonyms C(read) -> C(pull) and C(write) -> C(push) are accepted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Supports built-ins C(pull), C(triage), C(push), C(maintain), C(admin) and custom repository roles (GitHub Enterprise). | |
- Synonyms C(read) -> C(pull) and C(write) -> C(push) are accepted. | |
- Supports built-ins V(pull), V(triage), V(push), V(maintain), V(admin) and custom repository roles (GitHub Enterprise). | |
- Synonyms V(read) -> V(pull) and V(write) -> V(push) are accepted. |
Please use semantic markup as documented in:
https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_documenting.html#semantic-markup-within-module-documentation
try: # Python 3 | ||
from unittest.mock import patch | ||
except Exception: # Python 2 fallback | ||
try: | ||
from mock import patch # type: ignore | ||
except Exception: | ||
patch = None # type: ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See other tests for examples.
try: # Python 3 | |
from unittest.mock import patch | |
except Exception: # Python 2 fallback | |
try: | |
from mock import patch # type: ignore | |
except Exception: | |
patch = None # type: ignore | |
from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import patch |
# Skip the entire module on Python 2.7 if 'mock' isn't available | ||
if sys.version_info[0] < 3 and patch is None: # type: ignore | ||
import pytest # type: ignore | ||
pytest.skip("mock not available on Python 2.7 test env", allow_module_level=True) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that is unnecessary
#!/usr/bin/python | ||
# -*- coding: utf-8 -*- | ||
|
||
# Copyright (c) 2025, community.general contributors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is meant to have your name on it, not this generic text. Copilot is cheating on you :-P
# Use the recommended media type that supports newer fields and features | ||
'Accept': 'application/vnd.github+json', | ||
# Pin to a stable API version when available | ||
'X-GitHub-Api-Version': '2022-11-28', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hardcoded magic value here is not a good practice. Why specifically this version? Would different users want to use different versions? Should this be a parameter? If it must be fixed, please make a constant (by the beginning of the file) and add a note in the documentation about it, for the benefit of the module users.
sample: | ||
subject: team | ||
subject_identifier: backend | ||
repository: myorg/myrepo | ||
permission: push | ||
state: present |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a valid sample for that RV. Please see other modules.
return 'pull' | ||
if low == 'write': | ||
return 'push' | ||
if low in BUILTIN_PERMISSIONS: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this constant was a dict, mapping the desired permission to the permission name effectively used, this entire function could be made much simpler. Something like:
return PERM_MAP.get(p.lower(), p)
(Assuming if the builtin are in the map, mapping to themselves).
# Attempt to match custom role by case-insensitive name | ||
roles = session.get_custom_repo_roles(org) | ||
match = None | ||
desired_lower = str(desired).lower() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why would it ever not be a string to begin with?
if perm == 'read': | ||
return 'pull' | ||
if perm == 'write': | ||
return 'push' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are you normalizing "manually" here if there is a function to normalize it?
SUMMARY
Add a new Ansible module
community.general.github_repo_permission
to manage repository permissions for an organization team (by slug) or a user (collaborator) on GitHub. The module supports both built-in permissions (pull
,triage
,push
,maintain
,admin
) and custom repository roles (GitHub Enterprise Server). It is idempotent, supportscheck_mode
, and includes verification with small retries to account for eventual consistency on GHE.ISSUE TYPE
COMPONENT NAME
github_repo_permission
ADDITIONAL INFORMATION
github_team_repository
) directly within Ansible to grant/revoke repo permissions for teams and users.team_slug
) or user (username
) for a givenrepository
(owner/repo).read
→pull
,write
→push
.role_name
.check_mode
fully supported;access_token
markedno_log
./orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}
/orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}
/repos/{owner}/{repo}/teams
/repos/{owner}/{repo}/collaborators/{username}
/repos/{owner}/{repo}/collaborators/{username}/permission
/orgs/{org}/custom-repository-roles
Accept: application/vnd.github+json
,X-GitHub-Api-Version: 2022-11-28
api_url
ending with/api/v3
. A warning is emitted if/api/v4
(GitLab-style) is detected.