diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a807eae --- /dev/null +++ b/Dockerfile @@ -0,0 +1,64 @@ +# Dockerfile provides minimal tooling and source dependency management for +# any Go projects at Vungle. +# +# Tag: vungle/golang[:]; e.g. vungle/golang:1.5, vungle/golang:1.5.2. +FROM golang:1.6-alpine + +RUN apk add -q --update \ + && apk add -q \ + bash \ + git \ + && rm -rf /var/cache/apk/* + +# OUTDIR specifies a directory in which projects can create output files so that +# these output files can be consumed by other processes. Downstream projects can +# choose to mount OUTDIR to a volume directly or create a directory and perform +# `docker cp ...` later. +ENV OUTDIR /out +ENV GO15VENDOREXPERIMENT 1 + +########################## +# Testing and Tooling +# +# NOTE: For testing and tooling binaries that are actually built with Go, we +# want to only retain its binaries to avoid unexpected source dependencies bleed +# into the project source code. +########################## +RUN go get -u \ + # Unit test report generation. + github.com/jstemmer/go-junit-report \ + + # Coverage report generation. + github.com/t-yuki/gocover-cobertura \ + github.com/wadey/gocovmerge \ + + # Code analysis tool: golint. + github.com/golang/lint/golint \ + && rm -rf $GOPATH/src/* && rm -rf $GOPATH/pkg/* + +ENV GLIDE_VERSION 0.10.2 + +########################## +# Dependency Management +########################## +# Install Glide. +RUN mkdir -p /tmp && cd /tmp \ + && curl -fsSL https://github.com/Masterminds/glide/releases/download/$GLIDE_VERSION/glide-$GLIDE_VERSION-linux-amd64.tar.gz \ + -o glide.tar.gz \ + && tar -xzf glide.tar.gz \ + && mv linux-amd64/glide /usr/local/bin/glide \ + && rm -rf /tmp/* + +# TODO: Benchmark report tools. + +########################## +# Testing scripts +########################## +COPY files/report.sh /usr/local/bin/report.sh +COPY files/coverage.sh /usr/local/bin/coverage.sh + +########################## +# Code Analysis scripts +########################## +COPY files/lint.sh /usr/local/bin/lint.sh + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e91bc56 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +account = vungle +project = golang + +all: build test push deploy + +build: + @echo "Building..." + @docker build . | tail -n 1 | awk '{print $$3}' | xargs echo -n > .last_build + @echo "Build ID: $$(cat .last_build)" + +test: + @docker run -ti --rm $$(cat .last_build) /bin/bash -c 'curl -s -o /dev/null -w "%{http_code}" http://www.example.org/' + +tag: + @docker tag $$(cat .last_build) $(account)/$(project):$$(cat .last_build) + +push: tag + @echo "Pushing to $(account)/$(project):$$(cat .last_build)" + @docker push $(account)/$(project):$$(cat .last_build) + +push_latest: + @echo "Pushing to $(account)/$(project)" + @docker tag $$(cat .last_build) $(account)/$(project) + @docker push $(account)/$(project) + +push_release_tag: + @echo "Pushing to $(account)/$(project):$(release_tag)" + @docker tag $$(cat .last_build) $(account)/$(project):$(CIRCLE_TAG) + @docker push $(account)/$(project):$(CIRCLE_TAG) diff --git a/README.md b/README.md new file mode 100644 index 0000000..73b19c2 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +[![Circle CI](https://circleci.com/gh/Vungle/docker-golang/tree/master.svg?style=svg)](https://circleci.com/gh/Vungle/docker-golang/tree/master) + +# docker-golang + +Dockerized golang image using alpine linux + +## Builds + +Builds are automatically pushed to docker hub via circleci as you commit. + +* master branch -> latest tag +* creating a release tag will also create a corresoponding image tag + diff --git a/circle.yml b/circle.yml new file mode 100644 index 0000000..25649fe --- /dev/null +++ b/circle.yml @@ -0,0 +1,23 @@ +machine: + services: + - docker +dependencies: + override: + - docker info + - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS + - make build + +test: + override: + - make test + +deployment: + latest: + branch: master + commands: + - make push_latest + + release: + tag: /.*/ + commands: + - make push_release_tag diff --git a/files/coverage.sh b/files/coverage.sh new file mode 100755 index 0000000..b16eab5 --- /dev/null +++ b/files/coverage.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# coverage.sh runs coverage analysis tests on all non-vendored Go packages under +# the current directory. It generates a combined coverage profile, +# `coverall.out`, an XML version of the coverage report, `coverall.xml`, and +# dumps verbose test results of each package to stdout. +set -e + +if [ -z "$OUTDIR" ]; then + echo "Missing environment variable: OUTDIR" + exit 1 +fi + +profiles=() +for package in $(go list ./... | egrep -v "vendor"); do + # Normalize package name to file name. + filename=$OUTDIR/$(echo "$package-cover.out" | sed "s/\//-/g") + + # Leak only stdout for further processing. + go test -v -coverprofile=$filename -covermode=count $package + + if [ -f "$filename" ]; then + profiles+=($filename) + fi +done + +# Combine all inidividual cover profiles into one. +gocovmerge ${profiles[@]} > $OUTDIR/coverall.out +echo "${profiles[@]} " > $OUTDIR/tested.log +rm ${profiles[@]} + +# Convert from cover profile to XML. +gocover-cobertura < $OUTDIR/coverall.out > $OUTDIR/coverall.xml diff --git a/files/lint.sh b/files/lint.sh new file mode 100755 index 0000000..184142c --- /dev/null +++ b/files/lint.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# lint.sh runs code analysis on the current source code and fails in case any analysis result was +# indicates ill-intended code. + +# Run go fmt. +files=$(go fmt $(go list ./... | grep -v vendor)) +if [[ -n $files ]]; then + echo "The following files are malformatted; please run go fmt!" + echo $files + exit 1 +fi + +# Run go vet. +go vet $(go list ./... | grep -v vendor) +if [[ $? -ne 0 ]]; then + echo "Some files may contain mistakes; please run go vet!" + exit 1 +fi + +golint ./... | egrep -v "vendor|ALL_CAPS" diff --git a/files/report.sh b/files/report.sh new file mode 100755 index 0000000..3ffc56b --- /dev/null +++ b/files/report.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# report.sh generates an XML version of the Go unit test report from the stdout +# of any `go test -v` command. report.xml will be generated as an output of +# report.sh. +if [ -z "$OUTDIR" ]; then + echo "Missing environment variable: OUTDIR" + exit 1 +fi + +go-junit-report > $OUTDIR/report.xml