woodpecker/docs/versioned_docs/version-2.8/20-usage/51-plugins/20-creating-plugins.md

4.6 KiB

Creating plugins

Creating a new plugin is simple: Build a Docker container which uses your plugin logic as the ENTRYPOINT.

Settings

To allow users to configure the behavior of your plugin, you should use settings:.

These are passed to your plugin as uppercase env vars with a PLUGIN_ prefix. Using a setting like url results in an env var named PLUGIN_URL.

Characters like - are converted to an underscore (_). some_String gets PLUGIN_SOME_STRING. CamelCase is not respected, anInt get PLUGIN_ANINT.

Basic settings

Using any basic YAML type (scalar) will be converted into a string:

Setting Environment value
some-bool: false PLUGIN_SOME_BOOL="false"
some_String: hello PLUGIN_SOME_STRING="hello"
anInt: 3 PLUGIN_ANINT="3"

Complex settings

It's also possible to use complex settings like this:

steps:
  - name: plugin
    image: foo/plugin
    settings:
      complex:
        abc: 2
        list:
          - 2
          - 3

Values like this are converted to JSON and then passed to your plugin. In the example above, the environment variable PLUGIN_COMPLEX would contain {"abc": "2", "list": [ "2", "3" ]}.

Secrets

Secrets should be passed as settings too. Therefore, users should use from_secret.

Plugin library

For Go, we provide a plugin library you can use to get easy access to internal env vars and your settings. See https://codeberg.org/woodpecker-plugins/go-plugin.

Metadata

In your documentation, you can use a Markdown header to define metadata for your plugin. This data is used by our plugin index.

Supported metadata:

  • name: The plugin's full name
  • icon: URL to your plugin's icon
  • description: A short description of what it's doing
  • author: Your name
  • tags: List of keywords (e.g. [git, clone] for the clone plugin)
  • containerImage: name of the container image
  • containerImageUrl: link to the container image
  • url: homepage or repository of your plugin

If you want your plugin to be listed in the index, you should add as many fields as possible, but only name is required.

Example plugin

This provides a brief tutorial for creating a Woodpecker webhook plugin, using simple shell scripting, to make HTTP requests during the build pipeline.

What end users will see

The below example demonstrates how we might configure a webhook plugin in the YAML file:

steps:
  - name: webhook
    image: foo/webhook
    settings:
      url: https://example.com
      method: post
      body: |
        hello world        

Write the logic

Create a simple shell script that invokes curl using the YAML configuration parameters, which are passed to the script as environment variables in uppercase and prefixed with PLUGIN_.

#!/bin/sh

curl \
  -X ${PLUGIN_METHOD} \
  -d ${PLUGIN_BODY} \
  ${PLUGIN_URL}

Package it

Create a Dockerfile that adds your shell script to the image, and configures the image to execute your shell script as the main entrypoint.

# please pin the version, e.g. alpine:3.19
FROM alpine
ADD script.sh /bin/
RUN chmod +x /bin/script.sh
RUN apk -Uuv add curl ca-certificates
ENTRYPOINT /bin/script.sh

Build and publish your plugin to the Docker registry. Once published, your plugin can be shared with the broader Woodpecker community.

docker build -t foo/webhook .
docker push foo/webhook

Execute your plugin locally from the command line to verify it is working:

docker run --rm \
  -e PLUGIN_METHOD=post \
  -e PLUGIN_URL=https://example.com \
  -e PLUGIN_BODY="hello world" \
  foo/webhook

Best practices

  • Build your plugin for different architectures to allow many users to use them. At least, you should support amd64 and arm64.
  • Provide binaries for users using the local backend. These should also be built for different OS/architectures.
  • Use built-in env vars where possible.
  • Do not use any configuration except settings (and internal env vars). This means: Don't require using environment and don't require specific secret names.
  • Add a docs.md file, listing all your settings and plugin metadata (example).
  • Add your plugin to the plugin index using your docs.md (the example above in the index).