Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
6ed7a0a
Major refactor for notification system
robbykap Feb 13, 2026
27aa6c6
Fix action paths
robbykap Feb 13, 2026
963d88b
Update mdxcanvas_automation.yaml
robbykap Feb 13, 2026
c61eb59
Fix paths
robbykap Feb 13, 2026
9ad268b
Revert "Fix paths"
robbykap Feb 13, 2026
71fea04
Update mdxcanvas_automation.yaml
robbykap Feb 13, 2026
9c33d8e
Update mdxcanvas_automation.yaml
robbykap Feb 13, 2026
fee6ec8
Update mdxcanvas_automation.yaml
robbykap Mar 4, 2026
3e2fb33
Update mdxcanvas_automation.yaml
robbykap Mar 4, 2026
0009f21
Update mdxcanvas_automation.yaml
robbykap Mar 4, 2026
191a83a
Update formatting_utils.py
robbykap Mar 4, 2026
3e3834b
Update formatting_utils.py
robbykap Mar 4, 2026
7d94cf4
Update formatting_utils.py
robbykap Mar 4, 2026
7b7ccaf
Update .gitignore
robbykap Apr 1, 2026
38f5f4a
Redesign course notifications as plain text
robbykap Apr 1, 2026
556616a
Fix reusable workflow checkout refs
robbykap Apr 1, 2026
1508b63
Add explicit utils_ref for reusable workflow tests
robbykap Apr 1, 2026
a0b4b37
Install markdowndata for course notifications
robbykap Apr 1, 2026
0ddf516
Polish Discord course notification layout
robbykap Apr 1, 2026
188f9fb
Redesign notification UI as hybrid embed + plain text
robbykap Apr 1, 2026
03e34c9
Move Canvas/Docker notifications to rich embeds
robbykap Apr 1, 2026
280e13c
Add whitespace and block quotes to embed fields
robbykap Apr 1, 2026
db7275f
Add spacer fields between major embed sections
robbykap Apr 1, 2026
e79b891
Split long item lists across multiple fields for Discord limits
robbykap Apr 1, 2026
9d5465e
Use visible separator line for spacers between embed sections
robbykap Apr 1, 2026
5309ca1
Stack two invisible spacer fields for visible gap between sections
robbykap Apr 1, 2026
2b74728
Fix emoji mapping: case-insensitive lookup + add missing types
robbykap Apr 1, 2026
ad80857
Remove type label from item lines, keep emoji only
robbykap Apr 1, 2026
159e4ef
Use thumbtack emoji for all items with type labels
robbykap Apr 1, 2026
5b8c77a
Add discord_limits module with constants, calc_embed_size, split_content
robbykap Apr 8, 2026
024f183
Add EmbedBuilder to discord_limits.py with tests
robbykap Apr 8, 2026
e9bf8ca
Fix double-counting bug in EmbedBuilder.can_add_field
robbykap Apr 8, 2026
5d065ad
Tasks 5 & 6: strip send_notification.py and formatting_utils.py to th…
robbykap Apr 8, 2026
cf7829a
Rewrite canvas_format with tabulate overview and limit-aware builders
robbykap Apr 8, 2026
8d352ab
Rewrite docker_format.py with MessageBuilder, simplify send_course.py…
robbykap Apr 8, 2026
2aa6ca9
Add integration tests with real payload and edge cases
robbykap Apr 8, 2026
7c6d6dc
Update mdxcanvas_automation.yaml
robbykap Apr 8, 2026
54bdbf8
Update canvas_format.py
robbykap Apr 8, 2026
12d2dbf
Update canvas_format.py
robbykap Apr 8, 2026
39bc745
Finalized discord notifications for docker and mdxcanvas
robbykap Apr 14, 2026
bc4117f
fixed cicd for docker
robbykap Apr 14, 2026
2cfa55f
Remove PyPI notification migration from PR
robbykap Apr 15, 2026
a1472b0
Over View -> Overview
robbykap Apr 15, 2026
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
Binary file added .DS_Store
Binary file not shown.
64 changes: 64 additions & 0 deletions .github/actions/send-course-notification/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Send Course Notification
description: Create fallback output if needed and send course notification to Discord

inputs:
notification-type:
description: "Type of notification: 'canvas' or 'docker'"
required: true
output-type:
description: "Output type for fallback: 'MDXCanvas' or 'Docker'"
required: true
payload-path:
description: "Path to the output JSON file"
required: true
stdout-log:
description: "Path to stdout log file"
required: true
stderr-log:
description: "Path to stderr log file"
required: true
course-id:
description: "Course ID"
required: true
course-name:
description: "Course name"
required: true
course-url:
description: "Course URL"
required: true
discord-role:
description: "Discord CI/CD role ID"
required: true
discord-webhook-url:
description: "Discord webhook URL"
required: true

