Repository navigation
Releases
Vesper v0.2.0-rc.2
Second release candidate of v0.2. It fixes the one bug found by the
end-to-end test on a real server with a GitHub App.
Fixed: after a push, the preview could stay on the previous commit
until the next resync (up to 10 minutes). GitHub reports a workflow run
as completed slightly before its API does. Vesper now checks a running
build again every 30 seconds instead of waiting for the next event.
Upgrade from rc.1: apply the install.yaml and install-github.yaml
of this release. Nothing else changes.
Changelog
Bug fixes
- fix(integrations): check a running build again, not only on the next event (#185) (@damnthonyy)
Verify the downloads
shasum -a 256 --check --ignore-missing checksums.txt
gh attestation verify vesperctl_0.2.0-rc.2_linux_amd64.tar.gz --repo eventide-oss/vesperThe second command checks that the archive was built from this
repository by its release workflow. See docs/release.md.
Vesper v0.2.0-rc.1
The first release candidate of v0.2: the GitHub integration. A pull request gets its preview by itself, and Vesper shows its state on it, with a deployment and one comment (ADR-0007).
vesper-github, the webhook endpoint of a GitHub App, installed with the newinstall-github.yaml;PreviewSource, to allow a repository and set the defaults of its previews;- every pull request gets a preview once its image is built;
no-previewstops one, each commit resets its TTL; - the docs site, the comparison with Argo CD and Flux, and isolation verified on Calico and Cilium.
A release candidate, for testing: v0.1.0 stays the latest release. Thanks to @Ranjithsingh2004 for the first external contributions: a troubleshooting page and vesperctl version -o json.
Changelog
Features
- feat(api): add PreviewSource to allow repositories and set their defaults (#174) (@damnthonyy)
- feat(cli): print the version as JSON (#152) (@Ranjithsingh2004)
- feat(integrations): add vesper-github, the webhook endpoint of the GitHub App (#176) (@damnthonyy)
- feat(integrations): authenticate GitHub webhook deliveries (#175) (@damnthonyy)
- feat(integrations): decide the preview of a pull request (#178) (@damnthonyy)
- feat(integrations): show the state of a preview on its pull request (#181) (@damnthonyy)
- feat(integrations): talk to GitHub as the GitHub App (#177) (@damnthonyy)
- feat(integrations): turn pull requests into previews (#179) (@damnthonyy)
- feat(integrations): write deployments and the comment of a preview (#180) (@damnthonyy)
Other changes
- chore(docs): add a troubleshooting page (#150) (@Ranjithsingh2004)
- ci(release): publish the manifests of vesper-github (#183) (@damnthonyy)
- docs(adr): design the GitHub integration (#173) (@damnthonyy)
- docs: add a landing page to the documentation site (#165) (@damnthonyy)
- docs: adopt the Vesper visual identity in the README (#163) (@damnthonyy)
- docs: explain how Vesper compares with Argo CD and Flux (#171) (@damnthonyy)
- docs: publish the documentation as a site on GitHub Pages (#164) (@damnthonyy)
- test(cli): make TestList independent of the second it runs in (#170) (@damnthonyy)
- test(networking): verify preview isolation on Calico and Cilium (#169) (@damnthonyy)
Verify the downloads
shasum -a 256 --check --ignore-missing checksums.txt
gh attestation verify vesperctl_0.2.0-rc.1_linux_amd64.tar.gz --repo eventide-oss/vesperThe second command checks that the archive was built from this
repository by its release workflow. See docs/release.md.
Vesper v0.1.0
The first release of Vesper: ephemeral preview environments for Kubernetes. You declare a PreviewEnvironment; Vesper runs it in a namespace of its own, gives it an address, and deletes it, namespace included, when its time to live ends.
What's in v0.1.0
- An isolated namespace per preview: the restricted Pod Security profile, a ResourceQuota, a LimitRange and a default-deny NetworkPolicy that keeps a preview away from the other previews, from the rest of the cluster and from the API server and kubelets of the nodes.
- A public address: with
--preview-domain, each preview gets an Ingress through the ingress controller of the cluster, over HTTPS with--preview-tlsand a wildcard certificate. - A lifetime: a TTL from 1 minute to 7 days (24 hours by default). When it passes, the preview and its namespace are deleted; a finalizer makes sure the cleanup runs.
vesperctl:create,list,get,extendanddelete, as a table, JSON or YAML, with documented exit codes.vesperctl getshows the phase, the URL, the expiry, the conditions and the events.- Readable status: the conditions
Ready,AvailableandExpiredwith a reason, and Kubernetes events at each change. - Prometheus metrics: the previews per phase and the expiries, behind authentication.
- A verifiable release: binaries for Linux, macOS and Windows (amd64 and arm64), checksums, build provenance attestations, and a multi-platform image that runs as a non-root user, pinned by digest in
install.yaml. Built with Go 1.27.4.
Install
kubectl apply -f https://github.com/eventide-oss/vesper/releases/download/v0.1.0/install.yaml
kubectl -n vesper-system rollout status deploy/vesper-controller-managerThen follow the quickstart on a local kind cluster, or try Vesper on a server with k3s, a domain and HTTPS. To keep operator flags such as --preview-domain across upgrades, use a kustomize overlay, as the quickstart shows.
Verify the downloads
shasum -a 256 --check --ignore-missing checksums.txt
gh attestation verify install.yaml --repo eventide-oss/vesper
gh attestation verify "oci://$(grep -o 'ghcr.io/eventide-oss/vesper:[^ ]*' install.yaml)" --repo eventide-oss/vesperUpgrading from a release candidate
Apply the install.yaml of v0.1.0 over the release candidate: the API is the same v1alpha1, and running previews are kept. The release candidates before rc.2 have an isolation gap (GHSA-m437-fj8p-6x8h), and every release candidate was built with Go 1.27.3 (GO-2026-6859): upgrade.
Known limits
- A namespace is a soft boundary: Vesper isolates previews from each other, but does not promise hard multi-tenant isolation. See the security model.
- The API is
v1alpha1: it may change before v1.0. - A preview runs one application from one image. You create it yourself, with
vesperctlorkubectl.
What's next
v0.2 creates, updates and deletes previews from pull requests, through a GitHub App that posts the URL of the preview on the pull request. Follow the milestone, and the good first issues if you want to help.
Changes since v0.1.0-rc.3
Vesper v0.1.0-rc.3
The third release candidate of Vesper, and the one checked against the v0.1 acceptance criteria. If it passes, v0.1.0 is cut from the same commit.
What changed since rc.2
vesperctl getshows the events of a preview: the last 10 events the operator recorded, oldest first, after the conditions, askubectl describedoes. Only the events of this preview are shown, not those of an earlier one with the same name; a user who cannot read events gets a note, not an error. The JSON and YAML output is unchanged.- Documentation: a quickstart on kind, a guide to try Vesper on a server with k3s and HTTPS, the security model, the architecture and a generated CRD reference.
- Project: every Go file carries a license header, checked in CI.
Install
kubectl apply -f https://github.com/eventide-oss/vesper/releases/download/v0.1.0-rc.3/install.yaml
kubectl -n vesper-system rollout status deploy/vesper-controller-managerTo keep operator flags such as --preview-domain across upgrades, use a kustomize overlay, as the quickstart shows.
Verify the downloads
shasum -a 256 --check --ignore-missing checksums.txt
gh attestation verify install.yaml --repo eventide-oss/vesper
gh attestation verify "oci://$(grep -o 'ghcr.io/eventide-oss/vesper:[^ ]*' install.yaml)" --repo eventide-oss/vesperKnown limits
- This is a release candidate: try it, do not run it in production yet.
- A namespace is a soft boundary: Vesper isolates previews from each other, but does not promise hard multi-tenant isolation. See the security model.
- The API is
v1alpha1: it may change before v1.0.
Changelog
Features
- feat(cli): show the events of a preview in vesperctl get (#151) (@damnthonyy)
Other changes
- docs(security): describe the security model and its limits (#135) (@damnthonyy)
- docs: add a quickstart on kind (#136) (@damnthonyy)
- docs: add the CRD reference and an architecture overview (#137) (@damnthonyy)
- docs: polish the README and check license headers (#138) (@damnthonyy)
- docs: try Vesper on a server with k3s (#134) (@damnthonyy)
Vesper v0.1.0-rc.2
The second release candidate of Vesper. It fixes a gap in the network isolation of previews found while running v0.1.0-rc.1 on a real server: upgrade from v0.1.0-rc.1.
Security fix
On a cluster whose nodes have public addresses, such as k3s on a VPS, a preview could open connections to the Kubernetes API server and to the services of the nodes (the kubelet, NodePort Services) through those addresses. It got no credentials, and the API server and the kubelet required authentication, but ADR-0005 states that previews cannot reach them. Clusters whose nodes only have private addresses, such as kind, were not affected.
The operator now reads the addresses of the nodes and of the API server, and denies the public ones to every preview, keeping the policy up to date when they change. It needs two new read-only rights, on nodes and endpointslices, which come with install.yaml.
As a consequence, a preview can no longer call a public URL served by the same cluster, such as another preview.
Advisory: GHSA-m437-fj8p-6x8h.
Also new
- The operator logs its version when it starts:
Starting Vesper {"version": "v0.1.0-rc.2"}.
Upgrade
kubectl apply -f https://github.com/eventide-oss/vesper/releases/download/v0.1.0-rc.2/install.yaml
kubectl -n vesper-system rollout status deploy/vesper-controller-managerApplying install.yaml resets the arguments of the operator: add --preview-domain (and --preview-tls) again if you set them.
Verify the downloads
shasum -a 256 --check --ignore-missing checksums.txt
gh attestation verify install.yaml --repo eventide-oss/vesper
gh attestation verify "oci://$(grep -o 'ghcr.io/eventide-oss/vesper:[^ ]*' install.yaml)" --repo eventide-oss/vesperKnown limits
- This is a release candidate: try it, do not run it in production yet.
- A namespace is a soft boundary: Vesper isolates previews from each other, but does not promise hard multi-tenant isolation.
- The API is
v1alpha1: it may change before v1.0.
Changelog
Bug fixes
- fix(security): deny the public addresses of the cluster to previews (GHSA-m437-fj8p-6x8h)
Vesper v0.1.0-rc.1
The first release candidate of Vesper: a Kubernetes operator and its CLI, vesperctl, that give every pull request a preview environment of its own, isolated in its own namespace, reachable at its own address, and deleted when its time is up.
This candidate is for trying Vesper on a cluster of your own: do not run it in production yet. Feedback is welcome in the issues.
Highlights
- One resource per preview. A
PreviewEnvironment(vesper.eventide.dev/v1alpha1) names an image, pinned by tag or digest (neverlatest), a port, replicas, environment variables and a lifetime between 1 minute and 7 days. The API server checks every field before the operator sees it. - Isolated by default. Each preview runs in a namespace of its own, with the Pod Security
restrictedprofile, a ResourceQuota and a LimitRange, a NetworkPolicy that denies everything but the traffic it needs, and no ServiceAccount token. - A public address. With
--preview-domain, each preview gets an Ingress and a URL; with--preview-tls, over HTTPS, using the wildcard certificate of the ingress controller, so no private key ever lands in a preview namespace. - A lifecycle you can follow. Previews expire after their TTL and can be extended; a finalizer cleans everything up; conditions and events say what happens and why.
vesperctl.list,get,create,extendanddelete, with table, JSON or YAML output and stable exit codes.- Metrics. Prometheus metrics of previews per phase and of expirations, behind authentication.
- A verifiable release.
vesperctlfor Linux, macOS and Windows (amd64 and arm64), a multi-arch operator image that runs as a non-root user, and aninstall.yamlthat pins that image by digest. Every file and the image carry a signed provenance attestation.
Install
kubectl apply -f https://github.com/eventide-oss/vesper/releases/download/v0.1.0-rc.1/install.yaml
kubectl -n vesper-system rollout status deploy/vesper-controller-managerThen create a preview:
vesperctl create demo --image nginxinc/nginx-unprivileged:1.27-alpine --port 8080 --ttl 2h
vesperctl get demoThe operator image is ghcr.io/eventide-oss/vesper:v0.1.0-rc.1. To give previews a public address, set --preview-domain (and --preview-tls) on the operator, as docs/development.md describes.
Verify the downloads
shasum -a 256 --check --ignore-missing checksums.txt
gh attestation verify install.yaml --repo eventide-oss/vesper
gh attestation verify "oci://$(grep -o 'ghcr.io/eventide-oss/vesper:[^ ]*' install.yaml)" --repo eventide-oss/vesperKnown limits
- A namespace is a soft boundary: Vesper isolates previews from each other, but does not promise hard multi-tenant isolation. Do not run untrusted code next to sensitive workloads.
- Previews are created with
vesperctlorkubectl. Pull requests creating their own previews, private images and protected URLs come with v0.2 (milestone P5). - The API is
v1alpha1: it may change before v1.0.
Changelog
Features
- feat(api): add status, conditions and printer columns (#81)
- feat(api): define PreviewEnvironment v1alpha1 spec with validation (#79)
- feat(api): show where a preview runs in status.namespace (#115)
- feat(cli): add Kubernetes client factory with client-go (#69)
- feat(cli): add
vesperctl get <name>(#71) - feat(cli): add
vesperctl list(#70) - feat(cli): add global flags (kubeconfig, context, namespace) (#68)
- feat(cli): add output formats (table, json, yaml) (#72)
- feat(cli): add vesperctl create (#110)
- feat(cli): add vesperctl delete with confirmation (#114)
- feat(cli): add vesperctl extend (#113)
- feat(cli): add vesperctl version command (#10)
- feat(cli): adopt Cobra and migrate the version command (#67)
- feat(cli): consistent errors, exit codes and shell completion (#73)
- feat(controller): create the Deployment from the image (#85)
- feat(controller): create the Service of a preview (#87)
- feat(controller): derive the public host name of a preview (#102)
- feat(controller): reconciler skeleton and namespace per preview (#83)
- feat(controller): report the state of a preview in conditions and events (#108)
- feat(controller): track preview objects with labels instead of owner references (#88)
- feat(lifecycle): TTL expiry with requeue and ADR-0004 (#98)
- feat(lifecycle): finalizer and clean deletion (#97)
- feat(networking): expose a preview with an Ingress hostname (#103)
- feat(networking): serve previews over HTTPS with --preview-tls (#119)
- feat(observability): add Prometheus metrics for previews (#118)
- feat(operator): scaffold the operator with Kubebuilder (#78)
- feat(security): bound the resources of each preview (#104)
- feat(security): isolate each preview with a NetworkPolicy (#105)
- feat(security): keep previews restricted and trim operator rights (#106)
Other changes
- Initial commit
- build(release): add GoReleaser config for vesperctl (#121)
- chore(deps): configure Dependabot for Go modules and Actions (#62)
- chore(dev): add kind dev cluster and make targets (#61)
- chore(release): publish operator image and install bundle (#123)
- chore: add FUNDING.yml (#77)
- chore: bootstrap contribution conventions (#2)
- chore: initialize Go module and repository layout (#5)
- chore: upgrade Go to 1.27.3 and the tools that depend on it (#8)
- ci(release): release on version tags with notes and provenance (#122)
- ci: add workflow for vet, test, lint and vulncheck (#6)
- ci: enforce DCO sign-off on pull requests (#63)
- ci: generate manifests in CI and fail on drift (#93)
- docs: add ADR template, ADR-0001 and learning journal (#66)
- docs: add CONTRIBUTING, CODE_OF_CONDUCT and GOVERNANCE (#64)
- docs: add SECURITY policy and issue templates (#65)
- docs: add a cheat sheet of the everyday commands (#112)
- docs: explain previews and the project status in the README (#76)
- docs: record the namespace per preview and CRD scope decisions (#94)
- docs: turn the README trial into a step-by-step walkthrough (#92)
- test(cli): integration tests against kind with a stub CRD (#74)
- test(cli): run the integration tests on the generated CRD (#82)
- test(controller): expire a preview in envtest and report coverage (#117)
- test(controller): set up envtest and first controller tests (#90)
- test(e2e): run the life of a preview through vesperctl (#116)
- test(e2e): smoke test of the operator on kind (#95)