Skip to content

Add reusable announcements workflow - #461

Closed
svrnm wants to merge 1 commit into
open-telemetry:mainfrom
svrnm:feat/announcement-workflow
Closed

svrnm wants to merge 1 commit into
open-telemetry:mainfrom
svrnm:feat/announcement-workflow

Conversation

@svrnm

@svrnm svrnm commented Oct 13, 2026

Copy link
Copy Markdown
Member

Note

Large parts of this PR were generated with AI (Claude Code): most of the
code, the tests, and the documentation. I directed the design, made the
decisions described below, and ran the end-to-end tests listed under
Testing. Please review it with that in mind; feedback on anything that
looks off is very welcome.

Summary

Adds a reusable announcements workflow that distributes an announcement to
LinkedIn, Bluesky, and Mastodon (through Buffer), Slack (through a Workflow
Builder webhook), and mailing lists (through the Groups.io API).

The first use case is opentelemetry.io: after a blog post is deployed, announce
it on every channel with a short blurb and a link. The blurb lives in the post's
front matter and is reviewed in the blog PR:

announcement:
  text: >-
    The Collector reached v1.0! Here is what stability means for you.

Design

  • Payload vs. config. The payload is title, text, url (plus optional
    per-channel overrides). Channels, destinations, mode, and credentials are
    caller configuration.
  • One structure for every channel. Buffer channels get text + url,
    Slack gets title + text + url, Groups.io uses title as the subject.
    Each rendered message is checked against the channel's limit (Bluesky 300,
    Mastodon 500, LinkedIn 3,000, Slack 40,000).
  • Two jobs. check runs without an environment or secrets: it validates,
    renders each message to the job summary, and can wait until the URL returns
    200 (wait_for_url_minutes), so posts are only announced once deployed.
    deliver runs in the caller's announcements environment, so required
    reviewers approve before any remote write.
  • Modes. check (default; validation only, suitable for pull requests),
    draft (native drafts in Buffer and Groups.io; Slack is previewed only), and
    publish.
  • Code from the workflow's own commit. Delivery code is loaded with a
    self-repository action (uses: $/.github/scripts/announcements), so no
    caller checkout or floating ref is involved. actionlint 1.7.12 does not know
    this syntax yet; .github/actionlint.yaml ignores that finding.
  • No automatic write retries, no deduplication. A per-destination report
    (status, remote IDs, sanitized errors) is uploaded as an artifact.
  • Python standard library only; 37 unit tests run in announcements-test.yml.

The README documents the opentelemetry.io caller (front matter contract, a PR
check workflow, and an announce-on-push workflow). That integration will be a
separate PR in opentelemetry.io.

Testing

