update : 0001-01-01
2020-05-16 / @syui

github

pull-reqが来たときgithub-actionsを実行してhtml,sqlをreviewする

今回は、pull-reqが来たときgh-actionsを実行してlintでreviewやらreview-supportをするbotを作ってみた話。突然やる気になって作り始めてしまったという。

sql lintは、sqlintを使いました。

$ sudo gem i sqlint
$ sqlint index.sql
on:
  pull_request:
    types: opened
#on:
#  push:
#    branchs:
#    - test
jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - name: Set up Ruby 2.6
      uses: actions/setup-ruby@v1
      with:
        ruby-version: 2.6.x
    - name: gem i
      run: gem i sqlint
    - name: run sqlint
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        GITHUB_REPOSITORY: ${{ github.repository }}
        URL: ${{ github.event.pull_request.comments_url }}
        GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
      run: |
		#test
		#pull_number=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
		#pull_number=1
		#URL=https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${pull_number}/comments
		# review sqlint
		if ! lint_body=`sqlint views/news/index.sql`;then
			lint_body=`sqlint views/news/index.sql|tr '"' "'"|tr '\n' '.'`
			echo $lint_body
			curl -X POST \
			-H "Authorization: token ${GITHUB_TOKEN}" \
			-d "{\"body\": \"### :exclamation: sqlint ...no\n${lint_body}\"}" \
			${URL}
		fi

ここでは、sqlint views/news/index.sqlをcheckして、結果をgithub-pullreq-commentにpostしています。

sqlintの実行結果がなかなか厄介で、ifを使わないとerrorになってしまい、かつexport/dev/null 2>&1で回避できませんでした。

次に、gh-actionsでhtmllint-cliでhtmlの文法をチェックする方法です。htmllint-cliの実行結果も改行コードや空行などがgithub-apiを使ったpostに邪魔になることがあるので注意です。

$ npm i -g htmllint-cli
$ htmllint index.html
on:
  pull_request:
    types: opened
#on:
#  push:
#    branchs:
#    - test
jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
    - name: run htmllint-cli
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        GITHUB_REPOSITORY: ${{ github.repository }}
        URL: ${{ github.event.pull_request.comments_url }}
        GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
      run: |
		#test
		#pull_number=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
		#pull_number=1
		#URL=https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${pull_number}/comments
		npm i -D htmllint-cli -s
		./node_modules/htmllint-cli/bin/cli.js init
		lint_body=`./node_modules/htmllint-cli/bin/cli.js views/news/index.html`
		curl -X POST \
		-H "Authorization: token ${GITHUB_TOKEN}" \
		-d "{\"body\": \"${lint_body}\"}" \
		${URL}

最終的に完成したやつを載せておきます。raw_urlは本来いらなくて、curlではなく直接pathを通せばいいんだけど、なにかに使えるかもと思って残してる。

on:
  pull_request:
    types: opened

jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - name: Set up Ruby 2.6
      uses: actions/setup-ruby@v1
      with:
        ruby-version: 2.6.x
    - name: gem i
      run: gem i sqlint
    - name: lint and support
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        GITHUB_REPOSITORY: ${{ github.repository }}
        URL: ${{ github.event.pull_request.comments_url }}
        GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
      run: |
        # setup
        pull_number=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
        npm i -D htmllint-cli -s
        ./node_modules/htmllint-cli/bin/cli.js init
        export GOPATH=$HOME/go
        export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
        go get -v github.com/syui/xq
        # webhook=google translate
        #url=${{ secrets.WEBHOOK_URL }}

        # feed
        url_arch="https://www.archlinux.org/feeds/news/"
        url_archjp="https://www.archlinux.jp/feeds/news.xml"
        xml=index.xml
        xmljp=news.xml
        curl -sL $url_arch -o $xml
        curl -sLO $url_archjp
        link=`xq l l $xml`
        link=${link%*/}
        link=${link##*/}
        linkjp=`xq l l $xmljp`
        linkjp=${linkjp%*/}
        linkjp=${linkjp##*/}
        if [ "${link}" = "${linkjp}" ];then
          echo ok `xq l l $xmljp`
          exit
        fi
        title=`xq l title $xml`
        date_xml=`date --date="$(xq p $xml)" +"%Y-%m-%d" -u`
        body=`xq l description $xml|tr -d '\n'|sed -e 's/<[^>]*>//g' -e 's/\*//g'`
        author=`xq $xml | jq -r ".[0].author.name"`
        up_xml=${date_xml}

        # google translate 
        #title_ja=`curl -L -d "{\"txt\":\"$title\"}" $url`
        #body_ja=`curl -L -d "{\"txt\":\"$body\"}" $url|sed 's/&#39;//g'`

        # github api : pull-req
        p=p.json
        URL=https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${pull_number}/comments
        curl -H "Authorization: token ${GITHUB_TOKEN}" \
          https://api.github.com/repos/${GITHUB_REPOSITORY}/pulls/${pull_number}/files > $p

        # support views/news/index.sql
        cat $p | jq -r ".[]|select(.filename == \"views/news/index.sql\")"|jq -r ".blob_url"
        check=`cat $p | jq -r ".[]|select(.filename == \"views/news/index.sql\")"`
        if [ -n "$check" ];then
          body_c="> ${link}\n${title}\n${date_xml}\n${up_xml}\n${author}"
          gh_url=`echo $check | jq -r ".blob_url"`"#L17-L23"
          raw_url=`echo $check | jq -r ".raw_url"`
          curl -X POST \
             -H "Authorization: token ${GITHUB_TOKEN}" \
             -d "{\"body\": \"${gh_url}\n\n${body_c}\"}" \
             ${URL}       
        fi

        # review sqlint
        if ! lint_body=`sqlint views/news/index.sql`;then
          lint_body=`sqlint views/news/index.sql|tr '"' "'"|tr '\n' '.'`
          echo $lint_body
          curl -X POST \
             -H "Authorization: token ${GITHUB_TOKEN}" \
             -d "{\"body\": \"### :exclamation: sqlint ...no\n${lint_body}\"}" \
             ${URL}
        fi

        # support views/news/${link}.html
        cat $p | jq -r ".[]|select(.filename == \"views/news/${link}.html\")"|jq -r ".blob_url"
        check=`cat $p | jq -r ".[]|select(.filename == \"views/news/${link}.html\")"`
        if [ -n "$check" ];then
          line=`echo $check | jq -r ".additions"`
          gh_url=`echo $check | jq -r ".blob_url"`"#L1-L${line}"
          curl -X POST \
             -H "Authorization: token ${GITHUB_TOKEN}" \
             -d "{\"body\": \"${gh_url}\n\n> ${body}\n\n$(xq l l $xml)\"}" \
             ${URL}
        fi

        # review htmllint
        raw_url=`echo $check | jq -r ".raw_url"`
        curl -sLO $raw_url
        lint_body=`./node_modules/htmllint-cli/bin/cli.js ${link}.html|sed '/^$/d'|tr '\n' '.'|tr '"' "'"`
        lint_body="\n"`echo $lint_body | grep -v "found 0 errors"`
        if [ -n "$lint_body" ];then
          lint_body="### :exclamation: htmllint ...no\n${lint_body}"
        else
          lint_body="### :white_check_mark: htmllint ...ok\nviews/news/${link}.html"
        fi
        curl -X POST \
           -H "Authorization: token ${GITHUB_TOKEN}" \
           -d "{\"body\": \"${lint_body}\"}" \
           ${URL}