Skip to content

ci(validate-go-project): let a caller size the Go memory cap to its own runner #1223

Description

@devantler

🤖 Generated by the Agentic Engineer

Evidence

validate-go-project.yaml hard-codes GOMEMLIMIT: 8GiB on both memory-hungry Go analysis jobs (govulncheck and deadcode). That value is chosen for ubuntu-latest on a public repository, which GitHub documents as 16 GB — it leaves half the host for everything GOMEMLIMIT does not govern.

On a private repository the standard ubuntu-latest runner has 8 GB. 8GiB is about 8.59 GB, so the cap would exceed the machine's entire memory and provide no headroom at all — reinstating exactly the OOM class that PR #1218 was opened to fix (an opaque exit 143 that no retry clears).

The workflow's own comment already tells such a consumer what to do: use a larger runner or a caller-side cap below it. The second half of that sentence names a remedy that does not exist — GOMEMLIMIT is a literal in the job's env:, and workflow_call.inputs exposes no way to lower it. A private consumer's only options today are forking the workflow or paying for a larger runner.

Audience and problem

Any future private-repository consumer of this reusable workflow. There is no such consumer todayksail is currently the only external caller, it is public, and the organisation's only private repository has no Go workflow — which is why this is filed rather than fixed inside #1218.

Hypothesis

Exposing the cap as a workflow_call input with the current value as its default lets a private consumer size the limit to its own runner without forking, and makes the documented remedy true. Being additive with an unchanged default, it cannot affect the existing public consumer.

Success signal

A private-repository caller can run this workflow to completion on a standard runner by passing a lower cap, with no fork and no larger-runner spend. Baseline: impossible today. Guardrail: ksail's scan time and OOM rate must not change, since its effective value is unchanged.

Acceptance criteria

  • workflow_call.inputs gains an input for the Go memory cap, defaulting to the current 8GiB.
  • Both jobs that set GOMEMLIMIT consume it.
  • test-govulncheck-timeout.sh still enforces the ceiling. This is the load-bearing part: the guard reads .jobs.*.env.GOMEMLIMIT from the YAML, so once that value becomes a ${{ inputs.… }} expression the guard sees an expression string rather than a number and rejects it. It must resolve the input's default instead, and must still fail closed when it can resolve neither.
  • A caller-supplied value is validated by the same decimal/digit-bound parsing the guard already applies, so an override cannot smuggle in an unchecked value.
  • The workflow comment is corrected to name the mechanism that exists.

Size

Small-to-medium. The workflow change is a handful of lines; the guard change is the real work, because it must keep every property proven in #1218 — decimal parsing, the per-unit digit bound, and failing closed on anything it cannot compare.

Found while resolving a Codex review finding on #1218.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions