New to Kestra?
Use blueprints to kickstart your first workflows.
Announce software releases on Bluesky automatically with Kestra. A CI webhook posts version and highlights as a skeet and confirms the post in Slack.
The release is not done when the artifact is published; it is done when the community knows. This blueprint closes that last step: the CI release job POSTs a small JSON payload to a Kestra webhook, io.kestra.plugin.bluesky.BlueskyExecution posts the announcement as an execution-notification skeet through your project's Bluesky account, and Slack confirms internally that the public post went out. Bluesky is where a growing share of developer communities now live, so treating it as a first-class release channel, automated like the rest of the pipeline, keeps announcements consistent and immediate.
Because the skeet is public the moment the task succeeds, the flow keeps the post text deliberately templated and short. Anything a human should review before publication belongs upstream in the CI job that builds the payload, not in ad-hoc edits after the fact. The plugin reinforces that discipline with a fixed post shape: every skeet opens with the execution state and flow id, carries the custom copy and the version, and closes with a link to the execution, so the community sees the release pipeline working in public.
release_webhook trigger (io.kestra.plugin.core.trigger.Webhook) exposes a URL your CI release job POSTs to with version and highlights in the JSON body.post_release (io.kestra.plugin.bluesky.BlueskyExecution) authenticates with the handle and app password from secrets and posts the announcement, carrying the highlights in customMessage and the version as a customFields entry. Both use {{ trigger.body.version ?? inputs.version }} style fallbacks, so a manual execution with inputs works exactly like a webhook-triggered one.RUNNING: company.team/bluesky-release-notes-post, then the custom message, a version: v1.2.3 line from the custom fields, and a closing link to the execution in the Kestra UI. Bluesky's 300-grapheme limit applies to that whole rendered post, not just the highlights.confirm_internally posts the version and execution id to Slack, so the team sees every public announcement in the release channel.errors block posts a distinct Slack alert when posting to Bluesky failed, because a release that shipped without its announcement is easy to miss otherwise.A curl call in CI could hit the Bluesky API too, but it would leave no execution history, no retry on a transient API error, no secret management for the app password, and no alert when the post silently fails. Kestra gives the announcement the same operational guarantees as the deployment itself: secrets stay in the secret store, every post is an auditable execution, and a failure pages the team instead of disappearing into a CI log.
BLUESKY_IDENTIFIER: the Bluesky handle, for example yourproject.bsky.social.BLUESKY_APP_PASSWORD: an app password generated in Bluesky settings.SLACK_WEBHOOK_URL: Slack incoming webhook URL.version and highlights in the body.customFields entry.post_release, as shown in the blog announcer blueprint.