diff --git a/.woodpecker/pull_request.yml b/.woodpecker/pull_request.yml
new file mode 100644
index 0000000..cb5cdd0
--- /dev/null
+++ b/.woodpecker/pull_request.yml
@@ -0,0 +1,46 @@
+pipeline:
+  lint-go:
+    image: golangci/golangci-lint
+    group: lint-build
+    commands:
+      - golangci-lint run *.go --enable=gofumpt
+    when:
+      path: "*.go"
+  lint-docker:
+    image: hadolint/hadolint:latest-debian
+    group: lint-build
+    commands:
+      - hadolint --ignore DL3003 Dockerfile
+    when:
+      path: "Dockerfile"
+  build-go:
+    image: golang
+    group: lint-build
+    commands:
+      - go build
+    when:
+      path: ["Dockerfile", "*.go"]
+  build-docker-pr:
+    image: plugins/kaniko
+    settings:
+      repo: mcs94/gitea-comment
+      tags: latest
+      dockerfile: Dockerfile
+      no_push: true
+    when:
+      event: pull_request
+      branch: main
+      path: ["Dockerfile", "*.go"]
+  build-docker:
+    image: plugins/kaniko
+    settings:
+      repo: mcs94/gitea-comment
+      tags: latest
+      dockerfile: Dockerfile
+      username: mcs94
+      password:
+        from_secret: docker_password
+    when:
+      event: [push, tag]
+      branch: main
+      path: ["Dockerfile", "*.go"]
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..8f988a1
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,15 @@
+# syntax=docker/dockerfile:1
+## Build
+FROM golang:1.19.2-alpine3.16 AS build
+WORKDIR /app
+COPY go.mod ./
+# COPY go.sum ./
+RUN go mod download
+COPY *.go ./
+RUN go build -o /main
+
+## Deploy
+FROM alpine:3.16.2
+WORKDIR /
+COPY --from=build /main /main
+ENTRYPOINT ["/main"]
\ No newline at end of file
diff --git a/README.md b/README.md
index 88cda9a..82fede5 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,48 @@
 # gitea-comment-plugin
-Woodpecker Plugin for Gitea PR Comments
+
+A Woodpecker plugin to post comments onto a Gitea Pull Request.
+
+Note this currently only works on `pull request` events.
+
+## Usage/Examples
+
+```yaml
+pipeline:
+  comment:
+    image: mcs94/gitea-comment
+    settings:
+      gitea_address: https://gitea.url.goes.here
+      gitea_token:
+        from_secret: gitea_token
+      comment: >
+        ✅ Build ${CI_BUILD_EVENT} of `${CI_REPO_NAME}` has status `${CI_BUILD_STATUS}`.
+
+        📝 Commit by ${CI_COMMIT_AUTHOR} on `${CI_COMMIT_BRANCH}`:
+
+        `${CI_COMMIT_MESSAGE}`
+
+        🌐 ${CI_BUILD_LINK}
+    when:
+      event: [pull_request]
+```
+
+Produces something with looks like the screenshot below on pull requests:
+
+![comments](img/comments.png)
+
+## Authors
+
+* [@markopolo123](https://www.github.com/markopolo123)
+
+## Running just the container
+
+```bash
+docker run \
+-e PLUGIN_COMMENT="test comment" \
+-e PLUGIN_GITEA_TOKEN="tokenhere" \
+-e PLUGIN_GITEA_ADDRESS="https://gitea.url.here" \
+-e CI_REPO_OWNER="repoowwer" \
+-e CI_REPO_NAME="yourrepo" \
+-e CI_COMMIT_PULL_REQUEST=8 \
+test-gitea
+```
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..64b852b
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module gitea-comment
+
+go 1.19
\ No newline at end of file
diff --git a/img/comments.png b/img/comments.png
new file mode 100644
index 0000000..d0e210e
Binary files /dev/null and b/img/comments.png differ
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..d6af081
--- /dev/null
+++ b/main.go
@@ -0,0 +1,95 @@
+package main
+
+import (
+	"bytes"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"log"
+	"net/http"
+	"os"
+	"strconv"
+)
+
+type Payload struct {
+	Body string `json:"body"`
+}
+
+func LookupEnvOrString(key string, defaultVal string) string {
+	if val, ok := os.LookupEnv(key); ok {
+		return val
+	}
+	return defaultVal
+}
+
+func LookupEnvOrInt(key string, defaultVal int) int {
+	if val, ok := os.LookupEnv(key); ok {
+		v, err := strconv.Atoi(val)
+		if err != nil {
+			log.Fatalf("LookupEnvOrInt[%s]: %v", key, err)
+		}
+		return v
+	}
+	return defaultVal
+}
+
+func main() {
+	var giteaToken string
+	var giteaAddress string
+	var comment string
+	var repoOwner string
+	var repoName string
+	var prIndex int
+
+	flag.StringVar(&giteaToken, "gitea-token", LookupEnvOrString("PLUGIN_GITEA_TOKEN", giteaToken), "API token for Gitea")
+	flag.StringVar(&giteaAddress, "gitea-address", LookupEnvOrString("PLUGIN_GITEA_ADDRESS", giteaAddress), "Gitea URL")
+	flag.StringVar(&comment, "comment", LookupEnvOrString("PLUGIN_COMMENT", comment), "Comment for Gitea")
+	flag.StringVar(&repoOwner, "repo-owner", LookupEnvOrString("CI_REPO_OWNER", repoOwner), "Owner of the repository")
+	flag.StringVar(&repoName, "repo-name", LookupEnvOrString("CI_REPO_NAME", repoName), "Name of the repository")
+	flag.IntVar(&prIndex, "pr-index", LookupEnvOrInt("CI_COMMIT_PULL_REQUEST", prIndex), "Index of the PR")
+
+	flag.Parse()
+
+	if comment == "" {
+		panic("You must provide a comment")
+	}
+	if giteaToken == "" {
+		panic("You must provide a Gitea API Token")
+	}
+	if giteaAddress == "" {
+		panic("You must provide a Gitea URL")
+	}
+	if repoOwner == "" {
+		panic("You must provide an repo owner")
+	}
+	if repoName == "" {
+		panic("You must provide a repo name")
+	}
+	if prIndex == 0 {
+		panic("You must provide an index for PR")
+	}
+
+	data := Payload{
+		Body: comment,
+	}
+	payloadBytes, err := json.Marshal(data)
+	if err != nil {
+		panic(err)
+	}
+	body := bytes.NewReader(payloadBytes)
+
+	url := fmt.Sprintf("%s/api/v1/repos/%s/%s/issues/%d/comments?access_token=%s", giteaAddress, repoOwner, repoName, prIndex, giteaToken)
+
+	req, err := http.NewRequest("POST", url, body)
+	if err != nil {
+		panic(err)
+	}
+	req.Header.Set("Accept", "application/json")
+	req.Header.Set("Content-Type", "application/json")
+
+	resp, err := http.DefaultClient.Do(req)
+	if err != nil {
+		panic(err)
+	}
+	defer resp.Body.Close()
+}