Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force to exit in Github Actions step

I want to exit a job if a specific condition is met:

jobs:
  foo:
    steps:
      ...
      - name: Early exit
        run: exit_with_success # I want to know what command I should write here
        if: true
      - run: foo
      - run: ...
 ...

How can I do this?

like image 333
Yohei Avatar asked Mar 08 '20 16:03

Yohei


People also ask

How do I exit an action in GitHub?

There is currently no way to exit a job arbitrarily, but there is a way to allow skipping subsequent steps if an earlier step failed, by using conditionals: jobs: foo: steps: ...

How do I skip steps in GitHub actions?

Github action for skipping workflows upon matching or finding phrase in commit message(s) or pull request. Works by searching for phrase in or matching RegExp with commit message(s), pull request title, and/or pull request body. skip output value can then be used to conditionally skip the following jobs or steps.

How do I cancel a GitHub deployment?

Canceling a workflow run From the list of workflow runs, click the name of the queued or in progress run that you want to cancel. In the upper-right corner of the workflow, click Cancel workflow.

How do I restart an action in GitHub?

To re-run a failed workflow run, use the run rerun subcommand. Replace run-id with the ID of the failed run that you want to re-run. If you don't specify a run-id , GitHub CLI returns an interactive menu for you to choose a recent failed run.


1 Answers

There is currently no way to exit a job arbitrarily, but there is a way to allow skipping subsequent steps if an earlier step failed, by using conditionals:

jobs:
  foo:
    steps:
      ...
      - name: Early exit
        run: exit_with_success # I want to know what command I should write here
      - if: failure()
        run: foo
      - if: failure()
        run: ...
 ...

The idea is that if the first step fails, then the rest will run, but if the first step doesn't fail the rest will not run.

However, it comes with the caveat that if any of the subsequent steps fail, the steps following them will still run, which may or may not be desirable.


Another option is to use step outputs to indicate failure or success:

jobs:
  foo:
    steps:
      ...
      - id: s1
        name: Early exit
        run: # exit_with_success
      - id: s2
        if: steps.s1.conclusion == 'failure'
        run: foo
      - id: s3
        if: steps.s2.conclusion == 'success'
        run: ...
 ...

This method works pretty well and gives you very granular control over which steps are allowed to run and when, however it became very verbose with all the conditions you need.


Yet another option is to have two jobs:

  • one which checks your condition
  • another which depends on it:
jobs:
  check:
    outputs:
      status: ${{ steps.early.conclusion }}
    steps:
      - id: early
        name: Early exit
        run: # exit_with_success
  work:
    needs: check
    if: needs.check.outputs.status == 'success'
    steps:
      - run: foo
      - run: ...
 ...

This last method works very well by moving the check into a separate job and having another job wait and check the status. However, if you have more jobs, then you have to repeat the same check in each one. This is not too bad as compared to doing a check in each step.


Note: In the last example, you can have the check job depend on the outputs of multiple steps by using the object filter syntax, then use the contains function in further jobs to ensure none of the steps failed:

jobs:
  check:
    outputs:
      status: ${{ join(steps.*.conclusion) }}
    steps:
      - id: early
        name: Early exit
        run: # exit_with_success
      - id: more_steps
        name: Mooorreee
        run: # exit_maybe_with_success
  work:
    needs: check
    if: !contains(needs.check.outputs.status, 'failure')
    steps:
      - run: foo
      - run: ...

Furthermore, keep in mind that "failure" and "success" are not the only conclusions available from a step. See steps.<step id>.conclusion for other possible reasons.

like image 74
smac89 Avatar answered Oct 18 '22 07:10

smac89