CodeyBot
CodeyBot is a Discord bot in the CSC server. CodeyBot can do a bunch of different things, from administrative actions to information and games.
Historical Note
We used to have a team dedicated to developing CodeyBot within the CSC Committee, called CodeyBot Developer team. However, as of Fall 2025, in order to make the CSC Committee more efficient and organized, CodeyBot Developer team has been dissolved. The responsibilities of maintaining and developing CodeyBot now falls in the hands of Termcom.
Contribution
The repo for CodeyBot is public, so you don't have to be a member of Termcom to develop CodeyBot (of course only Termcom has access to perform maintenance). Whether you're in Termcom or just an enthusiastic individual, please visit https://github.com/uwcsc/codeybot. It should have all the instructions for you to contribute to CodeyBot.
Management/Maintenance (For Termcom only)
Now here comes the fun part. It's fun because there has never been a single documentation on this stuff. But I didn't enjoy that kind of fun. So please read this.
Repo owners
Just make sure you do these 2 things:
- Update the owner(s) of the CodeyBot repo (if you have to) under https://github.com/orgs/uwcsc/teams/discord. Only the owner can review PRs, approve PRs, merge PRs into
mainand push code tomainwithout having to make a PR. - Update the owner(s) of the CodeyBot repo in
.github/CODEOWNERS. By doing this, whenever a PR is made and review is requested, it will default to the right owner(s).
Discord Mod for Ban Appeal
If you haven't noticed already, CSC Committee has Discord Moderators. And like it or not, they need to ban people from CSC server quite frequently. Whenever a server member is banned, they get DM'ed by CodeyBot on why they were banned and who they could get in touch for further details. This who is usually the team lead of the Discord Moderators. And they might change, from term to term. As such, at the beginning of every term, make sure that the variable MOD_USER_ID_FOR_BAN_APPEAL is set to the Discord user ID of the right person. The variable can be found in config/production/vars.json in the repo.
Hosting
We have 3 servers to host CodeyBot for different purposes. All 3 servers are CSC Cloud VMs. Ask the current Termcom Lead/Sysadmin for access to the VMs. These 3 servers are:
codey-staging: for staging, i.e. verifying that themainbranch is behaving properly before shipping to production.codey-prod: for production, i.e. the CodeyBot currently sitting in the CSC server.codey-bootcamp: a different version of CodeyBot tailored for CSC Bootcamp events (which happens every now and then).
Note: there are discussions to move CodeyBot to caffeine because CloudStack is not kind. As of this writing, this still remains a discussion.
VM Access
I told you that CodeyBot is hosted on CloudStack. What I did not tell you is that CloudStack is broken. More specifically, you cannot add your own SSH key from the web interface, nor can you access the console from the web interface.
As such, until CodeyBot is migrated away from CloudStack, make sure there is at least 1 person who already has access to the VMs so that they can give you access to the VMs. Just give them your public SSH key and they can add you to the VMs.
Structure
For the sake of brevity, let environment be a variable, where environment is one of production, staging, bootcamp.
On the corresponding VM, go to ~/codey/{environment}. In this directory, when you ls -al, you should see 4 things:
.env: This file contains the secret tokens needed for CodeyBot to work properly. It should not be changed (there's literally nothing to update there).db/: This directory contains a SQLite database used by CodeyBot. Do not let this database disappear, or you're not gonna find any good reasons to explain to CSC server members how their coins just vanished into thin air.docker-compose.yml: This file allows you to start the bot withdocker-compose up -dand stop the bot withdocker-compose down. Note that this file is the same ascodeybot/docker/{environment}/docker-compose.yml. For reasons I'll explain later, thedocker-compose.ymlin the VM is manually synced to the one in the repo.logs/: This directory contain the logs from the Docker container. Not much importance.
Now, when you docker ps -a, you should see 2 containers:
codey-{environment}: The container that runs CodeyBot. It should not be down (if it does, it should auto restart).watchtower: The magic that allows CodeyBot to be automatically updated with the latest changes. It should not be down (if it does, it should auto restart). For reference, this is the command that ran the container the first time. Also, you can learn more about Watchtower here https://github.com/containrrr/watchtower.
docker run -d \
--name watchtower \
--restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower \
codey-{environment} \
--interval 30 \
--cleanup \
--debug
CI/CD pipeline
We consider 2 different situations:
- Staging: Whenever the
mainbranch changes, it triggers the corresponding code in.github/workflows/build.ymlthat builds the image and uploads it to Docker Hub. Watchtower looks out for image changes every 30 seconds. If the image is updated, Watchtower stops the current CodeyBot container, pulls the latest image, rebuilds the container and starts it up again. - Production: Whenever a release is made on GitHub, it triggers the corresponding code in
.github/workflows/build.ymlthat builds the image and uploads it to Docker Hub. Watchtower looks out for image changes every 30 seconds. If the image is updated, Watchtower stops the current CodeyBot container, pulls the latest image, rebuilds the container and starts it up again.
Due to the use of Watchtower, the docker-compose.yml to build the CodeyBot container cannot be automatically synced (without making things unnecessarily messy). In the past, we used GitHub SSH Action to sync everything (Docker image, docker-compose.yml, .env and rebuilding container). However, at some point, the SSH broke, and we never figured out why. And the SSH-related creds are stored as GitHub secrets, and I have zero idea which one means what. So I just went with Watchtower (it's a lot more reliable anyways, just need to manually update 1 file).