How to create an Action to conditionally add labels or milestones to a Pull Request

I am trying to create a GitHub Action in order to answer to a pull-request of anyone submitting it in the repository.

If in the pull-request someone has edited the file at a specific line, I would like the GitHub Action to trigger a check wether the value of the string is as expected or not. I would like the string to accept "one" or "more words", either "in the same order" or "in" "a" "randomized" "order" in the line.

If the conditions are met, I would like the GitHub Action to trigger a Milestone to the pull-request.

Either the conditions are met or not, I would also like the GitHub Action to trigger one or more label to the pull-request, the label depending on the if.

Finally I would like to trigger a comment also depending on wether the condition are met or not.

  1. In order to start the .yml file I start with name: action

  2. In order to trigger on pull-request I write on: pull_request:

  3. In order to introduce the builds I write jobs:

  4. In order to introduce the steps of the build I write build:

  5. In order to specify the hardware I write runs-on: ubuntu-latest

  6. In order to introduce the tasks I write steps:

  7. In order to look for all files in the repository I write - name: checkout uses: actions/checkout@v2

  8. In order to name and run the multiline task I write - name: Check value and label milestone and comment run: |

  9. In order to find the file that has just been commited for the pull-request I write file=$( git diff-tree --no-commit-id --name-only -r ${{ github.event.after }} ) and echo $file (I don’t know why this is necessary though)

  10. In order to find the line that should be checked I write line=$(sed -n '1p' $file) where I guess '1p' stands for the first line of the file, so that if I need the line number 8 I should write '8p'. And echo $line (I don’t know why this is necessary though)

  11. In order to compare the edited line with a model I have two ways to write the words either STR="several words", "several", "words" or SUB="several words", "several", "words". I don’t know what is the syntax of this in order to expect:

  • one "word"
  • "several words in a precise order"
  • "several" "words" "in" "any" "order"
  • "all" "the" "words"
  • "any" of the words
  • not this “word”
  • multiple of the above conditions altogether
  • any other useful conditioning from bash which I have forgotten that would be necessary to check values…
  1. In order to check if the word/s is/are written or not in the file at the exact line I write
if grep -q "$SUB" <<< "$line"; 
if [ `grep -c "$STR" 0/1` -ne '0' ];

(not sure if that’s possible though)
or maybe

