Skip to content

v1.5.0

Latest

Choose a tag to compare

@github-actions github-actions released this 15 Aug 15:35
· 1 commit to main since this release
v1.5.0
b5c6865

A minor release that makes VCS API-budget consumption measurable rather than guessed, and makes the plan-versus-apply decision a button rather than a hidden checkbox.

Highlights

  • VCS API-budget saturation, measured per connection — every VCS connection now reports a saturation verdict (idle / comfortable / tight / will_exhaust / exhausted), the consumption rate as a share of the budget, and when the budget runs out. The verdict is the number to read, not the remaining count: the budget refills on a fixed window, so remaining looks healthy right after a reset however fast it is being spent — an instance burning 11,400 calls/hour against a 5,000/hour budget read fine for part of every hour. Always on, no configuration, and it costs no extra API calls: the figures ride on headers providers already return. (#1334, #1339)

    Measured is meant literally: every REST call Terrapod makes to either provider is counted — poll lookups, PR/MR reads, archive downloads, and the comment and merge writes. Sparse git fetches are the one exclusion, because providers meter the git transport separately from the REST allowance the verdict is about. GitLab's budget is per minute where GitHub's is per hour, and the window is read from the response rather than assumed, so the two are not silently compared on different bases. Where a server reports no budget at all — a self-managed GitLab with limiting off — you get the rate and no verdict rather than an invented one. (#1345)

  • A breakdown of who is spending it — knowing you are over budget is half the problem; the other half is which repositories to move and where to split them. Calls are attributed to the repo, workspace, module or policy set that made them, with a rollup by workspace label. Labels matter because the second remedy is splitting load across more connections, and one connection per team scales where one shared extra connection does not. The per-consumer view is held in Redis rather than on Prometheus labels deliberately — repo and workspace are unbounded, and an estate with thousands of workspaces would wreck the metric. (#1339)

  • Plan or plan + apply is now a button, not a hidden checkbox — queueing an apply from a workspace took four steps: reveal "Plan options", find "Plan only", uncheck it, press Queue run. The decision that matters on every run sat in a collapsed panel behind a checkbox you could not see without opening it. It is now two buttons, and which one you press is the whole choice. Pressing Plan does exactly what it did before. Plan + apply respects the workspace auto-apply setting — it means "this run may apply", not "skip the confirmation gate" — and is disabled while a branch, tag or commit is selected, because the server forces those runs plan-only. (#1340)

  • A drift run that found drift now offers a remedy — drift runs are plan-only by design, since a scheduled job must not change infrastructure on its own. But that left the operator looking at a reported problem with nothing to do about it. A drift run with changes now offers the same Plan + apply, queuing a fresh ordinary run against current configuration rather than applying the drift run's own plan, which is a detection artifact. Applying is one of two answers to drift; updating the configuration to match what is deployed is the other, and stays your call. (#1340)

  • New can-queue-apply workspace permissioncan-queue-run covers plan only, so a UI could not tell whether to offer an apply and had to either hide it from people who held the grant or show a control that would 403 on press. Purely additive to the permissions block. (#1340)

Bug Fixes

  • Autodiscovery no longer re-fetches repository metadata the poll cycle already has — the autodiscovery pass asked the provider for the default branch, branch SHA and open-PR list on repos the workspace poll had just fetched and cached in the same cycle, because its three call sites passed no cache. On an instance with autodiscovery rules that was duplicate spend against the rate limit, every cycle, on exactly the repos the poll had already looked at. The cache is now built once per cycle and shared by both passes. (#1329)

    The call sites were only half of it. The cache argument was optional and trailing, which made the uncached path the default and left a forgetful call site looking correct in review — the same shape as the total VCS outage in #1244. It is now keyword-only with no default, so omitting it is a TypeError rather than a silent slow path.

Maintenance

  • Go modules build with 1.26.6, clearing two stdlib advisories.

  • Default trivy version bumped to 0.74.0 (registry.platform_tools.trivy_version). opa (1.19.0) and checkov (3.3.9) were already current. These tools are pulled through the binary cache rather than baked into the images, so an operator can move them with a helm upgrade without waiting for a Terrapod release.

    If you mirror platform tools internally and left trivy_version at the default, seed 0.74.0 (and its checksum manifest) before upgrading, or pin trivy_version: "0.73.0" in your values. This only affects installs that both use an internal mirror and have selected trivy as a security-scan engine — the default engine is checkov, and trivy is fetched only when selected.

Upgrade notes

Nothing to do for most installs. No migrations, and no removed or renamed API attributes, config keys or Helm values — a lagging runner, listener, SDK or provider is unaffected.

Two things worth knowing:

  • Internal platform-tool mirrors: see the trivy note under Maintenance.
  • vcs-connection-id on workspace create/update is now honoured as an attribute, not only as a relationship. It was previously accepted and silently dropped, which was quiet data loss; a malformed value now returns 422 rather than being ignored. go-terrapod, the provider, the migration tools and the web UI all use the relationship form and are unaffected — this only reaches a raw-HTTP integration that was sending the attribute and relying on it being ignored.

Full Changelog: v1.4.1...v1.5.0