Skip to content

[open-actions-fake-strategist] Support step timeout-minutes across scripts and actions聽#168

Description

@kelos-bot

馃 Open Actions Strategist Agent @gjkim42

Latest verdict

Selected compatibility roadmap increment

Implement official jobs.<job_id>.steps[*].timeout-minutes for workflow script steps and invocations of supported JavaScript and composite actions.

The area assessed is job and step execution deadlines: both workflow-syntax fields, their expression contexts and execution limits, timeout propagation, and resulting failure/cleanup behavior. The coverage pattern is a working job-wide deadline and failure-handling foundation with the entire step-deadline path missing. This is a shared parser/planner/runner capability, not a request to fix one workflow or improve its error message.

This is the strongest unclaimed next increment because it removes a parsing barrier across build, setup, integration-test, and teardown steps while reusing existing execution and result handling. Larger migration blockers are already tracked: reusable workflows #23, containers #113, shells #117, and caching #41.

Real workload evidence, pinned to Cilium commit 629ba134:

The pinned VM helper metadata confirms it is a composite action. These establish usage of both step forms; they are not a claim that this change alone makes Cilium's entire CI portable. Deleting these fields or wrapping shell commands with timeout changes workflows and cannot uniformly cover action invocations.

Documentation contract and current coverage

Contract Current default-branch evidence Next action
Job deadlines: 360-minute default, bounded by runner execution limits JobTimeout and parser tests; controller capping and plan construction Preserve the implemented job deadline and administrator maximum
Queue and execution limits: separate budgets Scheduling-delay test; startup waiting is still bounded by installation-token expiry; #153 is complete and credential lifetime remains #114 Do not fold queue time or token refresh into this increment
Step deadlines: positive whole minutes, maximum 360 on hosted and self-hosted runners, expiry stops the process workflow.Step lacks the field; strict decoding rejects it Add the missing workflow field and carry it through the immutable plan
Step timeout expression contexts, including steps, env, secrets, and hashFiles; official fromJSON(env.time) example ExpressionStep already provides the required availability; resolveWorkflowStep has no timeout evaluation Resolve in the runner at step execution, rather than in job planning
Deadline isolation and failure handling runner.Step, plan mapping, and execution loop provide only the job/cleanup context Introduce a step execution deadline without cancelling the parent job

The area is not yet fully compatible at its outer limits either. GitHub specifies a 24-hour self-hosted queue budget and five-day execution ceiling. Runner selection does not expire jobs waiting for a matching Runner; the native Job startup deadline begins after assignment. Job timeout capping follows the administrator maximum without a separate five-day ceiling. These limit cases affect prolonged waiting or unusually long execution, while every explicitly timed step is rejected today. Prioritize step deadlines and leave queue expiry, global limit alignment, and credential renewal outside this increment.

The documentation defines step failure tolerance through continue-on-error, steps.outcome/conclusion, and status functions. As supplementary implementation evidence for their timeout interaction, GitHub's own StepsRunner.RunStepAsync classifies a step deadline as failure when the job has not been cancelled, then applies continue-on-error. Do not extend #84's whole-job timeout exception to this distinct case.

Minimal proposal and acceptance criteria

Keep the existing Project, Runner, WorkflowRun, and WorkflowJob manifests. Extend the workflow model, immediate and deferred serialized step payloads, runner validation/evaluation, and execution path. Follow the existing plan-version upgrade contract; retain decoding of supported older plans.

  1. Accept omission, literal integers from 1 through 360, and expressions resolving to that range. Reject invalid literals and resolved values, including zero, negatives, fractions, and values above 360. Preserve existing behavior when omitted.
  2. Validate expression availability during parsing and evaluate at the eligible step's execution with its effective environment and preceding step outputs. Cover the official fromJSON(env.time) form and a preceding output. Keep secret-derived values out of persisted plans and diagnostics.
  3. Enforce a separate deadline on run and supported uses steps. The earlier job deadline still wins. For a composite invocation, preserve the caller's deadline through nested scripts/actions. In particular, commandContext currently replaces the supplied context with the job context; simply wrapping the outer call is insufficient. Termination must finish even when a shell leaves a child holding output pipes.
  4. With a live parent job, expiry yields step outcome: failure; without tolerance, conclusion: failure, ordinary later steps skip, and failure()/always() steps remain eligible. With continue-on-error: true, conclusion: success and normal execution continues. A step-only expiry must not set cancelled() or turn the job into JobTimedOut; final job/run success or failure follows the effective step results.
  5. Preserve action post-hook execution after a timed-out action. Subsequent workflow cleanup and post hooks must not inherit the expired step context or bypass the remaining job deadline. Preserve existing whole-job timeout, external cancellation, and bounded job-cleanup behavior.
  6. Add conformance coverage across parser, serialized plan, runtime evaluation, script/JavaScript/composite execution, tolerance, status functions, post hooks, and competing step/job deadlines. Include both successful completion and expiry, nested composites, and process-child termination; use controlled deadlines or synchronization for fast tests. Update the timeout reference with implemented behavior and verify via Makefile targets.

Docker actions, repository-local action resolution, composite metadata extensions, background/parallel steps, token refresh, and general cancellation redesign remain outside this increment.

Assessment validation

On 2026-09-19 at default branch d5e4fdfa906d07929ace30e6f01c4609c096154a, ran make test with temporary Go overlays, -p 1 -count=1 -json, and an exact filter selecting 23 top-level tests: two assessment probes and 21 existing tests. All 23 top-level tests and their 49 subtests passed; no selected tests or subtests were skipped.

  • The parser probe covers omission, literal 1, literal 360, and ${{ fromJSON(env.time) }} on both run and uses steps inside a ten-minute job. Both omitted cases parse and retain the job timeout; all six configured step deadlines fail with field timeout-minutes not found in type workflow.Step.
  • The context probe confirms that executionState.commandContext replaces both live and expired caller deadlines with the live job context. This is the propagation obstacle used by nested composite execution.
  • Executed existing tests cover job-timeout parsing and expressions, persisted planning, controller plan construction and timeout capping, scheduling-delay exclusion, startup-deadline replacement and credential bounds, runner job deadlines and cleanup, script/JavaScript/composite failure tolerance, step-tolerance expressions, nested composite execution, cancellation cleanup, and post-condition status handling. Expression-availability and supported-plan-version checks also passed.

The temporary probes assert the observed gaps; they are assessment evidence, not conformance tests for implemented step-timeout support. No deployed control plane or live GitHub Actions timeout run was used. Repository files remain unchanged.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions