Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 23 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,26 @@ jobs:
gh release create "$GITHUB_REF_NAME" dist/*
--title "$GITHUB_REF_NAME"
--notes-file notes.md

- name: Announce on Slack
env:
WEBHOOK: ${{ secrets.RELEASE_SLACK_WEBHOOK_URL }}
RELEASE_URL: ${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}
run: |
if [ -z "$WEBHOOK" ]; then
echo "::warning::RELEASE_SLACK_WEBHOOK_URL is not set, skipping the announcement"
exit 0
fi
# Escape Slack's entities first (& < > are markup to it, so an unescaped
# "<SDK>" in a commit message would vanish), then markdown -> mrkdwn,
# which renders neither "### x" nor "**bold**". Truncated well under
# Slack's 40k text limit; the link carries the full notes either way.
body=$(sed -e 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g' notes.md \
| sed -E 's/^#+ +(.*)$/*\1*/; s/\*\*([^*]+)\*\*/*\1*/g' \
| head -c 3500)
jq -n --arg tag "$GITHUB_REF_NAME" --arg url "$RELEASE_URL" \
--arg repo "$GITHUB_REPOSITORY" --arg body "$body" \
'{text: ("*\($repo) \($tag)* released\n<\($url)|Release notes> · `uv add lighton-sdk`\n\n\($body)")}' \
> slack.json
curl -sS --fail-with-body -X POST -H 'Content-Type: application/json' \
--data @slack.json "$WEBHOOK"
23 changes: 20 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,28 @@ generalize speculatively for a shape only one subclass needs.
`DESC` (optional) becomes the **annotated tag message**, free-text release notes.
- The pushed tag fires `.github/workflows/release.yml`: it re-checks `tag == uv version`,
`uv build`s the sdist+wheel, runs **git-cliff** (`cliff.toml`, conventional-commit
grouping), prepends the annotated-tag message (the `DESC`) above the changelog, and
`gh release create`s with the artifacts attached.
grouping), prepends the annotated-tag message (the `DESC`) above the changelog,
publishes to PyPI, `gh release create`s with the artifacts attached, and finally
announces on Slack.
- **Changelog credits contributors** via `commit.author.name` in `cliff.toml`, which
squash-merged PRs carry from the PR author. Deliberately the git name and not a
GitHub `@handle`: a handle would auto-link in a release but needs `[remote.github]`
plus a token, and would make the changelog un-renderable offline. Note git author
names are whatever each contributor configured, so spelling can vary between commits.
- **Slack announcement** is the last step, posting the assembled notes to the
`RELEASE_SLACK_WEBHOOK_URL` repo secret. It **skips with a warning when the secret is
absent**, so a fork or a repo without Slack still releases cleanly. The notes are
markdown and Slack speaks mrkdwn, so the step escapes `& < >` first (they are markup
to Slack, and an unescaped `<SDK>` in a commit message would silently vanish), then
rewrites `### x` and `**bold**` to `*x*`, and caps the body well under Slack's 40k
limit; the linked release always carries the full text. The payload is built with
`jq --arg`, never string interpolation, so quotes and `$` in a commit message can't
break the JSON. It runs **after** the release exists, so a webhook failure can never
cost you the release, but it does fail the job loudly rather than announcing nothing
in silence.
- **Version is single-source:** `pyproject.toml`. `__version__` in `lighton/__init__.py`
reads it via `importlib.metadata.version("lighton")`, don't hard-code it back.
- Attach-wheels only; no PyPI publish yet (add `uv publish` + a trusted publisher when wanted).
- Artifacts are attached to the release **and** published to PyPI (`uv publish`, `PYPI_PUBLISH_TOKEN` secret).

## Conventions

Expand Down
7 changes: 6 additions & 1 deletion cliff.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# git-cliff — changelog from conventional commits. See https://git-cliff.org
#
# Contributor credit uses `commit.author.name`, the git author, which squash-merged
# PRs carry from the PR author. A GitHub @handle would auto-link in a release, but
# needs [remote.github] plus a token, and would leave the changelog un-renderable
# offline; the name is free and works everywhere.
[changelog]
header = ""
body = """
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{% for commit in commits %}
- {{ commit.message | upper_first }}\
- {{ commit.message | upper_first }}{% if commit.author.name %} ({{ commit.author.name }}){% endif %}\
{% endfor %}
{% endfor %}
"""
Expand Down