11 KiB
Krew Release Automation Guide
This document explains how kubescape automates publishing to the Kubernetes plugin package manager, krew.
What is Krew?
Krew is a plugin manager for kubectl. It allows users to discover and install kubectl plugins easily. You can learn more about krew at https://krew.sigs.k8s.io/.
How kubescape publishes to krew
We use the krew-release-bot to automatically create pull requests to the kubernetes-sigs/krew-index repository whenever a new release of kubescape is published.
Setup Overview
The automation consists of three components:
.krew.yaml- A template file that the bot uses to generate the krew plugin manifest.github/workflows/02-release.yaml- GitHub Actions workflow that runs the krew-release-bot after a successful release.goreleaser.yaml- GoReleaser configuration that defines the krew manifest (though upload is skipped)
Why Use krew-release-bot Instead of GoReleaser's Built-in Krew Support?
You might have noticed that GoReleaser has built-in krew support in its krews section. However, almost all projects (including stern) use skip_upload: true and rely on krew-release-bot instead. Here's why:
Problems with GoReleaser's Built-in Krew Publishing
To use GoReleaser's direct krew publishing, you would need to:
krews:
- name: kubescape
skip_upload: false # Instead of true
repository:
owner: kubernetes-sigs
name: krew-index
token: "{{ .Env.KREW_INDEX_TOKEN }}" # Required!
pull_request:
enabled: true # Requires GoReleaser Pro for cross-repo PRs
This approach has several critical issues:
-
Permission Barrier: Almost no one has write access to
kubernetes-sigs/krew-index. You would need special permissions from the Krew maintainers, which is rarely granted. -
Security Risk: You'd need to store a GitHub personal access token with write access to the krew-index in your repository secrets. This token could be compromised and used to make unauthorized changes to the krew-index.
-
GoReleaser Pro Required: To create pull requests to a different repository (cross-repository), you need GoReleaser Pro, which is a paid product.
-
Manual Work: Even if you had access, you'd need to manually configure and maintain the repository settings, tokens, and potentially deal with rate limits and authentication issues.
Why krew-release-bot is the Right Solution
The krew-release-bot was created by the Kubernetes community (in collaboration with the Krew team) specifically to solve these problems:
-
No Repository Access Required: The bot acts as an intermediary with pre-configured access to krew-index. You don't need write permissions.
-
No Tokens Needed: It uses GitHub's
GITHUB_TOKEN(automatically available in GitHub Actions) via webhooks and events. No personal access tokens required. -
Designed for Krew: It's specifically built for the krew-index workflow and integrates with Krew's automation.
-
Automatic Merging: The Krew team has configured their CI to automatically test and merge PRs from krew-release-bot (usually within 5-10 minutes).
-
Officially Recommended: The Krew team explicitly recommends this approach in their documentation as the standard way to automate plugin updates.
-
Free and Open Source: No paid subscriptions required.
The Real-World Evidence
Looking at recent pull requests to kubernetes-sigs/krew-index, almost all automated plugin updates are created by krew-release-bot. You'll see patterns like:
Author: krew-release-bot
Title: "release new version v0.6.11 of radar"
This demonstrates that the entire Kubernetes ecosystem has standardized on krew-release-bot, not GoReleaser's built-in publishing.
Summary
While GoReleaser's built-in krew support exists in the code, it's practically unusable for the krew-index repository due to permission and security constraints. The krew-release-bot is the de facto standard because:
- It works without special permissions
- It's more secure
- It integrates with Krew's automation
- It's free and recommended by the Krew team
This is why we use skip_upload: true in GoReleaser and let krew-release-bot handle the actual publishing.
The Template File
The .krew.yaml file in the repository root is a Go template that contains placeholders for dynamic values:
apiVersion: krew.googlecontainertools.github.com/v1alpha2
kind: Plugin
metadata:
name: kubescape
spec:
version: {{ .TagName }}
platforms:
- selector:
matchLabels:
os: linux
arch: amd64
{{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_linux_amd64.tar.gz" $version) .TagName }}
bin: kubescape
- selector:
matchLabels:
os: linux
arch: arm64
{{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_linux_arm64.tar.gz" $version) .TagName }}
bin: kubescape
- selector:
matchLabels:
os: darwin
arch: amd64
{{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_darwin_amd64.tar.gz" $version) .TagName }}
bin: kubescape
- selector:
matchLabels:
os: darwin
arch: arm64
{{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_darwin_arm64.tar.gz" $version) .TagName }}
bin: kubescape
- selector:
matchLabels:
os: windows
arch: amd64
{{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_windows_amd64.tar.gz" $version) .TagName }}
bin: kubescape.exe
- selector:
matchLabels:
os: windows
arch: arm64
{{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_windows_arm64.tar.gz" $version) .TagName }}
bin: kubescape.exe
shortDescription: Scan resources and cluster configs against security frameworks.
description: |
Kubescape is the first tool for testing if Kubernetes is deployed securely
according to mitigations and best practices. It includes risk analysis,
security compliance, and misconfiguration scanning with an easy-to-use
CLI interface, flexible output formats, and automated scanning capabilities.
Features:
- Risk analysis: Identify vulnerabilities and security risks in your cluster
- Security compliance: Check your cluster against multiple security frameworks
- Misconfiguration scanning: Detect security misconfigurations in your workloads
- Flexible output: Results in JSON, SARIF, HTML, JUnit, and Prometheus formats
- CI/CD integration: Easily integrate into your CI/CD pipeline
homepage: https://kubescape.io/
caveats: |
Requires kubectl and basic knowledge of Kubernetes.
Run 'kubescape scan' to scan your Kubernetes cluster or manifests.
The {{ .TagName }} is replaced with the release tag (e.g., v3.0.0), {{ trimPrefix "v" .TagName }} removes the version prefix, and {{ addURIAndSha ... }} calculates the SHA256 checksum for the binary archive.
Release Workflow
The release workflow (.github/workflows/02-release.yaml) can be triggered in two ways:
- Automatic: When a new tag matching the pattern
v[0-9]+.[0-9]+.[0-9]+is pushed to the repository - Manual: Via
workflow_dispatchwith an optionalskip_publishinput
When the workflow is triggered:
- GoReleaser builds and publishes the release artifacts (unless
skip_publish=trueis set) - The krew-release-bot step runs conditionally:
- It runs when triggered by a tag push OR by
workflow_dispatchwithskip_publish=false - It skips when triggered by
workflow_dispatchwithskip_publish=true(default)
- It runs when triggered by a tag push OR by
- When it runs, the bot:
- Reads the
.krew.yamltemplate - Fills in the template with release information
- Creates a pull request to the
kubernetes-sigs/krew-indexrepository - The PR is automatically tested and merged by krew's infrastructure
- Reads the
Workflow Permissions
The release job has the following permissions:
permissions:
actions: read
checks: read
contents: write
deployments: read
discussions: read
id-token: write
issues: read
models: read
packages: write
pages: read
pull-requests: read
repository-projects: read
statuses: read
security-events: read
attestations: read
artifact-metadata: read
These permissions are necessary for GoReleaser to create releases and upload artifacts.
Testing the Template
Before committing changes to .krew.yaml, you can test how the template will be rendered using Docker:
docker run -v $(pwd)/.krew.yaml:/tmp/.krew.yaml ghcr.io/rajatjindal/krew-release-bot:v0.0.47 \
krew-release-bot template --tag v3.0.0 --template-file /tmp/.krew.yaml
This will output the generated krew manifest file, allowing you to verify:
- The version field is correct
- All download URLs are properly formatted
- The SHA256 checksum will be calculated correctly
Why skip_upload in GoReleaser?
In .goreleaser.yaml, the krews section has skip_upload: true:
krews:
- name: kubescape
ids:
- cli
skip_upload: true # We use krew-release-bot instead
homepage: https://kubescape.io/
description: It includes risk analysis, security compliance, and misconfiguration scanning with an easy-to-use CLI interface, flexible output formats, and automated scanning capabilities.
short_description: Scan resources and cluster configs against security frameworks.
This is intentional because:
- GoReleaser generates the manifest but doesn't have built-in support for submitting PRs to krew-index
- krew-release-bot is the recommended tool for krew automation by the Krew team
- Using krew-release-bot provides automatic testing and merging of version bump PRs
Manual Release Testing
You can test the release workflow manually without publishing to krew by using workflow_dispatch:
- Go to Actions tab in GitHub
- Select "02-create_release" workflow
- Click "Run workflow"
- The
skip_publishinput defaults totrue(publishing will be skipped) - Set
skip_publishtofalseif you want to test the full release process including krew indexing
Making Changes to the Template
If you need to update the krew manifest (e.g., change the description, add platforms, or update the binary location):
- Edit the
.krew.yamlfile - Test your changes with the Docker command shown above
- Commit and push the changes
- The next release will use the updated template
Installing kubescape via krew
Once the plugin is indexed in krew, users can install it with:
kubectl krew install kubernetes-sigs/kubescape
Or after index update:
kubectl krew install kubescape