Azure / login

Connect to Azure

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

1.6.0 versions Pre/Post Az CLI login commands need to honor any conditionals on the azure/login

JimSuplizio opened this issue · comments

I'm one of the EngSys guys on the azure-sdk and we have our own GitHub Actions workflows. Our azure login is conditional but the Pre/Post Az CLI login commands are being added indiscriminately. If the azure/login step has a conditional, the Pre/Post Az CLI Logins should have the same conditional. The Pre Az CLI command takes up 30 seconds to run which is bloating our Actions run times anywhere from 2x to 10x. In the interim, I've had to pin to azure/login@v1.5.1 to alleviate this problem.

The step has the following conditional
- name: 'Az CLI login'
if: ${{ github.event_name == 'issues' && github.event.action == 'opened' }}
uses: azure/login@v1

The repositories this is impacting are:

  • Azure/azure-sdk-for-net
  • Azure/azure-sdk-for-net-pr
  • Azure/azure-sdk-for-java
  • Azure/azure-sdk-for-java-pr
  • Azure/azure-sdk-for-python
  • Azure/azure-sdk-for-python-pr
  • Azure/azure-sdk-for-js
  • Azure/azure-sdk-for-js-pr
  • Azure/azure-sdk-for-c
  • Azure/azure-sdk-for-c-pr
  • Azure/azure-sdk-for-cpp
  • Azure/azure-sdk-for-go
  • Azure/azure-sdk-for-go-pr
  • Azure/azure-sdk-for-rust
  • Azure/azure-sdk-for-rust-pr
  • Azure/azure-sdk-for-ios
  • Azure/azure-sdk-for-ios-pr
  • Azure/azure-sdk-for-android
  • Azure/azure-sdk-for-android-pr
  • Azure/azure-sdk
  • Azure/azure-sdk-pr
  • Azure/azure-sdk-tools

This is an example where it's running when it shouldn't be. The Pre step running time took 3x longer to run that it did to install our actions processor and run the action.

/CC: @benbp @weshaggard

Hi @JimSuplizio, the issue you reported is indeed a problem, but it is currently not supported on GitHub. GitHub does provide an option, runs.pre-if, which allows us to define conditions for the pre: action execution. However, it has mentioned that

In pre-if, status check functions evaluate against the job's status, not the action's own status.

This limitation makes it impossible to have the pre/post azure/login steps use the same conditional logic as the azure/login step.

Additionally, it is impossible to read the if condition in the action script and skip the pre/post action. GitHub Actions evaluates the if expression itself and decides whether to include or exclude the step based on the result of the expression.

One potential solution could be to add a parameter like cleanup: on/off or an environment variable to control whether to skip the pre/post cleanup steps. We will discuss how to solve this issue and also investigate why the cleanup step takes 10+ seconds to finish. Thank you for bringing this to our attention.

@MoChilia Thank you for the update. I realize this might not be the easiest to solve because we do want to run the pre/post commands when we're running our Azure login.

Would an environment or parameter variable actually work? If the solution can't pull the conditional from the azure/login step then it at least needs to be configurable for a github.event_name and/or github.event.action. Would a parameter or setting an environment variable even accommodate this? That's just something to think about when looking at the solution.

As per the time it takes the Pre Az CLI command to run, I've seen the pre command take anywhere from 2 seconds to 45. I've also seen the azure/login step take that long. It seems more Azure related than network related, we install our actions processor from our dev feed and if it were network related I'd expect that to take longer.

@JimSuplizio
Yes, you're right. Adding an environment or parameter variable might not be the best option in your scenario. Could you separate the steps that require Azure/login from the others and execute them in one job? Then, apply the condition at the job level. This way, the job that includes azure/login together with pre/post cleanup can be bypassed entirely.

@MoChilia This is my workflow yml file that's handling all of our actions. Azure is only required for a specific isssues action. I guess I'm curious as to how these steps know there's an azure/login@v1.5.1 step and to inject pre/post command but can't see the conditional on the step and use that. Breaking this up into multiple actions is really not a great idea when this same yml is pushed out to 10 other repositories (with more incoming).

@JimSuplizio, why not try this? Consider elevating the condition to the job level. The job azure-actions will run on condition that if: ${{ github.event_name == 'issues' && github.event.action == 'opened' }} and the job event-handler will run after azure-actions on condition that if: always().

name: GitHub Event Processor
on:
  issues:
    types: [edited, labeled, opened, reopened, unlabeled]
  issue_comment:
    types: [created]
  pull_request_target:
    types: [closed, labeled, opened, reopened, review_requested, synchronize, unlabeled] 
