{"id":13645241,"url":"https://github.com/csweichel/werft","last_synced_at":"2025-07-08T15:04:43.791Z","repository":{"id":37096535,"uuid":"226575481","full_name":"csweichel/werft","owner":"csweichel","description":"Just Kubernetes Native CI","archived":false,"fork":false,"pushed_at":"2023-03-06T22:39:40.000Z","size":5195,"stargazers_count":192,"open_issues_count":52,"forks_count":39,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-07-01T21:06:17.782Z","etag":null,"topics":["continuous-integration","kubernetes"],"latest_commit_sha":null,"homepage":"https://werft.dev","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/csweichel.png","metadata":{"files":{"readme":"README.md","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}},"created_at":"2019-12-07T21:00:21.000Z","updated_at":"2025-06-27T00:45:49.000Z","dependencies_parsed_at":"2023-07-16T02:28:42.360Z","dependency_job_id":null,"html_url":"https://github.com/csweichel/werft","commit_stats":{"total_commits":273,"total_committers":19,"mean_commits":"14.368421052631579","dds":"0.35531135531135527","last_synced_commit":"9311b92c2061c7086f7bc330cc966d45b8f2f08d"},"previous_names":["32leaves/werft"],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/csweichel/werft","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csweichel%2Fwerft","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csweichel%2Fwerft/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csweichel%2Fwerft/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csweichel%2Fwerft/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/csweichel","download_url":"https://codeload.github.com/csweichel/werft/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csweichel%2Fwerft/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264292913,"owners_count":23586060,"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":["continuous-integration","kubernetes"],"created_at":"2024-08-02T01:02:31.981Z","updated_at":"2025-07-08T15:04:43.769Z","avatar_url":"https://github.com/csweichel.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/csweichel/werft) \n\n\u003ccenter\u003e\u003cimg src=\"logo.png\" width=\"200px\"\u003e\u003c/center\u003e\n\n# Werft\nWerft is a Kubernetes-native CI system. It knows no pipelines, just jobs and each job is a Kubernetes pod.\nWhat you do in that pod is up to you. We do not impose a \"declarative pipeline syntax\" or some groovy scripting language.\nInstead, Werft jobs have run Node, Golang or bash scripts in production environments.\n\n---\n- [Installation](#installation)\n  * [Github](#github)\n  * [Configuration](#configuration)\n  * [OAuth](#oauth)\n- [Setting up jobs](#setting-up-jobs)\n  * [GitHub events](#gitHub-events)\n- [Log Cutting](#log-cutting)\n  * [GitHub events](#gitHub-events)\n- [Authentication and Policies](#authentication-and-policies)\n- [Command Line Interface](#command-line-interface)\n  * [Installation](#installation-1)\n  * [Usage](#usage)\n- [Annotations](#annotations)\n- [Attribution](#attribution)\n- [Thank You](#thank-you)\n---\n\n## Installation\nThe easiest way to install Werft is using its [Helm chart](helm/).\nClone this repo, cd into `helm/` and install using \n```\nhelm dep update\nhelm upgrade --install werft .\n```\n\n### Git-hoster integration\nWerft integrates with Git hosting platforms using its plugin system.\nCurrently, werft ships with support for GitHub only ([plugins/github-repo](https://github.com/csweichel/werft/tree/cw/repo-plugins/plugins/github-repo) and [plugins/github-trigger](https://github.com/csweichel/werft/tree/cw/repo-plugins/plugins/github-trigger)).\n\nTo add support for other Git hoster, the `github-repo` plugin is a good starting point.\n\n#### GitHub\nTo use werft with GitHub you'll need a GitHub app.\nTo create the app, please [follow the steps here](https://developer.repositories.github.com/apps/building-github-apps/creating-a-github-app/).\n\nWhen creating the app, please use following values:\n\n| Parameter | Value | Description |\n| --------- | ----------- | ------- |\n| `User authorization callback URL` | `https://your-werft-installation.com/plugins/github-integration` | The `/plugins/github-integration` path is important, the domain should match your installation's `config.baseURL` |\n| `Webhook URL` | `https://your-werft-installation.com/plugins/github-integration` | The `/plugins/github-integration` path is important, the domain should match your installation's `config.baseURL` |\n| `Permissions` | Contents: Read-Only | |\n| | Commit Status: Read \u0026 Write | |\n| | Issues: Read \u0026 Write | |\n| | Pull Requests: Read \u0026 Write | |\n| `Events` | Meta | |\n| | Push | |\n| | Issue Comments | |\n\n### Configuration\n\nThe following table lists the (incomplete set of) configurable parameters of the Werft chart and their default values.\nThe helm chart's `values.yaml` is the reference for chart's configuration surface.\n\n| Parameter | Description | Default |\n| --------- | ----------- | ------- |\n| `repositories.github.webhookSecret` | Webhook Secret of your GitHub application. See [GitHub Setup](#github) | `my-webhook-secret` |\n| `repositories.github.privateKeyPath` | Path to the private key for your GitHub application. See [GitHub setup](#github) | `secrets/github-app.com` |\n| `repositories.github.appID` | AppID of your GitHub application. See [GitHub setup](#github) | `secrets/github-app.com` |\n| `repositories.github.installationID` | InstallationID of your GitHub application. Have a look at the _Advanced_ page of your GitHub app to find thi s ID. | `secrets/github-app.com` |\n| `config.baseURL` | URL of your Werft installatin | `https://demo.werft.dev` |\n| `config.timeouts.preperation` | Time a job can take to initialize | `10m` |\n| `config.timeouts.total` | Total time a job can take | `60m` |\n| `config.gcOlderThan` | Garbage Collect logs and job metadata for jobs older than the configured value | `null` |\n| `image.repository` | Image repository | `csweichel/werft` |\n| `image.tag` | Image tag | `latest` |\n| `image.pullPolicy` | Image pull policy | `Always` |\n| `replicaCount`  | Number of cert-manager replicas  | `1` |\n| `rbac.create` | If `true`, create and use RBAC resources | `true` |\n| `resources` | CPU/memory resource requests/limits | |\n| `nodeSelector` | Node labels for pod assignment | `{}` |\n| `affinity` | Node affinity for pod assignment | `{}` |\n\nSpecify each parameter using the `--set key=value[,key=value]` argument to `helm install`.\n\nAlternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example,\n\n```console\n$ helm install --name my-release -f values.yaml .\n```\n\u003e **Tip**: You can use the default [values.yaml](values.yaml)\n\n\n### OAuth\nWerft does not support OAuth by itself. However, using [OAuth Proxy](https://github.com/oauth2-proxy/oauth2-proxy) that's easy enough to add.\n\n## Setting up jobs\nWert jobs are files in your repository where one file represents one job.\nA Werft job file mainly consists of the [PodSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#podspec-v1-core) that will be run.\nWerft will add a `/workspace` mount to your pod where you'll find the checked out repository the job is running on.\n\nFor example:\n```YAML\npod:\n  containers:\n  - name: hello-world\n    image: alpine:latest\n    workingDir: /workspace\n    imagePullPolicy: IfNotPresent\n    command:\n    - sh \n    - -c\n    - |\n      echo Hello World\n      ls\n```\nThis job would print Hello World and list all files in the root of the repository.\n\nCheckout [werft's own build job](.werft/build-job.yaml) for a more complete example.\n\n\u003e **Tip**: You can use the werft CLI to create a new job using `werft init job`\n\n### GitHub events\nWerft starts jobs based on GitHub push events if the repository contains a `.werft/config.yaml` file, e.g.\n```YAML\ndefaultJob: \".werft/build-job.yaml\"\nrules:\n- path: \".werft/deploy.yaml\"\n  matchesAll:\n  - or: [\"repo.ref ~= refs/tags/\"]\n  - or: [\"trigger !== deleted\"]\n```\n\nThe example above starts `.werft/deploy.yaml` for all tags. For everything else it will start `.werft/build-job.yaml`.\n\n## Log Cutting\nWerft extracts structure from the log output its jobs produce. We call this process log cutting, because Werft understands logs as a bunch of streams/slices which have to be demultiplexed.\n\nThe default cutter in Werft expects the following syntax:\n\n| Code | Command | Description |\n| --------- | ----- | ----------- |\n| `[someID\\|PHASE] Some description here` | Enter new phase | Enters into a new phase identified by `someID` and described by `Some description here`. All output in this phase that does not explicitely name a slice will use `someID` as slice.\n| `[someID] Arbitrary output` | Log to a slice | Logs `Arbitrary output` and marks it as part of the `someID` slice.\n| `[someID\\|DONE]` | Finish a slice | Marks the `someID` slice as done. No more output is expected from this slice in this phase.\n| `[someID\\|FAIL] Reason` | Fail a slice | Marks the `someID` slice as failed becuase of `Reason`. No more output is expected from this slice in this phase. Failing a slice does not automatically fail the job.\n| `[type\\|RESULT] content` | Publish a result | Publishes `content` as result of type `type` \n\n\u003e **Tip**: You can produce this kind of log output using the Werft CLI: `werft log`\n\n## Authentication and Policies\nWerft supports authentication and API-based policies on its gRPC interface. This allows for great flexibility and control over the actions users can perform.\n\n\u003ca href=\"https://www.loom.com/share/8306d46d304c4912a33d21b8fafbea87\"\u003e\n    \u003cimg style=\"max-width:300px;\" src=\"https://cdn.loom.com/sessions/thumbnails/8306d46d304c4912a33d21b8fafbea87-with-play.gif\"\u003e\n  \u003c/a\u003e\n\n### Authentication\nAuthentication is performed using [credential helper](#credential-helper) and auth plugins. The latter are plugins which can interpret tokens send as part of the gRPC metadata, e.g. by the CLI. See [`plugins/github-auth`](plugins/github-auth) for an example auth plugin, and [`testdata/in-gitpod-config.yaml`](testdata/in-gitpod-config.yaml) for an example setup.\n\n### Policies\nWerft integrates the [Open Policy Agent](https://www.openpolicyagent.org/) to afford flexible control over which actions are allowed via the API.\nOnce enabled, all incoming gRPC calls are subject to the policy. Note: this does not affect the web UI or other plugins (e.g. the GitHub integration).\n\nTo enable API policies, set\n```YAML\nservice:\n  apiPolicy:\n    enabled: true\n    paths: \n      - testdata/policy/api.rego\n```\n\nwhere paths is a list of files or directories which contain the policies.\n\nFor each API request, werft will provide the following input to evaluate the policy:\n```json\n{\n    \"method\": \"/v1.WerftService/StartGitHubJob\",\n    \"metadata\": {\n        \":authority\": [\n            \"localhost:7777\"\n        ],\n        \"content-type\": [\n            \"application/grpc\"\n        ],\n        \"user-agent\": [\n            \"grpc-go/1.36.1\"\n        ],\n        \"x-auth-token\": [\n            \"some-value\"\n        ]\n    },\n    \"message\": {\n        \"metadata\": {\n            \"owner\": \"Christian Weichel\",\n            \"repository\": {\n                \"host\": \"github.com\",\n                \"owner\": \"csweichel\",\n                \"repo\": \"werft\",\n                \"ref\": \"refs/heads/csweichel/support-token-based-access-116\",\n                \"revision\": \"d2c02a67c6e13fc5c3b3f5afb3ae60a66add5caa\"\n            },\n            \"trigger\": 1\n        }\n    },\n    \"auth\": {\n        \"known\": true,\n        \"username\": \"csweichel\",\n        \"metadata\": {\n            \"name\": \"Christian Weichel\",\n            \"two-factor-authentication\": \"true\"\n        },\n        \"emails\": [\n            \"some@mail.com\"\n        ]\n    }\n}\n```\nThe auth section is present only when an [authentication plugin](#authentication) is configured, a token was sent, and the token/user is known to the auth plugins.\n\nYou can find an example policy in [`testdata/policy/api.rego`](testdata/policy/api.rego).\n\n## Command Line Interface\nWerft sports a powerful CLI which can be used to create, list, start and listen to jobs.\n\n### Installation\nThe Werft CLI is available on the [GitHub release page](https://github.com/csweichel/werft/releases), or using this one-liner:\n```bash\ncurl -L werft.dev/get-cli.sh | sh\n```\n\n### Usage\n```\nwerft is a very simple GitHub triggered and Kubernetes powered CI system\n\nUsage:\n  werft [command]\n\nAvailable Commands:\n  help        Help about any command\n  init        Initializes configuration for werft\n  job         Interacts with currently running or previously run jobs\n  log         Prints log-cuttable content\n  run         Starts the execution of a job\n  version     Prints the version of this binary\n\nFlags:\n  -h, --help          help for werft\n      --host string   werft host to talk to (defaults to WERFT_HOST env var) (default \"localhost:7777\")\n      --verbose       en/disable verbose logging\n\nUse \"werft [command] --help\" for more information about a command.\n```\n\n### Credential Helper\nThe werft CLI can send authentication tokens to werft, which are intepreted by the auth plugins for use with OPA policies. \nA credential helper is a program which prints a token on stdout and exits with code 0. Any other exit code will result in an error.\nThe token is opaque to werft and interpreted by auth plugins (see [Authentication and Policies](#authentication-and-policies)).\n\nWerft's CLI will pass context as a single line JSON via stdin to the credential helper. See `testdata/credential-helper.sh` for an example.\n\nTo enable this feature, set the `WERFT_CREDENTIAL_HELPER` env var to the command you would like to execute.\n\n## Annotations\nAnnotations are used by your werft job to make runtime decesions. Werft supports passing annotation in three ways:\n\n1. From PR description\n\nYou can add annotations in the following form to your Pull request description and werft will pick them up\n```sh\n/werft someAnnotation\n/werft someAnnotation=foobar\n- [x] /werft someAnnotation\n- [x] /werft someAnnotation=foobar\n```\n2. From Git commit\n\nWerft supports same format as above to pass annotations via commit message. Werft will use the top most commit only.\n\n3. From CLI\n```sh\nwerft run github -a someAnnotation=foobar\n```\n## Attribution\n\nLogo based on [Shipyard Vectors by Vecteezy](https://www.vecteezy.com/free-vector/shipyard)\n\n## Thank You\nThank you to our contributors:\n\n- [csweichel](https://github.com/csweichel)\n- [corneliusludmann](https://github.com/corneliusludmann)\n- [jankeromnes](https://github.com/jankeromnes)\n- [JesterOrNot](https://github.com/JesterOrNot)\n- [IQQBot](https://github.com/IQQBot)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsweichel%2Fwerft","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcsweichel%2Fwerft","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsweichel%2Fwerft/lists"}