Skip to content
This repository was archived by the owner on Nov 14, 2024. It is now read-only.

chore: run automatic build and test #13

Merged
merged 1 commit into from
Sep 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Build

on:
push:
branches:
- main

pull_request:
branches:
- main

workflow_dispatch:

permissions:
actions: none
checks: none
contents: read
deployments: none
issues: none
packages: none
pull-requests: none
repository-projects: none
security-events: none
statuses: none

jobs:
build:
name: Build
runs-on: ubuntu-20.04
steps:
- name: Cancel Previous Runs
if: github.event_type == 'pull_request'
uses: styfle/cancel-workflow-action@0.9.1

- name: Checkout
uses: actions/checkout@v2

- name: Install Go
uses: actions/setup-go@v2
with:
go-version: '^1.16.7'

- name: Install dependencies
run: ./scripts/install_deps.sh

- name: Lint
run: make lint

- name: Tests
run: ./scripts/test_go.sh
61 changes: 61 additions & 0 deletions scripts/install_deps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
#
# This script installs dependencies to /usr/local/bin.

set -euo pipefail
PROJECT_ROOT=$(git rev-parse --show-toplevel)
cd "$PROJECT_ROOT"
source "./scripts/lib.sh"

TMPDIR=$(mktemp -d)
TMPBIN="${TMPDIR}/bin"
BINDIR="/usr/local/bin"

curl_flags=(
--silent
--show-error
--location
)

# Install Go programs
export GOPATH="$TMPDIR/go"

run_trace false mkdir --parents "$GOPATH"

# goveralls collects code coverage metrics from tests
# and sends to Coveralls
run_trace false go install github.com/mattn/goveralls@v0.0.9

# Install binaries only
run_trace false sudo install --mode=0755 --target-directory="$BINDIR" "$GOPATH/bin/*"

# Install packages via apt where available
run_trace false sudo apt-get install --no-install-recommends --yes \
shellcheck

# Extract binaries as non-root user, then sudo install
run_trace false mkdir --parents "$TMPBIN"

# gotestsum makes test output more readable
GOTESTSUM_VERSION="1.7.0"
run_trace false curl "${curl_flags[@]}" "https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_linux_amd64.tar.gz" \| \
tar --extract --gzip --directory="$TMPBIN" --file=- gotestsum

# golangci-lint to lint Go code with multiple tools
GOLANGCI_LINT_VERSION="1.42.1"
run_trace false curl "${curl_flags[@]}" "https://github.com/golangci/golangci-lint/releases/download/v${GOLANGCI_LINT_VERSION}/golangci-lint-${GOLANGCI_LINT_VERSION}-linux-amd64.tar.gz" \| \
tar --extract --gzip --directory="$TMPBIN" --file=- --strip-components=1 "golangci-lint-${GOLANGCI_LINT_VERSION}-linux-amd64/golangci-lint"

# goreleaser to compile, cross-compile, and release binaries
GORELEASER_VERSION="0.178.0"
run_trace false curl "${curl_flags[@]}" "https://github.com/goreleaser/goreleaser/releases/download/v${GORELEASER_VERSION}/goreleaser_Linux_x86_64.tar.gz" \| \
tar --extract --gzip --directory="$TMPBIN" --file=- "goreleaser"

run_trace false sudo install --mode=0755 --target-directory="$BINDIR" "$TMPBIN/*"

run_trace false command -v \
golangci-lint \
goreleaser \
gotestsum

run_trace false sudo rm --verbose --recursive --force "$TMPDIR"
94 changes: 94 additions & 0 deletions scripts/lib.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env bash

set -euo pipefail

# Emit a message to stderr and exit.
#
# This prints the arguments to stderr before exiting.
#
# Example:
# error "Missing flag abc"
# program-failure-info | error
function error() {
set +x
echo
echo "$@" "$(cat)" >&2
echo
exit 1
}

# Check if dependencies are available.
#
# If any dependencies are missing, an error message will be printed to
# stderr and the program will exit, running traps on EXIT beforehand.
#
# Example:
# check_dependencies git bash node
check_dependencies() {
local missing=false
for command in "$@"; do
if ! command -v "$command" &> /dev/null; then
echo "$0: script requires '$command', but it is not in your PATH" >&2
missing=true
fi
done

if [ "$missing" = true ]; then
exit 1
fi
}

# Indent output by (indent) levels
#
# Example:
# echo "example" | indent 2
# cat file.txt | indent
function indent() {
local indentSize=2
local indent=1
if [ -n "${1:-}" ]; then
indent="$1"
fi
pr --omit-header --indent=$((indent * indentSize))
}

# Run a command, with tracing.
#
# This prints a command to stderr for tracing, in a format similar to
# the bash xtrace option (i.e. set -x, set -o xtrace), then runs it using
# eval if the first argument (dry run) is false.
#
# If dry run is true, the command and arguments will be printed, but
# not executed.
#
# Example:
# run_trace $DRY_RUN rm -rf /
# run_trace false echo "abc" \| indent
function run_trace() {
local args=("$@")
local dry_run="${args[0]}"
args=("${args[@]:1}")

# If we're running in GitHub Actions, use the special syntax
# to start/end a group for each traced command
if [[ -n "${GITHUB_ACTIONS:-}" && "$dry_run" = false ]]; then
echo "::group::Run ${args[*]}" >&2
else
echo "+ ${args[*]}" >&2
fi

local exit_status=0
if [ "$dry_run" = false ]; then
eval "${args[@]}"

# Save the exit status code from eval, otherwise it will be
# obscured by future commands.
exit_status="$?"
fi

if [[ -n "${GITHUB_ACTIONS:-}" && "$dry_run" = false ]]; then
echo "::endgroup::" >&2
fi

return "$exit_status"
}
59 changes: 59 additions & 0 deletions scripts/test_go.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
#
# Run unit and integration tests for Go code

set -euo pipefail
PROJECT_ROOT="$(git rev-parse --show-toplevel)"
cd "$PROJECT_ROOT"
source "./scripts/lib.sh"

echo "--- Running go test"
export FORCE_COLOR=true

test_args=(
-v
-failfast
"${TEST_ARGS:-}"
)

REPORTDIR="/tmp/testreports"
mkdir -p "$REPORTDIR"
TESTREPORT_JSON="$REPORTDIR/test_go.json"
TESTREPORT_XML="$REPORTDIR/test_go.xml"
COVERAGE="$REPORTDIR/test_go.coverage"

test_args+=(
"-covermode=set"
"-coverprofile=$COVERAGE"
)

# Allow failures to ensure that we can upload coverage
set +e

run_trace false gotestsum \
--debug \
--jsonfile="$TESTREPORT_JSON" \
--junitfile="$TESTREPORT_XML" \
--hide-summary=skipped \
--packages="./..." \
-- "${test_args[@]}"
test_status=$?

# The following steps should never fail, and if they do,
# we want to know about it, so fail the build
set -e

threshold="5s"
echo "--- ಠ_ಠ The following tests took longer than $threshold to complete:"
run_trace false gotestsum tool slowest \
--jsonfile="$TESTREPORT_JSON" \
--threshold="$threshold"

# From time to time, Coveralls seems to have an issue on their end, so
# make a best-effort attempt to upload coverage but ignore failures
set +e
echo "--- Uploading test coverage report to Coveralls..."
run_trace false goveralls -service=github -coverprofile="$COVERAGE"
set -e

exit $test_status