permissions:
    issues: write
    pull-requests: write
    # For OIDC auth
    id-token: write
    contents: read

jobs:
  azure-actions:
    name: Run Azure actions
    runs-on: ubuntu-latest
    if: ${{ github.event_name == 'issues' && github.event.action == 'opened' }}
    steps:
      - name: 'Az CLI login'
        uses: azure/login@v1
        with:
            client-id: ${{ secrets.AZURE_CLIENT_ID }}
            tenant-id: ${{ secrets.AZURE_TENANT_ID }}
            subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

      - name: 'Run Azure CLI commands'
        run: |
          LABEL_SERVICE_API_KEY=$(az keyvault secret show \
            --vault-name issue-labeler \
            -n issue-labeler-func-key \
            -o tsv \
            --query value)

          echo "::add-mask::$LABEL_SERVICE_API_KEY"
          echo "LABEL_SERVICE_API_KEY=$LABEL_SERVICE_API_KEY" >> $GITHUB_ENV

  event-handler:
     needs: azure-actions
     name: Handle ${{ github.event_name }} ${{ github.event.action }} event
     runs-on: ubuntu-latest
     if: always()
     steps:
         - name: Install GitHub Event Processor
           run: ...
        - name: Process Action Event
           run: ...

It might require some effort to change the YAML in your 10+ repositories, but I can't think of a better option. I hope this helps. If there are any misunderstandings about your workflow, please let me know.

@MoChilia would elevating the condition to the job level prevent the pre/post Az CLI commands from being added if the condition wasn't met?

@JimSuplizio, the pre/post Azure CLI commands won't run because the entire job will be bypassed.

@MoChilia your suggested solution of splitting jobs works for limiting the pre/post commands but there's a couple of things were overlooked. First, our use of the AZ command sets a variable that needs to get passed to the other job. You can look here and see where I've taken your suggestion and added the code that set that variable in the job's output to pass to the other job. The problem here is that the variable coming out of Azure is a secret which can't be passed. The entire reason we're using Azure to get LABEL_SERVICE_API_KEY is because the login information wouldn't change willy-nilly but the LABEL_SERVICE_API_KEY could change at any time.

@JimSuplizio, I have found this docs for Masking and passing a secret between jobs or workflows. But it seems not work. So, I tried to pass secret between jobs with base64 encoding, which seems to work. You can have a try.

jobs:
  azure-actions:
    name: Retrieve Label Service Key from Azure
    runs-on: ubuntu-latest
    if: ${{ github.event_name == 'issues' && github.event.action == 'opened' }}
    outputs:
      API_KEY: ${{ steps.generate-key.outputs.API_KEY }}
    steps:
      - name: 'Run Azure CLI commands'
        id: generate-key
        run: |
          LABEL_SERVICE_API_KEY=1111
          LABEL_SERVICE_API_KEY_BASE64=$(echo -n $LABEL_SERVICE_API_KEY | base64 -w 0)
          echo -n "API_KEY=$LABEL_SERVICE_API_KEY_BASE64" >> $GITHUB_OUTPUT

  event-handler:
    needs: azure-actions
    name: Handle ${{ github.event_name }} ${{ github.event.action }} event
    runs-on: ubuntu-latest
    if: always()
    steps:
      - name: use api key
        shell: bash
        run: |
          LABEL_SERVICE_API_KEY=$(echo -n ${{needs.azure-actions.outputs.API_KEY}} | base64 --decode)
          echo "$LABEL_SERVICE_API_KEY"

@MoChilia Ignoring the obvious security issues with doing this, doesn't this seem like something that's way beyond what I should even remotely have to do. I don't feel like checking for a conditional and adding it to the pre/post commands would be nearly as complex as the suggestions to 'fix' this. Frankly, the dog and pony show required for the suggestions here is infinitely more complex than just having two processing jobs, one that needs Azure and one that doesn't, with conditionals at the job level. This is less than ideal but far less of a confusing mess.

@JimSuplizio, I agree, it's clearer. To sum up, the limitation that pre/post steps cannot share the same condition as the main step is intentional in GitHub's design. Our ability to resolve this issue within the scope of this action is somewhat limited. One possible solution is to elevate the condition to the job level.
If you have any suggestions for improving our action, please let me know. Or feel free to close this issue if you have no further questions.

Closing the issue for now. Feel free to reopen it if you have any further questions.