End to end in a test repository with a Hugo site on Netlify, drafts only:
https://github.com/svrnm/announcements-playground

  • A PR with a blurb that is too long failed the check ("bluesky message is
    363 characters including the URL; the limit is 300"); after shortening it,
    the check passed.
  • After merge, the workflow derived the post URL, waited for the deploy,
    requested approval, and created a Groups.io draft. Slack was previewed.
Path Live status
Groups.io drafts Verified on groups.io
Groups.io publish (/postdraft) Not yet verified
Buffer drafts and publish Not yet verified
Slack Webhook accepts the payload; delivery to a channel not yet confirmed

The unverified paths are covered by unit tests with mocked requests and are
marked as experimental in the README.

Visibility

In a public caller, logs, job summaries, and the report artifact are public;
only credentials are secret. The README says not to use the workflow for
embargoed content from a public repository.

🤖 Generated with Claude Code

Distributes an announcement (title, text, url) to LinkedIn, Bluesky, and
Mastodon through Buffer, to Slack through a Workflow Builder webhook, and to
mailing lists through the Groups.io API. Every channel renders the same
structure, and each rendered message is checked against the channel's
length limit.

The workflow runs in two jobs. `check` has no environment and no secrets:
it validates and renders the announcement and can wait until its URL is
live. `deliver` runs in the caller's environment, so required reviewers
approve before any remote write. Modes are `check` (validate only, for pull
requests), `draft` (native drafts in Buffer and Groups.io), and `publish`.

Delivery code is loaded from the workflow's own commit through a
self-repository action (`uses: $/...`). Reports record status and remote IDs
per destination; there are no automatic write retries.

The README documents an opentelemetry.io caller that announces blog posts
with an `announcement` front matter block once they are deployed.

Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>
@svrnm
svrnm requested a review from a team as a code owner October 13, 2026 09:09
@svrnm
svrnm requested review from trask and a balanced review from Copilot and removed request for Copilot October 13, 2026 09:09
@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Pull request dashboard status

Closed · refreshed 2026-10-14 09:44 UTC

Status above doesn't look right?
  • Anything look wrong? Report it with what you expected; it helps us improve the dashboard.

@svrnm

svrnm commented Oct 13, 2026

Copy link
Copy Markdown
Member Author

@open-telemetry/docs-approvers @open-telemetry/social-media-approvers @open-telemetry/sig-end-user-approvers please take a look as I assume you all to become consumers of that. I spend some cycles (tokens) on building this out and testing it.

@trask

trask commented Oct 13, 2026

Copy link
Copy Markdown
Member

hey @svrnm! is there another repo currently wanting this outside of opentelemetry.io?

@svrnm

svrnm commented Oct 13, 2026

Copy link
Copy Markdown
Member Author

hey @svrnm! is there another repo currently wanting this outside of opentelemetry.io?

I would like to find a second repo (community, a special one) where we can drive postings from across the whole org, so SIGs can do postings more easily and on their own. Also end user SIG is currently doing social media postings, so they could leverage it the same way.

@avillela

Copy link
Copy Markdown

@svrnm as discussed with @danielgblanco, let's create a central repo so we can run this workflow. The suggestion was opentelemetry-announcements. We could also use this as the "book of record" for all social posts going forward.

@svrnm

svrnm commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

superseded by open-telemetry/community#3775 code will be moved over there

@svrnm svrnm closed this Oct 14, 2026
svrnm added a commit to svrnm/opentelemetry-announcements that referenced this pull request Oct 26, 2026
Ports the delivery code from open-telemetry/shared-workflows#461 to the
announcement file format. When a file is added under announcements/, a
workflow checks and previews it without credentials, waits for approval of
the announcements environment, then:

- posts to Bluesky, Mastodon and LinkedIn through Buffer, with the image
  and its alt text, and schedules the follow-ups at their publish_at time
- sends the Slack text through a Workflow Builder webhook
- posts the mailing list email through the Groups.io API

Modes are check, draft and publish; merges use the ANNOUNCEMENT_MODE
variable and default to draft until the delivery paths are verified.
Writes are not retried, and a report of every delivery is uploaded.

The README now documents the file format, the checks, publishing, and
the setup of the environment, secrets, targets and Slack workflow.

Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>
svrnm added a commit to open-telemetry/opentelemetry-announcements that referenced this pull request Oct 28, 2026
* Add announcement schema and CI check

Adds a JSON Schema for announcement YAML files, an example, and a
workflow that checks announcements/**/*.yaml and examples/**/*.yaml:

- structure against the schema
- character limits per channel (links count as 23 characters)
- image files exist
- in pull requests, for new or changed announcements: publish_at is in
  the future (error) and links are reachable (warning)

Problems are reported as annotations on the line where they occur.

Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>

* Count punctuation after links and report invalid URLs

- Punctuation right after a link (like a full stop) now counts toward the
  length limit.
- A malformed URL is reported as a warning instead of crashing the check.

Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>

* Publish announcements to their channels

Ports the delivery code from open-telemetry/shared-workflows#461 to the
announcement file format. When a file is added under announcements/, a
workflow checks and previews it without credentials, waits for approval of
the announcements environment, then:

- posts to Bluesky, Mastodon and LinkedIn through Buffer, with the image
  and its alt text, and schedules the follow-ups at their publish_at time
- sends the Slack text through a Workflow Builder webhook
- posts the mailing list email through the Groups.io API

Modes are check, draft and publish; merges use the ANNOUNCEMENT_MODE
variable and default to draft until the delivery paths are verified.
Writes are not retried, and a report of every delivery is uploaded.

The README now documents the file format, the checks, publishing, and
the setup of the environment, secrets, targets and Slack workflow.

Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>

* Count lengths per channel and queue delivery runs

Count post length the way Buffer validates it for each channel: links
as 23 on Mastodon and 24 on LinkedIn, with text in UTF-16 code units;
links as their host plus up to 16 characters on Bluesky; links in full
on Slack.

Queue waiting delivery runs instead of replacing the pending one, so
a push's announcements aren't lost while an earlier run awaits approval.

Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants