Skip to content

feat(cost): CI cost-guardrail — price manifest changes, flag/block PR $ deltas#20

Merged
mayur-tolexo merged 1 commit into
mainfrom
feat/cost-guardrail
Jun 2, 2026
Merged

feat(cost): CI cost-guardrail — price manifest changes, flag/block PR $ deltas#20
mayur-tolexo merged 1 commit into
mainfrom
feat/cost-guardrail

Conversation

@mayur-tolexo

Copy link
Copy Markdown
Owner

Implements the roadmap's CI cost-guardrail (Phase 2): a kubetidy cost command that prices a PR's resource-request changes — no cluster needed — so CI can say "this PR adds $400/mo" and optionally block it.

Usage

kubectl tidy cost ./manifests                          # total $/mo of a manifest set
kubectl tidy cost --base /tmp/base --head ./manifests  # diff before→after
kubectl tidy cost --base B --head H --fail-over 200    # exit non-zero if it adds > $200/mo
kubectl tidy cost --base B --head H -o json            # machine-readable
kubetidy cost · base → head

  this change adds $88/mo  ($27/mo → $116/mo)

  WORKLOAD                                       BEFORE      AFTER      DELTA
  Deployment/shop/checkout-api                      $27       $109       +$82  (changed)
  StatefulSet/shop/cache                              —         $7        +$7  (added)

How

  • internal/manifest — pure YAML/JSON → []model.Workload parser (Deployment/StatefulSet/DaemonSet/ReplicaSet; requests normalized to millicores/bytes), plus CostWorkloads (× replicas, via costmodel) and Compare (added/removed/changed/unchanged + net delta).
  • internal/cli/cost.gocost [manifests…] or --base/--head (file or dir); table/json; --fail-over <budget> is the CI gate; --cpu-cost/--mem-cost overrides. Derived blended pricing (no cluster).
  • docs/examples/cost-guardrail.yml — ready-to-copy GitHub Action: diffs base vs head via git worktree, comments the table on the PR, and enforces a budget. Kept under docs/ so it doesn't auto-run on this repo.

Tests

internal/manifest 86.1% (parser incl. DaemonSet defaults, namespace default, bad-YAML error; Compare add/remove/change). cost CLI: diff output, guardrail pass/fail, single-set total, no-input error. Full go build/vet/gofmt/test ./... + golangci-lint (0 issues) green.

Follow-ups

  • Publish a real composite/Docker GitHub Action (uses: mayur-tolexo/kubetidy@v0) wrapping this.
  • Cost from manifests vs the live cluster (what the PR changes relative to what's running).

… $ deltas

New `kubetidy cost` command (Phase 2): prices CPU/memory requests in Kubernetes
manifests with no cluster access, and — given --base/--head — reports the monthly
$ a change adds or saves ("this change adds $88/mo"). The CI guardrail.

- internal/manifest: pure YAML/JSON → []model.Workload parser (Deployments,
  StatefulSets, DaemonSets, ReplicaSets; requests normalized to millicores/bytes),
  plus CostWorkloads + Compare (added/removed/changed/unchanged + net delta).
- internal/cli/cost.go: `cost [manifests…]` or `--base/--head` (file or dir);
  table or `-o json`; `--fail-over <budget>` exits non-zero on a net increase >
  budget; `--cpu-cost/--mem-cost` overrides. Uses derived blended pricing.
- docs/examples/cost-guardrail.yml: ready-to-copy GitHub Action (comment the delta
  via git worktree base-diff + optional budget enforcement). Under docs/ so it
  doesn't auto-run on this repo.
- docs: README cost section, ROADMAP checked off, CHANGELOG (Unreleased).

Coverage: manifest 86.1%, cost CLI paths tested (diff, guardrail pass/fail, total,
no-input). Full build/vet/fmt/test/lint green.
@mayur-tolexo
mayur-tolexo merged commit 3d0c7f8 into main Jun 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant