我尝试在Github Actions的v2版本中运行go的静态分析工具
由于 GitHub Actions 的版本升级,我也对自己创建的动作进行了修改。
我所创造的东西。(Wǒ suǒ de )

目前支持的静态分析工具有以下几种。
fmt
https://golang.org/cmd/gofmt/vet
https://golang.org/cmd/vet/imports
https://godoc.org/golang.org/x/tools/cmd/goimportslint
https://godoc.org/golang.org/x/lint/golintshadow
https://godoc.org/golang.org/x/tools/go/analysis/passes/shadow/cmd/shadowstaticcheck
https://godoc.org/honnef.co/go/tools/cmd/staticcheckerrcheck
https://godoc.org/github.com/kisielk/errchecksec
https://godoc.org/github.com/securego/gosec/cmd/gosec只要您按照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 Tokenflags
""
コマンド実行時に追加するフラグignore-defer
false
errcheck実行時に deferのエラーチェックを無視するか否か在创建行动时所做的事情。
据说行动有两种模式。
-
- type script actions
- container actions
因为我想使用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之外也可以在环境中传递,所以我觉得选择哪个有点困惑。不知道应该如何优雅地写出来?
另外,如果能在构建Docker时传递ARG,似乎也能在操作中不用进行golang自身的版本管理,感觉很好。(由于我还没阅读文档,所以也许是可以做到的……)
最后,entrypoint.sh 文件编写了一个 shell 脚本。由于太长,这里只写一部分,整个内容请点击这里查看。
#!/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 :
– Qiita上的链接:homines22的资源中心提供了一个有关此事的详细解释。
– Qiita上的链接:homines22的资源中心有一个关于此问题的详细介绍。
https://github.com/actions/container-template :
– GitHub上的链接:在container-template存储库中,您可以找到有关此模板的更多信息。
– GitHub上的链接:container-template存储库中提供关于此模板的更多详细信息。