"Run if previous Step failed" doesn't seem to mean really "previous" Step

I have a workflow (simplified) as this:

  1. Package (gradlew assembleDebug)
  2. Unit test (gradlew jacocoTestDebugUnitTestReport)
  3. Instrumental test (Virtual Device Testing)
  4. Jacoco report upload

When 1 fails, the workflow should stop. As long as 1 passes, even if 2 fails, workflow should continue to 3 and 4. How should I configure this?

In such a workflow, the “Run if previous Step failed” switch only works on 2 (for which I should uncheck), but not on 3 or 4. If I check “Run if previous Step failed” for 3 or 4, then when 1 fails, they will still run, which is pointless.

The only configuration you need is marking step 2. as skippable: https://devcenter.bitrise.io/tips-and-tricks/dont-mark-build-failed-if-step-fails/. Unfortunately it is not (yet) supported by graphical workflow editor so you need to use text mode (bitrise.yml).

1 Like

Doesn’t skippable mean this step doesn’t fail a job? Step 2 is unit test. I need it the job to fail when unit test doesn’t pass.

Correct @sah.

If you’d need the build to fail but want to run specific steps even if a previous step fails, then you can mark those steps to “always run” (Run if previous Step failed) on the web UI, just enable this option/toggle:

Or in YML mode use is_always_run: true, you can find an example here: Steps in YAML | Bitrise DevCenter

If I understood correctly @sah doesn’t want to run steps 2-4 if 1. fails. So is_always_run for steps 2-4 is not a solution. On the other hand, if 1. fails next ones will fail immediately so effectively there is a little difference between this and not running steps 2-4.

It seems that such effect is not directly achievable with single switches, but here are some examples:

  1. Use is_always_run and run_if: https://devcenter.bitrise.io/tips-and-tricks/disable-a-step-by-condition/ to decide when steps 2-4 should run.
  2. Mark step 2. as skippable and add step 5. which distinguishes if 2. failed and fails the build if so.

Yes, you are right. The workflow should logically be something like this:

   [BUILD]  =>  [TEST]             =>  [COVERAGE]

             2. Unit test
           /                      \
1. Package                          4. Jacoco report
           \                      /
             3. Instrumental test

, where 2 and 3 could actually run in parallel, as long as 1 passes. And as long as either (2 or 3) is run, pass or fail, 4 should run. It’s similar to the stage concept in gitlab-ci.

Does this look like something that should be supported by bitrise? Your suggestion looks a bit hacky, and honestly I haven’t figured out how to use is_always_run and run_if to achieve this.

is_always_run: true causes that step will run no matter if build is in failed state or not.
Using run_if you can skip step execution conditionally.

In this case it can be something like that:
run_if: '{{getenv "SOME_VAR_EXPORTED_BY_STEP_1" | ne ""}}'

If step 1. fails it won’t export any output environment variable so its value will be empty when evaluating run_if expression.

1 Like

OK now I understand your solution. But still, it feels a bit hacky. I think Bitrise should provide something similar to the stage concept. Do you think?

Sure, it’s definitely planned (stage like concept), please vote & comment at: Parallel Builds: Seperate stacks for seperate workflows + trigger multiple workflows (builds) at the same time

In the meantime, in this specific case I’d suggest you to simply check the report before uploading it, whether it exists at the path. Mark the “Jacoco report upload” step with is_always_run: true and simply check whether the report is available at the path. If no other step is marked with is_always_run then if Package would fail the report will not be generated, and so the report uploader step will simply terminate due to the lack of report file to upload. If “Package” step succeeds then the process will continue with the unit test step. If that fails indeed this will skip the VDT step but the report will still be uploaded by the uploader step.

Depends on the details of course, whether you actually need to run the VDT step if the Unit Test step fails, otherwise this should provide the functionality you described.

Thanks. I’ll try your suggestion.

1 Like