woodpecker/docs/docs/20-usage/51-plugins/20-creating-plugins.md

140 lines
4.6 KiB
Markdown
Raw Normal View History

# 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:
```yaml
steps:
2024-01-22 07:18:50 +00:00
- 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
Bump follow-redirects and fix broken anchors (#3488) - Bump `follow-redirects` to fix sec scan - Remove archived plugin `Chart releaser` - Fix broken anchors ``` Exhaustive list of all broken anchors found: - Broken anchor on source page path = /docs/0.15/administration/agent-config: -> linking to /docs/0.15/usage/pipeline-syntax#step-when---conditional-execution - Broken anchor on source page path = /docs/0.15/development/docs: -> linking to /docs/0.15/development/getting-started#nodejs--yarn - Broken anchor on source page path = /docs/0.15/development/ui: -> linking to /docs/0.15/development/getting-started#nodejs--yarn -> linking to /docs/0.15/development/getting-started#debugging - Broken anchor on source page path = /docs/1.0/development/ui: -> linking to /docs/1.0/development/getting-started#debugging - Broken anchor on source page path = /docs/2.0/administration/agent-config: -> linking to /docs/2.0/administration/backends/kubernetes#configuration - Broken anchor on source page path = /docs/2.0/administration/server-config: -> linking to forges/github#configuration (resolved as: /docs/2.0/administration/forges/github#configuration) - Broken anchor on source page path = /docs/2.0/development/ui: -> linking to /docs/2.0/development/getting-started#debugging - Broken anchor on source page path = /docs/2.0/usage/matrix-workflows: -> linking to /docs/2.0/administration/backends/kubernetes#nodeSelector - Broken anchor on source page path = /docs/2.1/administration/agent-config: -> linking to /docs/2.1/administration/backends/kubernetes#configuration - Broken anchor on source page path = /docs/2.1/development/ui: -> linking to /docs/2.1/development/getting-started#debugging - Broken anchor on source page path = /docs/2.1/usage/matrix-workflows: -> linking to /docs/2.1/administration/backends/kubernetes#nodeSelector - Broken anchor on source page path = /docs/2.2/administration/agent-config: -> linking to /docs/2.2/administration/backends/local#further-configuration - Broken anchor on source page path = /docs/2.2/development/ui: -> linking to /docs/2.2/development/getting-started#debugging - Broken anchor on source page path = /docs/2.2/usage/matrix-workflows: -> linking to /docs/2.2/administration/backends/kubernetes#nodeSelector - Broken anchor on source page path = /docs/next/administration/agent-config: -> linking to /docs/next/administration/backends/local#further-configuration - Broken anchor on source page path = /docs/next/development/ui: -> linking to /docs/next/development/getting-started#debugging - Broken anchor on source page path = /docs/next/usage/matrix-workflows: -> linking to /docs/next/administration/backends/kubernetes#nodeSelector - Broken anchor on source page path = /docs/next/usage/plugins/creating-plugins: -> linking to /docs/next/usage/secrets#use-secrets-in-settings - Broken anchor on source page path = /docs/administration/agent-config: -> linking to /docs/administration/backends/local#further-configuration - Broken anchor on source page path = /docs/development/ui: -> linking to /docs/development/getting-started#debugging - Broken anchor on source page path = /docs/usage/matrix-workflows: -> linking to /docs/administration/backends/kubernetes#nodeSelector ```
2024-03-15 10:56:31 +00:00
Secrets should be passed as settings too. Therefore, users should use [`from_secret`](../40-secrets.md#use-secrets-in-settings-and-environment).
## 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](/plugins).
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:
```yaml
steps:
2024-01-22 07:18:50 +00:00
- 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_`.
```bash
#!/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.
```dockerfile
# 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.
```shell
docker build -t foo/webhook .
docker push foo/webhook
```
Execute your plugin locally from the command line to verify it is working:
```shell
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](../50-environment.md#built-in-environment-variables) where possible.
- Do not use any configuration except settings (and internal env vars). This means: Don't require using [`environment`](../50-environment.md) and don't require specific secret names.
- Add a `docs.md` file, listing all your settings and plugin metadata ([example](https://github.com/woodpecker-ci/plugin-git/blob/main/docs.md)).
- Add your plugin to the [plugin index](/plugins) using your `docs.md` ([the example above in the index](https://woodpecker-ci.org/plugins/Git%20Clone)).