我尝试在Github Actions的v2版本中运行go的静态分析工具

由于 GitHub Actions 的版本升级,我也对自己创建的动作进行了修改。

我所创造的东西。(Wǒ suǒ de )

スクリーンショット.png

目前支持的静态分析工具有以下几种。

只要您按照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”来指定的变量如下所示。

変数名デフォルトなにrunN/A実行するコマンド(上の表から選ぶ)directory.静的解析を実行する場所の相対パスcommenttruePRにコメントするか否かtoken""GitHub Tokenflags""コマンド実行時に追加するフラグignore-deferfalseerrcheck実行時に 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存储库中提供关于此模板的更多详细信息。

bannerAds