Compare commits

..

No commits in common. "96a3d20312fab1fbbd14b7400f64f6cb71ebab25" and "691c8a4adce2f644188d7bc463836cf2178c2e16" have entirely different histories.

7 changed files with 172 additions and 280 deletions

3
.gitignore vendored
View File

@ -298,5 +298,4 @@ dmypy.json
# End of https://www.toptal.com/developers/gitignore/api/vscode,python # End of https://www.toptal.com/developers/gitignore/api/vscode,python
repos/* repos/
!repos/.gitkeep

View File

@ -36,9 +36,9 @@ pytest -svv
## Commands & Features ## Commands & Features
### `archive-repos` ### `archive-all-repos`
archive repos in gitea organization according to regex (dry-run enabled by default) archive all repos in gitea organization
### `unwatch-all-repos` ### `unwatch-all-repos`
@ -87,7 +87,7 @@ Example: `python3 -m joint_teapot create-personal-repos --suffix "-p1"` will cre
### `create-teams` ### `create-teams`
create teams on gitea by canvas groups. To integrate with webhooks, it's recommended to set suffix to `-gitea`. create teams on gitea by canvas groups
### `create-webhooks-for-mm` ### `create-webhooks-for-mm`

View File

@ -1,7 +1,7 @@
import json import json
import os import os
import re import re
from datetime import datetime from datetime import datetime, timedelta, timezone
from pathlib import Path from pathlib import Path
from time import sleep from time import sleep
from typing import TYPE_CHECKING, List from typing import TYPE_CHECKING, List
@ -16,7 +16,7 @@ from joint_teapot.utils import joj3
from joint_teapot.utils.logger import logger, set_logger from joint_teapot.utils.logger import logger, set_logger
if TYPE_CHECKING: if TYPE_CHECKING:
pass import focs_gitea
app = Typer(add_completion=False) app = Typer(add_completion=False)
@ -90,16 +90,8 @@ def create_issue_for_repos(
use_regex: bool = Option( use_regex: bool = Option(
False, "--regex", help="repo_names takes list of regexes if set" False, "--regex", help="repo_names takes list of regexes if set"
), ),
milesetone: str = Option("", "--milestone", help="milestone title"),
labels: List[str] = Option(
[],
"--label",
help="labels to add to the issue (use --label A --label B to add multiple)",
),
) -> None: ) -> None:
tea.pot.create_issue_for_repos( tea.pot.create_issue_for_repos(repo_names, title, body, from_file, use_regex)
repo_names, title, body, from_file, use_regex, milesetone, labels
)
@app.command("create-comment", help="create a comment for an issue on gitea") @app.command("create-comment", help="create a comment for an issue on gitea")
@ -111,17 +103,11 @@ def create_comment(
tea.pot.create_comment(repo_name, index, body) tea.pot.create_comment(repo_name, index, body)
@app.command( @app.command("create-milestones", help="create milestones on gitea")
"create-milestones", def create_milestone_for_repos(
help="create milestones on gitea", repo_names: List[str], title: str, description: str, due_on: datetime
)
def create_milestones(
title: str,
regex: str = Argument(".+"),
due_on: str = Argument("", help="milestone due-on date [%YYYY-%MM-%DD]"),
description: str = Argument(""),
) -> None: ) -> None:
tea.pot.gitea.create_milestones(title, regex, due_on, description) tea.pot.create_milestone_for_repos(repo_names, title, description, due_on)
@app.command("check-issues", help="check the existence of issue by title on gitea") @app.command("check-issues", help="check the existence of issue by title on gitea")
@ -155,11 +141,9 @@ def close_all_issues() -> None:
tea.pot.gitea.close_all_issues() tea.pot.gitea.close_all_issues()
@app.command( @app.command("archive-all-repos", help="archive all repos in gitea organization")
"archive-repos", help="archive repos in gitea organization according to regex" def archive_all_repos() -> None:
) tea.pot.gitea.archive_all_repos()
def archive_repos(regex: str = Argument(".+"), dry_run: bool = Option(True)) -> None:
tea.pot.gitea.archive_repos(regex, dry_run)
@app.command("unwatch-all-repos", help="unwatch all repos in gitea organization") @app.command("unwatch-all-repos", help="unwatch all repos in gitea organization")
@ -200,7 +184,7 @@ def upload_assignment_grades(assignments_dir: Path, assignment_name: str) -> Non
@app.command( @app.command(
"create-group-channels-on-mm", "create-group-channels-on-mm",
help="create channels for student groups according to group information on" help="create channels for student groups according to group information on"
" gitea; to integrate with webhooks, it's recommended to set suffix to '-gitea'", " gitea",
) )
def create_group_channels_on_mm( def create_group_channels_on_mm(
prefix: str = Option(""), prefix: str = Option(""),
@ -237,8 +221,7 @@ def create_personal_channels_on_mm(
"and configure them so that updates on gitea will be pushed to the mm channel", "and configure them so that updates on gitea will be pushed to the mm channel",
) )
def create_webhooks_for_mm( def create_webhooks_for_mm(
regex: str = Argument(""), regex: str = Argument(""), git_suffix: bool = Option(False)
gitea_suffix: bool = Option(True, help="append gitea suffix to mm channel names"),
) -> None: ) -> None:
repo_names = [ repo_names = [
group_name group_name
@ -246,9 +229,7 @@ def create_webhooks_for_mm(
if re.match(regex, group_name) if re.match(regex, group_name)
] ]
logger.info(f"{len(repo_names)} pair(s) of webhooks to be created: {repo_names}") logger.info(f"{len(repo_names)} pair(s) of webhooks to be created: {repo_names}")
tea.pot.mattermost.create_webhooks_for_repos( tea.pot.mattermost.create_webhooks_for_repos(repo_names, tea.pot.gitea, git_suffix)
repo_names, tea.pot.gitea, gitea_suffix
)
@app.command( @app.command(
@ -323,24 +304,57 @@ def joj3_all_env(
"sha": env.github_sha, "sha": env.github_sha,
"commitMsg": env.joj3_commit_msg, "commitMsg": env.joj3_commit_msg,
} }
gitea_actions_url = (
f"https://{settings.gitea_domain_name}{settings.gitea_suffix}/"
+ f"{settings.gitea_org_name}/{submitter_repo_name}/"
+ f"actions/runs/{env.github_run_number}"
)
submitter_repo_url = ( submitter_repo_url = (
f"https://{settings.gitea_domain_name}{settings.gitea_suffix}/" f"https://{settings.gitea_domain_name}{settings.gitea_suffix}/"
+ f"{settings.gitea_org_name}/{submitter_repo_name}" + f"{settings.gitea_org_name}/{submitter_repo_name}"
) )
gitea_actions_url = f"{submitter_repo_url}/actions/runs/{env.github_run_number}"
gitea_issue_url = "" gitea_issue_url = ""
if not skip_result_issue: if not skip_result_issue:
issue_number = tea.pot.joj3_post_issue( title, comment = joj3.generate_title_and_comment(
env, env.joj3_output_path,
max_total_score,
gitea_actions_url, gitea_actions_url,
env.github_run_number,
env.joj3_conf_name,
env.github_actor,
env.github_sha,
submitter_in_issue_title, submitter_in_issue_title,
submitter_repo_name, env.joj3_run_id,
max_total_score,
) )
res["issue"] = issue_number title_prefix = joj3.get_title_prefix(
gitea_issue_url = f"{submitter_repo_url}/issues/{issue_number}" env.joj3_conf_name, env.github_actor, submitter_in_issue_title
)
joj3_issue: focs_gitea.Issue
issue: focs_gitea.Issue
for issue in tea.pot.gitea.issue_api.issue_list_issues(
tea.pot.gitea.org_name, submitter_repo_name, state="open"
):
if issue.title.startswith(title_prefix):
joj3_issue = issue
logger.info(f"found joj3 issue: #{joj3_issue.number}")
break
else:
joj3_issue = tea.pot.gitea.issue_api.issue_create_issue(
tea.pot.gitea.org_name,
submitter_repo_name,
body={"title": title_prefix + "0", "body": ""},
)
logger.info(f"created joj3 issue: #{joj3_issue.number}")
gitea_issue_url = joj3_issue.html_url
logger.info(f"gitea issue url: {gitea_issue_url}") logger.info(f"gitea issue url: {gitea_issue_url}")
echo(json.dumps(res)) # print result to stdout for joj3 log parser tea.pot.gitea.issue_api.issue_edit_issue(
tea.pot.gitea.org_name,
submitter_repo_name,
joj3_issue.number,
body={"title": title, "body": comment},
)
res["issue"] = joj3_issue.number
print(json.dumps(res)) # print result to stdout for joj3 log parser
if skip_scoreboard and skip_failed_table: if skip_scoreboard and skip_failed_table:
return return
lock_file_path = os.path.join( lock_file_path = os.path.join(
@ -449,7 +463,6 @@ def joj3_check_env(
app.pretty_exceptions_enable = False app.pretty_exceptions_enable = False
set_settings(Settings(_env_file=env_path)) set_settings(Settings(_env_file=env_path))
set_logger(settings.stderr_log_level) set_logger(settings.stderr_log_level)
logger.info(f"debug log to file: {settings.log_file_path}")
env = joj3.Env() env = joj3.Env()
if "" in ( if "" in (
env.github_actor, env.github_actor,
@ -457,10 +470,98 @@ def joj3_check_env(
): ):
logger.error("missing required env var") logger.error("missing required env var")
raise Exit(code=1) raise Exit(code=1)
msg, failed = tea.pot.joj3_check_submission_count( submitter_repo_name = env.github_repository.split("/")[-1]
env, grading_repo_name, group_config, scoreboard_filename repo: Repo = tea.pot.git.get_repo(grading_repo_name)
now = datetime.now(timezone.utc)
items = group_config.split(",")
comment = ""
failed = False
pattern = re.compile(
r"joj3: update scoreboard for (?P<exercise_name>.+?) "
r"by @(?P<submitter>.+) in "
r"(?P<gitea_org_name>.+)/(?P<submitter_repo_name>.+)@(?P<commit_hash>.+)"
) )
echo(json.dumps({"msg": msg, "failed": failed})) # print result to stdout for joj3 time_windows = []
valid_items = []
for item in items:
name, values = item.split("=")
max_count, time_period = map(int, values.split(":"))
if max_count < 0 or time_period < 0:
continue
since = now - timedelta(hours=time_period)
time_windows.append(since)
valid_items.append((name, max_count, time_period, since))
all_commits = []
if time_windows:
earliest_since = min(time_windows).strftime("%Y-%m-%dT%H:%M:%S")
commits = repo.iter_commits(paths=scoreboard_filename, since=earliest_since)
for commit in commits:
lines = commit.message.strip().splitlines()
if not lines:
continue
match = pattern.match(lines[0])
if not match:
continue
d = match.groupdict()
if (
env.joj3_conf_name != d["exercise_name"]
or env.github_actor != d["submitter"]
or submitter_repo_name != d["submitter_repo_name"]
):
continue
groups_line = next((l for l in lines if l.startswith("groups: ")), None)
commit_groups = (
groups_line[len("groups: ") :].split(",") if groups_line else []
)
all_commits.append(
{
"time": commit.committed_datetime,
"groups": [g.strip() for g in commit_groups],
}
)
for name, max_count, time_period, since in valid_items:
submit_count = 0
time_limit = now - timedelta(hours=time_period)
for commit in all_commits:
if commit["time"] < time_limit:
continue
if name:
target_group = name.lower()
commit_groups_lower = [g.lower() for g in commit["groups"]]
if target_group not in commit_groups_lower:
continue
submit_count += 1
logger.info(
f"submitter {env.github_actor} is submitting for the {submit_count + 1} time, "
f"{min(0, max_count - submit_count - 1)} time(s) remaining, "
f"group={name}, "
f"time period={time_period} hour(s), "
f"max count={max_count}, submit count={submit_count}"
)
use_group = False
if name:
comment += f"keyword `{name}` "
for group in env.joj3_groups or "":
if group.lower() == name.lower():
use_group = True
break
else:
use_group = True
comment += (
f"in last {time_period} hour(s): "
f"submit count {submit_count}, "
f"max count {max_count}"
)
if use_group and submit_count + 1 > max_count:
failed = True
comment += ", exceeded"
comment += "\n"
if failed:
title = "### Submission Count Check Failed:"
else:
title = "### Submission Count Check Passed:"
msg = f"{title}\n{comment}\n"
print(json.dumps({"msg": msg, "failed": failed})) # print result to stdout for joj3
logger.info("joj3-check-env done") logger.info("joj3-check-env done")

View File

@ -2,22 +2,17 @@ import functools
import glob import glob
import os import os
import re import re
from datetime import datetime, timedelta, timezone from datetime import datetime
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, TypeVar from typing import Any, Callable, Dict, List, Optional, TypeVar
import mosspy import mosspy
from git import Repo
from joint_teapot.config import settings from joint_teapot.config import settings
from joint_teapot.utils import joj3
from joint_teapot.utils.logger import logger from joint_teapot.utils.logger import logger
from joint_teapot.utils.main import default_repo_name_convertor, first from joint_teapot.utils.main import default_repo_name_convertor, first
from joint_teapot.workers import Canvas, Git, Gitea, Mattermost from joint_teapot.workers import Canvas, Git, Gitea, Mattermost
from joint_teapot.workers.joj import JOJ from joint_teapot.workers.joj import JOJ
if TYPE_CHECKING:
import focs_gitea
_T = TypeVar("_T") _T = TypeVar("_T")
@ -111,7 +106,7 @@ class Teapot:
return None return None
team_name, number_str = name.split(" ") team_name, number_str = name.split(" ")
number = int(number_str) number = int(number_str)
return f"{team_name}{number:02}" return f"{team_name}-{number:02}"
return self.gitea.create_teams_and_repos_by_canvas_groups( return self.gitea.create_teams_and_repos_by_canvas_groups(
self.canvas.students, self.canvas.groups, convertor, convertor self.canvas.students, self.canvas.groups, convertor, convertor
@ -146,8 +141,6 @@ class Teapot:
body: str, body: str,
from_file: bool = False, from_file: bool = False,
use_regex: bool = False, use_regex: bool = False,
milestone: str = "",
labels: List[str] = [],
) -> None: ) -> None:
if from_file: if from_file:
try: try:
@ -175,7 +168,7 @@ class Teapot:
affected_repos = repo_names affected_repos = repo_names
for repo_name in affected_repos: for repo_name in affected_repos:
self.gitea.create_issue(repo_name, title, content, True, milestone, labels) self.gitea.create_issue(repo_name, title, content)
def create_comment( def create_comment(
self, self,
@ -185,6 +178,12 @@ class Teapot:
) -> None: ) -> None:
self.gitea.create_comment(repo_name, index, body) self.gitea.create_comment(repo_name, index, body)
def create_milestone_for_repos(
self, repo_names: List[str], title: str, description: str, due_on: datetime
) -> None:
for repo_name in repo_names:
self.gitea.create_milestone(repo_name, title, description, due_on)
def check_exist_issue_by_title( def check_exist_issue_by_title(
self, repo_names: List[str], title: str self, repo_names: List[str], title: str
) -> List[str]: ) -> List[str]:
@ -230,152 +229,6 @@ class Teapot:
self.canvas.students, invite_teaching_teams self.canvas.students, invite_teaching_teams
) )
def joj3_post_issue(
self,
env: joj3.Env,
max_total_score: int,
gitea_actions_url: str,
submitter_in_issue_title: bool,
submitter_repo_name: str,
) -> int:
title, comment = joj3.generate_title_and_comment(
env.joj3_output_path,
gitea_actions_url,
env.github_run_number,
env.joj3_conf_name,
env.github_actor,
env.github_sha,
submitter_in_issue_title,
env.joj3_run_id,
max_total_score,
)
title_prefix = joj3.get_title_prefix(
env.joj3_conf_name, env.github_actor, submitter_in_issue_title
)
joj3_issue: focs_gitea.Issue
issue: focs_gitea.Issue
new_issue = False
for issue in self.gitea.issue_api.issue_list_issues(
self.gitea.org_name, submitter_repo_name, state="open"
):
if issue.title.startswith(title_prefix):
joj3_issue = issue
logger.info(f"found joj3 issue: #{joj3_issue.number}")
break
else:
new_issue = True
joj3_issue = self.gitea.issue_api.issue_create_issue(
self.gitea.org_name,
submitter_repo_name,
body={"title": title, "body": comment},
)
logger.info(f"created joj3 issue: #{joj3_issue.number}")
gitea_issue_url = joj3_issue.html_url
logger.info(f"gitea issue url: {gitea_issue_url}")
if not new_issue:
self.gitea.issue_api.issue_edit_issue(
self.gitea.org_name,
submitter_repo_name,
joj3_issue.number,
body={"title": title, "body": comment},
)
return joj3_issue.number
def joj3_check_submission_count(
self,
env: joj3.Env,
grading_repo_name: str,
group_config: str,
scoreboard_filename: str,
) -> Tuple[str, bool]:
submitter_repo_name = env.github_repository.split("/")[-1]
repo: Repo = self.git.get_repo(grading_repo_name)
now = datetime.now(timezone.utc)
items = group_config.split(",")
comment = ""
failed = False
pattern = re.compile(
r"joj3: update scoreboard for (?P<exercise_name>.+?) "
r"by @(?P<submitter>.+) in "
r"(?P<gitea_org_name>.+)/(?P<submitter_repo_name>.+)@(?P<commit_hash>.+)"
)
time_windows = []
valid_items = []
for item in items:
name, values = item.split("=")
max_count, time_period = map(int, values.split(":"))
if max_count < 0 or time_period < 0:
continue
since = now - timedelta(hours=time_period)
time_windows.append(since)
valid_items.append((name, max_count, time_period, since))
all_commits = []
if time_windows:
earliest_since = min(time_windows).strftime("%Y-%m-%dT%H:%M:%S")
commits = repo.iter_commits(paths=scoreboard_filename, since=earliest_since)
for commit in commits:
lines = commit.message.strip().splitlines()
if not lines:
continue
match = pattern.match(lines[0])
if not match:
continue
d = match.groupdict()
if (
env.joj3_conf_name != d["exercise_name"]
or env.github_actor != d["submitter"]
or submitter_repo_name != d["submitter_repo_name"]
):
continue
groups_line = next((l for l in lines if l.startswith("groups: ")), None)
commit_groups = (
groups_line[len("groups: ") :].split(",") if groups_line else []
)
all_commits.append(
{
"time": commit.committed_datetime,
"groups": [g.strip() for g in commit_groups],
}
)
for name, max_count, time_period, since in valid_items:
submit_count = 0
time_limit = now - timedelta(hours=time_period)
for commit in all_commits:
if commit["time"] < time_limit:
continue
if name:
target_group = name.lower()
commit_groups_lower = [g.lower() for g in commit["groups"]]
if target_group not in commit_groups_lower:
continue
submit_count += 1
logger.info(
f"submitter {env.github_actor} is submitting for the {submit_count + 1} time, "
f"{min(0, max_count - submit_count - 1)} time(s) remaining, "
f"group={name}, "
f"time period={time_period} hour(s), "
f"max count={max_count}, submit count={submit_count}"
)
use_group = True
if name:
comment += f"keyword `{name}` "
use_group = name.lower() in env.joj3_groups.lower()
comment += (
f"in last {time_period} hour(s): "
f"submit count {submit_count}, "
f"max count {max_count}"
)
if use_group and submit_count + 1 > max_count:
failed = True
comment += ", exceeded"
comment += "\n"
if failed:
title = "### Submission Count Check Failed:"
else:
title = "### Submission Count Check Passed:"
msg = f"{title}\n{comment}\n"
return msg, failed
if __name__ == "__main__": if __name__ == "__main__":
teapot = Teapot() teapot = Teapot()

View File

@ -1,4 +1,5 @@
import re import re
from datetime import datetime
from enum import Enum from enum import Enum
from functools import lru_cache from functools import lru_cache
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, TypeVar from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, TypeVar
@ -344,8 +345,6 @@ class Gitea:
title: str, title: str,
body: str, body: str,
assign_every_collaborators: bool = True, assign_every_collaborators: bool = True,
milestone: str = "",
labels: list[str] = [],
) -> None: ) -> None:
assignees = [] assignees = []
if assign_every_collaborators: if assign_every_collaborators:
@ -357,33 +356,10 @@ class Gitea:
repo_name, repo_name,
) )
] ]
milestone_id = None
if milestone:
milestone_list = self.issue_api.issue_get_milestones_list(
self.org_name, repo_name
)
if milestone not in [m.title for m in milestone_list]:
logger.warning(f"Milestone {milestone} does not exist in {repo_name}")
else:
milestone_id = first(
[m.id for m in milestone_list if m.title == milestone]
)
labels_id = []
if labels:
labels_list = self.issue_api.issue_list_labels(self.org_name, repo_name)
labels_id = [l.id for l in labels_list if l.name in labels]
if not labels_id:
logger.warning(f"no label matches {labels}")
self.issue_api.issue_create_issue( self.issue_api.issue_create_issue(
self.org_name, self.org_name,
repo_name, repo_name,
body={ body={"title": title, "body": body, "assignees": assignees},
"title": title,
"body": body,
"assignees": assignees,
"milestone": milestone_id,
"labels": labels_id,
},
) )
logger.info(f'Created issue "{title}" in {repo_name}') logger.info(f'Created issue "{title}" in {repo_name}')
@ -406,22 +382,15 @@ class Gitea:
repo_name: str, repo_name: str,
title: str, title: str,
description: str, description: str,
due_on: str, due_on: datetime,
) -> None: ) -> None:
if due_on == "":
self.issue_api.issue_create_milestone(
self.org_name,
repo_name,
body={"title": title, "description": description},
)
return
self.issue_api.issue_create_milestone( self.issue_api.issue_create_milestone(
self.org_name, self.org_name,
repo_name, repo_name,
body={ body={
"title": title, "title": title,
"description": description, "description": description,
"due_on": due_on + "T23:59:59.999+08:00", "due_on": due_on.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
}, },
) )
@ -444,16 +413,10 @@ class Gitea:
self.org_name, repo_name, issue.number, body={"state": "closed"} self.org_name, repo_name, issue.number, body={"state": "closed"}
) )
def archive_repos(self, regex: str = ".+", dry_run: bool = True) -> None: def archive_all_repos(self) -> None:
if dry_run: for repo in list_all(self.organization_api.org_list_repos, self.org_name):
logger.info("Dry run enabled. No changes will be made to the repositories.")
logger.info(f"Archiving repos with name matching {regex}")
for repo_name in self.get_all_repo_names():
if re.match(regex, repo_name):
logger.info(f"Archived {repo_name}")
if not dry_run:
self.repository_api.repo_edit( self.repository_api.repo_edit(
self.org_name, repo_name, body={"archived": True} self.org_name, repo.name, body={"archived": True}
) )
def unwatch_all_repos(self) -> None: def unwatch_all_repos(self) -> None:
@ -500,21 +463,6 @@ class Gitea:
) )
logger.info(f"Unsubscribed from {sub.name}") logger.info(f"Unsubscribed from {sub.name}")
def create_milestones(
self, milestone: str, regex: str, due_date: str, description: str
) -> None:
for repo_name in self.get_all_repo_names():
if not re.match(regex, repo_name):
continue
milestone_list = self.issue_api.issue_get_milestones_list(
self.org_name, repo_name
)
if milestone in [m.title for m in milestone_list]:
logger.warning(f"Milestone {milestone} already exists in {repo_name}")
continue
self.create_milestone(repo_name, milestone, description, due_date)
logger.info(f"Created milestone {milestone} in {repo_name}")
if __name__ == "__main__": if __name__ == "__main__":
gitea = Gitea() gitea = Gitea()

View File

@ -36,7 +36,7 @@ class Mattermost:
except Exception: except Exception:
logger.error("Cannot login to Mattermost") logger.error("Cannot login to Mattermost")
return return
if "admin" not in operator["roles"] and "system_user" not in operator["roles"]: if "admin" not in operator["roles"]:
logger.error("Please make sure you have enough permission") logger.error("Please make sure you have enough permission")
try: try:
self.team = self.endpoint.teams.get_team_by_name(team_name) self.team = self.endpoint.teams.get_team_by_name(team_name)
@ -167,14 +167,12 @@ class Mattermost:
logger.info(f"Added member {member} to channel {channel_name}") logger.info(f"Added member {member} to channel {channel_name}")
def create_webhooks_for_repos( def create_webhooks_for_repos(
self, repos: List[str], gitea: Gitea, gitea_suffix: bool self, repos: List[str], gitea: Gitea, git_suffix: bool
) -> None: ) -> None:
# one group corresponds to one repo so these concepts can be used interchangeably # one group corresponds to one repo so these concepts can be used interchangeably
for repo in repos: for repo in repos:
channel_name = f"{repo}-gitea" if gitea_suffix else repo logger.info(f"Creating webhooks for repo {gitea.org_name}/{repo}")
logger.info( channel_name = f"{repo}-git" if git_suffix else repo
f"Creating webhooks for repo {gitea.org_name}/{repo} and channel {channel_name}"
)
try: try:
mm_channel = self.endpoint.channels.get_channel_by_name( mm_channel = self.endpoint.channels.get_channel_by_name(
self.team["id"], channel_name self.team["id"], channel_name
@ -205,16 +203,9 @@ class Mattermost:
events=[ events=[
"issues_only", "issues_only",
"issue_comment", "issue_comment",
"issue_assign",
"pull_request_only", "pull_request_only",
"pull_request_comment", "pull_request_comment",
"pull_request_review", "pull_request_review",
"pull_request_review_request",
"push",
"create",
"delete",
"release",
"wiki",
], ],
config={ config={
"url": f"https://{self.url}{self.url_suffix}/hooks/{mm_webhook['id']}", "url": f"https://{self.url}{self.url_suffix}/hooks/{mm_webhook['id']}",

View File