runs:
using: composite
steps:
- name: Create fallback output if needed
shell: bash
run: |
PYTHONPATH=utils python -m notifications.fallback \
--output-type "${{ inputs.output-type }}" \
--output-path "${{ inputs.payload-path }}" \
--stdout-log "${{ inputs.stdout-log }}" \
--stderr-log "${{ inputs.stderr-log }}" \
--action-url "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"

- name: Send course notification to Discord
shell: bash
env:
DISCORD_WEBHOOK_URL: ${{ inputs.discord-webhook-url }}
run: |
PYTHONPATH=utils python -m notifications.send_course \
--type "${{ inputs.notification-type }}" \
--payload "${{ inputs.payload-path }}" \
--course-id "${{ inputs.course-id }}" \
--course-name "${{ inputs.course-name }}" \
--course-url "${{ inputs.course-url }}" \
--author "${{ github.actor }}" \
--author-icon "https://github.com/${{ github.actor }}.png" \
--branch "${{ github.ref_name }}" \
--cicd-id "${{ inputs.discord-role }}" \
--action-url "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
59 changes: 28 additions & 31 deletions .github/workflows/docker_automation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ on:
course_id:
required: true
type: string
course_name:
required: true
type: string
course_url:
required: true
type: string
utils_ref:
required: false
default: main
type: string
secrets:
discord_role:
required: true
Expand Down Expand Up @@ -35,8 +45,13 @@ jobs:
uses: actions/checkout@v4
with:
repository: BYU-CS-Course-Ops/utils
ref: ${{ inputs.utils_ref }}
path: utils

- name: Install notification dependencies
shell: bash
run: pip install discord-webhook markdowndata ${{ inputs.extra-packages }}

- name: Get changed files
run: |
files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }})
Expand Down Expand Up @@ -72,35 +87,17 @@ jobs:
--root-dir "${{ github.workspace }}" \
> "$STDOUT_LOG" 2> "$STDERR_LOG"

- name: Create fallback output if needed
- name: Send course notification
if: always()
run: |
python utils/course_updates/create_fallback.py \
--output-type Docker \
--output-path "${{ github.workspace }}/.github/logs/docker_output.json" \
--stdout-log "${{ github.workspace }}/.github/logs/docker_stdout.log" \
--stderr-log "${{ github.workspace }}/.github/logs/docker_stderr.log" \
--action-url "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"

