added documentation for plugin development

This commit is contained in:
Brad Rydzewski 2015-07-11 18:01:59 -07:00
parent 9fc02e360a
commit ccfd75196b
7 changed files with 282 additions and 10 deletions

View file

@ -1,3 +1,5 @@
> **WARNING** the 0.4 branch is very unstable. We only recommend running this branch if you plan to dig into the codebase, troubleshoot issues and contribute (please do!). We will notify the broader community once this branch is more stable.
Drone is a Continuous Integration platform built on container technology. Every build is executed inside an ephemeral Docker container, giving developers complete control over their build environment with guaranteed isolation.
### Goals
@ -10,6 +12,7 @@ Drone documentation is organized into several categories:
* [Setup Guide](http://readme.drone.io/docs/setup/)
* [Build Guide](http://readme.drone.io/docs/build/)
* [Plugin Guide](http://readme.drone.io/docs/plugin/)
* [API Reference](http://readme.drone.io/docs/api/)
### Community

3
doc/plugin/README.md Normal file
View file

@ -0,0 +1,3 @@
* [Overview](overview.md)
* [Example](example.md)
* [Publish](publish.md)

156
doc/plugin/example.md Normal file
View file

@ -0,0 +1,156 @@
# Plugin Tutorial
We're going to create a plugin that allows Drone to send a webhook when a build completes. The webhook will send an http POST request to one or more URLs with the build details, encoded in JSON format.
## Plugin Yaml
Many plugins call for some options the user can set, which can be specified in the `.drone.yml` file. This is an example configuration for our `webhook` plugin:
```yaml
---
notify:
webhook:
image: bradrydzewski/webhook
urls:
- http://foo.com/post/to/this/url
```
The `image` attribute refers to the name of our plugin's Docker image. The `urls` attribute is a custom option allowing the user to define the list of webhook urls.
## Plugin executable
The next step is to write the code for our plugin. Our plugin will need access to information about the running build, and it will need its configuration options. Luckily, the build and repository details are passed to the program as a JSON encoded string over `arg[1]`.
The Drone team created the `drone-plugin-go` library to simplify plugin development, and we'll use this library to create our webhook plugin. First, we'll need to download the library using `go get` and import into our `main.go` file:
```go
import (
"github.com/drone/drone-plugin-go"
)
```
Next we'll need to read and unmarshal the repository and build detail from `arg[1]`. Our plugin package provides simple helper functions, modeled after the `flag` package, to fetch this data. We'll also need to read and unmarshal our plugin options. Plugin options are passed as the `vargs` paramter.
```go
func main() {
var repo = plugin.Repo{}
var build = plugin.Build{}
var vargs = struct {
Urls []string `json:"urls"`
}{}
plugin.Param("repo", &repo)
plugin.Param("build", &build)
plugin.Param("vargs", &vargs)
plugin.Parse()
// post build and repo data to webhook urls
}
```
Once we've parsed the build and repository details, and the webhook urls, we are ready to make the http requests. First, we'll need to construct our payload and marshal to JSON:
```go
data := struct{
Repo plugin.Repo `json:"repo"`
Build plugin.Build `json:"build"`
}{repo, build}
payload, _ := json.Marshal(&data)
```
And finally, for each URL in the list, we post the JSON payload:
```go
for _, url := range vargs.Urls {
resp, _ := http.Post(url, "application/json", bytes.NewBuffer(payload))
resp.Body.Close()
}
```
## Plugin image
Since plugins are distributed as Docker images, we'll need to create a `Dockerfile` for our plugin:
```dockerfile
FROM gliderlabs/alpine:3.1
RUN apk-install ca-certificates
ADD drone-webhook /bin/
ENTRYPOINT ["/bin/drone-webhook"]
```
We recommend using the `gliderlabs/alpine` base image due to its compact size. Plugins are downloaded automatically during build execution, therefore, smaller images and faster download times provide a better overall user experience.
## Plugin testing
We can quickly test our plugin from the command line, with dummy data, to make sure everything works. Note that you can send the JSON string over `stdin` instead of `arg[1]` only when testing:
```bash
go run main.go <<EOF
{
"repo": {
"owner": "octocat",
"name": "hello-world",
"full_name": "octocat/hello-world"
},
"build": {
"number": 1,
"status": "success"
},
"vargs": {
"urls": [ "http://foo.com/post/to/this/url" ]
}
}
EOF
```
## Complete example
Here is the complete Go program:
```go
import (
"bytes"
"encoding/json"
"net/http"
"github.com/drone/drone-plugin-go"
)
func main() {
var repo = plugin.Repo{}
var build = plugin.Build{}
var vargs = struct {
Urls []string `json:"urls"`
}{}
plugin.Param("repo", &repo)
plugin.Param("build", &build)
plugin.Param("vargs", &vargs)
plugin.Parse()
// data structure
data := struct{
Repo plugin.Repo `json:"repo"`
Build plugin.Build `json:"build"`
}{repo, build}
// json payload that will be posted
payload, _ := json.Marshal(&data)
// post payload to each url
for _, url := range vargs.Urls {
resp, _ := http.Post(url, "application/json", bytes.NewBuffer(payload))
resp.Body.Close()
}
}
```
And the Dockerfile:
```dockerfile
FROM gliderlabs/alpine:3.1
RUN apk-install ca-certificates
ADD drone-webhook /bin/
ENTRYPOINT ["/bin/drone-webhook"]
```

66
doc/plugin/overview.md Normal file
View file

@ -0,0 +1,66 @@
# Overview
Drone has a robust plugin model that allows you to extend the platform to meet your unique project needs. This documentation describes the Drone plugin architecture and will help you create your own custom plugins. If you are searching for existing plugins please see the [plugin marketplace](http://addons.drone.io).
## How Plugins Work
Plugins are simply Docker containers that attach to your build at runtime and perform custom operations. These operations may include deploying code, publishing artifacts and sending notifications.
Plugins are declared in the `.drone.yml` file. When Drone encounters a plugin it attempts to download from the registry (if not already downloaded) and then execute. This is an example of the [slack plugin](https://github.com/drone-plugins/drone-slack) configuration:
```yaml
---
notify:
slack:
image: plugins/slack
webhook_url: https://hooks.slack.com/services/...
username: captain_freedom
channel: ics
```
Plugins receive plugin configuration data, repository and build data as an encoded JSON string. The plugin can use this data when executing its task. For example, the [slack plugin](https://github.com/drone-plugins/drone-slack) uses the build and repository details to format and send a message to a channel.
Plugins also have access to the `/drone` volume, which is shared across all containers, including the build container. The repository is cloned to a subdirectory of `/drone/src`, which means plugins have access to your source code as well as any generated assets (binary files, reports, etc). For example, the [heroku plugin](https://github.com/drone-plugins/drone-heroku) accesses your source directory and executes `git push heroku master` to deploy your code.
## Plugin Input
Plugins receive build details via `arg[1]` as a JSON encoded string. The payload includes the following data structures:
* `repo` JSON representation of the repository
* `build` JSON representation of the build, including commit and pull request
* `vargs` JSON representation of the plugin configuration, as defined in the `.drone.yml`
Drone provides a simple [plugin library](https://github.com/drone/drone-plugin-go) that helps read and unmarshal the input parameters:
```go
func main() {
var repo = plugin.Repo{}
var build = plugin.Build{}
var vargs = struct {
Webhook string `json:"webhook_url"`
Username string `json:"username"`
Channel string `json:"channel"`
}{}
plugin.Param("repo", &repo)
plugin.Param("build", &build)
plugin.Param("vargs", &vargs)
plugin.Parse()
// send slack notification
}
```
## Plugin Output
Plugins cannot send structured data back to Drone. Plugins can, however, write information to stdout so that it appears in the logs. Plugins can fail a build by exiting with a non-zero status code.
You may be asking yourself "how do I send reports or metrics back to Drone" or "how do I generate and store artificats in Drone"? The answer is that you cannot. Instead, you should use plugins to generate reports and send to third party services (like Coveralls) or generate and upload artifacts to third party storage services (like Bintray or S3).
## Plugin Reference
These are existing plugins that you can reference when building your own:
* [Slack](https://github.com/drone-plugins/drone-slack) - publish messages to a Slack channel when your build finishes
* [Heroku](https://github.com/drone-plugins/drone-heroku) - deploy your application to Heroku
* [Docker](https://github.com/drone-plugins/drone-docker) - build and publish your Docker image to a registry

44
doc/plugin/publish.md Normal file
View file

@ -0,0 +1,44 @@
# Publishing Plugins
Plugins must be published to a Docker registry in order for Drone to download and execute at runtime. You can publish to the official registry (at [index.docker.io](https://index.docker.io)) or to a private registry.
## Plugin marketplace
Official plugins are published to [index.docker.io/u/plugins](https://index.docker.io/u/plugins/) and are listed in the [plugin marketplace](http://addons.drone.io). If you would like to submit your plugin to the marketplace, as an officially supported Drone plugin, it must meet the following criteria:
* Plugin is useful to the broader community
* Plugin is documented
* Plugin is written in Go [1]
* Plugin has manifest file
* Plugin uses Apache2 license
* Plugin uses `gliderlabs/apline` base image (unless technical limitations prohibit)
[1] Although plugins can be written in any language, official plugins must be written in Go. The core Drone team consists of primarily Go developers and we simply lack the expertise and bandwidth to support multiple stacks. This may change in the future (remember, this is still a young project) but for now this remains a requirement.
## Plugin manifest
The plugin manifest, a subsection of the `.drone.yml` file, contains important information about your plugin:
* `name` - display name of the plugin
* `desc` - brief description of the plugin
* `type` - type of plugin. Possible values are clone, publish, deploy, notify
* `image` - image repository in the Docker registry
Here is the [example manifest](https://github.com/drone-plugins/drone-slack/blob/master/.drone.yml) for the slack plugin:
```yaml
---
plugin:
name: Slack
desc: Sends build status notifications to your Slack channel.
type: notify
image: plugins/drone-slack
labels:
- chat
- messaging
```
## Plugin documentation
The plugin documentation is stored in the `./DOCS.md` file in the root of the repository. This file is used to auto-generate the documentation displayed in the [plugin marketplace](http://addons.drone.io).

View file

@ -4,7 +4,7 @@ Drone uses the local Docker daemon (at `unix:///var/run/docker.sock`) to execute
Configure a single Docker host (1x build concurrency):
```
```bash
DOCKER_HOST="unix:///var/run/docker.sock"
```
@ -14,7 +14,7 @@ Configure Drone to run multiple, concurrent builds by increasing the number of r
Configure multiple Docker hosts (4x build concurrency):
```
```bash
DOCKER_HOST_1="unix:///var/run/docker.sock"
DOCKER_HOST_2="unix:///var/run/docker.sock"
DOCKER_HOST_3="unix:///var/run/docker.sock"
@ -23,7 +23,7 @@ DOCKER_HOST_4="unix:///var/run/docker.sock"
Configure a single, external Docker host (1x build concurrency):
```
```bash
DOCKER_HOST="tcp://1.2.3.4:2376"
DOCKER_CA="/path/to/ca.pem"
@ -33,7 +33,7 @@ DOCKER_KEY="/path/to/key.pem"
Configure multiple, external Docker hosts (4x build concurrency using 2 remote servers):
```
```bash
DOCKER_HOST_1="tcp://1.2.3.4:2376"
DOCKER_HOST_2="tcp://1.2.3.4:2376"
@ -59,14 +59,14 @@ This will generate the following files:
Tell Drone where to find the `cert.pem` and `key.pem`:
```
```bash
DOCKER_CERT="/path/to/cert.pem"
DOCKER_KEY="/path/to/key.pem"
```
If you are running Drone inside Docker you will need to mount the volume containing the certificate:
When running Drone inside Docker, you'll need to mount the volume containing the certificate:
```
```bash
docker run
--volume /path/to/cert.pem:/path/to/cert.pem \
--volume /path/to/key.pem:/path/to/key.pem \
@ -81,11 +81,11 @@ DOCKER_OPTS="--tlsverify --tlscacert=/etc/ssl/docker/ca.pem --tlscert=/etc/ssl/d
Verify that everything is configured correctly by connecting to a remote Docker server from our Drone server using the following command:
```
```bash
sudo docker \
--tls \
--tlscacert=/path/to/ca.pem \
--tlscert=/path/to/cert.pem \
--tlskey=/path/to/key.pem \
-H=1.2.3.4:2376 version
-H="1.2.3.4:2376" version
```

View file

@ -2,7 +2,7 @@
Drone comes with built-in support for GitHub and GitHub Enterprise. To enable and configure GitHub, you should set the following environment variables:
```
```bash
REMOTE_DRIVER="github"
GITHUB_CLIENT="c0aaff74c060ff4a950d"