# Copyright 2020 The Periph Authors. All rights reserved. # Use of this source code is governed under the Apache License, Version 2.0 # that can be found in the LICENSE file. # References: # https://github.com/actions/checkout # https://github.com/actions/setup-go # https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token#using-the-github_token-in-a-workflow # https://help.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions/ # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions # https://docs.github.com/en/rest/commits/comments#create-a-commit-comment # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#pull_request # https://docs.github.com/en/actions/learn-github-actions/contexts on: [push, pull_request] name: Run tests jobs: # Runs go test both with code coverage sent to codecov, race detector and # benchmarks. At the end do a quick check to ensure the tests to not leave # files in the tree. test: name: "test: go${{matrix.gover}}.x/${{matrix.os}}" runs-on: "${{matrix.os}}" continue-on-error: true defaults: run: shell: bash strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] # Do not forget to bump every 6 months! gover: ["1.19"] env: PYTHONDONTWRITEBYTECODE: x steps: - name: Turn off git core.autocrlf if: matrix.os == 'windows-latest' run: git config --global core.autocrlf false - uses: actions/checkout@v3 with: fetch-depth: 2 - uses: actions/setup-go@v3 with: go-version: "~${{matrix.gover}}.0" cache: true - name: 'go install necessary tools' if: always() run: | go install github.com/maruel/pat/cmd/ba@latest - name: 'Check: go test -cover' if: always() run: go test -timeout=120s -covermode=count -coverprofile coverage.txt -bench=. -benchtime=1x ./... # Don't send code coverage if anything failed to reduce spam. - uses: codecov/codecov-action@v2 - name: 'Cleanup' if: always() run: rm coverage.txt - name: 'Check: go test -race' run: go test -timeout=120s -race -bench=. -benchtime=1x ./... - name: 'Check: benchmark 📈' run: ba -against HEAD~1 - name: 'Check: go test -short (CGO_ENABLED=0)' env: CGO_ENABLED: 0 run: go test -timeout=120s -short -bench=. -benchtime=1x ./... - name: 'Check: go test -short (32 bits)' if: matrix.os != 'macos-latest' env: GOARCH: 386 run: go test -timeout=120s -short -bench=. -benchtime=1x ./... - name: "Check: tree is clean" if: always() run: | # Nothing should have changed in the tree up to that point and no # unsuspected file was created. TOUCHED=$(git status --porcelain --ignored) if ! test -z "$TOUCHED"; then echo "Oops, something touched these files, please cleanup:" echo "$TOUCHED" git diff false fi # Run linters. This workflow can be merged with the test_all one if desired # to cut on runtime, at the cost of latency. I dislike waiting for results # so I prefer to run them in parallel. lint: name: "lint: go${{matrix.gover}}.x/${{matrix.os}}" runs-on: "${{matrix.os}}" continue-on-error: true defaults: run: shell: bash strategy: fail-fast: false matrix: # You may want to run only on linux to save on cost. Projects with # OS-specific code benefits from explicitly linting on macOS and # Windows. os: [ubuntu-latest, macos-latest, windows-latest] # Do not forget to bump every 6 months! gover: ["1.19"] env: PYTHONDONTWRITEBYTECODE: x steps: - name: Turn off git core.autocrlf if: matrix.os == 'windows-latest' run: git config --global core.autocrlf false - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: go-version: "~${{matrix.gover}}.0" cache: true - name: "Debug" run: | echo HOME = $HOME echo GITHUB_WORKSPACE = $GITHUB_WORKSPACE echo PATH = $PATH echo "" echo $ ls -l $HOME/go/bin ls -la $HOME/go/bin - name: 'go install necessary tools' if: always() run: | go install github.com/gordonklaus/ineffassign@latest go install github.com/securego/gosec/v2/cmd/gosec@latest go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest go install honnef.co/go/tools/cmd/staticcheck@latest - name: 'go install necessary tools (ubuntu)' if: always() && matrix.os == 'ubuntu-latest' run: | go install github.com/client9/misspell/cmd/misspell@latest go install github.com/google/addlicense@latest - name: 'Check: go vet' if: always() run: go vet -unsafeptr=false ./... - name: 'Check: go vet shadow; shadowed variables' if: always() run: | SHADOW_TOOL="$(which shadow)" if [ -f "${SHADOW_TOOL}.exe" ]; then SHADOW_TOOL="${SHADOW_TOOL}.exe" fi go vet -vettool=$SHADOW_TOOL ./... - name: 'Check: inefficient variable assignment' if: always() run: ineffassign ./... - name: 'Check: staticcheck' if: always() # SA1019: Foo is deprecated run: staticcheck -checks inherit,-SA1019 ./... - name: 'Check: gosec' if: always() run: gosec -fmt=golint -quiet ./... # The following checks are not dependent on the OS or go build tags. Only # run them on ubuntu-latest since it's the fastest one. - name: 'Check: no executable was committed (ubuntu)' if: always() && matrix.os == 'ubuntu-latest' run: | if find . -path ./.git -prune -o -type f -executable -print | grep -e . ; then echo 'Do not commit executables' false fi - name: 'Check: addlicense; all sources have a license header (ubuntu)' if: always() && matrix.os == 'ubuntu-latest' run: addlicense -check . - name: 'Check: gofmt; code is well formatted (ubuntu)' if: always() && matrix.os == 'ubuntu-latest' run: | FILES=$(gofmt -s -l .) if ! test -z "$FILES"; then echo 'Please run `gofmt -s -w` on the following files:' >> _gofmt.txt echo "" >> _gofmt.txt for FILE in ${FILES}; do echo "- ${FILE}" >> _gofmt.txt done cat _gofmt.txt echo "## ⚠ gofmt Failed" >> ../_comments.txt echo "" >> ../_comments.txt cat _gofmt.txt >> ../_comments.txt echo "" >> ../_comments.txt false fi - name: "Check: misspelling; code doesn't contain misspelling (ubuntu)" if: always() && matrix.os == 'ubuntu-latest' run: | ERR=$(misspell .) if ! test -z "$ERR"; then echo "$ERR" echo "## ⚠ misspell Failed" >> ../_comments.txt echo "" >> ../_comments.txt echo "$ERR" >> ../_comments.txt echo "" >> ../_comments.txt false fi - name: 'Send comments' if: failure() run: | if [ -f ../_comments.txt ]; then URL="${{github.event.issue.pull_request.url}}" if test -z "$URL"; then URL="${{github.api_url}}/repos/${{github.repository}}/commits/${{github.sha}}/comments" fi echo "Sending $(cat ../_comments.txt|wc -l) lines of comments to ${URL}" curl -sS --request POST \ --header "Authorization: Bearer ${{secrets.GITHUB_TOKEN}}" \ --header "Content-Type: application/json" \ --data "$(cat ../_comments.txt | jq -R --slurp '{body: .}')" \ "${URL}" > /dev/null rm ../_comments.txt fi - name: "Check: go generate doesn't modify files" if: always() run: | go generate ./... # Also test for untracked files. go generate should not generate ignored # files either. TOUCHED=$(git status --porcelain --ignored) if ! test -z "$TOUCHED"; then echo "go generate created these files, please fix:" echo "$TOUCHED" false fi - name: "Check: go mod tidy doesn't modify files" if: always() run: | go mod tidy TOUCHED=$(git status --porcelain --ignored) if ! test -z "$TOUCHED"; then echo "go mod tidy was not clean, please update:" git diff false fi - name: 'Test on periph.io/x/cmd' # Force an upgrade to test cmd with tip of tree devices. run: | cd .. git clone --depth 1 https://github.com/periph/cmd cd cmd go mod edit -replace=periph.io/x/devices/v3=../devices go get -t ./... go test -short ./... # Ensure tests pass on oldest supported Go version. old: name: "test: go${{matrix.gover}}/${{matrix.os}}" runs-on: "${{matrix.os}}" continue-on-error: true defaults: run: shell: bash strategy: fail-fast: false matrix: os: [ubuntu-latest] # https://github.com/golang/go/issues/55078 # golang.org/x/sys/unix broke on Go versions before 1.17. Not worth # fixing. gover: ['1.17.13'] env: PYTHONDONTWRITEBYTECODE: x steps: - name: Turn off git core.autocrlf if: matrix.os == 'windows-latest' run: git config --global core.autocrlf false - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: go-version: "=${{matrix.gover}}" - name: 'Check: go test' run: go test -timeout=120s -bench=. -benchtime=1x ./... codeql: name: "codeql: go${{matrix.gover}}.x/${{matrix.os}}" runs-on: "${{matrix.os}}" continue-on-error: true strategy: fail-fast: false matrix: os: [ubuntu-latest] # Do not forget to bump every 6 months! gover: ["1.19"] permissions: security-events: write steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: go-version: "~${{matrix.gover}}.0" cache: true - name: Initialize CodeQL uses: github/codeql-action/init@v2 with: languages: go - name: Autobuild uses: github/codeql-action/autobuild@v2 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2