Skip to content

CI: classify artifact capacity exhaustion separately from transient upload transport #209

Description

@MrFr3di

Problem

MuxTV's accepted evidence uploader (#141 / #176) correctly retries transient publication failures such as ECONNRESET and keeps evidence publication mandatory. The current repository failure mode is different and deterministic:

Failed to CreateArtifact: Artifact storage quota has been hit. Unable to upload any new artifacts. Usage is recalculated every 6-12 hours.

During the short 2026-08-25 self-hosted window this caused workflows with successful substantive work to finish red, including:

This must remain fail-closed for acceptance evidence, but must not be confused with a product/test failure or treated as a transient transport reset.

Current repository facts

The shared action .github/actions/upload-evidence-with-retry/action.yml already uses retention-days: 7 by default and performs one bounded retry plus REST reconciliation. This issue must not be framed as fixing a 90-day default retention problem.

#141 remains authoritative for transient transport/reconciliation. Capacity exhaustion is a separate state.

Official constraints

GitHub documents that:

  • artifact storage is quota/billing capacity distinct from Actions cache storage and is shared with GitHub Packages allowance;
  • deleting artifacts can reclaim current storage, but deletion is irreversible;
  • storage usage/billing views can lag after deletion (GitHub documents a 6–12 hour update window);
  • per-artifact retention is supported;
  • artifact deletion requires Actions write permission.

References:

Required design

1. Preserve fail-closed acceptance semantics

If mandatory evidence cannot be published because capacity is exhausted, the workflow must still fail. Do not add continue-on-error as the final policy and do not claim acceptance GREEN.

2. Separate workload verdict from publication verdict

Emit a stable summary/diagnostic state that distinguishes at least:

A red workflow caused by capacity must say explicitly that the substantive workload may have succeeded but acceptance evidence was not published.

3. Do not blindly retry deterministic capacity failures

If quota exhaustion can be classified reliably from supported action/API signals, stop before the second upload attempt and fail with the capacity-specific explanation. If actions/upload-artifact does not expose a stable machine-readable reason, do not parse fragile log prose in production merely to save one retry; first introduce a reliable preflight/API boundary or document that limitation.

4. Auditable cleanup only

Do not bulk-delete repository artifacts without an inventory and allowlist. Deletion is irreversible.

Before any cleanup automation, classify artifacts by provenance and value, for example:

  • accepted main/manual acceptance evidence — longest retained class;
  • active PR/device investigation evidence — bounded medium retention;
  • superseded diagnostic/PR evidence — shortest retention / cleanup candidate.

Any cleanup implementation must be dry-run/read-only by default, report artifact id/name/run/created/expires/size when the API provides it, and require an explicit policy for destructive deletion.

5. Retention policy

Evaluate whether high-volume ephemeral PR/device artifacts should use a shorter explicit retention than the current shared default 7 days while durable acceptance evidence keeps a longer bounded retention. Do not apply a blanket reduction until actual artifact inventory shows it is justified.

Acceptance

  • capacity exhaustion is distinguishable from product/test failure in job summary/logs;
  • transient CI: harden self-hosted evidence artifact upload against transient transport resets #141 behavior remains intact;
  • deterministic capacity failure is not blindly retried where a stable classifier exists;
  • mandatory evidence remains fail-closed;
  • no artifact is deleted without an auditable inventory/policy;
  • no PAT/admin secret is added solely to make ordinary workflows look green;
  • storage remediation does not create or modify Android AVD identities.

Ordering

This is CI signal/reliability work and may proceed runner-independently where testable. It must not modify frozen U0/#189 product source or reorder U0 -> U1 -> M0 -> #190 isolated landing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions