Data report"State of code review 2024" is now liveRead the full report

GitHub Actions timeouts

Kenny DuMez
Kenny DuMez
Graphite software engineer

One of the challenges developers may face when using GitHub Actions are timeouts during the execution of workflows. This guide will explain the common reasons for these timeouts and provide practical solutions to resolve them.

A timeout in GitHub Actions occurs when a job or step within a workflow exceeds the maximum allowed execution time set by GitHub or defined in the workflow file. This leads to the termination of the job, which can halt your CI/CD pipeline and require manual intervention to resolve.

Reason: The job might be trying to build a large project or perform a resource-intensive task that exceeds the default timeout limit.

Solution:

  • Optimize the build process: Look for ways to optimize your build scripts. This could involve caching dependencies or using lighter Docker images.
  • Increase the timeout limit: You can specify a longer timeout duration for a job or step using the timeout-minutes attribute in your workflow file.

Example:

Terminal
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 60 # Increase this timeout value as needed
steps:
- uses: actions/checkout@v2
- name: Build the project
run: make build

Reason: Steps that involve downloading dependencies or pushing large artifacts might fail due to poor network conditions or slow download speeds.

Solution:

  • Use GitHub's cache: Implement caching for dependencies to reduce the frequency and volume of network requests.
  • Retry steps on failure: Implement a retry mechanism for steps that fail due to transient network issues.

Example:

Terminal
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v2
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-m2
- name: Download dependencies
run: mvn dependency:resolve
- name: Build
run: mvn package

This GitHub Action leverages caching by saving and retrieving the Maven dependencies stored in the ~/.m2 directory, using a cache key that is uniquely generated based on the hash of the pom.xml files across the project. If the dependencies have not changed (i.e., the pom.xml hash remains the same), the cache hit allows the workflow to skip re-downloading these dependencies, thereby speeding up the build process.

Reason: A step may be waiting indefinitely for user input or an external trigger that never occurs.

Solution:

  • Implement timeouts in scripts: Ensure that any custom script or third-party action used in your workflow has its own timeout mechanism.
  • Avoid waiting for external triggers within jobs: Design workflows to be triggered by these events rather than waiting for them during execution.

Example:

Terminal
steps:
- name: Wait for external service
run: |
timeout 15m ./wait-for-service.sh # Timeout after 15 minutes

Here's an example of a workflow designed to have timeouts within scripts and avoids waiting for external triggers during job execution:

Terminal
name: Example Workflow with Timeout
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Run build script with timeout
run: |
timeout 15m ./build-script.sh
shell: bash
- name: Run tests
run: |
timeout 10m npm test
shell: bash
- name: Post build cleanup
if: always()
run: ./cleanup-script.sh
shell: bash

The timeout command is used to ensure that the build-script.sh and npm test commands complete within 15 minutes and 10 minutes respectively, preventing them from running indefinitely.

This workflow is triggered by code pushes and pull requests to the main branch rather than waiting for any manual trigger or external event during execution. This design ensures that the workflow is responsive to code changes and automates execution without delays.

Reason: The job might be consuming excessive CPU or memory resources, causing slowdowns or crashes.

Solution:

  • Optimize resource usage: Profile and optimize your scripts or applications to use resources more efficiently.
  • Adjust GitHub Actions runners: If using self-hosted runners, ensure they are adequately provisioned to handle the workload. This might include increasing CPU power, memory, and disk space, or improving network bandwidth to accommodate the demands of complex or concurrent jobs. Ensuring that self-hosted runners are properly configured and scaled allows for smoother, faster CI/CD processes and reduces the likelihood of timeouts or performance bottlenecks during automation.

Reason: Errors in the workflow file or bugs in the scripts can cause unexpected delays or infinite loops.

Solution:

  • Review and test workflow files: Regularly review and test your workflows to ensure they are configured correctly and free of bugs.
  • Use linters and validators: Employ YAML linters and GitHub Actions validators to catch common mistakes in workflow definitions.

For further reading on resolving timeouts in GitHub Actions workflows see the official GitHub documentation.

Stay unblocked. Ship faster.
Experience the new developer workflow - create, review, and merge code continuously. Get started with one command.
Learn more

Give your PR workflow
an upgrade today

Stack easier | Ship smaller | Review quicker

Or install our CLI.
Product Screenshot 1
Product Screenshot 2