{"id":29210684,"url":"https://github.com/embarkstudios/k8s-buildkite-plugin","last_synced_at":"2026-02-07T14:02:10.335Z","repository":{"id":35661719,"uuid":"186636597","full_name":"EmbarkStudios/k8s-buildkite-plugin","owner":"EmbarkStudios","description":"Run any buildkite build step as a Kubernetes Job","archived":false,"fork":false,"pushed_at":"2025-09-22T08:40:10.000Z","size":117,"stargazers_count":52,"open_issues_count":6,"forks_count":17,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-02-02T07:47:17.337Z","etag":null,"topics":["buildkite","buildkite-plugin","ci","hacktoberfest","jsonnet","k8s","kubernetes"],"latest_commit_sha":null,"homepage":"https://embark.dev","language":"Jsonnet","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EmbarkStudios.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE-APACHE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-05-14T14:13:00.000Z","updated_at":"2025-12-04T08:25:57.000Z","dependencies_parsed_at":"2025-07-02T21:07:38.481Z","dependency_job_id":"f072932b-a5e9-4020-94a0-341903455af3","html_url":"https://github.com/EmbarkStudios/k8s-buildkite-plugin","commit_stats":null,"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"purl":"pkg:github/EmbarkStudios/k8s-buildkite-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmbarkStudios%2Fk8s-buildkite-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmbarkStudios%2Fk8s-buildkite-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmbarkStudios%2Fk8s-buildkite-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmbarkStudios%2Fk8s-buildkite-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EmbarkStudios","download_url":"https://codeload.github.com/EmbarkStudios/k8s-buildkite-plugin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmbarkStudios%2Fk8s-buildkite-plugin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29196616,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T12:38:28.597Z","status":"ssl_error","status_checked_at":"2026-02-07T12:38:23.888Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["buildkite","buildkite-plugin","ci","hacktoberfest","jsonnet","k8s","kubernetes"],"created_at":"2025-07-02T21:07:34.684Z","updated_at":"2026-02-07T14:02:10.316Z","avatar_url":"https://github.com/EmbarkStudios.png","language":"Jsonnet","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kubernetes Buildkite Plugin\n\n[![Build Status](https://badge.buildkite.com/c061bcad854e7a95c03d1baebfab8a01dc25768dab272dd8e5.svg)](https://buildkite.com/embark-studios/k8s-buildkite-plugin)\n[![Contributor Covenant](https://img.shields.io/badge/contributor%20covenant-v1.4%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md)\n[![Embark](https://img.shields.io/badge/embark-open%20source-blueviolet.svg)](https://github.com/EmbarkStudios)\n\nAn opinionated [Buildkite plugin](https://buildkite.com/docs/agent/v3/plugins) for running pipeline steps as [Kubernetes Jobs](https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/) on a cluster with minimal effort.\n\nThe plugin tries to stay reasonably compatible with the [Docker plugin](https://github.com/buildkite-plugins/docker-buildkite-plugin) to make it easy to change pipelines to run on a cluster. It also takes lots of inspiration from the [kustomize-job-buildkite-plugin](https://github.com/MYOB-Technology/kustomize-job-buildkite-plugin).\n\n## Quirks \u0026 Issues\n\nSince the step isn't actually performed by the build-agent itself, but in a separately scheduled (and isolated) container, a few things don't work as on a \"normal\" build-agent.\n\nThe build step container will have the `buildkite-agent` binary mounted at `/usr/local/bin/buildkite-agent` to allow using the agent subcommands for annotations, metadata and artifacts directly.\n\nThis behavior may be disabled by setting `mount-buildkite-agent: false` in the pipeline.\n\n\u003e ** Note: ** The user is responsible for making sure the container specified in `image` contains any external dependencies required by the otherwise statically linked buildkite-agent binary. This includes certificate authorities, and possibly git and ssh depending on how it's being used.\n\n### Build artifacts\n\nAs the build-agent doesn't run in the same container as the actual commands, automatic upload of artifacts specified in `artifact_paths` won't work.\nA workaround to this is to run `buildkite-agent artifact upload ...` as a command in the step itself.\n\n\n## Example\n\n```yaml\nsteps:\n  - command: \"echo 'Hello, World!'\"\n    plugins:\n      - EmbarkStudios/k8s:\n          image: alpine\n```\n\nIf you want to control how your command is passed to the container, you can use the `command` parameter on the plugin directly:\n\n```yaml\nsteps:\n  - plugins:\n      - EmbarkStudios/k8s:\n          image: \"embarkstudios/fortune\"\n          always-pull: true\n          command: [\"startrek\"]\n```\n\nYou can pass in additional environment variables, including values from a [Secret](https://kubernetes.io/docs/concepts/configuration/secret/):\n\n```yaml\nsteps:\n  - command:\n      - \"yarn install\"\n      - \"yarn run test\"\n    plugins:\n      - EmbarkStudios/k8s:\n          image: \"node:7\"\n          environment:\n            - \"MY_SPECIAL_BUT_PUBLIC_VALUE=kittens\"\n          environment-from-secret:\n            - \"kitten-secrets\"\n```\n\nUsing External Secrets\n```yaml\nsteps:\n  - command:\n      - az login -u $(\u003c /externalsecrets/azuser) -p $(\u003c /externalsecrets/azpassword)\n    plugins:\n      - EmbarkStudios/k8s:\n          image: mcr.microsoft.com/azure-cli\n          secret-store: vault-external-store\n          external-secrets:\n          - \"azuser:secret/azure:azure-user\"\n          - \"azpassword:secret/azure:azure-password\"\n```\n\n## Configuration\n\n### Required\n\n### `image` (required, string)\n\nThe name of the container image to use.\n\nExample: `golang:1.12.5`\n\n### Optional\n\n### `always-pull` (optional, boolean)\n\nWhether to always pull the latest image before running the command. Sets [imagePullPolicy](https://kubernetes.io/docs/concepts/containers/images/#updating-images) on the container. If `false`, the value `IfNotPresent` is used.\n\nDefault: `false`\n\n### ``image-pull-secret`` (optional, string)\n\nThe name of the secret that holds the credentials for a remote container registry.\n\n\n### `command` (optional, array)\n\nSets the command for the container. Useful if the container image has an entrypoint, but requires extra arguments.\n\nNote that [this has different meaning than in Docker](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#notes). This sets the `args` field for the Container.\n\nThis option can't be used if your step already has a top-level, non-plugin `command` option present.\n\nExamples: `[ \"/bin/mycommand\", \"-c\", \"test\" ]`, `[\"arg1\", \"arg2\"]`\n\n### `entrypoint` (optional, string)\n\nOverride the image’s default entrypoint.\n\nNote that [this has different meaning than in Docker](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#notes). This sets the `command` field for the Container.\n\nExample: `/my/custom/entrypoint.sh`\n\n### `environment` (optional, array)\n\nAn array of additional environment variables to pass into to the docker container. Items can be specified as `KEY=value`.\n\nExample: `[ \"FOO=bar\", \"MY_SPECIAL_BUT_PUBLIC_VALUE=kittens\" ]`\n\n### `environment-from-secret` (optional, string or array)\n\nOne or more [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) that should be added to the container as environment variables. Each key in the secret will be exposed as an environment variable. If specified as an array, all listed secrets will be added in order.\n\nExample: `my-secrets`\n\n### `init-environment-from-secret` (optional, string or array)\n\nOne or more [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) that should be added to the [job init container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) as environment variables. Each key in the secret will be exposed as an environment variable. If specified as an array, all listed secrets will be added in order.\n\nExample: `my-secrets`\n\n### `init-image` (optional, string)\n\nOverride the [job initContainer](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/). A buildkite-agent binary is expected to exist to do the checkout, along with git and ssh. The default is to use a public image based on the Dockerfile in this repository. If set to an empty string no init container is used.\n\nExample: `embarkstudios/k8s:1.0.0`\n\n### `privileged` (optional, boolean)\n\nWether to run the container in [privileged mode](https://kubernetes.io/docs/concepts/workloads/pods/pod/#privileged-mode-for-pod-containers).\n\n### `secret-name` (optional, string)\n\nThe name of the secret containing the buildkite agent token and, optionally, ssh or git credentials used for bootstrapping in the init container.\n\n### `agent-token-secret-key` (optional, string)\n\nThe key of the secret value containing the buildkite agent token, within the secret specified in `secret-name`.\n\n### `git-credentials-secret-name` (optional, string)\n\nThe name of the secret containing the git credentials used for checking out source code with HTTPS.\n\n### `git-credentials-secret-key` (optional, string)\n\nThe key of the secret value containing the git credentials used for checking out source code with HTTPS.\n\nThe contents of this file will be used as the [git credential store](https://git-scm.com/docs/git-credential-store) file.\n\n### `git-ssh-secret-name` (optional, string)\n\nThe name of the secret containing the git credentials used for checking out source code with SSH.\n\n### `git-ssh-secret-key` (optional, string)\n\nThe key of the secret value containing the SSH key used when checking out source code with SSH as transport.\n\n### `mount-hostpath` (optional, string or array)\n\nMount a host path as a directory inside the container. Must be in the form of `/host/path:/some/mount/path`.\nMultiple host paths may be mounted by specifying a list of host/mount pairs.\n\nExample: `my-secret:/my/secret`\n\n### `mount-secret` (optional, string or array)\n\nMount a secret as a directory inside the container. Must be in the form of `secretName:/some/mount/path`.\nMultiple secrets may be mounted by specifying a list of secret/mount pairs.\n\nExample: `my-secret:/my/secret`\n\n### `mount-secret-permissions` (optional, string)\n\nThe file permissions for mounted secrets. Must be a decimal number representing the octal file mode.\n\nDefault: `256` (octal `0400` - read-only for owner)\nCommon values: `420` (octal `0644` - readable by all), `292` (octal `0444` - read-only for all)\n\nExample: `420`\n\n### `default-secret-name` (optional, string)\n\nThe name of the secret containing the buildkite agent token, ssh and git credentials used for bootstrapping in the init container. The key names of the secret are not configurable and as such must contain the following:\n```yaml\n  buildkite-agent-token: \u003ctoken\u003e\n  git-credentials: \u003ccredentials\u003e\n  ssh-key: \u003csshkey\u003e\n```\nThis is useful if you have control over secret creation and would like to avoid explicitly providing the key and secret names.\n\nExample: `buildkite-secret`\n\n### `external-secrets` (optional, string or array)\n\n**The [External Secrets Operator](https://external-secrets.io/) must be installed in your cluster to use the ``external-secrets`` arguments**.\n\nMount one or many secrets as a directory inside the container from an external source using [ExternalSecrets](https://external-secrets.io/). Must be in the form `secretKey:externalProperty:externalKey`.\n\n`external-secrets-mount-path` can be set to change where the secrets are mounted, but they must all be mounted to the same location.\n`secret-store` or `cluster-store` must be defined to specify what existing SecretStore to pull data from. Only one can be defined.\n\nExample\n```yaml\nsecret-store: vault-backend\nexternal-secrets:\n- \"ciPassword:secret/dev/ci:ci-password\"\n- \"ciUser:secret/dev/ci:ci-user\"\n```\n\nWill create an ExternalSecret resource pulling from the vault-backend Secret Store, which will create a secret with keys `ciPassword` and `ciUser` using the values from the `secret/dev/ci` properties and `ci-password` and `ci-user` keys.\n\n**This has only been tested with Vault, other keystores may or may not function as expected**\n\n### `secret-store` (optional, string)\n\nDescribes the SecretStore to pull ExternalSecrets from.\n\nMust be used with the ``external-secrets`` argument and cannot be used with the `cluster-store` argument\n\n### `cluster-store` (optional, string)\n\nDescribes the ClusterStore to pull ExternalSecrets from.\n\nMust be used with the ``external-secrets`` argument and cannot be used with the ``secret-store`` argument\n\n### `mount-path-external-secrets` (optional,string)\n\nSets the mount path of the external secrets\n\nDefault: ``/externalsecrets``\n\n### `build-path-host-path` (optional, string)\n\nOptionally mount a [host path](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) to be used as base directory for buildkite builds. This allows local caching and incremental builds using fast local storage.\n\nShould be used with some care, since the actual storage used is outside the control of Kubernetes itself.\n\nExample: `/var/lib/buildkite/builds`\n\n### `build-path-pvc` (optional, string)\n\nOptionally mount an existing [Persistent Volume Claim](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) used as backing storage for the build.\n\n### `git-mirrors-host-path` (optional, string)\n\nOptionally mount a [host path](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) to be used as [git-mirrors](https://forum.buildkite.community/t/shared-git-repository-checkouts-in-the-agent/443) path. This enables multiple pipelines to share a single git repository.\n\nShould be used with some care, since the actual storage used is outside the control of Kubernetes itself.\n\nExample: `/var/lib/buildkite/builds`\n\n### `resources-request-cpu` (optional, string)\n\nSets [cpu request](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) for the build container.\n\n### `resources-limit-cpu` (optional, string)\n\nSets [cpu limit](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) for the build container.\n\n### `resources-request-memory` (optional, string)\n\nSets [memory request](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) for the build container.\n\n### `resources-limit-memory` (optional, string)\n\nSets [memory limit](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) for the build container.\n\n### `service-account-name` (optional, string)\n\nSets the [service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) for the build container.\n\nDefault: `default`\n\n### `use-agent-node-affinity` (optional, boolean)\n\nIf set to `true`, the spawned jobs will use the same [node affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/), [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/), and [nodeSelector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) as the buildkite agent.\n\n### `workdir` (optional, string)\n\nOverride the working directory to run the command in, inside the container. The default is the build directory where the buildkite bootstrap and git checkout runs.\n\n### `patch` (optional, string)\n\n(Advanced / hack use). Provide a [jsonnet](https://jsonnet.org/) function to transform the resulting job manifest.\n\nExample:\n```\npatch: |\n  function(job) job {\n    spec+: {\n      template+: {\n        spec+: {\n          tolerations: [ { key: 'foo', value: 'bar', operator: 'Equal', effect: 'NoSchedule' }, ],\n        },\n      },\n    },\n  }\n```\n\n### `print-resulting-job-spec` (optional, boolean)\n\nIf set to `true`, the resulting k8s job spec is printed to the log. This can be useful when debugging.\n\n### `print-resulting-secret-spec` (optional, boolean)\n\nIf external secrets are being used, will print the secret spec to the log. This can be useful when debugging.\n\n### `job-backoff-limit` (optional, integer)\n\nConfigures [`spec.backoffLimit`](https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy) to enable retries of job's pod creation.\nDefault value: `0`.\n\n### `job-ttl-seconds-after-finished` (optional, integer)\n\nConfigures [`spec.ttlSecondsAfterFinished`](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/) on the k8s job, requires TTL Controller enabled in the cluster, otherwise ignored.\nDefault value: `86400`.\n\n### `jobs-cleanup-via-plugin` (optional, boolean)\n\nIf set to `true`, the plugin cleans up k8s jobs older than 1 day even if they're still running.\nDefault value: `true`.\n\nIf you have [TTL Controller](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/) enabled or some other means to cleanup finished jobs, it is recommended to set the value to `false` in order to reduce load on k8s api servers.\n\n### `job-cleanup-after-finished-via-plugin` (optional, boolean)\n\nIf set to `true` plugin cleans up finished k8s job.\nDefault value: `true`.\n\nIf you have TTL controller or https://github.com/lwolf/kube-cleanup-operator running, it is highly recommended to set the value to `false` to reduce load on k8s api servers.\n\n## Low Level Configuration via Environment Variables\n\nSome of the plugin options can be configured via environment variables as following ([also see Buildkite docs](https://buildkite.com/docs/pipelines/environment-variables#defining-your-own)):\n\n```yaml\nenv:\n  BUILDKITE_PLUGIN_K8S_JOB_APPLY_RETRY_INTERVAL_SEC: \"10\"\n```\n\n### BUILDKITE_PLUGIN_K8S_JOB_APPLY_RETRY_INTERVAL_SEC\n\n- Configures the interval between attempts to schedule the k8s job\n- Default: `5`\n- Unit type: integer seconds\n\n### BUILDKITE_PLUGIN_K8S_JOB_APPLY_TIMEOUT_SEC\n\n- Configures the total time limit across attempts to schedule the k8s job\n- Default: `120`\n- Unit type: integer seconds\n\n### BUILDKITE_PLUGIN_K8S_JOB_STATUS_RETRY_INTERVAL_SEC\n\n- Configures the interval between attempts to get k8s job status\n- Default: `5`\n- Unit type: integer seconds\n\n### BUILDKITE_PLUGIN_K8S_LOG_COMPLETE_RETRY_INTERVAL_SEC\n\n- Configures the interval between attempts to verify that log streaming has ended\n- Default: `1`\n- Unit type: integer seconds\n\n### BUILDKITE_PLUGIN_K8S_LOG_COMPLETE_TIMEOUT_SEC\n\n- Configures the total time limit across attempts to verify that log streaming has ended\n- Default: `30`\n- Unit type: integer seconds\n\n### BUILDKITE_PLUGIN_K8S_LOG_RETRY_INTERVAL_SEC\n\n- Configures the interval between attempts to stream job logs\n- Default: `3`\n- Unit type: integer seconds\n\n### BUILDKITE_PLUGIN_K8S_LOG_ATTEMPT_TIMEOUT_SEC\n\n- Configures time limit for a _single_ plugin attempt to stream job logs\n- Default: `5`\n- Unit type: integer seconds\n\n### BUILDKITE_PLUGIN_K8S_JOB_CLEANUP_RETRY_INTERVAL_SEC\n\n- Configures the interval between attempts to cleanup finished jobs\n- Default: `5`\n- Unit type: integer seconds\n\n### BUILDKITE_PLUGIN_K8S_JOB_CLEANUP_TIMEOUT_SEC\n\n- Configures the total time limit across attempts to cleanup finished jobs\n- Default: `60`\n- Unit type: integer seconds\n\n## Contributing\n\nWe welcome community contributions to this project.\n\nPlease read our [Contributor Guide](CONTRIBUTING.md) for more information on how to get started.\n\n## License\n\nLicensed under either of\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fembarkstudios%2Fk8s-buildkite-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fembarkstudios%2Fk8s-buildkite-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fembarkstudios%2Fk8s-buildkite-plugin/lists"}