Skip to content

community: alert on help wanted labels, and test the send path - #18

Merged
usik-luke-trl merged 1 commit into
mainfrom
community/label-alerts
Oct 6, 2026
Merged

usik-luke-trl merged 1 commit into
mainfrom
community/label-alerts

Conversation

@usik-luke-trl

Copy link
Copy Markdown
Contributor

채널 매트릭스가 약속한 알림 5종 중 두 번째를 붙입니다. 저장소 웹훅은 이벤트 타입으로만 구독하고 라벨 필터가 없어서, 이건 Actions에서 돌아야 합니다.

help wanted와 good first issue만 메시지를 만듭니다. 나머지는 조용히 종료합니다 — 라벨 변경마다 알리는 채널은 사람들이 음소거합니다.

전송 경로에 테스트가 없었습니다

이게 핵심입니다. 웹훅이 설정돼 있지 않으면 모든 실제 실행이 "출력만" 분기를 타므로, 아무 데도 안 보내는 알림기와 잘 되는 알림기가 겉보기에 똑같습니다.

tools/test_chat.py가 덮습니다 — 목적지 우선순위(Discord/Slack/둘 다/없음), 플랫폼별 페이로드 모양, 그리고 urlopen을 스텁한 실제 POST (url·body·content-type·method 전부 검증).

tools/chat.py가 목적지 선택과 페이로드를 전담해서, Discord/Slack 결정이 한 곳에만 있습니다.

돌려보다 버그를 찾았습니다

GITHUB_EVENT_PATH가 없으면 Path("")가 현재 디렉터리가 되고, 디렉터리는 .exists()가 참이라 .을 읽으려다 IsADirectoryError가 납니다. 경로가 되기 전에 거르도록 고쳤고 회귀 테스트를 붙였습니다.

pull_request_target에 대해

리뷰어가 당연히 의심해야 할 트리거라 설명을 워크플로 안에 적어 뒀습니다.

issues: [labeled]는 PR에서 안 울리고, fork의 pull_request는 시크릿을 못 봅니다 — 외부 기여에 help wanted를 붙이는 바로 그 순간 웹훅이 비어버립니다.

여기서 안전한 이유는 actions/checkout에 ref를 주지 않아 base 커밋을 체크아웃하기 때문입니다. PR의 코드는 실행되지 않습니다. 다음에 이 파일을 건드릴 사람이 ref:를 추가할 사람이라, 그 제약을 트리거 바로 옆에 적었습니다.

검증

  • pytest tools/test_chat.py — 10 passed
  • ruff check . — All checks passed
  • 라벨 알림기를 실제 이벤트 페이로드 모양으로 수동 확인 (감시 대상 / 비대상 / 페이로드 없음 / 디렉터리)
  • 테스트를 pyproject.toml과 ci.yml 양쪽에 등록 — CI가 파일을 개별 지정해서, 안 하면 안 돌아갑니다

🤖 Generated with Claude Code

https://claude.ai/code/session_01K599fUWZZYdiL4ekUq4Vhs

Adds the second of the five alert kinds the channel matrix commits to. Repository
webhooks subscribe by event type and cannot filter on labels, so this has to run in
Actions where the label is in the event payload.

Only `help wanted` and `good first issue` produce a message. Everything else exits
quietly -- a channel that announces every label change is one people mute, and each
watched label is a promise that the channel will care.

tools/chat.py now owns destination selection and payload shape, shared by both
notifiers, so the Discord/Slack decision lives in one place and neither notifier
hard-codes a platform.

The send path had no test and could not get one from a live run: with no webhook
configured every real invocation takes the "print instead" branch, so a notifier that
posts nowhere looks exactly like one that works. tools/test_chat.py covers
destination precedence, both payload shapes, and an actual POST with urlopen stubbed
-- asserting url, body, content type and method.

Running it also found a bug before it shipped. With GITHUB_EVENT_PATH unset,
Path("") is the current directory and a directory passes .exists(), so the script
tried to read "." and raised IsADirectoryError. Now rejected before it becomes a
path, with a regression test.

On pull_request_target: `issues: [labeled]` does not fire for pull requests, and
`pull_request` from a fork cannot see secrets -- the webhook would be empty exactly
when an outside contribution gets marked help wanted. It is safe here because
actions/checkout with no `ref` takes the base commit, so no PR code runs. That
constraint is written in the workflow next to the trigger, since the next person to
touch it is the one who would add `ref:`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K599fUWZZYdiL4ekUq4Vhs
@usik-luke-trl
usik-luke-trl merged commit 4e788eb into main Oct 6, 2026
6 checks passed
@usik-luke-trl
usik-luke-trl deleted the community/label-alerts branch October 6, 2026 05:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant