You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
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.
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.
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.
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.
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.
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.
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.
馃 Open Actions Strategist Agent @gjkim42
Latest verdict
VALID2026-09-26T00:06:38Zd5e4fdf, and nothing has merged since the last check, so theworkflow.Step, strict decoding,runner.Step,commandContext, andExpressionStepreferences still hold. The current documentation source still defines the step deadline as the "maximum number of minutes to run the step before killing the process" (maximum 360 on hosted and self-hosted runners, "must be a positive integer"). The context table lists exactly the contexts thatExpressionStepprovides, plushashFiles, and thefromJSON(env.time)example is unchanged. I ran a new survey on a fourth sample that does not overlap the earlier ones: 36 repositories sparse-cloned on 2026-09-26 (Grafana, Next.js, VS Code, Node.js, CPython, PyTorch, Vault, Gitea, Loki, OpenTelemetry Collector, Kafka, Neovim, Ruff, uv, NumPy, pandas, scikit-learn, Backstage, n8n, and others). Usingmake testwith a temporary overlay, the currentworkflow.Parseaccepts 305 of 1,024 workflow files (30%). Steptimeout-minutesappears on 119 steps in 48 files across 12 repositories. It is the only parse blocker in 5 files, including VS Code editor tests and Gitea license generation. The nearest untracked gaps are comparable in size but not clearly more impactful. Trigger names outside the supported set reject the whole workflow (workflow uses unsupported trigger): 25 files across 14 repositories, and the only blocker in 6. Most of these arebranch_protection_rulein 8 OpenSSF Scorecard workflows, all of which also needsecurity-events/id-tokenpermissions (Support every documented GITHUB_TOKEN permission key聽#118, Support GitHub Actions OIDC tokens聽#31);repository_dispatchappears in 5 repositories. This is the next candidate.run-nameappears in 52 files across 6 repositories and is the only blocker in 8 files, 5 of them in n8n. Theruns-ongroup mapping appears in 1 file. Theactions-ngastep keys (background,wait,wait-all) andcache-modeeach appear in one repository. The largest rejections are already tracked: permission keys Support every documented GITHUB_TOKEN permission key聽#118 (249 files), path and branch-ignore filters Support GitHub branch-ignore and path trigger filters聽#116, reusable workflows includingworkflow_calloutputs and secrets Support local reusable workflows聽#23/Support cross-repository reusable workflow calls聽#119, environments Support GitHub Environments and environment-scoped secrets聽#29/[open-actions-fake-user] Support jobs.<job_id>.environment or document it as unsupported聽#76,defaultsand shells Match GitHub run-step shell and defaults.run semantics聽#117, relative-path actions Support repository-local actions referenced with relative paths聽#112, and containers Support job containers, service containers, and Docker container actions聽#113. The slot has no comments or assignees. Open PRs Add run create command for manual workflows聽#182 and Match gh run in the workflow run CLI聽#181 (last updated 2026-09-24), Support matrix include and exclude expansions聽#68, Support protected workflow environments聽#63, and Test deployed Open Actions console聽#9 contain no step-timeout changes. The proposal and acceptance criteria remain valid. No live control-plane run was used, and repository files are unchanged.Selected compatibility roadmap increment
Implement official
jobs.<job_id>.steps[*].timeout-minutesfor 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
timeoutchanges workflows and cannot uniformly cover action invocations.Documentation contract and current coverage
JobTimeoutand parser tests; controller capping and plan constructionworkflow.Steplacks the field; strict decoding rejects itsteps,env,secrets, andhashFiles; officialfromJSON(env.time)exampleExpressionStepalready provides the required availability;resolveWorkflowStephas no timeout evaluationrunner.Step, plan mapping, and execution loop provide only the job/cleanup contextThe 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 ownStepsRunner.RunStepAsyncclassifies a step deadline as failure when the job has not been cancelled, then appliescontinue-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.
fromJSON(env.time)form and a preceding output. Keep secret-derived values out of persisted plans and diagnostics.runand supportedusessteps. The earlier job deadline still wins. For a composite invocation, preserve the caller's deadline through nested scripts/actions. In particular,commandContextcurrently 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.outcome: failure; without tolerance,conclusion: failure, ordinary later steps skip, andfailure()/always()steps remain eligible. Withcontinue-on-error: true,conclusion: successand normal execution continues. A step-only expiry must not setcancelled()or turn the job intoJobTimedOut; final job/run success or failure follows the effective step results.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, ranmake testwith 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.1, literal360, and${{ fromJSON(env.time) }}on bothrunandusessteps inside a ten-minute job. Both omitted cases parse and retain the job timeout; all six configured step deadlines fail withfield timeout-minutes not found in type workflow.Step.executionState.commandContextreplaces both live and expired caller deadlines with the live job context. This is the propagation obstacle used by nested composite execution.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.