Rework addons (use rpc) (#3268)

Co-authored-by: Anbraten <6918444+anbraten@users.noreply.github.com>
This commit is contained in:
qwerty287
2024-04-15 10:04:21 +02:00
committed by GitHub
parent b177d82064
commit 00f0fcd416
29 changed files with 1309 additions and 385 deletions

View File

@@ -135,5 +135,5 @@ docker run --rm \
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://codeberg.org/woodpecker-plugins/plugin-docker-buildx/src/branch/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/Docker%20Buildx)).
- 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)).

View File

@@ -473,12 +473,6 @@ Supported variables:
- `owner`: the repo's owner
- `repo`: the repo's name
### `WOODPECKER_ADDONS`
> Default: empty
List of addon files. See [addons](./75-addons/75-overview.md).
---
### `WOODPECKER_LIMIT_MEM_SWAP`
@@ -559,4 +553,8 @@ See [Bitbucket configuration](./11-forges/50-bitbucket.md#configuration)
### `WOODPECKER_GITLAB_...`
See [Gitlab configuration](./11-forges/40-gitlab.md#configuration)
See [GitLab configuration](./11-forges/40-gitlab.md#configuration)
### `WOODPECKER_ADDON_FORGE`
See [addon forges](./11-forges/100-addon.md).

View File

@@ -0,0 +1,68 @@
# Addon forges
If the forge you're using does not comply with [Woodpecker's requirements](../../92-development/02-core-ideas.md#forge) or your setup is too specific to be added to Woodpecker's core, you can write your own forge using an addon forge.
:::warning
Addon forges are still experimental. Their implementation can change and break at any time.
:::
:::danger
You need to trust the author of the addon forge you use. It can access authentication codes and other possibly sensitive information.
:::
## Usage
To use an addon forge, download the correct addon version. Then, you can add the following to your configuration:
```ini
WOODPECKER_ADDON_FORGE=/path/to/your/addon/forge/file
```
In case you run Woodpecker as container, you probably want to mount the addon binary to `/opt/addons/`.
### Bug reports
If you experience bugs, please check which component has the issue. If it's the addon, **do not raise an issue in the main repository**, but rather use the separate addon repositories. To check which component is responsible for the bug, look at the logs. Logs from addons are marked with a special field `addon` containing their addon file name.
## List of addon forges
If you wrote or found an addon forge, please add it here so others can find it!
_Be the first one to add your addon forge!_
## Creating addon forges
Addons use RPC to communicate to the server and are implemented using the [`go-plugin` library](https://github.com/hashicorp/go-plugin).
### Writing your code
This example will use the Go language.
Directly import Woodpecker's Go packages (`go.woodpecker-ci.org/woodpecker/woodpecker/v2`) and use the interfaces and types defined there.
In the `main` function, just call `"go.woodpecker-ci.org/woodpecker/v2/server/forge/addon".Serve` with a `"go.woodpecker-ci.org/woodpecker/v2/server/forge".Forge` as argument.
This will take care of connecting the addon forge to the server.
### Example structure
```go
package main
import (
"context"
"net/http"
"go.woodpecker-ci.org/woodpecker/v2/server/forge/addon"
forgeTypes "go.woodpecker-ci.org/woodpecker/v2/server/forge/types"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
)
func main() {
addon.Serve(config{})
}
type config struct {
}
// `config` must implement `"go.woodpecker-ci.org/woodpecker/v2/server/forge".Forge`. You must directly use Woodpecker's packages - see imports above.
```

View File

@@ -1,97 +0,0 @@
# Creating addons
Addons are written in Go.
## Writing your code
An addon consists of two variables/functions in Go.
1. The `Type` variable. Specifies the type of the addon and must be directly accessed from `shared/addons/types/types.go`.
2. The `Addon` function which is the main point of your addon.
This function takes the `zerolog` logger you should use to log errors, warnings, etc. as argument.
It returns two values:
1. The actual addon. For type reference see [table below](#return-types).
2. An error. If this error is not `nil`, Woodpecker exits.
Directly import Woodpecker's Go package (`go.woodpecker-ci.org/woodpecker/woodpecker/v2`) and use the interfaces and types defined there.
### Return types
| Addon type | Return type |
| ---------- | -------------------------------------------------------------------- |
| `Forge` | `"go.woodpecker-ci.org/woodpecker/woodpecker/v2/server/forge".Forge` |
### Using configurations
If you write a plugin for the server (`Forge` and the services), you can access the server config.
Therefore, use the `"go.woodpecker-ci.org/woodpecker/v2/server".Config` variable.
:::warning
The config is not available when your addon is initialized, i.e., the `Addon` function is called.
Only use the config in the interface methods.
:::
## Compiling
After you write your addon code, compile your addon:
```sh
go build -buildmode plugin
```
The output file is your addon that is now ready to be used.
## Restrictions
Addons must directly depend on Woodpecker's core (`go.woodpecker-ci.org/woodpecker/woodpecker/v2`).
The addon must have been built with **exactly the same code** as the Woodpecker instance you'd like to use it on. This means: If you build your addon with a specific commit from Woodpecker `next`, you can likely only use it with the Woodpecker version compiled from this commit.
Also, if you change something inside Woodpecker without committing, it might fail because you need to recompile your addon with this code first.
In addition to this, addons are only supported on Linux, FreeBSD, and macOS.
:::info
It is recommended to at least support the latest version of Woodpecker.
:::
### Compile for different versions
As long as there are no changes to Woodpecker's interfaces,
or they are backwards-compatible, you can compile the addon for multiple versions
by changing the version of `go.woodpecker-ci.org/woodpecker/woodpecker/v2` using `go get` before compiling.
## Logging
The entrypoint receives a `zerolog.Logger` as input. **Do not use any other logging solution.** This logger follows the configuration of the Woodpecker instance and adds a special field `addon` to the log entries which allows users to find out which component is writing the log messages.
## Example structure
```go
package main
import (
"context"
"net/http"
"github.com/rs/zerolog"
"go.woodpecker-ci.org/woodpecker/v2/server/forge"
forge_types "go.woodpecker-ci.org/woodpecker/v2/server/forge/types"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
addon_types "go.woodpecker-ci.org/woodpecker/v2/shared/addon/types"
)
var Type = addon_types.TypeForge
func Addon(logger zerolog.Logger) (forge.Forge, error) {
logger.Info().Msg("hello world from addon")
return &config{l: logger}, nil
}
type config struct {
l zerolog.Logger
}
// In this case, `config` must implement `forge.Forge`. You must directly use Woodpecker's packages - see imports above.
```

View File

@@ -1,40 +0,0 @@
# Addons
:::warning
Addons are still experimental. Their implementation can change and break at any time.
:::
:::danger
You need to trust the author of the addons you use. Depending on their type, addons can access forge authentication codes, your secrets or other sensitive information.
:::
To adapt Woodpecker to your needs beyond the [configuration](../10-server-config.md), Woodpecker has its own **addon** system, built ontop of [Go's internal plugin system](https://go.dev/pkg/plugin).
Addons can be used for:
- Forges
## Restrictions
Addons are restricted by how Go plugins work. This includes the following restrictions:
- only supported on Linux, FreeBSD, and macOS
- addons must have been built for the correct Woodpecker version. If an addon is not provided specifically for this version, you likely won't be able to use it.
## Usage
To use an addon, download the addon version built for your Woodpecker version. Then, you can add the following to your configuration:
```ini
WOODPECKER_ADDONS=/path/to/your/addon/file.so
```
In case you run Woodpecker as container, you probably want to mount the addon binaries to `/opt/addons/`.
You can list multiple addons, Woodpecker will automatically determine their type. If you specify multiple addons with the same type, only the first one will be used.
Using an addon always overwrites Woodpecker's internal setup. This means, that a forge addon will be used if specified, no matter what's configured for the forges natively supported by Woodpecker.
### Bug reports
If you experience bugs, please check which component has the issue. If it's the addon, **do not raise an issue in the main repository**, but rather use the separate addon repositories. To check which component is responsible for the bug, look at the logs. Logs from addons are marked with a special field `addon` containing their addon file name.

View File

@@ -1,6 +0,0 @@
label: 'Addons'
collapsible: true
collapsed: true
link:
type: 'doc'
id: 'overview'

View File

@@ -8,7 +8,7 @@
## Addons and extensions
If you are wondering whether your contribution will be accepted to be merged in the Woodpecker core, or whether it's better to write an
[addon](../30-administration/75-addons/75-overview.md), [extension](../30-administration/100-external-configuration-api.md) or an
[addon forge](../30-administration/11-forges/100-addon.md), [extension](../30-administration/100-external-configuration-api.md) or an
[external custom backend](../30-administration/22-backends/50-custom-backends.md), please check these points:
- Is your change very specific to your setup and unlikely to be used by anyone else?