"""Lambda handler — announces a new release to the shift channel. Invoked by the release workflow (``.github/workflows/release.yaml``) once a minor or major version has been tagged *and* the new code has deployed successfully. The event carries the version and notes already extracted from CHANGELOG.md by the workflow, so this function never reads the changelog file itself (it ships only in the slack-bot package, not here). Event shape (the frozen contract between release.yaml and this function): {"version": "1.10.0", "notes": "", "date_label": "June 11, 2026"} """ import logging import os from slack_sdk import WebClient from shared.blocks import build_release_announcement_blocks from shared.secrets import get_secret logger = logging.getLogger() logger.setLevel(logging.INFO) def handler(event, context): event = event or {} version = event.get("version") notes = event.get("notes") date_label = event.get("date_label", "") if not version or not notes: raise ValueError("event requires non-empty 'version' and 'notes'") bot_token = get_secret(os.environ["SLACK_BOT_TOKEN_SECRET"]) channel_id = os.environ["SHIFT_CHANNEL"] slack = WebClient(token=bot_token) blocks = build_release_announcement_blocks(version, notes, date_label) result = slack.chat_postMessage( channel=channel_id, blocks=blocks, text=f"What's New — v{version}", ) logger.info("Announced v%s to %s (ts=%s)", version, channel_id, result["ts"]) return {"announced": True, "version": version, "ts": result["ts"]}