Henrik K
Henrik K

Reputation: 1061

Github actions if conditional evaluation

I have created a github actions script to check how a stock price is updating during the day (all details omitted for brevity in this post).

When the current price is higher than or equal to the price limit and the previous price is lower than the price limit 
OR
When the current price is lower than or equal to the price limit and the previous price is higher than the price limit

a limit event occurs.

the code can be found below and also on this link

name: if conditional limit

on:
  workflow_dispatch:

jobs:
  scheduled:
    runs-on: ubuntu-latest
    steps:
    - name: Check out this repo
      uses: actions/checkout@v2
    - name: Fetch latest data
      run: |-
        prev_price=9.88
        cur_price=10.2
        echo "this is the current price ${cur_price}"
        echo "this is the previous price ${prev_price}"
        price_limit=8.81
        echo "this is the price limit ${price_limit}"
        echo "GITHUB_PRICE_LIMIT=${price_limit}" >> $GITHUB_ENV
        echo "GITHUB_CUR_PRICE=${cur_price}" >> $GITHUB_ENV
        echo "GITHUB_PREV_PRICE=${prev_price}" >> $GITHUB_ENV
        echo "GITHUB_MAIL_UPDATE=0" >> $GITHUB_ENV
    - name: test for limit event
      if: (((env.GITHUB_CUR_PRICE >= env.GITHUB_PRICE_LIMIT) &&  (env.GITHUB_PREV_PRICE < env.GITHUB_PRICE_LIMIT)) || ((env.GITHUB_CUR_PRICE <= env.GITHUB_PRICE_LIMIT) &&  (env.GITHUB_PREV_PRICE > env.GITHUB_PRICE_LIMIT)))
      run: |-
        echo "limit event occurred"

I am very new to github actions, so please bear with me if I have missed something. Also, if this isn't the idiomatic way to achieve the effect that I am after, please let me know.

Observed behaviour: Limit event occurs

Expected behaviour: No limit event should occur (according to my understanding of the defined logic)

Upvotes: 1

Views: 1755

Answers (3)

Henrik K
Henrik K

Reputation: 1061

I got a lot of inspiration from GuiFalourds answer, so it feels right to tick it.

To work around this limitation, I ended up creating a javascript action that implements the logic. I used this tutorial and modified it for my own purposes.

Upvotes: 1

GuiFalourd
GuiFalourd

Reputation: 22890

Your logic is right, the problem seems to be related to the way expressions are read by the runner.

Just an observation regarding the naming convention you used: It's not recommended to use the prefix GITHUB_ as if you attempt to override the value of one of the default github environment variables, the assignment is ignored.

However, that isn't the reason why it's not working in your case.


Here is my contribution, even if I didn't find a solution (yet). It could help others...

I tested 3 different ways to perform what you did:

  • using outputs
  • using directly number values
  • using env variables (as you did or as workflow env variables)

It only worked as expected using directly the number values

Numbers

    - name: With Numbers
      run: |
        echo "(1) CURRENT PRICE >= PRICE LIMIT:" ${{ 10.20 >= 8.81 }}
        echo "(2) PREVIOUS PRICE < PRICE LIMIT:" ${{ 9.88 < 8.81 }}
        echo "(3) CURRENT PRICE <= PRICE LIMIT:" ${{ 10.20 <= 8.81 }}
        echo "(4) PREVIOUS PRICE > PRICE LIMIT:" ${{ 9.88 > 8.81 }}
        echo "(1) AND (2):" ${{ (10.20 >= 8.81) && (9.88 < 8.81) }}
        echo "(3) AND (4):" ${{ (10.20 <= 8.81) && (9.88 > 8.81) }}
        echo "(1) AND (2) OR (3) AND (4):" ${{ (((10.20 >= 8.81) && (9.88 < 8.81)) || ((10.20 <= 8.81) && (9.88 > 8.81))) }}

Numbers

Expressions return incorrect values for the others implementations

Outputs

    - name: With Outputs
      run: |
        echo "(1) CURRENT PRICE >= PRICE LIMIT:" ${{ steps.datas.outputs.current >= steps.datas.outputs.limit }}
        echo "(2) PREVIOUS PRICE < PRICE LIMIT:" ${{ steps.datas.outputs.previous < steps.datas.outputs.limit }}
        echo "(3) CURRENT PRICE <= PRICE LIMIT:" ${{ steps.datas.outputs.current <= steps.datas.outputs.limit }}
        echo "(4) PREVIOUS PRICE > PRICE LIMIT:" ${{ steps.datas.outputs.previous > steps.datas.outputs.limit }}
        echo "(1) AND (2):" ${{ (steps.datas.outputs.current >= steps.datas.outputs.limit) && (steps.datas.outputs.previous < steps.datas.outputs.limit) }}
        echo "(3) AND (4):" ${{ (steps.datas.outputs.current <= steps.datas.outputs.limit) && (steps.datas.outputs.previous > steps.datas.outputs.limit) }}
        echo "(1) AND (2) OR (3) AND (4):" ${{ (((steps.datas.outputs.current >= steps.datas.outputs.limit) && (steps.datas.outputs.previous < steps.datas.outputs.limit)) || ((steps.datas.outputs.current <= steps.datas.outputs.limit) && (steps.datas.outputs.previous > steps.datas.outputs.limit))) }}

Outputs

Env Variables

    - name: With Env Variables
      run: |
        echo "(1) CURRENT PRICE >= PRICE LIMIT:" ${{ env.CUR_PRICE >= env.PRICE_LIMIT }}
        echo "(2) PREVIOUS PRICE < PRICE LIMIT:" ${{ env.PREV_PRICE < env.PRICE_LIMIT }}
        echo "(3) CURRENT PRICE <= PRICE LIMIT:" ${{ env.CUR_PRICE <= env.PRICE_LIMIT }}
        echo "(4) PREVIOUS PRICE > PRICE LIMIT:" ${{ env.PREV_PRICE > env.PRICE_LIMIT }}
        echo "(1) AND (2):" ${{ (env.CUR_PRICE >= env.PRICE_LIMIT) && (env.PREV_PRICE < env.PRICE_LIMIT) }}
        echo "(3) AND (4):" ${{ (env.CUR_PRICE <= env.PRICE_LIMIT) && (env.PREV_PRICE > env.PRICE_LIMIT) }}
        echo "(1) AND (2) OR (3) AND (4):" ${{ (((env.CUR_PRICE >= env.PRICE_LIMIT) && (env.PREV_PRICE < env.PRICE_LIMIT)) || ((env.CUR_PRICE <= env.PRICE_LIMIT) && (env.PREV_PRICE > env.PRICE_LIMIT))) }}

Env Variables

Upvotes: 1

Krzysztof Madej
Krzysztof Madej

Reputation: 40553

Please try to wrap your if logic into ${{ }}:

    - name: test for limit event
      if: ${{ (((env.GITHUB_CUR_PRICE >= env.GITHUB_PRICE_LIMIT) &&  (env.GITHUB_PREV_PRICE < env.GITHUB_PRICE_LIMIT)) || ((env.GITHUB_CUR_PRICE <= env.GITHUB_PRICE_LIMIT) &&  (env.GITHUB_PREV_PRICE > env.GITHUB_PRICE_LIMIT))) }}
      run: |-
        echo "limit event occurred"

Upvotes: 2

Related Questions