Skip to content

feat(workflows): make shell step timeout configurable (#3327)#3328

Merged
mnriem merged 7 commits into
github:mainfrom
Noor-ul-ain001:feat/3327-shell-timeout
Jul 13, 2026
Merged

feat(workflows): make shell step timeout configurable (#3327)#3328
mnriem merged 7 commits into
github:mainfrom
Noor-ul-ain001:feat/3327-shell-timeout

Conversation

@Noor-ul-ain001

Copy link
Copy Markdown
Contributor

Summary

Closes #3327. The workflow shell step hardcoded a 300-second subprocess timeout with no way to override it, so any command that legitimately runs longer than five minutes — a full build, a MegaLinter/golangci-lint aggregator, an integration-test target — was killed with TimeoutExpired and failed the entire run. There was no YAML knob to raise the limit, which made shell steps unusable as a probe/gate over real project QA commands.

Changes

  • Add an optional timeout field (seconds) to the shell step, read via config.get("timeout", 300) and threaded into subprocess.run. Defaults to 300 so existing workflows are unaffected.
  • The timeout failure message now reports the configured value instead of a hardcoded 300.
  • validate rejects a timeout that is not a positive number. bool is rejected explicitly — it is an int subclass, but timeout: true is a config error, not a duration.
- id: qa
  type: shell
  timeout: 1800        # seconds; optional, default 300
  run: make code-qa

Acceptance criteria (from the issue)

  • A timeout: value overrides the 300s default and is honored by subprocess.run.
  • Omitting timeout: preserves current behavior (300s).
  • validate rejects a non-positive or non-numeric timeout.
  • A test asserts the configured value is threaded through.

Testing

Seven new tests under TestShellStep:

  • configured timeout is passed to subprocess.run
  • default 300 preserved when omitted
  • timeout error message reflects the configured value
  • validate rejects non-positive (0, -30) and non-numeric ("30", True) values
  • validate accepts positive int/float

pytest tests/test_workflows.py::TestShellStep → 13 passed. Confirmed the behavior-changing tests fail without the source change (test-the-test via git stash).

🤖 Generated with Claude Code

The `shell` step hardcoded a 300s subprocess timeout, so any command
that legitimately runs longer than five minutes (a full build, a linter
aggregator, an integration-test target) was killed with TimeoutExpired
and failed the whole run, with no YAML knob to raise the limit.

Add an optional `timeout` field (seconds) that defaults to 300 for
backward compatibility and is threaded through to `subprocess.run`. The
timeout failure message now reports the configured value instead of a
hardcoded 300. `validate` rejects a `timeout` that is not a positive
number (bool is rejected explicitly, since it is an int subclass but a
config error rather than a duration).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes the workflow shell step’s subprocess timeout configurable per-step (defaulting to the historical 300s), so longer-running QA/build commands can run without being killed by a hardcoded limit.

Changes:

  • Add optional timeout (seconds) to shell step execution, defaulting to 300.
  • Update the timeout failure message to report the configured timeout.
  • Add/extend ShellStep validation and unit tests to cover timeout behavior and invalid values.
Show a summary per file
File Description
src/specify_cli/workflows/steps/shell/init.py Threads timeout from config into subprocess.run, updates timeout error message, and validates timeout input.
tests/test_workflows.py Adds TestShellStep coverage for default/configured timeout wiring, error messaging, and validation cases.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment thread src/specify_cli/workflows/steps/shell/__init__.py Outdated
Comment thread tests/test_workflows.py
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Low

The isfinite guard added in 955d46a rejects YAML .inf/.nan timeouts, but no test asserted it. inf and nan are floats that pass a plain > 0 check (nan <= 0 is False), so without an explicit case a regression could silently reaccept them and crash subprocess.run(timeout=...) at runtime. Addresses the remaining Copilot review comment on PR github#3328.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Low

Comment thread src/specify_cli/workflows/steps/shell/__init__.py Outdated

@mnriem mnriem left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address Copilot feedback. Also please do not resolve conversations

Address Copilot review feedback on github#3328: the per-step `timeout`
option was not reflected in the public workflow docs. The Shell Steps
section only showed `run:`, so readers couldn't discover `timeout:`,
its unit (seconds), or its default (300).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Low

Comment thread src/specify_cli/workflows/steps/shell/__init__.py Outdated
Noor-ul-ain001 and others added 2 commits July 9, 2026 23:11
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…eout

# Conflicts:
#	src/specify_cli/workflows/steps/shell/__init__.py

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Low

Comment thread src/specify_cli/workflows/steps/shell/__init__.py Outdated
@mnriem

mnriem commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Please address Copilot feedback

…ne path

Address Copilot review feedback on github#3328:

- Remove the dead "fall back to default" timeout block in execute(): it
  re-read `timeout` from config immediately after, so the fallback was
  discarded and its comment contradicted the new fail-on-invalid behavior.
- Extract a single `_timeout_error()` helper shared by execute() and
  validate() so both reject the same values with the same message, instead
  of two drifting copies of the check.
- Hoist the duplicated inline `import math` to module scope.
- Add test_execute_fails_cleanly_on_invalid_timeout: asserts execute()
  fails the step (rather than raising) on an unvalidated string/bool/inf/0
  timeout, covering the engine-skips-validate path Copilot flagged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Low

@mnriem mnriem self-requested a review July 13, 2026 15:31
@mnriem mnriem merged commit 32952c9 into github:main Jul 13, 2026
12 checks passed
@mnriem

mnriem commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Thank you!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Make the shell step's execution timeout configurable (currently hardcoded to 300s)

4 participants