Skip to content

Commit 8419f59

Browse files
authored
Merge pull request #124 from OpenRailAssociation/fix-dry-run-child-team
2 parents 0e70187 + bd963ec commit 8419f59

File tree

9 files changed

+186
-16
lines changed

9 files changed

+186
-16
lines changed

.github/workflows/real-test.yaml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# SPDX-FileCopyrightText: 2025 DB Systel GmbH
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
name: Test with real GitHub org
6+
7+
on:
8+
pull_request:
9+
workflow_dispatch:
10+
11+
jobs:
12+
selftest:
13+
runs-on: ubuntu-24.04
14+
env:
15+
GITHUB_APP_ID: ${{ secrets.TEST_GITHUB_APP_ID }}
16+
GITHUB_APP_PRIVATE_KEY: ${{ secrets.TEST_GITHUB_APP_PRIVATE_KEY }}
17+
steps:
18+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
19+
- uses: ./.github/actions/poetrybuild
20+
- name: Replace data in config files
21+
run: |
22+
sed -i "s/TEST_GITHUB_ORG/${{ secrets.TEST_GITHUB_ORG }}/g" tests/data/config/org_files/*.yaml
23+
sed -i "s/TEST_USER/${{ secrets.TEST_USER }}/g" tests/data/config/org_files/*.yaml
24+
sed -i "s/TEST_USER/${{ secrets.TEST_USER }}/g" tests/data/config/teams_files/*.yaml
25+
- name: Prepare for first run
26+
run: |
27+
mkdir -p tests/data/config/teams
28+
cp tests/data/config/teams_files/teams_changes.yaml tests/data/config/teams/teams.yaml
29+
cp tests/data/config/org_files/org_changes.yaml tests/data/config/org.yaml
30+
- name: Run 1 (changes) - dry run
31+
run: poetry run gh-org-mgr sync -c tests/data/config/ --dry -vv
32+
- name: Run 1 (changes) - prod run
33+
run: poetry run gh-org-mgr sync -c tests/data/config/ -vv
34+
- name: Prepare for second run, reverting to original state
35+
run: |
36+
cp tests/data/config/teams_files/teams_orig.yaml tests/data/config/teams/teams.yaml
37+
cp tests/data/config/org_files/org_orig.yaml tests/data/config/org.yaml
38+
- name: Run 2 (revert) - dry run
39+
run: poetry run gh-org-mgr sync -c tests/data/config/ --dry -vv
40+
- name: Run 2 (revert) - prod run
41+
run: poetry run gh-org-mgr sync -c tests/data/config/ -vv

gh_org_mgr/_gh_org.py

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@
88
import sys
99
from dataclasses import asdict, dataclass, field
1010

11-
from github import (
12-
Auth,
13-
Github,
11+
from github import Auth, Github, GithubIntegration
12+
from github.GithubException import (
13+
BadCredentialsException,
1414
GithubException,
15-
GithubIntegration,
1615
UnknownObjectException,
1716
)
18-
from github.GithubException import BadCredentialsException
1917
from github.NamedUser import NamedUser
2018
from github.Organization import Organization
2119
from github.Repository import Repository
@@ -54,6 +52,7 @@ class GHorg: # pylint: disable=too-many-instance-attributes, too-many-lines
5452
current_repos_collaborators: dict[Repository, dict[str, str]] = field(default_factory=dict)
5553
configured_repos_collaborators: dict[str, dict[str, str]] = field(default_factory=dict)
5654
archived_repos: list[Repository] = field(default_factory=list)
55+
unconfigured_teams: list[Team] = field(default_factory=list)
5756
unconfigured_team_repo_permissions: dict[str, dict[str, str]] = field(default_factory=dict)
5857
stats: OrgChanges = field(default_factory=OrgChanges)
5958

@@ -296,7 +295,18 @@ def create_missing_teams(self, dry: bool = False):
296295
for team, attributes in self.configured_teams.items():
297296
if team not in existent_team_names:
298297
if parent := attributes.get("parent"): # type: ignore
299-
parent_id = self.org.get_team_by_slug(sluggify_teamname(parent)).id
298+
try:
299+
parent_id = self.org.get_team_by_slug(sluggify_teamname(parent)).id
300+
except UnknownObjectException:
301+
if dry:
302+
logging.debug(
303+
"For team %s, the configured parent team's ('%s') ID wasn't found, "
304+
"probably because it should be created but it's a dry-run. "
305+
"We set a default ID of 424242",
306+
team,
307+
parent,
308+
)
309+
parent_id = 424242
300310

301311
logging.info("Creating team '%s' with parent ID '%s'", team, parent_id)
302312
self.stats.create_team(team)
@@ -594,31 +604,38 @@ def sync_teams_members(self, dry: bool = False) -> None: # pylint: disable=too-
594604
team.name,
595605
)
596606

597-
def get_unconfigured_teams(
607+
def get_and_delete_unconfigured_teams(
598608
self, dry: bool = False, delete_unconfigured_teams: bool = False
599609
) -> None:
600610
"""Get all teams that are not configured locally and optionally remove them"""
601611
# Get all teams that are not configured locally
602-
unconfigured_teams: list[Team] = []
603612
for team in self.current_teams:
604613
if team.name not in self.configured_teams:
605-
unconfigured_teams.append(team)
614+
self.unconfigured_teams.append(team)
606615

607-
if unconfigured_teams:
616+
if self.unconfigured_teams:
608617
if delete_unconfigured_teams:
609-
for team in unconfigured_teams:
618+
for team in self.unconfigured_teams:
610619
logging.info("Deleting team '%s' as it is not configured locally", team.name)
611620
self.stats.delete_team(team=team.name, deleted=True)
612621
if not dry:
613-
team.delete()
622+
try:
623+
team.delete()
624+
except UnknownObjectException as e:
625+
logging.info(
626+
"Team '%s' could not be deleted, probably because it was already "
627+
"deleted as part of a parent team. "
628+
"Error: %s",
629+
team.name,
630+
e,
631+
)
614632
else:
615-
unconfigured_teams_str = [team.name for team in unconfigured_teams]
616633
logging.warning(
617634
"The following teams of your GitHub organisation are not "
618635
"configured locally: %s. Taking no action about these teams.",
619-
", ".join(unconfigured_teams_str),
636+
", ".join([team.name for team in self.unconfigured_teams]),
620637
)
621-
for team in unconfigured_teams:
638+
for team in self.unconfigured_teams:
622639
self.stats.delete_team(team=team.name, deleted=False)
623640

624641
def get_members_without_team(

gh_org_mgr/manage.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def main():
145145
org.sync_teams_members(dry=args.dry)
146146
# Report and act on teams that are not configured locally
147147
log_progress("Checking for unconfigured teams...")
148-
org.get_unconfigured_teams(
148+
org.get_and_delete_unconfigured_teams(
149149
dry=args.dry,
150150
delete_unconfigured_teams=cfg_app.get("delete_unconfigured_teams", False),
151151
)

tests/data/config/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SPDX-FileCopyrightText: 2025 DB Systel GmbH
2+
# SPDX-License-Identifier: CC0-1.0
3+
4+
org.yaml
5+
teams/teams.yaml

tests/data/config/app.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# SPDX-FileCopyrightText: 2024 DB Systel GmbH
2+
# SPDX-License-Identifier: CC0-1.0
3+
4+
# ------------------------------------------------------------------------------
5+
# General configuration for this program
6+
# ------------------------------------------------------------------------------
7+
8+
# github_token: ghp_test
9+
# github_app_id: 12345
10+
# github_app_private_key: |
11+
# ------BEGIN RSA PRIVATE KEY-----
12+
# ...
13+
# ------END RSA PRIVATE KEY-----
14+
15+
# Delete teams that are not configured
16+
delete_unconfigured_teams: true
17+
18+
# Remove members that are not configured
19+
remove_members_without_team: true
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# SPDX-FileCopyrightText: 2025 DB Systel GmbH
2+
# SPDX-License-Identifier: CC0-1.0
3+
4+
# ------------------------------------------------------------------------------
5+
# General configuration for the GitHub organisation
6+
# ------------------------------------------------------------------------------
7+
8+
# Name of the GitHub organisation
9+
org_name: TEST_GITHUB_ORG
10+
org_owners:
11+
- TEST_USER
12+
13+
# Default settings. Will be overridden if set in a team.
14+
# If neither defaults nor team settings are present:
15+
# - when creating a new team, will take GitHub's defaults.
16+
# - when syncing settting of a team, will not touch the current status.
17+
defaults:
18+
team:
19+
# Description of a team
20+
# description: ""
21+
# Level of privacy of a team. Can be "secret" or "closed"
22+
privacy: "secret"
23+
# Notification setting of a team. Can be "notifications_enabled" or "notifications_disabled"
24+
notification_setting: "notifications_enabled"
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# SPDX-FileCopyrightText: 2025 DB Systel GmbH
2+
# SPDX-License-Identifier: CC0-1.0
3+
4+
# ------------------------------------------------------------------------------
5+
# General configuration for the GitHub organisation
6+
# ------------------------------------------------------------------------------
7+
8+
# Name of the GitHub organisation
9+
org_name: TEST_GITHUB_ORG
10+
org_owners:
11+
- TEST_USER
12+
13+
# Default settings. Will be overridden if set in a team.
14+
# If neither defaults nor team settings are present:
15+
# - when creating a new team, will take GitHub's defaults.
16+
# - when syncing settting of a team, will not touch the current status.
17+
defaults:
18+
team:
19+
# Description of a team
20+
# description: ""
21+
# Level of privacy of a team. Can be "secret" or "closed"
22+
privacy: "closed"
23+
# Notification setting of a team. Can be "notifications_enabled" or "notifications_disabled"
24+
notification_setting: "notifications_enabled"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# SPDX-FileCopyrightText: 2025 DB Systel GmbH
2+
# SPDX-License-Identifier: CC0-1.0
3+
4+
Test1:
5+
description: First test team with a new description
6+
privacy: closed
7+
member:
8+
- TEST_USER
9+
10+
Test2:
11+
parent: Test1
12+
privacy: closed
13+
description: Second test team
14+
maintainer:
15+
- TEST_USER
16+
17+
Test3:
18+
notification_setting: notifications_disabled
19+
privacy: closed
20+
21+
Test3-child:
22+
parent: Test3
23+
description: Child of Test3
24+
privacy: closed
25+
member:
26+
- TEST_USER
27+
28+
Test4:
29+
member:
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# SPDX-FileCopyrightText: 2025 DB Systel GmbH
2+
# SPDX-License-Identifier: CC0-1.0
3+
4+
Test1:
5+
description: First test team
6+
member:
7+
8+
Test2:
9+
privacy: secret
10+
description: Second test team
11+
member:

0 commit comments

Comments
 (0)