Announce harness releases on Twitter (#341)

* Announce harness releases on Twitter

Mirror pydantic-ai's post-release tweet so a PyPI publish also posts to
the shared @pydantic account, keeping release visibility consistent
across the workspace. Version is read from the tag ref since the
release job emits no version output.

Requires the TWITTER_* secrets to be provisioned on this repo.

* Scope send-tweet secrets to the release environment

zizmor's secrets-outside-env audit fails the lint job because the tweet
job reads the TWITTER_* secrets without a dedicated environment. Bind it
to the release environment, matching the release job's convention for
secret-using jobs (the harness has no zizmor ignore config like
pydantic-ai does).
This commit is contained in:
Aditya Vardhan
2026-07-09 08:45:46 -06:00
committed by GitHub
parent 545a703227
commit 1229858a57
+41
View File
@@ -263,3 +263,44 @@ jobs:
- run: uv build
- uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
send-tweet:
name: Send tweet
needs: [release]
if: needs.release.result == 'success'
runs-on: ubuntu-latest
environment: release
steps:
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.12'
- name: Install dependencies
run: pip install tweepy==4.14.0
- name: Send tweet
shell: python
run: |
import os
import tweepy
client = tweepy.Client(
access_token=os.getenv("TWITTER_ACCESS_TOKEN"),
access_token_secret=os.getenv("TWITTER_ACCESS_TOKEN_SECRET"),
consumer_key=os.getenv("TWITTER_CONSUMER_KEY"),
consumer_secret=os.getenv("TWITTER_CONSUMER_SECRET"),
)
version = os.getenv("VERSION")
tweet = os.getenv("TWEET").format(version=version)
client.create_tweet(text=tweet)
env:
# The tag ref (e.g. "v1.2.3") already carries the leading v, so it is
# used verbatim in both the message and the release URL.
VERSION: ${{ github.ref_name }}
TWEET: |
Pydantic AI Harness {version} is out! 🎉
https://github.com/pydantic/pydantic-ai-harness/releases/tag/{version}
TWITTER_CONSUMER_KEY: ${{ secrets.TWITTER_CONSUMER_KEY }}
TWITTER_CONSUMER_SECRET: ${{ secrets.TWITTER_CONSUMER_SECRET }}
TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}