Bug in IF conditions on inputs for reusable workflows
Problem
Problem: When a reusable workflow (called workflow), contains if conditions (based on the input of the job) at job level, there is a observation that the if condition seems to execute and use value globally (causing jobs which are being skipped because of a check). Example > Caller workflow: Simple workflow calling a reusable workflow passing in the github event (PR or push) to the reusable workflow [code block] > Reusable workflow: Workflow with a sequence of job which has conditions based on the input (whether it is a pull_request or a push) [code block] Observation - Job 3 gets the check skipped , even though the condition is valid and matches as Job 2 (Job 3 only depends on success of job 2 and the same `IF` condition as job2. - On removal of the `IF` condition on Job 4 , then Job 3 executes fine . Which implies of some sort of "state" of the IF condition (since there is no relationship between Job 4 and Job 3). The observation of runs can be found in this repository here -> https://github.com/action-foobar/action-testing/actions/runs/1682109402 PS: This was working perfectly fine till 11PM GMT 10th Jan . (as we have a lot of jobs in our org on this setup)
Unverified for your environment
Select your OS to check compatibility.
1 Fix
Fix IF Condition State Issue in Reusable Workflows
The observed behavior is due to the global state of the IF conditions in the reusable workflow, which causes unintended job skipping. When an IF condition is evaluated, it seems to affect subsequent jobs even if they are not directly related, leading to inconsistent execution based on previous job evaluations.
Awaiting Verification
Be the first to verify this fix
- 1
Refactor IF Conditions
Modify the IF conditions in the reusable workflow to ensure they are evaluated independently for each job. This can be done by encapsulating the conditions within a separate job that sets an output variable based on the input event type.
yamljobs: check_event: runs-on: ubuntu-latest outputs: is_pull_request: ${{ steps.check.outputs.is_pull_request }} steps: - name: Check Event Type id: check run: | echo "::set-output name=is_pull_request::$(if [ '${{ inputs.event }}' == 'pull_request' ]; then echo 'true'; else echo 'false'; fi)" - 2
Update Job Dependencies
Adjust the dependencies of Job 2 and Job 3 to reference the output from the check_event job instead of relying solely on their own IF conditions. This ensures that each job's execution is based on the latest evaluated state.
yamljobs: job2: needs: check_event if: needs.check_event.outputs.is_pull_request == 'true' runs-on: ubuntu-latest steps: - name: Job 2 Steps run: echo 'Executing Job 2' job3: needs: job2 if: needs.check_event.outputs.is_pull_request == 'true' runs-on: ubuntu-latest steps: - name: Job 3 Steps run: echo 'Executing Job 3' - 3
Remove Redundant IF Conditions
Eliminate any redundant IF conditions in Job 4 that may be causing interference with Job 3's execution. Ensure that Job 4's logic does not affect the state of Job 3.
yamljobs: job4: needs: job2 runs-on: ubuntu-latest steps: - name: Job 4 Steps run: echo 'Executing Job 4' - 4
Test the Workflow
Run the modified reusable workflow with both pull_request and push events to confirm that all jobs execute as expected without unintended skips.
yamlworkflow_dispatch: inputs: event: description: 'Event type' required: true default: 'push'
Validation
Confirm that all jobs execute correctly for both pull_request and push events without any unintended skips. Check the action logs for each job to ensure they run as expected based on the input event type.
Sign in to verify this fix
Environment
Submitted by
Alex Chen
2450 rep