github actionsのバージョンが上がったので、自分が作ったアクションも書き換えてみました。
作ったもの
対応している静的解析ツールは以下のものです。
READMEに書いてある通りなのですが、下記の感じでymlファイルを作ってもらえれば動きます。
name: static check
on: pull_request
jobs:
fmt:
name: Fmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: grandcolline/golang-github-actions@v1.0.0
with:
run: fmt
token: ${{ secrets.GITHUB_TOKEN }}
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: grandcolline/golang-github-actions@v1.0.0
with:
run: lint
token: ${{ secrets.GITHUB_TOKEN }}
withで指定できる変数は以下の通りです。
変数名 | デフォルト | なに |
---|---|---|
run |
N/A | 実行するコマンド(上の表から選ぶ) |
directory |
. |
静的解析を実行する場所の相対パス |
comment |
true |
PRにコメントするか否か |
token |
"" |
GitHub Token |
flags |
"" |
コマンド実行時に追加するフラグ |
ignore-defer |
false |
errcheck実行時に deferのエラーチェックを無視するか否か |
いか、アクション作成する際にやったこと
アクションには、2種類のパターンがあるそうです。
今回はgoを使いたかったので、container actionsにしました。
公式のテンプレート通りに以下の構成にしました。
.
├── Dockerfile
├── LICENSE
├── README.md
├── action.yml
└── entrypoint.sh
Dockerfileは使いたいツールをインストールして、最終的にentrypoint.sh
を実行するだけのシンプルなもの。
やりたい処理などは、entrypoint.sh
にゴリゴリ書いていく。
FROM golang::1.12.9
ENV GO111MODULE=on
RUN apt-get update && \
apt-get -y install jq && \
go get -u \
github.com/kisielk/errcheck \
golang.org/x/tools/cmd/goimports \
golang.org/x/lint/golint \
github.com/securego/gosec/cmd/gosec \
golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow \
honnef.co/go/tools/cmd/staticcheck
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
action.yamlは、公式のドキュメントを参考に作成。
name: "static analysis checker"
description: "static code analysis checker for golang"
author: "grandcolline"
inputs:
run:
description: "excute command. [errcheck/fmt/imports/lint/sec/shadow/staticcheck/vet]"
required: true
directory:
description: "action wroking directory."
default: "."
required: false
comment:
description: "send comment to PR if true."
default: true
required: false
token:
description: "github token. this is require when comment is true."
default: ""
required: false
flags:
description: "add flags"
default: ""
required: false
ignore-defer:
description: "if this is true, do not detect 'defer' with error. This is only valid when run is errcheck."
default: false
required: false
runs:
using: "docker"
image: "Dockerfile"
args:
- ${{ inputs.run }}
- ${{ inputs.directory }}
- ${{ inputs.comment }}
- ${{ inputs.token }}
- ${{ inputs.flags }}
- ${{ inputs.ignore-defer }}
branding:
icon: "alert-triangle"
color: "yellow"
args
以外にもenvironment
でも渡せるので、どちらにするかは迷いどころだと思いました。どのようにかくのが綺麗なんだろう🤔
あと、Dockerのビルド時に渡すARGもここから指定できれば、golang自体のバージョン管理もアクション側でしなくて良くなりそうで良さそうだなぁと感じました。(ドキュメントを読み込めてないので、もしかしたらできるのかもしれない・・・)
最後に、entrypoint.sh
はシェルを書く。
長いので一部だけ書くとこんな感じ。全体はこちらから。
# !/bin/sh
set -e
# ------------------------
# Environments
# ------------------------
RUN=$1
WORKING_DIR=$2
SEND_COMMNET=$3
GITHUB_TOKEN=$4
FLAGS=$5
IGNORE_DEFER_ERR=$6
COMMENT=""
SUCCESS=0
# ------------------------
# Functions
# ------------------------
send_comment() {
PAYLOAD=$(echo '{}' | jq --arg body "${COMMENT}" '.body = $body')
COMMENTS_URL=$(cat ${GITHUB_EVENT_PATH} | jq -r .pull_request.comments_url)
curl -s -S -H "Authorization: token ${GITHUB_TOKEN}" --header "Content-Type: application/json" --data "${PAYLOAD}" "${COMMENTS_URL}" > /dev/null
}
mod_download() {
if [ ! -e go.mod ]; then go mod init; fi
go mod download
if [ $? -ne 0 ]; then exit 1; fi
}
check_errcheck() {
if [ "${IGNORE_DEFER_ERR}" = "true" ]; then
IGNORE_COMMAND="| grep -v defer"
fi
set +e
OUTPUT=$(sh -c "errcheck ${FLAGS} ./... ${IGNORE_COMMAND} $*" 2>&1)
test -z "${OUTPUT}"
SUCCESS=$?
set -e
if [ ${SUCCESS} -eq 0 ]; then
return
fi
if [ "${SEND_COMMNET}" = "true" ]; then
COMMENT="## ⚠ errcheck Failed
\`\`\`
${OUTPUT}
\`\`\`
"
fi
}
# ------------------------
# Main Flow
# ------------------------
cd ${GITHUB_WORKSPACE}/${WORKING_DIR}
case ${RUN} in
"errcheck" )
mod_download
check_errcheck
;;
* )
echo "Invalid command"
exit 1
esac
if [ ${SUCCESS} -ne 0 ]; then
echo "Check Failed!!"
echo ${COMMENT}
if [ "${SEND_COMMNET}" = "true" ]; then
send_comment
fi
fi
exit ${SUCCESS}
最後に
アクションの書き方などのページがなくて辛かったですが、このあたりの記事がとても参考になりました。
感謝
https://qiita.com/homines22/items/0bc6c17e038b35fc8113
https://github.com/actions/container-template