skip to Main Content

We have a workflow file:

---
name: 'Deploy Test Env'

on:
  pull_request:
    types:
      - edited
      - opened
      - synchronize
    branches:
      - develop
    paths:
      - '**.js'

jobs:
  deploy:
    # yamllint disable rule:line-length
    name: '[DEV] DEPLOY'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Deploy
        run: |
          echo 'Deploy Dev Env by ${{ github.event.action }} event type' >> "${GITHUB_STEP_SUMMARY}"

When new Pull Request (feature_branchdevelop) is created or new commit inside feature_branch is occured, pull_request‘s opened (or synchronize) event is triggering Job.

Here is a paths condition: if none of JavaScript files are changed, application source code is the same and we don’t need to deploy new test environment. That is correct.

But, here is third action type: edited. It is used because we have environment parameters passed inside Pull Request message. And if message is changed (edited), it means that parameters possibly changed too, and we have to re-deploy test environment even if **.js files are not changed. But because of paths condition edited event will not be triggered too.

In other words, description should be looks like:

---
name: 'Deploy Test Env'

on:
  # will be triggered only if *.js files changed
  pull_request:
    types:
      - opened
      - synchronize
    branches:
      - develop
    paths:
      - '**.js'

  # will be triggered anytime when PR contents are updated
  pull_request:
    types:
      - edited
    branches:
      - develop

But YAML doesn’t support duplicated keys and this format is wrong.

OR:

on:
  pull_request:
    types:
      # paths are set only for `opened` and `synchronize` types
      - type: edited
      - type: opened
        paths:
          - '**.js'
      - type: synchronize
        paths:
          - '**.js'
    branches:
      - develop

But types should be a list…

The question is: Is it possible to describe desired behavior? Maybe pull_request may be passed twice as array or paths may be set under the edited type (something like my second example)

2

Answers


  1. Chosen as BEST ANSWER

    Here is one more example of reusable workflows:

    • .github/workflows/reuser_on_edited.yml
      the workflow will reuse to_reuse.yml jobs when PR contents are edited
    ---
    name: 'Reuser on Edited'
    
    on:
      pull_request:
        types:
          - edited
        branches:
          - 'develop'
    
    jobs:
      reuse:
        uses: ./.github/workflows/to_reuse.yml
        with:
          original_github: ${{ toJSON(github) }}
          other_input: 'BOOM! edited'
    
    • .github/workflows/reuser_on_pr_changed.yml
      the workflow will reuse to_reuse.yml jobs when some of **.js files is changed.
    ---
    name: 'Reuser on PR changed'
    
    on:
      pull_request:
        types:
          - opened
          - synchronize
        branches:
          - 'develop'
        paths:
          - '**.js'
    
    jobs:
      reuse:
        uses: ./.github/workflows/to_reuse.yml
        with:
          original_github: ${{ toJSON(github) }}
    
    • .github/workflows/to_reuse.yml
      the file to reuse jobs inside it
    on:
      workflow_call:
        inputs:
          original_github:
            type: string
            required: true
            description: "github context that passed from original workflow (JSON)"
          other_input:
            type: string
            default: 'default'
            required: false
            description: "just for LOLs"
    
    jobs:
      deploy_job:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout v2
            uses: actions/checkout@v2
            with:
              ref: ${{ fromJSON(inputs.original_github).event.pull_request.head.sha }}
    
          - name: Deploy
            run: |
              {
                echo 'Deploy Dev Env by `${{ fromJSON(inputs.original_github).event.action }}` event type';
                echo '';
                echo 'Also `${{ inputs.other_input }}` input is passed';
              } >> "${GITHUB_STEP_SUMMARY}"
    

    Original github context may be passed as JSON string and reused inside different workflow.

    Also, different conditions (paths, etc.) may be set for different pull_request action types.


  2. You can use reusable workflows to achieve this.

    Divide your workflow into three (3) workflows:

    • ci.yml: reusable workflow (workflow that performs stuff)
    • ci-pr-opened-synchronize.yml: reusable workflow caller (for PR opened/synchronize for .js files)
    • ci-pr-edited.yml: reusable workflow caller (for PR edited)

    The above reusable workflow callers will call the ci.yml workflow.


    Here’s a complete working example with .md files filter and PRs to the main branch (https://github.com/iamazeem/github-actions-reusable-workflow-test):

    ci.yml

    name: CI
    
    on:
      workflow_call:
        inputs:
          message:
            type: string
            description: custom message
            required: true
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - name: Print message
            if: ${{ inputs.message }}
            env:
              MESSAGE: ${{ inputs.message }}
            run: |
              echo "message: $MESSAGE"
    

    ci-pr-opened-synchronize.yml

    name: PR opened/synchronize
    
    on:
      pull_request:
        types:
          - opened
          - synchronize
        branches:
          - main
        paths:
          - '**.md'
    
    jobs:
      pr-open-sync:
        uses: ./.github/workflows/ci.yml
        with:
          message: 'PR opened/synchronized'
    

    ci-pr-edited.yml

    name: PR edited
    
    on:
      pull_request:
        types:
          - edited
        branches:
          - main
    
    jobs:
      pr-edited:
        uses: ./.github/workflows/ci.yml
        with:
          message: 'PR edited'
    

    You may check this PR and its respective actions for this sample:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search