Skip to content

How to Retry Failed Steps in GitHub Action Workflows

This article was written over 18 months ago and may contain information that is out of date. Some content may be relevant but please refer to the relevant official documentation or available resources for the latest information.

Sometimes things can go wrong in your GitHub Action workflow step(s), and you may want to retry them. In this article, we'll cover two methods for doing this!

Pre-requisites

  • Git This should be installed in your path.
  • GitHub account: We'll need this to use GitHub Actions.

Initial setup

In order to follow along, here are the steps you can take to setup your GitHub Actions workflow:

Initialize your git repository

In your terminal, run git init to create an empty git repository or skip this step if you already have an existing git repository.

Create a workflow file

GitHub workflow files are usually .yaml/.yml files that contain a series of jobs and steps to be executed by GitHub Actions. These files often reside in .github/workflows. If the directories do not exist, go ahead and create them. Create a file retry.yml in .github/workflows. For now, the file can contain the following:

name: "Retry action using retry step"
on:
	# This action is called when this is pushed to github
	push:
	# This action can be manually triggered
	workflow_call:
jobs:
    # This name is up to you
	retry-job:
		runs-on: "ubuntu-latest"
		name: My Job
		steps:
			- name: Checkout repository
			  uses: actions/checkout@v3

			- name: Print
			  run: |
				echo 'Hello'

Testing your workflow

You can test your GitHub Action workflow by pushing your changes to GitHub and going to the actions tab of the repository. You can also choose to test locally using Act.

Retrying failed steps

Approach 1: Using the retry-step action

By using the retry-step action, we can retry any failed shell commands. If our step or series of steps are shell commands, we can use the retry-step action to retry them.

If, however, you'd like to try retry a step that is using another action, then the retry-step action will NOT work for you. In that case, you may want to try the alternative steps mentioned below.

Modify your action file to contain the following:

name: "Retry action using retry step"
on:
	# This action is called when this is pushed to github
	push:
	# This action can be manually triggered
	workflow_call:
jobs:
    # This name is up to you
	retry-job:
		runs-on: "ubuntu-latest"
		name: My Job
		steps:
			- name: Checkout repository
			  uses: actions/checkout@v3

			- name: Use the reusable workflow
			  # Use the retry action
			  uses: nick-fields/retry@v2
			  with:
				max_attempts: 3
				retry_on: error
				timeout_seconds: 5
				# You can specify the shell commands you want to retry here
				command: |
					echo 'some command that would potentially fail'				

Approach 2: Duplicate steps

If you are trying to retry steps that use other actions, the retry-step action may not get the job done. In this case, you can still retry steps by retrying steps conditionally, depending on whether or not a step failed.

GitHub provides us with two main additional attributes in our steps:

  • continue-on-error - Setting this to true means that the even if the current step fails, the job will continue on to the next one (by default failure stops a job's running).
  • steps.{id}.outcome - where {id} is an id you add to the steps you want to retry. This can be used to tell whether a step failed or not, potential values include 'failure' and 'success'.
  • if - allows us to conditionally run a step
name: "Retry action using retry step"
on:
	# This action is called when this is pushed to GitHub
	push:
	# This action can be manually triggered
	workflow_call:
jobs:
    # This name is up to you
	retry-job:
		runs-on: "ubuntu-latest"
		name: My Job
		steps:
			- name: Checkout repository
			  uses: actions/checkout@v3

			- name: Some action that can fail
			  # You need to specify an id to be able to tell what the status of this action was
			  id: myStepId1
			  # This needs to be true to proceed to the next step of failure
			  continue-on-error: true
			  uses: actions/someaction

			# Duplicate of the step that might fail ~ manual retry
			- name: Some action that can fail
			  id: myStepId2
			  # Only run this step if step 1 fails. It knows that step one failed because we specified an `id` for the first step
			  if: steps.myStepId1.outcome == 'failure'
			  # This needs to be true to proceed to the next step of failure
			  continue-on-error: true
			  uses: actions/someaction

Bonus: Retrying multiple steps

If you want to retry multiple steps at once, then you can use composite actions to group the steps you want to retry, and then use the duplicate steps approach mentioned above.

Conclusion

How do you decide which approach to use?

  • If you are retrying a step that is only shell commands, then you can use the retry step action.

  • If you are retrying a step that needs to use another action, then you can use duplication of steps with conditional running to manually retry the steps.

This Dot is a consultancy dedicated to guiding companies through their modernization and digital transformation journeys. Specializing in replatforming, modernizing, and launching new initiatives, we stand out by taking true ownership of your engineering projects.

We love helping teams with projects that have missed their deadlines or helping keep your strategic digital initiatives on course. Check out our case studies and our clients that trust us with their engineering.

Let's innovate together!

We're ready to be your trusted technical partners in your digital innovation journey.

Whether it's modernization or custom software solutions, our team of experts can guide you through best practices and how to build scalable, performant software that lasts.

Prefer email? hi@thisdot.co