- name: Get user avatar
run: |
AVATAR_URL=$(curl -s https://api.github.com/users/${{ github.actor }} | jq -r '.avatar_url')
echo "AVATAR_URL=$AVATAR_URL" >> $GITHUB_ENV

- name: Install discord_webhook
run: |
pip install discord-webhook

- name: Send Discord Notification
env:
DISCORD_WEBHOOK_URL: ${{ secrets.discord_webhook_url }}
run: |
python utils/course_updates/send_course_notification.py \
--type "docker" \
--payload "${{ github.workspace }}/.github/logs/docker_output.json" \
--course-id "${{ inputs.course_id }}" \
--author "${{ github.actor }}" \
--author-icon "$AVATAR_URL" \
--branch "${{ github.ref }}" \
--cicd-id "${{ secrets.discord_role }}" \
--action-url "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
uses: ./utils/.github/actions/send-course-notification
with:
notification-type: docker
output-type: Docker
payload-path: ${{ github.workspace }}/.github/logs/docker_output.json
stdout-log: ${{ github.workspace }}/.github/logs/docker_stdout.log
stderr-log: ${{ github.workspace }}/.github/logs/docker_stderr.log
course-id: ${{ inputs.course_id }}
course-name: ${{ inputs.course_name }}
course-url: ${{ inputs.course_url }}
discord-role: ${{ secrets.discord_role }}
discord-webhook-url: ${{ secrets.discord_webhook_url }}
70 changes: 37 additions & 33 deletions .github/workflows/mdxcanvas_automation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ on:
course_id:
required: true
type: string
course_name:
required: true
type: string
course_url:
required: true
type: string
utils_ref:
required: false
default: main
type: string
mdxcanvas_version:
required: true
type: string
Expand Down Expand Up @@ -43,7 +53,7 @@ jobs:
OUTPUT_PATH: ${{ github.workspace }}/.github/logs/mdxcanvas_output.json

steps:
- name: Checkout repos
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0
Expand All @@ -53,12 +63,18 @@ jobs:
uses: actions/checkout@v4
with:
repository: BYU-CS-Course-Ops/utils
ref: ${{ inputs.utils_ref }}
path: utils

- name: Setup
run: |
mkdir -p "$LOGS_DIR"
pip install mdxcanvas==${{ inputs.mdxcanvas_version }} discord-webhook
- name: Install MDXCanvas
run: pip install mdxcanvas==${{ inputs.mdxcanvas_version }}

- name: Install notification dependencies
shell: bash
run: pip install discord-webhook markdowndata tabulate ${{ inputs.extra-packages }}

- name: Create logs directory
run: mkdir -p "$LOGS_DIR"

- name: Run MDXCanvas
id: mdxcanvas
Expand All @@ -80,36 +96,24 @@ jobs:
> "$LOGS_DIR/mdxcanvas.stdout.log" \
2> "$LOGS_DIR/mdxcanvas.stderr.log"

- name: Process results and notify
env:
DISCORD_WEBHOOK_URL: ${{ secrets.discord_webhook_url }}
- name: Print debug logs
run: |
echo "=== MDXCanvas STDOUT ==="
cat "$LOGS_DIR/mdxcanvas.stdout.log"

echo "=== MDXCanvas STDERR ==="
cat "$LOGS_DIR/mdxcanvas.stderr.log"

# Create fallback if needed
python utils/course_updates/create_fallback.py \
--output-type MDXCanvas \
--output-path "$OUTPUT_PATH" \
--stdout-log "$LOGS_DIR/mdxcanvas.stdout.log" \
--stderr-log "$LOGS_DIR/mdxcanvas.stderr.log" \
--action-url "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"

echo "=== Updated Output ==="
cat "$OUTPUT_PATH"

# Get avatar and send notification
AVATAR_URL=$(curl -s "https://api.github.com/users/${{ github.actor }}" | jq -r '.avatar_url')

python utils/course_updates/send_course_notification.py \
--type "canvas" \
--payload "$OUTPUT_PATH" \
--course-id "${{ inputs.course_id }}" \
--author "${{ github.actor }}" \
--author-icon "$AVATAR_URL" \
--branch "${{ github.ref }}" \
--cicd-id "${{ secrets.discord_role }}" \
--action-url "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"

- name: Send course notification
uses: ./utils/.github/actions/send-course-notification
with:
notification-type: canvas
output-type: MDXCanvas
payload-path: ${{ env.OUTPUT_PATH }}
stdout-log: ${{ env.LOGS_DIR }}/mdxcanvas.stdout.log
stderr-log: ${{ env.LOGS_DIR }}/mdxcanvas.stderr.log
course-id: ${{ inputs.course_id }}
course-name: ${{ inputs.course_name }}
course-url: ${{ inputs.course_url }}
discord-role: ${{ secrets.discord_role }}
discord-webhook-url: ${{ secrets.discord_webhook_url }}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.pyc
.idea/
test_notification.py
test_notification.py
.claude/worktrees/
28 changes: 16 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ on:

jobs:
docker_automation:
uses: BYU-CS-Course-Ops/utils/.github/workflows/docker_automation.yaml@main
with:
course_id: "235"
secrets:
discord_role: ${{ secrets.CICD_NOTIFY_DISCORD_ROLE }}
docker_user: ${{ secrets.DOCKER_USER }}
uses: BYU-CS-Course-Ops/utils/.github/workflows/docker_automation.yaml@main
with:
course_id: "235"
course_name: "CS 235 Spring 2025"
course_url: "https://example.com/courses/cs235"
secrets:
discord_role: ${{ secrets.CICD_NOTIFY_DISCORD_ROLE }}
docker_user: ${{ secrets.DOCKER_USER }}
docker_password: ${{ secrets.DOCKER_PASSWORD }}
discord_webhook_url: ${{ secrets.GHA_235_DISCORD_WEBHOOK }}
```
Expand All @@ -32,12 +34,14 @@ on:

jobs:
update-canvas:
uses: BYU-CS-Course-Ops/utils/.github/workflows/mdxcanvas_automation.yaml@main
with:
course_id: "235"
mdxcanvas_version: "0.3.0"
course_info_path: "_canvas-material/course-info/cs235_sp2025.json"
global_args_path: "_canvas-material/global_args.json"
uses: BYU-CS-Course-Ops/utils/.github/workflows/mdxcanvas_automation.yaml@main
with:
course_id: "235"
course_name: "CS 235 Spring 2025"
course_url: "https://example.com/courses/cs235"
mdxcanvas_version: "0.3.0"
course_info_path: "_canvas-material/course-info/cs235_sp2025.json"
global_args_path: "_canvas-material/global_args.json"
canvas_css_path: "_canvas-material/canvas.css" # Optional
template_path: "_canvas-material/course.canvas.md.xml.jinja"
secrets:
Expand Down
Loading