Home > Mobile >  How can I run a GitHub Actions job based on a complex condition (specific label removed)?
How can I run a GitHub Actions job based on a complex condition (specific label removed)?

Time:08-12

I have two reusable workflows to deploy and destroy GCP resources, which I call from one workflow based on different conditions.

One workflow creates infra and is triggered when the label preview is added to a PR:

on:
  pull_request:
    types: [opened, reopened, labeled]

jobs:
  create-infrastructure:
    if: ${{ contains( github.event.pull_request.labels.*.name, 'preview') }}
    # Call to a reusable workflow here

The second workflow I need to trigger when the PR is closed or when a specific label is removed; I tried this:

on:
  pull_request:
    types: [ closed, unlabeled ]

jobs:
  destroy_preview:
    if: ${{ contains( github.event.pull_request.labels.*.name, 'preview') }}
    uses: myrepo/.github/workflows/[email protected]
    with:
      project_id: xxx

I don't know how to define unlabeled for a specific label. It would be great if someone has any idea.

CodePudding user response:

The pull request webhook payload doesn't contain the removed label, as far as I can tell, but you can fetch the list of issue events (which work for pull requests, too), filter by unlabeled events, and then look at the label name of the last one.

Using the GitHub CLI in a run step, that might look something like this:

name: Preview removed workflow

on:
  pull_request:
    types:
      - unlabeled

jobs:
  destroy_preview:
    runs-on: ubuntu-20.04
    steps:
      - name: Check if "preview" was removed
        env:
          GITHUB_TOKEN: ${{ github.token }}
        run: |
          pr=${{ github.event.number }}
          label=$(gh api "repos/$GITHUB_REPOSITORY/issues/$pr/events" \
              --jq 'map(select(.event == "unlabeled"))[-1].label.name')

          if [[ $label == 'preview' ]]; then
              echo "The 'preview' label has been removed"
          fi

where you'd replace the echo with your infrastructure commands.


Now, if you want to call a reusable workflow when that specific label is removed, you have to somehow find a way to add a condition to the job where the reusable workflow is called.

One option is to make two jobs, one to check the condition and setting the result as a job output. The other job is set up as depending on the first one, and its if condition checks if the output was set to true.

This would look something like this (omitting the name and trigger, as they are identical to above):

jobs:
  checklabel:
    runs-on: ubuntu-20.04
    outputs:
      waspreview: ${{ steps.check.outputs.preview }}
    steps:
      - name: Check if "preview" was removed
        id: check
        env:
          GITHUB_TOKEN: ${{ github.token }}
        run: |
          pr=${{ github.event.number }}
          label=$(gh api "repos/$GITHUB_REPOSITORY/issues/$pr/events" \
              --jq 'map(select(.event == "unlabeled"))[-1].label.name')

          if [[ $label == 'preview' ]]; then
              echo "::set-output name=preview::true"
          fi

  destroy_preview:
    needs: checklabel
    if: needs.checklabel.outputs.waspreview
    uses: myrepo/.github/workflows/[email protected]
    with:
      project_id: xxx
  • Related