Skip to main content
Plugins / Bluesky Post

Bluesky Post

Post statuses to Bluesky.


Bluesky Post plugin

Woodpecker plugin to post statuses to Bluesky.

Usage

image: woodpeckerci/plugin-bluesky-post
settings:
  identifier: woodpecker-ci.org
  app_password:
    from_secret: bluesky_app_password
  text: We just released {{ CI_COMMIT_TAG }} 🚀

Settings

Setting Description Required? Default
service_url Bluesky service url, including protocol. No https://bsky.social
identifier Your Bluesky handle (without @) or did Yes
app_password Your Bluesky app password (How to get an app password) Yes
text Text to post (Allows Templating and auto detects facets) Yes (if ai_token is not set)
files ,-separated paths or globs of images or a video, see Media No
media { path, alt, captions } list, instead of files, see Media No
languages ,-separated language codes (max 3), e.g. en not english No
tags ,-separated list of post tags No
ai_token Provide an AI token (OpenAI) to generate a post text Yes (if text is not set)
ai_model Select the model used to generate a post text No gpt-5-nano
ai_url Base URL of an OpenAI compatible API, e.g. Ollama No OpenAI
ai_prompt Prompt used to generate a post text. (Allows Templating) No prompt
changelog_file File to use for the AI to make a changelog from. No CHANGELOG.md

Media

A post can have either up to 4 JPEG, PNG, GIF or WebP images of at most 2 MB each, or one MP4 video of at most 300 MB.

files takes paths or globs like dist/*.png, and the path of each file is used as its alt text.

settings:
  files:
    - dist/screenshot.png
    - docs/release/*.png

To set your own alt texts, use media instead of files. Each entry needs a path, globs are not supported. The alt text allows Templating, and without it the path is used. Set alt: "" for purely decorative images. A video can have up to 20 WebVTT captions of at most 20 kB each, every one with a BCP 47 language tag.

settings:
  media:
    - path: dist/screenshot.png
      alt: The new dashboard, released in {{ CI_COMMIT_TAG }}
    - path: dist/logo.png
      alt: ''
settings:
  media:
    - path: dist/demo.mp4
      alt: A 30 second tour of the new dashboard
      captions:
        - lang: en
          path: dist/demo.en.vtt
        - lang: de
          path: dist/demo.de.vtt

Videos are uploaded through the Bluesky video service, which processes them before the post is created. Bluesky-hosted accounts need a verified email address to upload videos, and the number of videos per day is limited.

All files are checked before anything is posted, and every problem is reported at once.

Get app password

In order to get an app password, go to https://bsky.app/settings/app-passwords and create a new app password.

Templating

You can use {{ CI_COMMIT_TAG }} and other environment variables in the text or ai_prompt settings. The ai_prompt template can also use {{ CHANGELOG }} to include the changelog of the release. The app_password and ai_token values are never available as placeholders, and AI generated text is posted as is.

Self-hosted models

Any server with an OpenAI compatible chat/completions endpoint works, for example Ollama. ai_token still enables the AI and is sent as bearer token; a local Ollama ignores it, so any value will do.

image: woodpeckerci/plugin-bluesky-post
settings:
  identifier: woodpecker-ci.org
  app_password:
    from_secret: bluesky_app_password
  ai_url: http://ollama:11434/v1
  ai_token: unused
  ai_model: llama3.2

Default AI prompt

Used when ai_prompt is not set. Copy of the prompt defined in src/utils.ts:

We want to announce the next version of our app on Bluesky.
Write a catchy post, so users will know why they should update to the newest
version. If there is no special feature included, just summarize the changes
in a few sentences. Reply with the post text only, at most 300 characters long.

The changelog entry: {{ changelog }}