{"id":26659220,"url":"https://github.com/aalbacetef/pirate","last_synced_at":"2025-10-08T21:05:03.958Z","repository":{"id":283326368,"uuid":"875353259","full_name":"aalbacetef/pirate","owner":"aalbacetef","description":"A webhooks taskrunner - run tasks easily based on webhooks!","archived":false,"fork":false,"pushed_at":"2025-03-19T16:41:18.000Z","size":67,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-19T17:32:06.882Z","etag":null,"topics":["go","golang","taskrunner","webhook","webhooks"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aalbacetef.png","metadata":{"files":{"readme":"README.asciidoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-19T18:42:13.000Z","updated_at":"2025-03-19T16:34:09.000Z","dependencies_parsed_at":"2025-03-19T17:43:03.893Z","dependency_job_id":null,"html_url":"https://github.com/aalbacetef/pirate","commit_stats":null,"previous_names":["aalbacetef/pirate"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalbacetef%2Fpirate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalbacetef%2Fpirate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalbacetef%2Fpirate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalbacetef%2Fpirate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aalbacetef","download_url":"https://codeload.github.com/aalbacetef/pirate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245440490,"owners_count":20615633,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","taskrunner","webhook","webhooks"],"created_at":"2025-03-25T10:18:48.614Z","updated_at":"2025-10-08T21:05:03.952Z","avatar_url":"https://github.com/aalbacetef.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"= pirate \n:author: Arturo Albacete\n:revdate: 2025-04-10\n:toc: macro\n:toclevels: 5\n\nimage:https://github.com/aalbacetef/pirate/actions/workflows/ci.yml/badge.svg[CI status] \nimage:https://img.shields.io/badge/License-BSD_3--Clause-blue.svg[License] \nimage:https://goreportcard.com/badge/github.com/aalbacetef/pirate[Go Report Card]\n\ntoc::[]\n\n\n== Introduction \n\nimage::misc/pirate-ship.jpg[] \n\n**Pirate** is a webhooks task runner. It aims to satisfy the need for running tasks based on webhook events.\n\n=== Running it\n\n**Command line flag**\n\nYou can pass in a config file using the `-config` flag:\n\n[source,bash]\n----\npirate -config ./path/to/ship.yml \n----\n\n**Environment variable**\n\nYou can set the environment variable: `PIRATE_CONFIG_PATH`\n\n**Default location**\n\nIf running without a config flag, it will look for a `ship.yml` in the current directory. \n\n\n\nExample config (see link:ship.sample.yml[ship.sample.yml]).\n[source,yaml]\n----\nserver:\n  # optional: defaults to 'localhost'\n  host: localhost\n\n  # required: port on which to listen to \n  port: 3939\n\n  # optional: maximum time allowed for a request, defaults to 5m0s \n  request-timeout: '2m30s'\n\n  # optional: maximum size of the header bytes, defaults to 1k\n  max-header-bytes: '10M'\n\n  logging:\n    # required: logging directory.\n    #   Will be created with permission 744 if it doesn't exist\n    #   Filename will be pirate.YYYY-MM-DD--hh:mm:ss.log\n    dir: './logs' \n\n    ## NOTE: special value :stdout: writes to standard output\n    # dir: ':stdout:'\n\n\nhandlers:\n  # NOTE: all fields of the handler are required unless stated otherwise\n  - endpoint: /webhooks/simple\n    name: simple webhook handler\n\n    # optional: handler execution policy, one of: drop, queue, parallel. Defaults to queue.\n    policy: drop \n\n    # authenticates the handler based on the value of the X-Authorization header \n    auth:\n      # a list validator will check if the token matches one of .token\n      validator: list\n      token: \n        - alpha\n        - beta\n    # script to run, the request headers and body are available as env vars.\n    run: |\n      SOME_VAR=\"some-variable\"\n      echo \"SOME_VAR: $SOME_VAR\"\n      echo \"body: $PIRATE_BODY\"\n      echo \"headers: $PIRATE_HEADERS\" \n      echo \"header param: $PIRATE_HEADERS_SOME_PARAM\"\n\n\n  - endpoint: /new-release\n    name: new release\n    policy: queue\n    auth:\n      # a command validator will pass if the run block exits with code = 0.\n      validator: command\n      run: |\n        echo \"offloading validation to another program\"\n        ./path/to/validator --token=\"$PIRATE_TOKEN\" --name=\"$PIRATE_NAME\"\n    run: | \n      # one can call scripts from the run block, this which makes it easier\n      # to implement complex workflows\n      ./scripts/handle-new-release.sh  \"$PIRATE_BODY\"\n----\n\n== Installation\n\n=== Binaries\n\nWe provide pre-built binaries for Linux on the releases page.\n\nSee link:https://github.com/aalbacetef/pirate/releases[Releases].\n\nYou can also just run the following command:\n[source,bash]\n----\ncurl -L -s -O https://github.com/aalbacetef/pirate/releases/download/v0.1.1/pirate \u0026\u0026 chmod +x ./pirate\n----\n\n=== Docker \n\nWe provide a docker image for ease of use. \n\nThe recommended way of using it is to mount your ship config as well as any needed directories. \n\nExample:\n\n[source,bash]\n----\ndocker run --rm -it \\\n  -v ./logs/:/app/logs \\\n  -v ./ship.yml:/app/ship.yml \\\n  -v /var/www/html:/app/blog-html \\\n  -p 39390:39390 \\\n  aalbacetef/pirate:latest\n----\n\n**Tips**\n\nDon't forget to set `server.host` to `0.0.0.0`. \nSome users might find it useful to set the logging to standard output, while others would prefer to mount the log directory.\n\n\n== Configuration\n\nPirate uses a YAML configuration file (`ship.yml`) to define server settings, logging, and webhook handlers.\n\n=== Server Configuration\n\nThe `server` section defines how Pirate listens for incoming webhook requests.\n\n[source,yaml]\n----\nserver:\n  host: localhost       # Optional: Defaults to 'localhost'\n  port: 3939            # Required: The port Pirate listens on\n  request-timeout: '5m0s' # Optional: Defaults to 5 minutes\n  max-header-bytes: '1k'  # Optional: Maximum size of request headers. Defaults to 1k (1024 bytes)\n\n----\n\n- *`host`* (optional) - The address Pirate binds to. Defaults to `localhost`.\n- *`port`* (required) - The port number Pirate listens on.\n- *`request-timeout`* (optional) - Maximum duration for processing a request. Defaults to `5m0s`.\n- *`max-header-bytes`* (optional) - Maximum size of request headers. Accepts values like `5k`, `10M`, `1G`, or plain numbers (e.g., `2048`). Defaults to `1k` (1024 bytes).\n\n=== Logging Configuration\n\nThe `logging` section controls where logs are stored.\n\n[source,yaml]\n----\nlogging:\n  dir: './logs'  # Required: Log directory or `:stdout:` for console output\n----\n\n* *`dir`* (required) - Directory where logs are saved.\n** If the directory does not exist, Pirate creates it with **744 permissions**.\n** Log files follow the format: `pirate.YYYY-MM-DD--HH:mm:ss.log`.\n** Special value `:stdout:` writes logs to standard output.\n\n=== Webhook Handlers\n\nThe `handlers` section defines webhook endpoints, authentication, and execution scripts.\n\n==== Example Handler\n\n[source,yaml]\n----\nhandlers:\n  - endpoint: /webhooks/simple\n    name: simple webhook handler\n    policy: drop\n    auth:\n      validator: list\n      token: \n        - alpha\n        - beta\n    run: |\n      echo \"body: $PIRATE_BODY\"\n      echo \"headers: $PIRATE_HEADERS\"\n----\n\nEach handler includes:\n\n* *`endpoint`* (required) - The URL path for this webhook (e.g., `/webhooks/simple`).\n* *`name`* (required) - A human-readable name for the handler.\n* *`policy`* (optional) - Execution policy. One of `drop`, `parallel`, `queue`. Defaults to `queue`. \n** `drop`: if webhook events come in while the handler is already running, they will be dropped.\n** `parallel`: handlers will run as webhooks come in.\n** `queue`: handlers will be queued as they come in.\n* *`auth`* (required, one of `list` or `command`) - Authentication method:\n** *`validator: list`* - Checks if the `X-Authorization` header matches one of the provided tokens.\n** *`validator: command`* - Runs a script and passes authentication if it exits with `0`.\n* *`run`* (required) - A shell script executed when the webhook is triggered. Available environment variables:\n** `$PIRATE_BODY`: The request body.\n** `$PIRATE_HEADERS`: All request headers.\n** `$PIRATE_HEADERS_\u003cHEADER_NAME\u003e`: A specific header value.\n\n==== Authentication Methods\n\n===== Token-based Authentication\n\n[source,yaml]\n----\nauth:\n  validator: list\n  token: \n    - alpha\n    - beta\n----\n\nPasses if `X-Authorization` header matches one of the values of the `token` list, in this case: `alpha` or `beta`.\n\n===== Command-based Authentication\n\n[source,yaml]\n----\nauth:\n  validator: command\n  run: |\n    echo \"running validation via a script\"\n    ./scripts/validate-user.sh \"$PIRATE_TOKEN\"\n----\n\nPasses if the run block exits with exit code 0. \nThe `X-Authorization` header's value is exposed as an environment variable: `PIRATE_TOKEN`.\nThe handler name is exposed as an environment variable: `PIRATE_NAME`.\n\n=== Running External Scripts\n\nPirate allows running external scripts to handle complex workflows.\n\n[source,yaml]\n----\nrun: |\n  ./scripts/handle-new-release.sh\n----\n\n== Notes On Security\n\n- We assume users are running **pirate** behind some reverse-proxy like NGINX so not much care has been given to reimplement features offered by it (for the MVP), like rate-limiting, but will be added in the future.\n\n- Don't use easy tokens for auth. If you need stricter checks use the command validator for more complex auth logic. In the future this will probably be passed a lot more request metadata.\n\n- **Pirate** creates its scripts by default under /tmp (which it cleans up after running). In the future this will be configurable.\n\n- **Pirate** responds with 404 even if validation fails, to not leak information. It does return a 405 if any method other than POST is used, but this shouldn't leak more information than only POST is accepted.\n\nThis tool assumes you trust yourself. If you're exposing it to the internet, make sure you know what you're doing. You’re the captain here, pirate doesn’t stop you from walking the plank if you tell it to.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faalbacetef%2Fpirate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faalbacetef%2Fpirate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faalbacetef%2Fpirate/lists"}