{"id":30737713,"url":"https://github.com/userdocs/gh-cli-workflow-reruns","last_synced_at":"2026-05-18T15:02:43.975Z","repository":{"id":308957519,"uuid":"621811320","full_name":"userdocs/gh-cli-workflow-reruns","owner":"userdocs","description":"Use gh cli to trigger a rerun of a local workflow on failure with some helpful outputs.","archived":false,"fork":false,"pushed_at":"2025-08-13T14:08:57.000Z","size":183,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-02T01:34:08.255Z","etag":null,"topics":["actions","gh-cli","github","workflow"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/userdocs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-03-31T12:44:08.000Z","updated_at":"2025-08-13T14:08:33.000Z","dependencies_parsed_at":"2025-08-08T23:28:22.507Z","dependency_job_id":"4a39fb63-8e9f-485e-968e-d7119f1f3096","html_url":"https://github.com/userdocs/gh-cli-workflow-reruns","commit_stats":null,"previous_names":["userdocs/gh-cli-workflow-reruns"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/userdocs/gh-cli-workflow-reruns","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/userdocs%2Fgh-cli-workflow-reruns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/userdocs%2Fgh-cli-workflow-reruns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/userdocs%2Fgh-cli-workflow-reruns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/userdocs%2Fgh-cli-workflow-reruns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/userdocs","download_url":"https://codeload.github.com/userdocs/gh-cli-workflow-reruns/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/userdocs%2Fgh-cli-workflow-reruns/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273517124,"owners_count":25119765,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actions","gh-cli","github","workflow"],"created_at":"2025-09-03T21:46:48.932Z","updated_at":"2026-05-18T15:02:43.866Z","avatar_url":"https://github.com/userdocs.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# gh cli workflow reruns\n\nAutomatically rerun failed github workflows\n\nThis is an example repo with a demonstration workflow to show how we can use just [gh cli](https://github.com/cli/cli) to trigger a rerun of failed jobs in a workflow using a drop in solution that only requires one customization.\n\n-   [Actions overview](https://github.com/userdocs/gh-cli-workflow-reruns/actions)\n-   [example-workflow.yml](https://github.com/userdocs/gh-cli-workflow-reruns/blob/main/.github/workflows/example-workflow.yml)\n-   [ci-auto-rerun-failed-jobs.yml](https://github.com/userdocs/gh-cli-workflow-reruns/blob/main/.github/workflows/ci-auto-rerun-failed-jobs.yml)\n\n### How the examples work\n\nThis example repo has a [matrix job](https://github.com/userdocs/gh-cli-workflow-reruns/blob/main/.github/workflows/example-workflow.yml) with two parts.\n\n```yml\nstrategy:\n    fail-fast: false\n    matrix:\n        name: [workflow-example]\n        conclusion: [\"job-success\", \"job-failure\"]\n```\n\nThis matrix fails on the second matrix in the first job, `job-failure`, until it has been rerun twice, based on the `github.run_attempt` context\n\n```yml\nif: matrix.conclusion == 'job-failure' \u0026\u0026 github.run_attempt \u003c 3\nrun: exit 1\n```\n\nOtherwise the `ci-auto-rerun-failed-jobs.yml` would attempt to rerun up to 5 (default) times before it stops. This setting can be configured.\n\n```yml\nif: inputs.attempts \u003c= inputs.retries\n```\n\nIt does this using this an end of workflow job and triggering the workflow file `ci-auto-rerun-failed-jobs.yml` if there were any failures `if:  failure()`\n\n### The fundamental components\n\nThere are 3 main components of this to apply. They will be detailed and explained here.\n\n#### Part 1\n\nThis goes at the start. It provides the core requirements to use the `ci-auto-rerun-failed-jobs.yml` workflow such as `workflow_dispatch` and `inputs`\n\n```yml\non:\n    workflow_dispatch:\n        inputs:\n            skip_rerun:\n                description: \"Skip rerun?\"\n                required: true\n                default: false\n                type: boolean\n            retries:\n                description: \"Number of rerun retries\"\n                required: true\n                default: \"5\"\n                type: choice\n                options: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\"]\n```\n\n\u003e [!NOTE]\n\u003e When manually running the job via `workflow_dispatch` you can set two options.\n\n-   `skip_rerun` - a true or false (default false) options to bypass the rerun.\n-   `retries` - the number of retry attempts as a list of options, 1 to 9 times.\n\n![](docs/assets/images/workflow_dispatch.png)\n\n#### Part 2\n\nThis would go at the end of you workflow, as a separate job, that you want to make sure completes. It will call the `ci-auto-rerun-failed-jobs.yml` and pass some critical inputs.\n\n\u003e [!WARNING]\n\u003e The one thing you need to make sure is customized is the `needs: [build, release]` to match the job name it is tracking. No other customizations are required.\n\u003e This job will work for `workflow_dispatch` and `schedule` jobs.\n\n```yaml\nci-auto-rerun-failed-jobs:\n    if: failure() \u0026\u0026 (github.event.inputs.skip_rerun || 'false') == 'false'\n    needs: [build, release]\n    concurrency:\n        group: ci-auto-rerun-failed-jobs\n        cancel-in-progress: true\n    permissions:\n        actions: write\n    runs-on: ubuntu-24.04-arm\n    env:\n        GH_TOKEN: \"${{ secrets.AUTO_RERUN || github.token }}\"\n        github_repo: \"\" # To use ci-auto-rerun-failed-jobs.yml hosted in a remote repository else default to the current repository. Requires PAT token AUTO_RERUN\n        retries: ${{ needs.scheduled_defaults.outputs.retries || '3' }}\n        distinct_id: ${{ github.event.inputs.distinct_id }}\n    steps:\n        - uses: actions/checkout@v4\n          with:\n              persist-credentials: false\n        - name: ci-auto-rerun-failed-jobs via ${{ env.github_repo || github.repository }}\n          run: \u003e\n              gh workflow run ci-auto-rerun-failed-jobs-action.yml\n              --repo \"${github_repo:-$GITHUB_REPOSITORY}\"\n              -f github_repo=${GITHUB_REPOSITORY}\n              -f run_id=${GITHUB_RUN_ID}\n              -f attempts=${GITHUB_RUN_ATTEMPT}\n              -f retries=${retries}\n              -f distinct_id=${distinct_id}\n```\n\n\u003e [!TIP]\n\u003e Since we are using [gh cli](https://cli.github.com/manual/index) you can define inputs to be passed you can add them like this\n\n```yml\n-f name=value\n```\n\nThe just add it as an input in the `ci-auto-rerun-failed-jobs.yml` and process it there as `${{ inputs.name }}`\n\n#### Part 3\n\nThis unique workflow will then take the defined inputs and rerun the job, watch it to conclusion and provide a small job summary\n\n\u003e [!NOTE]\n\u003e It works best locally but is setup to also be triggered from a remote repo\n\u003e\n\u003e You will need a PAT token configured as `secrets.AUTO_RERUN` with actions/content/workflow perms in the local and remote repo.\n\n```yaml\nname: ci auto rerun failed jobs\n\non:\n    workflow_dispatch:\n        inputs:\n            run_id:\n                description: \"The run id of the workflow to rerun\"\n                required: true\n            attempts:\n                description: \"The number of attempts to rerun the workflow\"\n                required: true\n            retries:\n                description: \"The number of retries to rerun the workflow\"\n                required: true\n            github_repo:\n                description: \"The repository to rerun the workflow\"\n                required: false\n            distinct_id:\n                description: \"The distinct id of the workflow to rerun\"\n                required: false\n\nrun-name: ci auto rerun failed jobs - attempt ${{ inputs.attempts }}\n\njobs:\n    gh-cli-rerun:\n        name: rerun - attempt ${{ inputs.attempts }}\n        permissions:\n            actions: write\n        runs-on: ubuntu-latest\n        env:\n            GH_TOKEN: \"${{ secrets.AUTO_RERUN || github.token }}\"\n        steps:\n            - name: Host - Checkout action ${{ inputs.distinct_id }}\n              uses: actions/checkout@v4\n\n            - name: gh cli rerun and summaries ${{ inputs.distinct_id }}\n              if: inputs.attempts \u003c= inputs.retries\n              run: |\n                  github_repo=\"${{ inputs.github_repo || github.repository }}\"\n                  failures=\"$(gh run view ${{ inputs.run_id }} --log-failed --repo \"${github_repo}\" | sed \"s,\\x1B\\[[0-9;]*[a-zA-Z],,g\")\"\n\n                  if [[ -z \"${failures}\" ]]; then\n                      failures=\"$(gh run view ${{ inputs.run_id }} --repo \"${github_repo}\" | sed \"s,\\x1B\\[[0-9;]*[a-zA-Z],,g\")\"\n                  fi\n\n                  if [[ \"${{ inputs.retries }}\" -ge \"2\" ]]; then\n                      gh run rerun \"${{ inputs.run_id }}\" --failed --debug --repo \"${github_repo}\"\n                  else\n                      gh run rerun \"${{ inputs.run_id }}\" --failed --repo \"${github_repo}\"\n                  fi\n\n                  printf '%b\\n' \"# gh cli workflow reruns\" \u003e\u003e $GITHUB_STEP_SUMMARY\n                  printf '\\n%b\\n' \":octocat: Here is a summary of inputs from the failed workflow\" \u003e\u003e $GITHUB_STEP_SUMMARY\n                  printf '\\n%b\\n' \"🟥 Failures at:\\n\\n\\`\\`\\`log\\n${failures}\\n\\`\\`\\`\" \u003e\u003e $GITHUB_STEP_SUMMARY\n                  printf '\\n%b\\n' \"🟦 Attempt: ${{ inputs.attempts }} - Rerun failed jobs in ${{ inputs.run_id }} :hammer:\" \u003e\u003e $GITHUB_STEP_SUMMARY\n\n                  if gh run watch ${{ inputs.run_id }} --exit-status --repo \"${github_repo}\"; then\n                      printf '\\n%b\\n' \"✅ Attempt: ${{ inputs.attempts }} succeeded 😺\" \u003e\u003e $GITHUB_STEP_SUMMARY\n                  else\n                      printf '\\n%b\\n' \"❌ Attempt: ${{ inputs.attempts }} failed 😾\" \u003e\u003e $GITHUB_STEP_SUMMARY\n                  fi\n```\n\n## Visual representation\n\nSome images visually demonstrating the progress of the example.\n\n#### First failure\n\n![](docs/assets/images/1.png)\n\n#### First rerun attempt\n\n![](docs/assets/images/2.png)\n\n#### Second rerun attempt\n\n![](docs/assets/images/3.png)\n\n#### Jobs successfully completed with no failures\n\n![](docs/assets/images/4.png)\n\n#### A helpful job summary\n\n#### ![](docs/assets/images/5.png)\n\n## Known limitations\n\nThere are a few things you need to understand about how this works and what you can and cannot do with it.\n\n### workflow_call\n\n-   `workflow_call` - This is used when calling the workflow from a reusable workflow. The problem with this is that the workflow is run as a child of the parent.\n\n    In order to rerun a workflow using `gh cli` it must have ended or you will get an error. So as this would be a child process it would prevent the parent from ending and prevent us from being able to rerun it. A child process attempting to restart the parent process. It won't work and you will get gh cli errors and a failed rerun.\n\n    ```\n    parent-worklow (ID)\n    ├─ child-failed-job\n    └─ child-rerun-job # a child trying to restart parent ID whilst running will result in an error\n    ```\n\n### schedule\n\n-   `schedule` - currently the `schedule` key cannot take inputs. So if your workflow was started via a schedule the`workflow_dispatch` inputs are all ignored and null. There are two ways to handle this.\n\n    We can set defaults like this, where we provide a default values if the inputs are null. These are what we call the schedule default values.\n\n    ```yml\n    if: failure() \u0026\u0026 (github.event.inputs.skip_rerun || 'true') == 'false'\n    run: gh workflow run ci-auto-rerun-failed-jobs.yml -f run_id=${{ github.run_id }} -f attempts=${{ github.run_attempt }} -f retries=${{ github.event.inputs.retries || '5' }}\n    ```\n\n    Another option is to use a small job to define the default values as outputs that can be used throughout the workflow:\n\n    ```yml\n    scheduled_defaults:\n    runs-on: ubuntu-latest\n    outputs:\n    skip_rerun: ${{ github.event.inputs.skip_rerun || 'false' }}\n    retries: ${{ github.event.inputs.retries || '5' }}\n    steps:\n        - name: Setting Outputs from inputs\n          run: printf '%b\\n\\n' \"Setting Outputs from Inputs\"\n    ```\n\n    So the checks would become like this instead\n\n    ```yml\n    if: failure() \u0026\u0026 needs.scheduled_defaults.outputs.skip_rerun == 'false'\n    run: gh workflow run ci-auto-rerun-failed-jobs.yml -f run_id=${{ github.run_id }} -f attempts=${{ github.run_attempt }} -f retries=${{ needs.scheduled_defaults.outputs.retries }}\n    ```\n\n### use as a composite action\n\nYou can use this via a composite action hosted in this repo using this example:\n\nhttps://github.com/userdocs/gh-cli-workflow-reruns/blob/main/.github/workflows/ci-auto-rerun-failed-jobs-action.yml\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuserdocs%2Fgh-cli-workflow-reruns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuserdocs%2Fgh-cli-workflow-reruns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuserdocs%2Fgh-cli-workflow-reruns/lists"}