Skip to main content
Plugins / mastodon-profile

mastodon-profile

by Woodpecker Authors

Keep a Mastodon profile in sync with your repository.


Overview

Describe the Mastodon profile your project should have, and the plugin makes the account match it.

The step is declarative. It reads the account's current profile, compares it to what you declared, and sends only the difference. Running it twice changes nothing the second time, and anything you leave out of the settings is left untouched on the server.

Features

  • Declarative profile: display name, bio and the metadata field table
  • Own the whole field table with fields, or just single entries with update_fields
  • Sends only what differs, and logs the difference it found
  • dry_run to see that difference without changing anything
  • {{ CI_COMMIT_TAG }} and other environment placeholders in any text setting

Simple Example

Keep one profile field current on every release, without touching the rest of the profile:

when:
  - event: tag

steps:
  mastodon:
    image: docker.io/woodpeckerci/plugin-mastodon-profile
    settings:
      server_url: https://floss.social
      access_token:
        from_secret: mastodon_token
      update_fields:
        - name: Version
          value: '{{ CI_COMMIT_TAG }}'

Settings

Settings Name Default Description
server_url Mastodon server URL, including the scheme. Required.
access_token Access token, see below. Required.
display_name unset Display name shown above the handle.
note unset Bio.
fields unset The whole metadata table. See below.
update_fields unset Single metadata entries. See below.
locked unset Whether the account requires follow requests.
bot unset Whether the account is flagged as a bot.
discoverable unset Whether the account is listed in the profile directory.
dry_run false Log the difference without sending it.
log_level info error, warn, info, debug or trace.

A setting left unset is not compared and not sent, so the step only owns the parts of the profile you declare. A setting that is written but empty is a mistake rather than an omission: fields and update_fields have to be a list, and locked, bot and discoverable have to say true or false.

note, fields and update_fields are compared against the unformatted copy Mastodon returns for the account's owner. A server that does not return it fails the step when one of them is declared, instead of guessing the current value and overwriting what it could not see.

Access token

Open your account's settings, go to Development and create a new application with the read:accounts and write:accounts scopes. Copy the value shown as Your access token and store it as a Woodpecker secret.

Restrict the secret to the events the step runs on, so a pull request from a fork cannot read it.

Fields

A stock Mastodon account holds four profile fields; some servers allow more. The server enforces its own limit and fails the step when a declaration goes past it. There are two ways to declare fields, and a step uses one or the other, never both.

update_fields owns only the entries it names. A matching field takes the new value and keeps its position, a name the account does not have yet is appended, and everything else is left exactly as it is. Use this when the profile is maintained by hand and the pipeline only owns one line of it.

settings:
  update_fields:
    - name: Version
      value: '{{ CI_COMMIT_TAG }}'

fields owns the whole table, in display order. A field you remove from the list is removed from the profile, and an empty list clears the table. Use this when the pipeline is the only thing that writes the profile.

Every entry needs a name. A value may be empty: the field is then kept, or created, with nothing in it.

settings:
  fields:
    - name: Version
      value: '{{ CI_COMMIT_TAG }}'
    - name: Docs
      value: https://woodpecker-ci.org

Names are matched without regard to case, and the spelling already on the account wins: update_fields with VERSION rewrites an existing Version rather than adding a second entry.

Leave both settings out to keep the table as it is.

Templating

Any text setting may contain {{ VARIABLE }} placeholders, which are replaced with that environment variable. Every CI_* variable is available, so {{ CI_COMMIT_TAG }} becomes the tag being released. An unknown name is left in place rather than replaced with nothing, so a typo is visible in the result.

Text is compared the way Mastodon stores it: leading and trailing whitespace is dropped, and a field name or value is cut to 255 characters. A note: | block ends in a newline, and without this would count as a change on every run.

Advanced Example

when:
  - event: tag
    evaluate: 'not (CI_COMMIT_TAG contains "rc")'

steps:
  mastodon:
    image: docker.io/woodpeckerci/plugin-mastodon-profile
    settings:
      server_url: https://floss.social
      access_token:
        from_secret: mastodon_token
      display_name: Woodpecker CI
      note: |
        Simple yet powerful CI/CD engine with great extensibility.
        Latest release: {{ CI_COMMIT_TAG }}
      bot: true
      discoverable: true
      # the pipeline owns the whole table here
      fields:
        - name: Version
          value: '{{ CI_COMMIT_TAG }}'
        - name: Website
          value: https://woodpecker-ci.org
        - name: Source
          value: https://codeberg.org/woodpecker-ci/woodpecker
        - name: Chat
          value: https://matrix.to/#/#woodpecker:matrix.org

Release candidates are filtered out with when, so the profile keeps pointing at the last stable release.