if [ `grep -c "$STR" <<< "$line" -ne '0' ];

or maybe

if grep -q "$SUB" <<< "$line" -ne '0' ; 
  1. In order to know if the condition is met I write then echo "Found"

  2. In order to find the right pull-request I write curl --request PATCH \ and --url ${{ github.event.pull_request.issue_url }} \ and --header 'authorization: token ${{ secrets.GITHUB_TOKEN }}' \ then in order to give the Milestone I write --data '{"milestone": Name}'

curl --request PATCH \
--url ${{ github.event.pull_request.issue_url }} \
--header 'authorization: token ${{ secrets.GITHUB_TOKEN }}' \
--data '{"milestone": Name}'
  1. In order to give the labels in this same then I continue writing
curl --request PATCH \
--url ${{ github.event.pull_request.issue_url }} \
--header 'authorization: token ${{ secrets.GITHUB_TOKEN }}' \
--data '{"labels": [ "one" ]}'
--data '{"labels": [ "blue" ]}'

I don’t know how to give multiple labels at the same time

  1. In order to send the comment in this same then I continue writing
curl --request POST \
--url ${{ github.event.pull_request.issue_url }}/comments \
--header 'authorization: token ${{ secrets.GITHUB_TOKEN }}' \
--data '{"body": "You may continue"}'
  1. In order to do the same with opposite data for the else I write
           else
             echo "Not Found"
             curl --request PATCH \
             --url ${{ github.event.pull_request.issue_url }} \
             --header 'authorization: token ${{ secrets.GITHUB_TOKEN }}' \
             --data '{"labels": [ "bug" ]}'
             curl --request POST \
             --url ${{ github.event.pull_request.issue_url }}/comments \
             --header 'authorization: token ${{ secrets.GITHUB_TOKEN }}' \
             --data '{"body": "You may try again"}'
             exit 1
           fi

which give a total of

name: action

on:    
  pull_request:
    
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: checkout
      uses: actions/checkout@v2

    - name: Check value and label milestone and comment
      run: |
           STR="several words", "several", "words"
           file=$( git diff-tree --no-commit-id --name-only -r ${{ github.event.after }} )
           echo $file
           line=$(sed -n '1p' $file)
           echo $line
           SUB='name: Octocat'
           if grep -q "$SUB" <<< "$line"; 
           if [ `grep -c "$STR" 0/1` -ne '0' ];
           then
             echo "Found"
             curl --request PATCH \
             --url ${{ github.event.pull_request.issue_url }} \
             --header 'authorization: token ${{ secrets.GITHUB_TOKEN }}' \
             --data '{"milestone": Name}'
             curl --request PATCH \
             --url ${{ github.event.pull_request.issue_url }} \
             --header 'authorization: token ${{ secrets.GITHUB_TOKEN }}' \
             --data '{"labels": [ "one" ]}'
             --data '{"labels": [ "blue" ]}'
             curl --request POST \
             --url ${{ github.event.pull_request.issue_url }}/comments \
             --header 'authorization: token ${{ secrets.GITHUB_TOKEN }}' \
             --data '{"body": "You may continue"}'
           else
             echo "Not Found"
             curl --request PATCH \
             --url ${{ github.event.pull_request.issue_url }} \
             --header 'authorization: token ${{ secrets.GITHUB_TOKEN }}' \
             --data '{"labels": [ "try again" ]}'
             curl --request POST \
             --url ${{ github.event.pull_request.issue_url }}/comments \
             --header 'authorization: token ${{ secrets.GITHUB_TOKEN }}' \
             --data '{"body": "You may try again"}'
             exit 1
           fi

any idea to make this work?

Hi @ojedavidea,

Based on your previous tickets, if you’d like to check if your PR commit contains some specified changes, you can use below format for checking:

git rev-list --all | GIT_PAGER=cat xargs git grep 'search_string'

For your case, if you’d like to check if string ‘name: Octocat’ is added in the file (eg: testname2), you can use below code:

      - name: checkout
        uses: actions/checkout@v2
      - name: check commit
        id: search
        run: |
          echo "::set-output name=exist::$(git rev-list --all | GIT_PAGER=cat xargs git grep 'name: Octocat' | grep '${{github.sha}}:testname2:name: Octocat')"   # add the {githubsha}:{filename}:{strings} for check
      - name: notfound
        if: steps.search.outputs.exist=='' # null means not found the string in commits in the specific file
        run: |
          echo not found!
      - name: found
        if: steps.search.outputs.exist!='' # found the string in commits in the specific file
        run: |
          echo found!

Please refer to my workflow for your reference.

Then you can add different operations to the found or ‘notfound’ steps, eg: add labels, comments, milestone…etc with your curl command.

You can also modify the search string to check more words as you’d like.

To add more labels, please add in data body, sample code below:

          curl --request PATCH \
            --url ${{ github.event.pull_request.issue_url }} \
            --header 'authorization: token ${{ secrets.GITHUB_TOKEN }}' \
            --data '{"milestone": 1, "labels": [ "bug", "question" ]}'

Thanks

1 Like

name: test

on:
pull_request:

jobs:
test_on_macos:
runs-on: macos-latest

env:
DEVELOPER_DIR: /Applications/Xcode_11.5.app/Contents/Developer
steps:
-uses: actions/checkout@v2
-run: xcrun swift test --enable-test-discovery --sanitize=thread

test_on_ubuntu_xenial:
container:
image: vapor/swift:5.2.2-xenial-ci
runs-on: ubuntu-latest
-run: apt update -y; apt install -y libsqlite3-dev
-uses: actions/checkout@v2
-run: swift test --enable-test-discovery --sanitize=thread

test_on_ubuntu_bionic:
container:
image: vapor/swift:5.2.2-bionic-ci
runs-on: ubuntu-latest
steps:
-run: apt update -y; apt install -y libsqlite3-dev
-uses: actions/checkout@v2
-run: swift test --enable-test-discovery --sanitize=thread