generated from nhcarrigan/template
docs: add README files for all script categories and update project docs
CI / dependency-pin-check-typescript (pull_request) Successful in 5s
CI / dependency-pin-check-python (pull_request) Successful in 4s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 57s
CI / python (pull_request) Successful in 9m33s
CI / typescript (pull_request) Successful in 9m41s
CI / dependency-pin-check-typescript (pull_request) Successful in 5s
CI / dependency-pin-check-python (pull_request) Successful in 4s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 57s
CI / python (pull_request) Successful in 9m33s
CI / typescript (pull_request) Successful in 9m41s
Add Getting Started sections and correct usage commands to all category READMEs (TypeScript, Python, Bash). Update top-level README.md and CLAUDE.md to reflect the Bash language, correct project structure, and accurate make run instructions. Remove completed DOCS_TODO.md.
This commit is contained in:
@@ -0,0 +1,883 @@
|
||||
# Cohort Scripts
|
||||
|
||||
Scripts for managing the NHCarrigan spring cohort programme. Covers the full lifecycle: applicant evaluation, Discord server setup, team assignment, member onboarding, activity tracking, and member removal.
|
||||
|
||||
Most scripts interact with the Discord API and require a `DISCORD_BOT_TOKEN`. Several also use the `gh` CLI for GitHub operations.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Run scripts via the interactive runner from the project root:
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → <script>
|
||||
```
|
||||
|
||||
Or run directly:
|
||||
|
||||
```bash
|
||||
cd python && op run --env-file=../prod.env -- uv run python cohort/<script>.py
|
||||
```
|
||||
|
||||
**Prerequisites:**
|
||||
- Run `make install-py` to set up the Python virtual environment.
|
||||
- Most scripts require `DISCORD_BOT_TOKEN` set in `prod.env`.
|
||||
- Scripts that manage GitHub teams require `gh auth login` to be run first.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
### Applicant Evaluation
|
||||
- [verify_discord.py](#verify_discordpy)
|
||||
- [evaluate_technical_proficiency.py](#evaluate_technical_proficiencypy)
|
||||
- [analyse_availability.py](#analyse_availabilitypy)
|
||||
- [generate_member_files.py](#generate_member_filespy)
|
||||
- [generate_timeslots.py](#generate_timeslotspy)
|
||||
|
||||
### Server Setup
|
||||
- [create_team_voice_channels.py](#create_team_voice_channelspy)
|
||||
- [fix_channel_permissions.py](#fix_channel_permissionspy)
|
||||
- [update_cohort_leads_permissions.py](#update_cohort_leads_permissionspy)
|
||||
- [list_all_guild_roles.py](#list_all_guild_rolespy)
|
||||
- [list_discord_roles.py](#list_discord_rolespy)
|
||||
- [check_channel_permissions.py](#check_channel_permissionspy)
|
||||
|
||||
### Member Onboarding
|
||||
- [send_team_messages.py](#send_team_messagespy)
|
||||
- [assign_cohort_role.py](#assign_cohort_rolepy)
|
||||
- [assign_team_roles.py](#assign_team_rolespy)
|
||||
- [add_github_team_members.py](#add_github_team_memberspy)
|
||||
|
||||
### Ongoing Management
|
||||
- [get_cohort_members.py](#get_cohort_memberspy)
|
||||
- [check_member_status.py](#check_member_statuspy)
|
||||
- [fetch_roster.py](#fetch_rosterpy)
|
||||
- [update_roster_messages.py](#update_roster_messagespy)
|
||||
- [send_checkin.py](#send_checkinpy)
|
||||
- [send_team_checkin.py](#send_team_checkinpy)
|
||||
- [send_team_messages.py](#send_team_messagespy)
|
||||
|
||||
### Activity Tracking
|
||||
- [discord_activity_checker.py](#discord_activity_checkerpy)
|
||||
- [catch_up_report.py](#catch_up_reportpy)
|
||||
- [check_lengths.py](#check_lengthspy)
|
||||
- [send_activity_report.py](#send_activity_reportpy)
|
||||
|
||||
### Member Removal
|
||||
- [remove_member.py](#remove_memberpy)
|
||||
- [remove_resigned_members.py](#remove_resigned_memberspy)
|
||||
- [remove_discord_roles.py](#remove_discord_rolespy)
|
||||
|
||||
---
|
||||
|
||||
## verify_discord.py
|
||||
|
||||
Reads Discord user IDs from a markdown table and verifies each one against the Discord API, checking whether the user is a member of the freeCodeCamp guild. Handles rate limits and retries automatically.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → verify_discord.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `table.md` | Markdown table | Applicant data; the script reads Discord IDs from the table rows |
|
||||
|
||||
**Output** (written to `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `discord_verification.json` | JSON object | Results grouped as `verified` (with username), `missing`, and `errors` lists |
|
||||
|
||||
---
|
||||
|
||||
## evaluate_technical_proficiency.py
|
||||
|
||||
Evaluates each applicant's technical proficiency by analysing their GitHub profile and self-described expertise. Scores applicants as Beginner, Intermediate, or Advanced based on public repository count, follower count, language variety, and keywords in their self-assessment text.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → evaluate_technical_proficiency.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
None. Uses the public GitHub API (unauthenticated, subject to rate limiting).
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `applicants_to_evaluate.json` | JSON array | Applicant records, each with a GitHub profile URL and a self-description field |
|
||||
|
||||
**Output** (written to `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `proficiency_evaluations.json` | JSON array | Proficiency scores (`Beginner`/`Intermediate`/`Advanced`) and detected tech stacks per applicant |
|
||||
|
||||
### Notes
|
||||
|
||||
- Unauthenticated GitHub API requests are rate-limited to 60 per hour. For large batches of applicants, consider adding a GitHub token or running the script in smaller chunks.
|
||||
|
||||
---
|
||||
|
||||
## analyse_availability.py
|
||||
|
||||
Parses a markdown table of applicant availability responses with timezone information, converts local timeslot selections to UTC, and produces a JSON summary of UTC coverage across morning, afternoon, evening, and night blocks per applicant.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → analyse_availability.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
None.
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `table.md` | Markdown table | Availability responses with timezone column |
|
||||
| `discord_verification.json` | JSON object | Output of `verify_discord.py` — used to link applicants to Discord usernames |
|
||||
|
||||
**Output** (written to `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `availability_analysis.json` | JSON object | UTC block distribution (morning/afternoon/evening/night) per applicant |
|
||||
|
||||
---
|
||||
|
||||
## generate_member_files.py
|
||||
|
||||
Consolidates all evaluation data into two markdown files: one for participants and one for team leaders. Each entry includes the member's tech stack, availability, proficiency level, and (for leaders) their leadership assessment.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → generate_member_files.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
None.
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `discord_verification.json` | JSON object | Verified applicant Discord info |
|
||||
| `proficiency_evaluations.json` | JSON array | Technical proficiency scores |
|
||||
| `availability_analysis.json` | JSON object | UTC availability blocks |
|
||||
| `leadership_candidates.json` | JSON array | Applicants being considered for leadership roles |
|
||||
| `leadership_evaluations.json` | JSON array | Leadership assessment results |
|
||||
|
||||
**Output** (written to `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `participants.md` | Markdown | Profile summary for each participant |
|
||||
| `leaders.md` | Markdown | Profile summary for each team leader candidate |
|
||||
|
||||
---
|
||||
|
||||
## generate_timeslots.py
|
||||
|
||||
Generates a list of hourly timeslots for use with the [Crabfit](https://crab.fit/) scheduling tool, covering a date range at Los Angeles timezone.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → generate_timeslots.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
None.
|
||||
|
||||
### Data Files
|
||||
|
||||
**Output** (written to `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `crabfit_timeslots.json` | JSON array of ISO-format strings | One entry per hour across the configured date range |
|
||||
|
||||
### Notes
|
||||
|
||||
- The date range and timezone are hardcoded in the script. Update the start/end date constants before running.
|
||||
|
||||
---
|
||||
|
||||
## create_team_voice_channels.py
|
||||
|
||||
Creates private voice channels for each cohort team in a specified Discord category. Each channel is visible and joinable only by members who have that team's role.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → create_team_voice_channels.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
None. Team role IDs and the target category ID are hardcoded in the script.
|
||||
|
||||
### Notes
|
||||
|
||||
- Update the team role IDs, channel names, and category ID constants in the script before running.
|
||||
|
||||
---
|
||||
|
||||
## fix_channel_permissions.py
|
||||
|
||||
Denies `Send Messages` and `Send Messages in Threads` permissions for the `@everyone` and `@cohort` roles on a specific Discord channel. Used to lock down a channel so only designated roles can post.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → fix_channel_permissions.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
None. The target channel ID is hardcoded in the script.
|
||||
|
||||
### Notes
|
||||
|
||||
- Update the `CHANNEL_ID` constant before running.
|
||||
|
||||
---
|
||||
|
||||
## update_cohort_leads_permissions.py
|
||||
|
||||
Grants the Cohort Leads role `MENTION_EVERYONE` and `PIN_MESSAGES` permissions across all 14 team channels.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → update_cohort_leads_permissions.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
None. Team channel IDs are hardcoded in the script.
|
||||
|
||||
---
|
||||
|
||||
## list_all_guild_roles.py
|
||||
|
||||
Lists all roles in the freeCodeCamp Discord guild, highlighting team and cohort-related roles. Useful for finding role IDs to use in other scripts.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → list_all_guild_roles.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
None. Output is printed to stdout.
|
||||
|
||||
---
|
||||
|
||||
## list_discord_roles.py
|
||||
|
||||
Lists Discord roles in the freeCodeCamp server, filtering for cohort-, leader-, and 2026-related roles.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → list_discord_roles.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
None. Output is printed to stdout.
|
||||
|
||||
---
|
||||
|
||||
## check_channel_permissions.py
|
||||
|
||||
Audits `cohort-team-*` Discord channels to identify incorrect `Send Messages` or `Send Messages in Threads` permissions on the `@everyone` or `@cohort` roles.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → check_channel_permissions.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
None. Results are printed to stdout.
|
||||
|
||||
---
|
||||
|
||||
## send_team_messages.py
|
||||
|
||||
Sends initial welcome and roster messages to all 14 team Discord channels, pins them, and saves the resulting message IDs, channel IDs, and role IDs to `data/team_message_ids.json`. This file is required by several other scripts.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → send_team_messages.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `team_assignments.json` | JSON object | Team rosters (leaders and participants per team) |
|
||||
| `applicants_to_evaluate.json` | JSON array | Applicant data used to populate roster messages |
|
||||
|
||||
**Output** (written to `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `team_message_ids.json` | JSON object | Channel ID, pinned message ID, and role ID per team name |
|
||||
|
||||
### Notes
|
||||
|
||||
- Run this **once** at the start of the cohort. Other scripts (`send_checkin.py`, `update_roster_messages.py`, etc.) depend on `team_message_ids.json`.
|
||||
|
||||
---
|
||||
|
||||
## assign_cohort_role.py
|
||||
|
||||
Assigns the Cohort Discord role to all cohort participants. Reads the full list of unique member Discord IDs from `team_assignments.json` and assigns the role to each one, with exponential backoff to handle rate limits.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → assign_cohort_role.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `team_assignments.json` | JSON object | Team rosters; all unique user IDs are extracted from here |
|
||||
|
||||
---
|
||||
|
||||
## assign_team_roles.py
|
||||
|
||||
Assigns team-specific Discord roles to all cohort participants based on their team membership in `team_assignments.json`. Uses exponential backoff for rate limit handling.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → assign_team_roles.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `team_assignments.json` | JSON object | Team rosters with Discord IDs and corresponding role IDs |
|
||||
|
||||
---
|
||||
|
||||
## add_github_team_members.py
|
||||
|
||||
Adds cohort members to their corresponding GitHub teams in the `nhcarrigan-spring-2026-cohort` organisation. Leaders are added to both the main team and the corresponding `-leaders` sub-team; participants are added to the main team only.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → add_github_team_members.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
None. Uses the `gh` CLI for authentication (run `gh auth login` first).
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `team_assignments.json` | JSON object | Team rosters with leader/participant distinction |
|
||||
| `discord_to_github.json` | JSON object | Maps Discord user IDs to GitHub usernames |
|
||||
|
||||
---
|
||||
|
||||
## get_cohort_members.py
|
||||
|
||||
Fetches all Discord guild members with the Cohort role and writes their IDs, usernames, and display names to a JSON file. Also prints a formatted list to stdout.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → get_cohort_members.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
**Output** (written to `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `active_cohort_members.json` | JSON array | Objects with `id`, `username`, and `display_name` for each Cohort role member |
|
||||
|
||||
---
|
||||
|
||||
## check_member_status.py
|
||||
|
||||
Verifies whether specific Discord member IDs are still in the freeCodeCamp guild by querying the Discord API. Used to confirm that removed members have been successfully ejected.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → check_member_status.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
None. The member IDs to check are hardcoded in the script. Update the list before running.
|
||||
|
||||
---
|
||||
|
||||
## fetch_roster.py
|
||||
|
||||
Fetches pinned messages from a specific team channel to retrieve the current roster.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → fetch_roster.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
None. Output is printed to stdout as JSON.
|
||||
|
||||
### Notes
|
||||
|
||||
- The target channel ID is hardcoded. Update it before running.
|
||||
|
||||
---
|
||||
|
||||
## update_roster_messages.py
|
||||
|
||||
Edits the pinned team roster messages in each Discord channel with the latest data from `team_assignments.json` and `discord_to_github.json`. Run this after any membership changes to keep the pinned rosters up to date.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → update_roster_messages.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `team_message_ids.json` | JSON object | Channel and message IDs per team (output of `send_team_messages.py`) |
|
||||
| `team_assignments.json` | JSON object | Current team rosters |
|
||||
| `discord_to_github.json` | JSON object | Discord ID → GitHub username mapping |
|
||||
|
||||
---
|
||||
|
||||
## send_checkin.py
|
||||
|
||||
Sends biweekly check-in prompts to all team Discord channels (except Jade Jasmine), automatically creating threads for responses. Members who do not respond face removal for inactivity.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → send_checkin.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `team_message_ids.json` | JSON object | Channel IDs per team |
|
||||
|
||||
---
|
||||
|
||||
## send_team_checkin.py
|
||||
|
||||
Sends a capacity check-in message to each team channel asking whether the team feels able to complete their project with their current member count, and inviting them to request support if needed.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → send_team_checkin.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `team_message_ids.json` | JSON object | Channel IDs per team |
|
||||
| `team_assignments.json` | JSON object | Current team rosters (used to mention team members) |
|
||||
|
||||
---
|
||||
|
||||
## discord_activity_checker.py
|
||||
|
||||
Scans each team's Discord channel and threads to identify members who have not sent a message within the last 36 hours. Can optionally send notification messages directly to inactive members via the `--send` CLI flag.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Check only (no messages sent)
|
||||
make run
|
||||
# Select: Python → cohort → discord_activity_checker.py
|
||||
|
||||
# Check and notify inactive members
|
||||
cd python && op run --env-file=../prod.env -- uv run python cohort/discord_activity_checker.py --send
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `team_assignments.json` | JSON object | Member lists per team |
|
||||
|
||||
**Output** (written to `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `discord_activity_report.json` | JSON object | Inactive members per team with their last message timestamp |
|
||||
|
||||
---
|
||||
|
||||
## catch_up_report.py
|
||||
|
||||
Generates a detailed markdown activity report covering Discord messages (in team channels and their threads) and GitHub activity (PRs, issues, comments, reviews, commits) since a configured start date. Uses async API calls for efficiency.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → catch_up_report.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `team_assignments.json` | JSON object | Team rosters |
|
||||
| `discord_to_github.json` | JSON object | Discord ID → GitHub username mapping |
|
||||
|
||||
**Output** (written to `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `catch_up_report.md` | Markdown table | Activity counts per member (Discord messages + GitHub contributions) per team |
|
||||
|
||||
### Notes
|
||||
|
||||
- The report start date is hardcoded in the script. Update it before each use.
|
||||
- GitHub activity is fetched via the unauthenticated public API; rate limiting may apply for large cohorts.
|
||||
|
||||
---
|
||||
|
||||
## check_lengths.py
|
||||
|
||||
Dry-run validation that parses `catch_up_report.md` and formats each team's data into Discord monospace table strings, checking whether any would exceed Discord's 2,000-character message limit before actually sending them.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → check_lengths.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
None.
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `catch_up_report.md` | Markdown table | Output of `catch_up_report.py` |
|
||||
|
||||
### Notes
|
||||
|
||||
- Run this after `catch_up_report.py` and before `send_activity_report.py` to catch any messages that would be rejected by Discord.
|
||||
|
||||
---
|
||||
|
||||
## send_activity_report.py
|
||||
|
||||
Parses `catch_up_report.md` and sends the formatted activity table for each team to its Discord channel as a monospace code block.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → send_activity_report.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input** (expected in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `catch_up_report.md` | Markdown table | Output of `catch_up_report.py` |
|
||||
|
||||
### Notes
|
||||
|
||||
- Run `check_lengths.py` first to verify that no messages exceed Discord's character limit.
|
||||
|
||||
---
|
||||
|
||||
## remove_member.py
|
||||
|
||||
Comprehensive member removal script. Given a Discord ID as a CLI argument, it:
|
||||
|
||||
1. Removes the member from `team_assignments.json`.
|
||||
2. Removes the member from `discord_to_github.json`.
|
||||
3. Prints GitHub removal instructions.
|
||||
4. Removes the member's Discord Cohort and team roles.
|
||||
5. Sends an announcement message to the team's Discord channel.
|
||||
6. Outputs markdown notes suitable for pasting into `COHORT_NOTES.md`.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
cd python && op run --env-file=../prod.env -- uv run python cohort/remove_member.py <discord_id>
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input/Output** (read and updated in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `team_assignments.json` | JSON object | Updated: member removed from their team |
|
||||
| `discord_to_github.json` | JSON object | Updated: Discord→GitHub mapping removed |
|
||||
| `team_message_ids.json` | JSON object | Read: used to find the team's Discord channel ID |
|
||||
|
||||
---
|
||||
|
||||
## remove_resigned_members.py
|
||||
|
||||
Removes a list of resigned member Discord IDs from `team_assignments.json`, updating team rosters and reporting which teams were affected. Does not interact with Discord or GitHub.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → remove_resigned_members.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
None.
|
||||
|
||||
### Data Files
|
||||
|
||||
**Input/Output** (read and updated in `data/`):
|
||||
|
||||
| File | Format | Description |
|
||||
|---|---|---|
|
||||
| `team_assignments.json` | JSON object | Updated in place; affected teams are reported to stdout |
|
||||
|
||||
### Notes
|
||||
|
||||
- The list of Discord IDs to remove is hardcoded in the script. Update it before running.
|
||||
- This script only updates the local JSON file. Run `update_roster_messages.py` and handle GitHub/Discord role removal separately.
|
||||
|
||||
---
|
||||
|
||||
## remove_discord_roles.py
|
||||
|
||||
Removes the Cohort and team-specific Discord roles from a hardcoded list of inactive members.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Python → cohort → remove_discord_roles.py
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `DISCORD_BOT_TOKEN` | Discord bot token |
|
||||
|
||||
### Data Files
|
||||
|
||||
None. Member IDs and their team-to-role mappings are hardcoded in the script. Update them before running.
|
||||
|
||||
Reference in New Issue
Block a user