From 4fdfc195e5cbfb63b5763bdd54b1b59ef3513baa Mon Sep 17 00:00:00 2001 From: Kell Sanders Date: Fri, 28 Feb 2025 13:25:34 -0600 Subject: [PATCH] fix: add [missing plugin tutorials](https://github.com/go-vela/docs-old/tree/main/content/plugins/tutorials) --- docs/usage/plugins/tutorials/bash.md | 1 - docs/usage/plugins/tutorials/go.md | 145 +++++++++++++++++++++ docs/usage/plugins/tutorials/kotlin.md | 174 +++++++++++++++++++++++++ docs/usage/plugins/tutorials/node.md | 127 ++++++++++++++++++ docs/usage/plugins/tutorials/python.md | 124 ++++++++++++++++++ docs/usage/plugins/tutorials/ruby.md | 123 +++++++++++++++++ 6 files changed, 693 insertions(+), 1 deletion(-) create mode 100644 docs/usage/plugins/tutorials/go.md create mode 100644 docs/usage/plugins/tutorials/kotlin.md create mode 100644 docs/usage/plugins/tutorials/node.md create mode 100644 docs/usage/plugins/tutorials/python.md create mode 100644 docs/usage/plugins/tutorials/ruby.md diff --git a/docs/usage/plugins/tutorials/bash.md b/docs/usage/plugins/tutorials/bash.md index 6bb6bdb..3710419 100644 --- a/docs/usage/plugins/tutorials/bash.md +++ b/docs/usage/plugins/tutorials/bash.md @@ -1,6 +1,5 @@ --- title: "Bash" -sidebar_position: 1 --- :::warning diff --git a/docs/usage/plugins/tutorials/go.md b/docs/usage/plugins/tutorials/go.md new file mode 100644 index 0000000..3461a14 --- /dev/null +++ b/docs/usage/plugins/tutorials/go.md @@ -0,0 +1,145 @@ +--- +title: "Go" +--- + +:::warning +We recommend reviewing [Docker's best practices](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) before attempting to create a custom plugin. + +We recommend that all plugins be placed inside a [scratch image](https://hub.docker.com/_/scratch). +::: + +## Overview + +From [Go documentation](https://golang.org/): + +> Go is an open source programming language that makes it easy to build simple, reliable, and efficient software. + +## Code + +To create a plugin using Go, we'll need to first decide what task we want this plugin to accomplish. + +For this example, we're going to create a program that makes an HTTP request from the provided input: + +```go +package main + +import ( + "fmt" + "net/http" + "os" + "strings" +) + +func main() { + // import method parameter from environment + method := os.Getenv("PARAMETER_METHOD") + // import body parameter from environment + body := os.Getenv("PARAMETER_BODY") + // import url parameter from environment + url := os.Getenv("PARAMETER_URL") + + // create payload from body + payload := strings.NewReader(body) + + // create new HTTP request from provided input + request, err := http.NewRequest(method, url, payload) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // send HTTP request and capture response + response, err := http.DefaultClient.Do(request) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // output the response + fmt.Println(response) +} +``` + +:::info +An example of this code is provided in the [go section](https://github.com/go-vela/vela-tutorials/tree/main/plugins/go) of the [go-vela/vela-tutorials](https://github.com/go-vela/vela-tutorials/tree/main/plugins) repository. +::: + +## Executable + +Now that we have the program to accomplish our plugin's task, we need to compile the code to produce an executable binary for the target platform: + +```sh +GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o vela-sample +``` + +:::warning +Please ensure the program is compiled for the right target platform. + +If it's not, the plugin may fail to properly run and produce unclear error messages. +::: + +## Image + +Once we have the executable needed to accomplish our plugin's task, we need to create a Dockerfile to produce an image. + +This image should contain the binary and be setup to run that binary when the plugin is executed: + +```docker +FROM golang:alpine + +RUN apk add --update --no-cache ca-certificates + +COPY vela-sample /bin/vela-sample + +ENTRYPOINT ["/bin/vela-sample"] +``` + +:::info +An example of this image is provided in the [target/vela-sample](https://hub.docker.com/r/target/vela-sample) Docker repository. +::: + +## Publishing + +In order to run the plugin in a pipeline, we'll need to make sure we build and publish it to a Docker registry: + +```sh +# build the image +docker build -t target/vela-sample:go . + +# publish the image +docker push target/vela-sample:go +``` + +:::info +This has the added benefit of enabling others in the community to consume your plugin! +::: + +## Troubleshooting + +To verify that the plugin performs the desired task, it can be executed locally via the command line: + +```sh +docker run --rm \ + -e PARAMETER_BODY="This is a sample Vela plugin written with Go" \ + -e PARAMETER_METHOD="POST" \ + -e PARAMETER_URL="http://vela.localhost.com" \ + target/vela-sample:go +``` + +## Usage + +After publishing the image to a Docker registry, it can be referenced in a pipeline: + +```yaml +version: "1" + +steps: + - name: sample go plugin + image: target/vela-sample:go + pull: always + parameters: + url: http://vela.localhost.com + method: POST + body: | + This is a sample Vela plugin written with Go +``` \ No newline at end of file diff --git a/docs/usage/plugins/tutorials/kotlin.md b/docs/usage/plugins/tutorials/kotlin.md new file mode 100644 index 0000000..744915b --- /dev/null +++ b/docs/usage/plugins/tutorials/kotlin.md @@ -0,0 +1,174 @@ +--- +title: "Kotlin" +--- + +:::warning +We recommend reviewing [Docker's best practices](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) before attempting to create a custom plugin. + +We recommend that all plugins be placed inside a [scratch image](https://hub.docker.com/_/scratch). +::: + +## Overview + +From [Kotlin documentation](https://www.kotlinlang.org/): + +> Kotlin is... +> +> A modern, concise and safe programming language that is easy to pick up, so you can create powerful applications immediately + +## Code + +To create a plugin using Kotlin, we'll need to first decide what task we want this plugin to accomplish. + +For this example, we're going to create a program that makes an HTTP request from the provided input: + +```kotlinlang +import org.http4k.client.ApacheClient +import org.http4k.core.* +import org.http4k.format.Jackson.auto +import yellowstone.cr.VCRException + +fun main() { + // get the vela parameters from env variables + val method = when ("METHOD".parameter.envOrDefault("GET").trim().lowercase()) { + "get" -> Method.GET + "put" -> Method.PUT + "post" -> Method.POST + "delete" -> Method.DELETE + else -> throw Exception("Method not supported") + } + val body = "BODY".parameter.env + val url = "URL".parameter.env + + // set up the clientId + val client: HttpHandler = ApacheClient() + + // make the request and print the result + println(Request(method, url).addBody(body).okOrDie(client).toObject()) +} + +// Helper functions +val String.env get() = System.getenv(this) ?: throw VCRException("The environment variable $this is required but missing!") +fun String.envOrDefault(default: String) = System.getenv(this) ?: default +val String.parameter get() = "PARAMETER_$this" +fun Request.okOrDie(client: HttpHandler) = client(this).let { response -> + response.takeIf { it.status.successful } + ?: throw Exception("Got unexpected ${response.status.code} from request ${method.name} $uri! ${response.bodyString()}") +} + +inline fun Response.toObject() = Body.auto().toLens()(this) +inline fun Request.addBody(t: T) = Body.auto().toLens()(t, this) +``` + +## Jar + +In order to make this code a runnable executable, you must first turn it into a jar file. Below is an example `build.gradle.kts` + +```kotlinlang +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + application + kotlin("jvm") version "1.5.10" +} + +repositories { + mavenCentral() +} + +application { + group = "mygroup" + mainClass.set("mygroup.MainKt") +} + +dependencies { + fun deps(format: String, vararg arr: String) = with(format) { arr.forEach { implementation(format(it)) } } + + implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("reflect")) + deps("org.http4k:http4k-%s:4.9.9.0", "client-apache", "format-jackson") +} + +tasks { + jar { + enabled = true + } + withType { + kotlinOptions.jvmTarget = JavaVersion.VERSION_11.majorVersion + } + withType { + useJUnitPlatform() + } +} +``` + +To build the jar, run `./gradlew clean build distTar` + +## Image + +Once we have the jar needed to accomplish our plugin's task, we need to create a Dockerfile to produce an image. + +This image should contain the jar and be setup to run that jar when the plugin is executed + +```docker +FROM alpine:latest + +# Install Java 11 +ENV JAVA_HOME /usr/lib/jvm/java-11-openjdk +ENV PATH $PATH:/usr/lib/jvm/java-11-openjdk/jre/bin:/usr/lib/jvm/java-11-openjdk + +RUN apk update && \ + apk upgrade && \ + apk --no-cache add openjdk11 --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community + +# copy the executable +ADD build/distributions/vela-sample.tar / + +CMD ["/vela-sample/bin/vela-sample"] +``` + +## Publishing + +In order to run the plugin in a pipeline, we'll need to make sure we build and publish it to a Docker registry: + +```sh +# build the image +docker build -t target/vela-sample:kotlin . + +# publish the image +docker push target/vela-sample:kotlin +``` + +:::info +This has the added benefit of enabling others in the community to consume your plugin! +::: + +## Troubleshooting + +To verify that the plugin performs the desired task, it can be executed locally via the command line: + +```sh +docker run --rm \ + -e PARAMETER_BODY="This is a sample Vela plugin written with Kotlin" \ + -e PARAMETER_METHOD="POST" \ + -e PARAMETER_URL="http://vela.localhost.com" \ + target/vela-sample:kotlin +``` + +## Usage + +After publishing the image to a Docker registry, it can be referenced in a pipeline: + +```yaml +version: "1" + +steps: + - name: sample kotlin plugin + image: target/vela-sample:kotlin + pull: always + parameters: + url: http://vela.localhost.com + method: POST + body: | + This is a sample Vela plugin written with Kotlin +``` \ No newline at end of file diff --git a/docs/usage/plugins/tutorials/node.md b/docs/usage/plugins/tutorials/node.md new file mode 100644 index 0000000..6aeedab --- /dev/null +++ b/docs/usage/plugins/tutorials/node.md @@ -0,0 +1,127 @@ +--- +title: "Node.js" +--- + +:::warning +We recommend reviewing [Docker's best practices](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) before attempting to create a custom plugin. + +We recommend that all plugins be placed inside a [scratch image](https://hub.docker.com/_/scratch). +::: + +## Overview + +From [Node.js documentation](https://nodejs.org/): + +> As an asynchronous event-driven JavaScript runtime, Node.js is designed to build scalable network applications. + +## Code + +To create a plugin using Node.js, we'll need to first decide what task we want this plugin to accomplish. + +For this example, we're going to create a program that makes an HTTP request from the provided input: + +```javascript +#!/usr/bin/env node + +const https = require("https"); +const url = require("url"); + +// import method parameter from environment +const method = process.env.PARAMETER_METHOD; +// import body parameter from environment +const body = process.env.PARAMETER_BODY; +// import url parameter from environment +const uri = process.env.PARAMETER_URL; + +// capture full URL from uri +const myURL = url.parse(uri); + +// create options for HTTP request +const options = { + method: method +}; + +// create new HTTP request from provided input +const req = https.request(myURL, options); + +// exit immediately if request errors +req.on("error", () => { + process.exit(1); +}); + +// write body to HTTP request +req.write(process.env.PARAMETER_BODY); + +// send HTTP request +req.end(); +``` + +:::info +An example of this code is provided in the [node.js section](https://github.com/go-vela/vela-tutorials/tree/main/plugins/node.js) of the [go-vela/vela-tutorials](https://github.com/go-vela/vela-tutorials/tree/main/plugins) repository. +::: + +## Image + +Once we have the executable needed to accomplish our plugin's task, we need to create a Dockerfile to produce an image. + +This image should contain the script and be setup to run that script when the plugin is executed: + +```docker +FROM node:alpine + +RUN apk add --update --no-cache ca-certificates + +COPY vela-sample.js /bin/vela-sample.js + +ENTRYPOINT ["node", "/bin/vela-sample.js"] +``` + +:::info +An example of this image is provided in the [target/vela-sample](https://hub.docker.com/r/target/vela-sample) Docker repository. +::: + +## Publishing + +In order to run the plugin in a pipeline, we'll need to make sure we build and publish it to a Docker registry: + +```sh +# build the image +docker build -t target/vela-sample:node . + +# publish the image +docker push target/vela-sample:node +``` + +:::info +This has the added benefit of enabling others in the community to consume your plugin! +::: + +## Troubleshooting + +To verify that the plugin performs the desired task, it can be executed locally via the command line: + +```sh +docker run --rm \ + -e PARAMETER_BODY="This is a sample Vela plugin written with Node.js" \ + -e PARAMETER_METHOD="POST" \ + -e PARAMETER_URL="http://vela.localhost.com" \ + target/vela-sample:node +``` + +## Usage + +After publishing the image to a Docker registry, it can be referenced in a pipeline: + +```yaml +version: "1" + +steps: + - name: sample node plugin + image: target/vela-sample:node + pull: always + parameters: + url: http://vela.localhost.com + method: POST + body: | + This is a sample Vela plugin written with Node.js +``` \ No newline at end of file diff --git a/docs/usage/plugins/tutorials/python.md b/docs/usage/plugins/tutorials/python.md new file mode 100644 index 0000000..e2692ba --- /dev/null +++ b/docs/usage/plugins/tutorials/python.md @@ -0,0 +1,124 @@ +--- +title: "Python" +--- + +:::warning +We recommend reviewing [Docker's best practices](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) before attempting to create a custom plugin. + +We recommend that all plugins be placed inside a [scratch image](https://hub.docker.com/_/scratch). +::: + +## Overview + +From [Python documentation](https://www.python.org/): + +> Python is a programming language that lets you work quickly and integrate systems more effectively. + +## Code + +To create a plugin using Python, we'll need to first decide what task we want this plugin to accomplish. + +For this example, we're going to create a program that makes an HTTP request from the provided input: + +```python +#!/usr/bin/env python + +import http.client +import os +import urlparse + +# import method parameter from environment +method = os.getenv['PARAMETER_METHOD'] +# import body parameter from environment +body = os.getenv['PARAMETER_BODY'] +# import url parameter from environment +url = os.getenv['PARAMETER_URL'] + +# capture full URI from url +uri = urlparse(url) + +# create new HTTP connection from URL +conn = http.client.HTTPSConnection(uri.hostname, uri.port) + +# create headers to be added to request +headers = {} + +# send HTTP request +conn.request(method, uri.path, body, headers) + +# capture the response +response = conn.getresponse() + +# output the response +print(response.read().decode("utf-8")) +``` + +:::info +An example of this code is provided in the [python section](https://github.com/go-vela/vela-tutorials/tree/main/plugins/python) of the [go-vela/vela-tutorials](https://github.com/go-vela/vela-tutorials/tree/main/plugins) repository. +::: + +## Image + +Once we have the script needed to accomplish our plugin's task, we need to create a Dockerfile to produce an image. + +This image should contain the script and be setup to run that script when the plugin is executed: + +```docker +FROM python:alpine + +RUN apk add --update --no-cache ca-certificates + +COPY vela-sample.py /bin/vela-sample.py + +ENTRYPOINT ["python", "/bin/vela-sample.py"] +``` + +:::info +An example of this image is provided in the [target/vela-sample](https://hub.docker.com/r/target/vela-sample) Docker repository. +::: + +## Publishing + +In order to run the plugin in a pipeline, we'll need to make sure we build and publish it to a Docker registry: + +```sh +# build the image +docker build -t target/vela-sample:python . + +# publish the image +docker push target/vela-sample:python +``` + +:::info +This has the added benefit of enabling others in the community to consume your plugin! +::: + +## Troubleshooting + +To verify that the plugin performs the desired task, it can be executed locally via the command line: + +```sh +docker run --rm \ + -e PARAMETER_BODY="This is a sample Vela plugin written with Python" \ + -e PARAMETER_METHOD="POST" \ + -e PARAMETER_URL="http://vela.localhost.com" \ + target/vela-sample:python +``` + +## Usage + +After publishing the image to a Docker registry, it can be referenced in a pipeline: + +```yaml +version: "1" + +steps: + - name: sample python plugin + image: target/vela-sample:python + pull: always + parameters: + url: http://vela.localhost.com + method: POST + body: | + This is a sample Vela plugin written with Python +``` \ No newline at end of file diff --git a/docs/usage/plugins/tutorials/ruby.md b/docs/usage/plugins/tutorials/ruby.md new file mode 100644 index 0000000..ac9071e --- /dev/null +++ b/docs/usage/plugins/tutorials/ruby.md @@ -0,0 +1,123 @@ +--- +title: "Ruby" +--- + +:::warning +We recommend reviewing [Docker's best practices](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) before attempting to create a custom plugin. + +We recommend that all plugins be placed inside a [scratch image](https://hub.docker.com/_/scratch). +::: + +## Overview + +From [Ruby documentation](https://www.ruby-lang.org/en/): + +> Ruby is... +> +> A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write. + +## Code + +To create a plugin using Ruby, we'll need to first decide what task we want this plugin to accomplish. + +For this example, we're going to create a program that makes an HTTP request from the provided input: + +```ruby +#!/usr/bin/env ruby + +require 'net/http' +require 'uri' + +# import method parameter from environment +method = ENV['PARAMETER_METHOD'] +# import body parameter from environment +body = ENV['PARAMETER_BODY'] +# import url parameter from environment +url = ENV['PARAMETER_URL'] + +# capture full URI from url +uri = URI(url) + +# create new HTTP client from URI +http = Net::HTTP.new(uri.host, uri.port) + +# send HTTP request and capture response +response = http.send_request( + method, + uri.path, + body, +) + +# output the response +puts response.read_body +``` + +:::info +An example of this code is provided in the [ruby section](https://github.com/go-vela/vela-tutorials/tree/main/plugins/ruby) of the [go-vela/vela-tutorials](https://github.com/go-vela/vela-tutorials/tree/main/plugins) repository. +::: + +## Image + +Once we have the script needed to accomplish our plugin's task, we need to create a Dockerfile to produce an image. + +This image should contain the script and be setup to run that script when the plugin is executed: + +```docker +FROM ruby:alpine + +RUN apk add --update --no-cache ca-certificates + +COPY vela-sample.rb /bin/vela-sample.rb + +ENTRYPOINT ["ruby", "/bin/vela-sample.rb"] +``` + +:::info +An example of this image is provided in the [target/vela-sample](https://hub.docker.com/r/target/vela-sample) Docker repository. +::: + +## Publishing + +In order to run the plugin in a pipeline, we'll need to make sure we build and publish it to a Docker registry: + +```sh +# build the image +docker build -t target/vela-sample:ruby . + +# publish the image +docker push target/vela-sample:ruby +``` + +:::info +This has the added benefit of enabling others in the community to consume your plugin! +::: + +## Troubleshooting + +To verify that the plugin performs the desired task, it can be executed locally via the command line: + +```sh +docker run --rm \ + -e PARAMETER_BODY="This is a sample Vela plugin written with Ruby" \ + -e PARAMETER_METHOD="POST" \ + -e PARAMETER_URL="http://vela.localhost.com" \ + target/vela-sample:ruby +``` + +## Usage + +After publishing the image to a Docker registry, it can be referenced in a pipeline: + +```yaml +version: "1" + +steps: + - name: sample ruby plugin + image: target/vela-sample:ruby + pull: always + parameters: + url: http://vela.localhost.com + method: POST + body: | + This is a sample Vela plugin written with Ruby +``` \ No newline at end of file