mirror of
https://github.com/Sea-Haven-Industries/afterhours-shift-manager.git
synced 2026-09-30 23:03:11 +00:00
Version the bot continuously from CHANGELOG.md (the single source of truth for both the version and the staff-readable notes) and surface changes to users in two ways: - A new afterhours-release-notifier Lambda posts a "What's New" message to the shift channel on minor/major releases (patches stay silent). - The bot gains an App Home "About" tab showing what it does, the command list, and the current version's notes. release.yaml runs on Deploy success (not release:published — GITHUB_TOKEN events don't start downstream workflows), checks out the deployed commit, and tags + publishes a GitHub Release + invokes the notifier. It assumes a dedicated, boundary-carrying OIDC role scoped to InvokeFunction on the notifier; the account's cfn role gates role creation on that boundary. The manual Version Bump workflow is retired. A CI guard enforces that a CHANGELOG edit is a clean SemVer bump and that the in-package copy matches.
67 lines
2.1 KiB
Python
67 lines
2.1 KiB
Python
"""Tests for the release-notifier Lambda handler."""
|
|
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.fixture
|
|
def slack(notifier_app, monkeypatch):
|
|
"""Fake Slack WebClient; chat_postMessage returns a message ts."""
|
|
fake = MagicMock(name="slack")
|
|
fake.chat_postMessage.return_value = {"ts": "111.222"}
|
|
monkeypatch.setattr(notifier_app, "WebClient", MagicMock(return_value=fake))
|
|
monkeypatch.setattr(notifier_app, "get_secret", lambda _id: "xoxb-test")
|
|
return fake
|
|
|
|
|
|
@pytest.fixture
|
|
def env(monkeypatch):
|
|
monkeypatch.setenv(
|
|
"SLACK_BOT_TOKEN_SECRET", "afterhours-shift-manager/slack-bot-token"
|
|
)
|
|
monkeypatch.setenv("SHIFT_CHANNEL", "C_RELEASES")
|
|
|
|
|
|
def test_posts_announcement_to_channel(notifier_app, slack, env):
|
|
result = notifier_app.handler(
|
|
{
|
|
"version": "1.10.0",
|
|
"notes": "**Release notes** now self-announce.",
|
|
"date_label": "June 11, 2026",
|
|
},
|
|
None,
|
|
)
|
|
|
|
assert result == {"announced": True, "version": "1.10.0", "ts": "111.222"}
|
|
slack.chat_postMessage.assert_called_once()
|
|
kwargs = slack.chat_postMessage.call_args.kwargs
|
|
assert kwargs["channel"] == "C_RELEASES"
|
|
assert kwargs["text"] == "What's New — v1.10.0"
|
|
# Markdown was converted to Slack mrkdwn in the rendered blocks.
|
|
rendered = str(kwargs["blocks"])
|
|
assert "*Release notes*" in rendered
|
|
|
|
|
|
def test_uses_the_slack_bot_token_secret(notifier_app, slack, env, monkeypatch):
|
|
seen = {}
|
|
monkeypatch.setattr(
|
|
notifier_app, "get_secret", lambda sid: seen.setdefault("id", sid) or "xoxb"
|
|
)
|
|
notifier_app.handler({"version": "2.0.0", "notes": "Big."}, None)
|
|
assert seen["id"] == "afterhours-shift-manager/slack-bot-token"
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"event",
|
|
[
|
|
{},
|
|
{"version": "1.10.0"}, # missing notes
|
|
{"notes": "x"}, # missing version
|
|
{"version": "", "notes": "x"}, # empty version
|
|
],
|
|
)
|
|
def test_rejects_incomplete_event(notifier_app, slack, env, event):
|
|
with pytest.raises(ValueError):
|
|
notifier_app.handler(event, None)
|
|
slack.chat_postMessage.assert_not_called()
|