coverport is a command-line interface for collecting code coverage from Go and Python applications running in Kubernetes, designed specifically for Konflux/Tekton integration pipelines and CI/CD automation.
v2 Architecture Updates:
- Added
processcommand for post-collection processing (git metadata extraction, cloning, coverage mapping, Codecov upload) - Introduced manifest-based workflow:
collectcreatesmetadata.jsonfor batch processing - Added direct URL collection via
NewClientForURL()for localhost/HTTP endpoints - Automatic PR detection from image metadata (Konflux annotations, branch patterns)
- Intelligent path remapping with
./prefix for Go tooling compatibility - HTML generation moved to
processphase for proper source code access
┌─────────────────────────────────────────────────────────────┐
│ coverport CLI │
│ │
│ ┌────────────┐ ┌────────────┐ ┌──────────────────────┐ │
│ │ collect │ │ discover │ │ (future commands) │ │
│ └─────┬──────┘ └─────┬──────┘ └──────────────────────┘ │
│ │ │ │
│ ┌─────▼───────────────▼────────────────────────────────┐ │
│ │ Command Layer (cobra) │ │
│ └─────┬────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────▼────────────────────────────────────────────────┐ │
│ │ Internal Packages │ │
│ │ ┌──────────────────┐ ┌────────────────────────┐ │ │
│ │ │ discovery/ │ │ snapshot/ │ │ │
│ │ │ - Image-based │ │ - Snapshot parsing │ │ │
│ │ │ pod discovery │ │ - Component extraction│ │ │
│ │ └──────────────────┘ └────────────────────────┘ │ │
│ └─────┬────────────────────────────────────────────────┘ │
└────────┼──────────────────────────────────────────────────┘
│
│ Uses
▼
┌─────────────────────────────────────────────────────────────┐
│ go-coverage-http/client Library │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ • CoverageClient │ │
│ │ • Pod port-forwarding │ │
│ │ • HTTP coverage collection │ │
│ │ • Report generation & filtering │ │
│ │ • Path remapping │ │
│ │ • OCI artifact push │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
│ Uses
▼
┌─────────────────────────────────────────────────────────────┐
│ Kubernetes & Go Tools │
│ • k8s.io/client-go • oras-go • go tool covdata │
└─────────────────────────────────────────────────────────────┘
Go applications:
- POST
/coverage→ binary coverage data (covmeta + covcounters) go tool covdataconverts to text/HTML reports locally
Python applications:
- GET
/health→ auto-detects Python coverage server - POST
/coverage/save→ triggers SIGHUP to Gunicorn (workers save coverage to/dev/shm) - GET
/coverage→ base64-encoded combined coverage data kubectl execrunscoverage xmlinside the pod to generate Cobertura XML- XML is fetched from the pod and saved locally
The Python flow generates XML inside the target pod because the CoverPort CLI container does not include Python. This is by design — it avoids adding Python dependencies to the CLI image while leveraging the Python runtime already present in the instrumented pod.
- Main CLI entry point
- Global flags and configuration
- Version information
- Help system
- Primary command for coverage collection
- Handles multiple discovery methods:
- Konflux/Tekton snapshots
- Container image references
- Label selectors
- Explicit pod names
- Orchestrates multi-component collection
- Manages OCI artifact push
- Pod discovery without collection
- Useful for debugging and validation
- Shows what pods will be targeted
Purpose: Intelligent pod discovery based on various criteria
Key Features:
- Image-based discovery: Normalizes and matches container images
- Cross-namespace search: Searches all non-system namespaces
- Label selector support: Standard Kubernetes label matching
- Component extraction: Identifies component names from labels or images
Main Types:
type PodInfo struct {
Name string
Namespace string
ComponentName string
Image string
ContainerName string
}
type ImageDiscovery struct {
clientset kubernetes.Interface
}Purpose: Parse and process Konflux/Tekton snapshots
Key Features:
- JSON snapshot parsing
- Component extraction
- Image list generation
- File and string input support
Main Types:
type Snapshot struct {
Components []Component `json:"components"`
}
type Component struct {
Name string `json:"name"`
ContainerImage string `json:"containerImage"`
Source Source `json:"source,omitempty"`
}When to use the CLI:
- CI/CD pipelines (Tekton, GitHub Actions, etc.)
- One-off manual coverage collection
- Multi-component applications
- Need for snapshot parsing
- OCI registry push automation
When to use the library directly:
- Custom Go test code (like e2e_test.go)
- Need programmatic control
- Custom workflows
- Integration into existing Go applications
The CLI implements a layered discovery approach:
- Snapshot-first: Konflux snapshots are the primary method
- Image-based: Direct image reference matching
- Label-based: Kubernetes label selectors
- Explicit: Manual pod specification
This prioritization reflects the most common CI/CD use cases.
Key design for multi-component handling:
coverage-output/
├── component-1/
│ └── test-name-component-1/
│ └── (coverage files)
├── component-2/
│ └── test-name-component-2/
│ └── (coverage files)
└── component-3/
└── test-name-component-3/
└── (coverage files)
Benefits:
- Clear separation of concerns
- Parallel processing friendly
- Easy to identify failures
- Simple to merge or analyze separately
By default, the CLI auto-processes coverage:
- Collect binary data
- Generate text report
- Remap paths
- Filter unwanted files
- Create HTML visualization
Rationale: Most CI/CD use cases want complete reports without manual intervention.
Built-in OCI push for:
- Persistent storage
- Integration with registry workflows
- Artifact metadata and annotations
- Automatic expiration
┌─────────────────┐
│ Deploy Apps │
│ (Tekton Task) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Run Tests │
│ (Tekton Task) │
└────────┬────────┘
│
▼
┌─────────────────────────────────────────┐
│ coverport collect │
│ --snapshot="$SNAPSHOT" │
│ ↓ │
│ 1. Parse snapshot │
│ 2. Discover pods (by image) │
│ 3. Collect from each pod │
│ 4. Process reports │
│ 5. Push to OCI registry │
└────────┬────────────────────────────────┘
│
▼
┌─────────────────┐
│ Analyze │
│ (SonarQube) │
└─────────────────┘
┌─────────────────┐
│ Deploy to │
│ Local Cluster │
│ (kind/minikube)│
└────────┬────────┘
│
▼
┌─────────────────┐
│ Manual Testing │
└────────┬────────┘
│
▼
┌──────────────────────────────────────┐
│ coverport collect │
│ --label-selector="app=myapp" │
│ ↓ │
│ 1. Discover pods (by label) │
│ 2. Collect coverage │
│ 3. Generate reports │
│ 4. Open HTML (no push) │
└────────┬─────────────────────────────┘
│
▼
┌─────────────────┐
│ Review in │
│ Browser │
└─────────────────┘
To add new commands (e.g., coverport merge, coverport report):
- Create
cmd/newcommand.go - Implement cobra command
- Add to
rootCmdininit() - Use existing internal packages
Example:
// cmd/merge.go
var mergeCmd = &cobra.Command{
Use: "merge",
Short: "Merge coverage from multiple sources",
Run: runMerge,
}
func init() {
rootCmd.AddCommand(mergeCmd)
}To add new discovery methods:
- Add method to
internal/discovery/discovery.go - Add flags to
cmd/collect.go - Add to discovery validation logic
To add custom report processing:
- Use the library's
CoverageClientdirectly - Implement custom logic in
cmd/collect.go - Add flags for configuration
coverport collect \
--snapshot="$SNAPSHOT" \
--test-name=e2e-test \
--push \
--repository=org/artifactsPros:
- No code required
- Built-in snapshot parsing
- Multi-component support
- OCI push included
- CI/CD ready
Cons:
- Less programmatic control
- Fixed workflow
- External process
client, _ := coverageclient.NewClient(namespace, outputDir)
client.SetSourceDirectory(projectRoot)
// For each pod
client.CollectCoverageFromPod(ctx, podName, testName, port)
client.GenerateCoverageReport(testName)
client.FilterCoverageReport(testName)
client.GenerateHTMLReport(testName)Pros:
- Full programmatic control
- Custom workflows
- Direct Go integration
- Test framework integration
Cons:
- More code to write
- Manual multi-component handling
- Need to handle errors explicitly
- Test discovery logic with fake Kubernetes client
- Test snapshot parsing
- Test path normalization
- Test against real Kubernetes cluster (kind)
- Test with actual coverage servers
- Verify OCI push (with test registry)
- Full pipeline simulation
- Multi-component scenarios
- Error handling validation
Currently sequential, but could be parallelized:
// Future enhancement
var wg sync.WaitGroup
for _, pod := range pods {
wg.Add(1)
go func(p PodInfo) {
defer wg.Done()
collectFromPod(ctx, config, p)
}(pod)
}
wg.Wait()- Cache namespace lists
- Reuse Kubernetes client
- Batch pod queries
- Stream large coverage files
- Clean up temp data
- Limit concurrent operations
- Credentials: Uses kubeconfig or in-cluster auth
- Registry: Leverages Docker credentials
- Network: Port-forward is temporary and scoped
- Permissions: Requires pod read and port-forward permissions
-
coverport merge- Merge multiple coverage reports -
coverport pull- Pull and extract OCI artifacts -
coverport report- Generate reports from existing data -
coverport diff- Compare coverage between runs - Parallel collection
- Progress bars for long operations
- JSON output mode
- Watch mode for continuous collection
- GitHub Actions
- GitLab CI
- SonarQube direct upload
- Slack notifications
- Prometheus metrics
See main project CONTRIBUTING.md for guidelines.
- Main library:
../client/client.go - Example test:
../test/e2e_test.go - go-coverage-http - Go coverage HTTP server
- py-coverage-http - Python coverage HTTP server
- Cobra documentation: https://cobra.dev/
- Kubernetes client-go: https://github.com/kubernetes/client-go