Class ApprovalQueueDecisionHandler

java.lang.Object
hudson.model.Queue.QueueDecisionHandler
io.jenkins.plugins.batchcontrol.queue.ApprovalQueueDecisionHandler
All Implemented Interfaces:
ExtensionPoint

@Extension @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public class ApprovalQueueDecisionHandler extends Queue.QueueDecisionHandler
The queue gate (SPEC item 6, D-03): every run path goes through Queue.QueueDecisionHandler, so approval-required jobs are controlled at one point.

Decision order:

  1. run control off or task not a job → pass;
  2. job not approval-required: a human submission (user, CLI, Replay, approved request) passes; anything else continues at the timer step (D-46a);
  3. approval marker present → validate and consume it (D-23), pass or refuse quietly;
  4. Pipeline Replay → refuse and record it; a person on the Replay page gets the refusal page and the CLI a one-line error (e2e-03 DEF-16, DEF-14), anything else is refused quietly;
  5. remote (build-token) cause → refuse and record the attempt (S-14); inside an HTTP request the caller gets a plain-text 403 (DEF-33/34), elsewhere the refusal is quiet;
  6. user-originated causes (UserIdCause, incl. the CLI subtype, and the deprecated UserCause, #37) → throw Failure with guidance and a link to the request screen (no silent failure, PoC finding D-1);
  7. automatic retry → judged by the retried build's causes; a retry of an approved or manual run is refused quietly;
  8. timer cause → pass unless blockTimer, refused quietly (unattended) and recorded; what the setting lets through must also be activated (SPEC item 6a);
  9. upstream cause → D-16 policy: pass unless blockUpstream; with blockUpstream only allow-listed upstream jobs pass, an empty/unset list blocks all; refused quietly (unattended, the upstream build surfaces the failure) and recorded; what the setting lets through must also be activated (SPEC item 6a);
  10. SCM causes and anything unknown/empty → pass only if activated (D-46b).

Steps from the timer step on apply to every job, with or without the job property and whatever approvalRequired says; a computed child's activation is carried by its computed-folder ancestor (D-46).

D-82: a job's sub-item (a matrix configuration, a Maven module) is judged by its parent job's approval property and activation; a run of it started by the parent's run in progress passes (step 1b), since the parent's run passed this gate itself.

A quiet refusal of a timer, upstream, SCM, unclassified or Replay submission writes a ChangeType.TRIGGER_BLOCKED record, coalesced per job and cause kind to one per TRIGGER_AUDIT_INTERVAL through BlockedAttemptAudit. The append is the only store I/O on this path and it touches one file under that file's own lock stripe, so it never waits behind retention or any other bulk work.

D-72: a refused submission never reaches the queue, so no queue listener deletes the temporary files of its file parameter values. When a person's own submission (step 4, the D-60 path) or a build-token submission (step 3) is refused, those files are disposed of before the refusal is thrown (disposeOwnValues(hudson.model.Job<?, ?>, java.util.List<hudson.model.Cause>, java.util.List<hudson.model.Action>)); re-runs, marker and unattended submissions are left alone, since their values may belong to another build.