Repository navigation
Conversation
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>
Pull request dashboard statusClosed · refreshed 2026-10-14 09:44 UTC Status above doesn't look right?
|
|
@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. |
|
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. |
|
@svrnm as discussed with @danielgblanco, let's create a central repo so we can run this workflow. The suggestion was |
|
superseded by open-telemetry/community#3775 code will be moved over there |
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>
* 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>
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
announcementsworkflow that distributes an announcement toLinkedIn, 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:
Design
title,text,url(plus optionalper-channel overrides). Channels, destinations, mode, and credentials are
caller configuration.
text+url,Slack gets
title+text+url, Groups.io usestitleas the subject.Each rendered message is checked against the channel's limit (Bluesky 300,
Mastodon 500, LinkedIn 3,000, Slack 40,000).
checkruns 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.deliverruns in the caller'sannouncementsenvironment, so requiredreviewers approve before any remote write.
check(default; validation only, suitable for pull requests),draft(native drafts in Buffer and Groups.io; Slack is previewed only), andpublish.self-repository action (
uses: $/.github/scripts/announcements), so nocaller checkout or floating ref is involved. actionlint 1.7.12 does not know
this syntax yet;
.github/actionlint.yamlignores that finding.(status, remote IDs, sanitized errors) is uploaded as an artifact.
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
363 characters including the URL; the limit is 300"); after shortening it,
the check passed.
requested approval, and created a Groups.io draft. Slack was previewed.
publish(/postdraft)publishThe 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