Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/diff-channels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Diff channels
on:
pull_request:
paths:
- channels.yml
- channels.schema.yml
jobs:
diff-channels:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/checkout@v4
with:
ref: ${{ github.base_ref }}
path: pr-base

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"

- name: Cache dependencies
uses: actions/cache@v3
id: cache-dep
with:
path: venv
key: deps-1-${{ hashfiles('script/requirements.txt') }}

- name: Install Dependencies
run: |
python3 -m venv venv
venv/bin/pip install -U pip wheel
venv/bin/pip install -r script/requirements.txt
venv/bin/pip install .

- name: Diff channels
run: |
source venv/bin/activate
python -m sr.discord_bot diff pr-base/channels.yml channels.yml > /tmp/channel-diff.txt

- name: Post diff as comment on PR
uses: thollander/actions-comment-pull-request@v3
with:
file-path: /tmp/channel-diff.txt
comment-tag: execution
2 changes: 2 additions & 0 deletions channels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@
- name: community-updates
topic: Discord community updates
use_case: discord
- name: example-channel
- name: example-channel-2

# Do not change the category below. It is populated automatically when users join.
- name: Welcome
Expand Down
36 changes: 28 additions & 8 deletions src/sr/discord_bot/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@
import sys
import logging
import argparse
from typing import TextIO, Literal

import sentry_sdk
from dotenv import load_dotenv
from discord import Intents

from sr.discord_bot.bot import BotClient
from sr.discord_bot.diff import diff_configs


class DiscordBotArgs(argparse.Namespace):
command: Literal['run', 'plan', 'apply', 'diff']
old_config: TextIO
new_config: TextIO


load_dotenv()
logger = logging.getLogger("srbot")
Expand All @@ -20,24 +29,35 @@
traces_sample_rate=1.0,
)

intents = Intents.default()
intents.members = True # Listen to member joins

token = os.getenv("DISCORD_TOKEN")
if token is None:
print("No token provided.", file=sys.stderr)
exit(1)

parser = argparse.ArgumentParser(description="Student Robotics Discord Bot")
subcommands = parser.add_subparsers(dest="command")
parser_run = subcommands.add_parser("run", help="Run the Discord bot")
parser_plan = subcommands.add_parser("plan", help="List pending guild changes")
parser_apply = subcommands.add_parser("apply", help="Apply pending guild changes")
parser_diff = subcommands.add_parser("diff", help="Compare two channel configurations")
parser_diff.add_argument("old_config", type=argparse.FileType('r'))
parser_diff.add_argument("new_config", type=argparse.FileType('r'))

args = parser.parse_args()

if args.command is None:
parser.print_help()
exit(1)
elif args.command == "diff":
# The diff command doesn't require us to connect to Discord so we can handle it here
if args.old_config is None or args.new_config is None:
parser.print_help()
exit(1)
diff_configs(args.old_config, args.new_config)
exit(0)

intents = Intents.default()
intents.members = True # Listen to member joins

token = os.getenv("DISCORD_TOKEN")
if token is None:
print("No token provided.", file=sys.stderr)
exit(1)

bot = BotClient(logger=logger, intents=intents)
bot.mode = args.command
Expand Down
2 changes: 2 additions & 0 deletions src/sr/discord_bot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,11 @@ async def on_ready(self) -> None:
if self.mode == 'plan':
await self.list_guilds()
await self.close()
exit(0)
if self.mode == 'apply':
await self.apply_changes()
await self.close()
exit(0)

async def _set_roles_and_channels(self, guild: Guild) -> None:
roles = await guild.fetch_roles()
Expand Down
19 changes: 19 additions & 0 deletions src/sr/discord_bot/diff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from typing import TextIO

import yaml

from sr.discord_bot.schema import ChannelDefinition
from sr.discord_bot.channel import ChannelSet


def diff_configs(old_config: TextIO, new_config: TextIO) -> None:
old_channels = [ChannelDefinition.load(ch) for ch in yaml.load(old_config.read(), Loader=yaml.Loader)]
new_channels = [ChannelDefinition.load(ch) for ch in yaml.load(new_config.read(), Loader=yaml.Loader)]
old = ChannelSet.from_definitions(old_channels)
new = ChannelSet.from_definitions(new_channels)
diff = ChannelSet.diff(old, new)
if len(diff) > 0:
for change in diff:
print(change)
else:
print("No changes found.")
Loading