Skip to content
Draft
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
17 changes: 17 additions & 0 deletions .band/changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Per-repo config for the changelog-generator skill
# (changelog-generator@private-agent-skills), read from this repo's working tree
# at run time. NON-SECRET values only — secrets come from the workflow env:
# LINEAR_API_KEY, SLACK_WEBHOOK_URL, DISCORD_DRAFT_WEBHOOK_URL.

# Fern docs repo that receives the changelog PR (opened as a DRAFT for a human to review and merge).
fern_repo: band-ai/fern
# Path within the Fern repo where changelog entries live. Match the layout of the
# newest existing entry in that repo.
fern_changelog_path: fern/changelog/sdks

# Linear: how to find the issues that belong to this SDK's releases. The skill
# queries the Linear GraphQL API and also matches issue identifiers (e.g. SDK-123)
# found in the release's merged PRs. Set at least the team key.
linear:
team_key: INT
# project: "Python SDK" # optional: narrow further by project name
82 changes: 82 additions & 0 deletions .github/workflows/changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Changelog

# Publishes the release changelog when a GitHub Release is published (i.e. after
# release-please's release PR is merged on main). Runs the shared
# `changelog-generator` skill via the Claude Code Action, which:
# - reads merged Linear issues for the version (Linear GraphQL API)
# - opens a DRAFT PR to the Fern docs repo for a human to review and merge
# - posts the announcement to Slack (incoming webhook)
# - drafts the announcement into the private Discord review channel (webhook)
# - writes back a Linear Release + release notes (Linear GraphQL API)

on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Release tag to generate the changelog for (defaults to latest release)"
required: false
type: string

# Never run two changelog jobs for the same ref at once.
concurrency:
group: changelog-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read

jobs:
changelog:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0 # full history so the skill can diff the release range

- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v3
with:
client-id: ${{ secrets.APP_CLIENT_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: band-ai
# Scope the token to exactly the repos the skill touches. The App must
# be installed on every repo listed here.
repositories: |
band-sdk-python
fern # Fern docs repo (github.com/band-ai/fern)
private-agent-skills # private marketplace repo the skill is installed from

# The marketplace repo is private, so the action needs credentials to clone
# it. Rewrite only that repo's URL to use the App token (scoped narrowly so
# other github.com fetches are unaffected).
- name: Allow cloning the private marketplace repo
run: |
git config --global \
url."https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/band-ai/private-agent-skills".insteadOf \
"https://github.com/band-ai/private-agent-skills"

- name: Generate and publish changelog
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ steps.app-token.outputs.token }}
plugin_marketplaces: "https://github.com/band-ai/private-agent-skills.git"
plugins: "changelog-generator@private-agent-skills"
prompt: "/changelog-generator:generate ${{ github.event.release.tag_name || inputs.tag }}"
claude_args: |
--allowedTools "Bash,Read,Write,Edit,Glob,Grep"
--max-turns 30
env:
# gh CLI + git use this token for the source repo and the Fern docs repo.
GH_TOKEN: ${{ steps.app-token.outputs.token }}
# Slack: posted live to the announcement channel.
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
# Discord: drafted into the private review channel for a human to forward.
DISCORD_DRAFT_WEBHOOK_URL: ${{ secrets.DISCORD_DRAFT_WEBHOOK_URL }}
# Linear: read issues + write the Release entry via GraphQL.
LINEAR_API_KEY: ${{ secrets.LINEAR_API_KEY }}