diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..d850e99ce04802df6ae20305739946e6b04f9f97 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,91 @@ +# Some resuable sections, note the top-level keys 'defaults' and 'tag_filters' +# have no special meaning, they just exist so I can alias them and import them +# in later blocks +defaults: &defaults + working_directory: /go/src/github.com/hyperledger/burrow + docker: + - image: circleci/golang:1.8.1 + +tag_filters: &tags_filters + tags: + only: /^v[0-9]+\.[0-9]+\.[0-9]+$/ + +version: 2 +jobs: + checkout_code: + <<: *defaults + steps: + - checkout + - run: go get github.com/Masterminds/glide + - run: glide install + + # Just persist the entire working dir (burrow checkout) + - persist_to_workspace: + root: . + paths: + - . + test: + <<: *defaults + steps: + - attach_workspace: + at: . + - run: make test + + test_integration: + <<: *defaults + steps: + - attach_workspace: + at: . + - run: make test_integration + + release: + <<: *defaults + steps: + # restore checkout + - attach_workspace: + at: . + # This allows us to perform our docker builds + - setup_remote_docker: + version: 17.06.1-ce + - run: docker login -u $DOCKER_USER -p $DOCKER_PASS quay.io + # build docker image and tag the image with the version, date, and commit hash + - run: make build_docker_db + - run: docker push quay.io/monax/db + + +workflows: + version: 2 + + test_and_release: + jobs: + - checkout_code: + # Rather annoyingly we need this boilerplate on all transitive + # dependencies if we want the deploy job to build against a version + # tag. + # Also note jobs build against all branches by default + filters: + <<: *tags_filters + - test: + requires: + - checkout_code + filters: + <<: *tags_filters + + - test_integration: + requires: + - checkout_code + filters: + <<: *tags_filters + + - release: + requires: + - test + - test_integration + filters: + branches: + # Although we seem to exclude the master branch below, since + # matching on tags is independent we will still build tags that + # happen to point to a commit on master + # We push dev pre-release images for every commit on develop + only: develop + diff --git a/.dockerignore b/.dockerignore index 7ab5de766b88dfef5e626f418ea883cbe3374bc5..9a1e1647f0dc47d7ebfe254c583d272b863513af 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,9 +1,14 @@ +.github .git +.gitignore .project run.sh -build +build_tool.sh +Makefile Vagrantfile +Dockerfile +CHANGELOG.md README.md -circle.yml -api.md +.circleci +docs vendor \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index e75eb594b4a6ce7fc19ecddc03bc1a585071de97..033acdbb92b2a466c2261bebbd89331cdbdd2c8e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,38 @@ -FROM quay.io/monax/build:0.16 +# We use a multistage build to avoid bloating our deployment image with build dependencies +FROM golang:1.9.0-alpine3.6 as builder MAINTAINER Monax <support@monax.io> -ENV TARGET burrow -ENV REPO $GOPATH/src/github.com/hyperledger/$TARGET +RUN apk add --no-cache --update git +RUN go get github.com/Masterminds/glide -ADD ./glide.yaml $REPO/ -ADD ./glide.lock $REPO/ +ENV REPO $GOPATH/src/github.com/hyperledger/burrow +COPY . $REPO WORKDIR $REPO RUN glide install -COPY . $REPO/. -RUN cd $REPO/cmd/$TARGET && \ - go build --ldflags '-extldflags "-static"' -o $INSTALL_BASE/$TARGET +# Build purely static binaries +RUN go build --ldflags '-extldflags "-static"' -o bin/burrow ./cmd/burrow +RUN go build --ldflags '-extldflags "-static"' -o bin/burrow-client ./client/cmd/burrow-client -# build customizations start here -RUN cd $REPO/client/cmd/burrow-client && \ - go build --ldflags '-extldflags "-static"' -o $INSTALL_BASE/burrow-client +# This will be our base container image +FROM alpine:3.6 + +# There does not appear to be a way to share environment variables between stages +ENV REPO /go/src/github.com/hyperledger/burrow + +ENV USER monax +ENV MONAX_PATH /home/$USER/.monax +RUN addgroup -g 101 -S $USER && adduser -S -D -u 1000 $USER $USER +VOLUME $MONAX_PATH +WORKDIR $MONAX_PATH +USER $USER:$USER + +# Copy binaries built in previous stage +COPY --from=builder $REPO/bin/* /usr/local/bin/ + +# Expose ports for 1337:burrow API; 46656:tendermint-peer; 46657:tendermint-rpc +EXPOSE 1337 +EXPOSE 46656 +EXPOSE 46657 + +CMD [ "burrow", "serve" ] diff --git a/Dockerfile.deploy b/Dockerfile.deploy deleted file mode 100644 index 8df703505fa669f198dcd8e4675718d5bd1480c7..0000000000000000000000000000000000000000 --- a/Dockerfile.deploy +++ /dev/null @@ -1,23 +0,0 @@ -FROM quay.io/monax/base:0.16 -MAINTAINER Monax <support@monax.io> - -ENV TARGET burrow - - -# Get the binary from the artefact in pwd/target/docker -COPY ./target/docker/"$TARGET".dockerartefact $INSTALL_BASE/$TARGET -RUN chmod +x --recursive $INSTALL_BASE - -# Finalize -RUN chown --recursive $USER:$USER /home/$USER -VOLUME $MONAX_PATH -WORKDIR $MONAX_PATH -USER $USER - -# runtime customization start here -# Expose ports for 1337:burrow API; 46656:tendermint-peer; 46657:tendermint-rpc -EXPOSE 1337 -EXPOSE 46656 -EXPOSE 46657 - -CMD [ "burrow", "serve" ] diff --git a/Makefile b/Makefile index 05859d13e25f3d424c56931b0a39a9ca27ddce0d..91b8dfc77c9d444fd19a8451e53cc025b19b8af4 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ SHELL := /bin/bash REPO := $(shell pwd) GOFILES_NOVENDOR := $(shell find ${REPO} -type f -name '*.go' -not -path "${REPO}/vendor/*") PACKAGES_NOVENDOR := $(shell go list github.com/hyperledger/burrow/... | grep -v /vendor/) -VERSION := $(shell cat ${REPO}/version/version.go | tail -n 1 | cut -d \ -f 4 | tr -d '"') +VERSION := $(shell go run ./util/version/cmd/main.go) VERSION_MIN := $(shell echo ${VERSION} | cut -d . -f 1-2) COMMIT_SHA := $(shell echo `git rev-parse --short --verify HEAD`) @@ -21,6 +21,10 @@ DOCKER_NAMESPACE := quay.io/monax greet: @echo "Hi! I'm the marmot that will help you with burrow v${VERSION}" +.PHONY: version +version: + @echo "${VERSION}" + ### Formatting, linting and vetting # check the code for style standards; currently enforces go formatting. @@ -117,8 +121,12 @@ build_race_client: # test burrow .PHONY: test -test: build - @go test ${PACKAGES_NOVENDOR} -tags integration +test: + @go test ${PACKAGES_NOVENDOR} + +.PHONY: test_integration +test_integration: + @go test ./rpc/tendermint/test -tags integration # test burrow with checks for race conditions .PHONY: test_race @@ -130,23 +138,7 @@ test_race: build_race # build docker image for burrow .PHONY: build_docker_db build_docker_db: check - @mkdir -p ${REPO}/target/docker - docker build -t ${DOCKER_NAMESPACE}/db:build-${COMMIT_SHA} ${REPO} - docker run --rm --entrypoint cat ${DOCKER_NAMESPACE}/db:build-${COMMIT_SHA} /usr/local/bin/burrow > ${REPO}/target/docker/burrow.dockerartefact - docker run --rm --entrypoint cat ${DOCKER_NAMESPACE}/db:build-${COMMIT_SHA} /usr/local/bin/burrow-client > ${REPO}/target/docker/burrow-client.dockerartefact - docker build -t ${DOCKER_NAMESPACE}/db:${VERSION} -f Dockerfile.deploy ${REPO} - - @rm ${REPO}/target/docker/burrow.dockerartefact - @rm ${REPO}/target/docker/burrow-client.dockerartefact - docker rmi ${DOCKER_NAMESPACE}/db:build-${COMMIT_SHA} - -### Test docker images for github.com/hyperledger/burrow - -# test docker image for burrow -.PHONY: test_docker_db -test_docker_db: check - docker build -t ${DOCKER_NAMESPACE}/db:build-${COMMIT_SHA} ${REPO} - docker run ${DOCKER_NAMESPACE}/db:build-${COMMIT_SHA} glide nv | xargs go test -tags integration + @./build_tool.sh ### Clean up diff --git a/build_tool.sh b/build_tool.sh new file mode 100755 index 0000000000000000000000000000000000000000..d9e2570e14d42d221ff46865409c60406996f404 --- /dev/null +++ b/build_tool.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +# ---------------------------------------------------------- +# PURPOSE + +# This is the build script for the Monax stack. It will +# build the tool into docker containers in a reliable and +# predictable manner. + +# ---------------------------------------------------------- +# REQUIREMENTS +# +# docker, go, make, and git installed locally + +# ---------------------------------------------------------- +# USAGE + +# build_tool.sh [version tag] + +# ---------------------------------------------------------- + +set -e + +IMAGE=${IMAGE:-"quay.io/monax/db"} +VERSION_REGEX="^v[0-9]+\.[0-9]+\.[0-9]+$" + +version=$(go run ./util/version/cmd/main.go) +tag=$(git tag --points-at HEAD) + +if [[ ${tag} =~ ${VERSION_REGEX} ]] ; then + # Only label a build as a release version when the commit is tagged + echo "Building release version (tagged $tag)..." + # Fail noisily when trying to build a release version that does not match code tag + if [[ ! ${tag} = "v$version" ]]; then + echo "Build failure: version tag $tag does not match version/version.go version $version" + exit 1 + fi +else + date=$(date +"%Y%m%d") + commit=$(git rev-parse --short HEAD) + version="$version-dev-$date-$commit" + echo "Building non-release version $version..." +fi + +if [[ "$1" ]] ; then + # If argument provided, use it as the version tag + echo "Overriding detected version $version and tagging image as $1" + version="$1" +fi + +docker build -t ${IMAGE}:${version} . + diff --git a/circle.yml b/circle.yml deleted file mode 100644 index a85d9ebfb6f7e7ef9a269d71bddb4c504c2ecd5e..0000000000000000000000000000000000000000 --- a/circle.yml +++ /dev/null @@ -1,50 +0,0 @@ -machine: - environment: - GOPATH: $HOME/.go_workspace - REPO: ${GOPATH}/src/github.com/hyperledger/burrow - GO15VENDOREXPERIMENT: 1 - pre: - - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0 - services: - - docker - post: - - git config --global user.email "billings@monax.io" - - git config --global user.name "Billings the Bot" - - rm -rf ${GOPATH%%:*}/src/github.com/hyperledger - - mkdir -p ${GOPATH%%:*}/src/github.com/hyperledger - - cp -r ${HOME}/${CIRCLE_PROJECT_REPONAME} ${GOPATH%%:*}/src/github.com/hyperledger/. - -dependencies: - override: - - sudo apt-get update && sudo apt-get install -y libgmp3-dev - - sudo apt-get install jq curl && go get github.com/Masterminds/glide - -test: - pre: - - cd $REPO && glide install - # Test the build target for burrow - - echo "Build target burrow..." && cd $REPO && go install ./cmd/burrow && burrow --help - # Test the build target for burrow-client - - echo "Build target burrow-client..." && cd $REPO && go install ./client/cmd/burrow-client && burrow-client --help - override: - # We only wish to test our packages not vendored ones - - echo "Running unit tests..." && cd $REPO && glide novendor | xargs go test -tags integration - # - echo "Running integration tests..." && cd $REPO && "tests/circle_test.sh" # | tee $CIRCLE_ARTIFACTS/output.log; test ${PIPESTATUS[0]} -eq 0" - -deployment: - develop: - branch: develop - commands: - - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS quay.io - # build docker image and tag the image with the version, date, and commit hash - - tests/build_tool.sh - - docker push quay.io/monax/db - tagged-releases: - tag: /v[0-9]+(\.[0-9]+)*/ - commands: - - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS quay.io - # build docker image and tag the image with the version; - # once the commit is tagged the docker image for this version tag is - # considered immutable. - - tests/build_tool.sh - - docker push quay.io/monax/db diff --git a/rpc/tendermint/test/common.go b/rpc/tendermint/test/common.go deleted file mode 100644 index 13d4aca450e1c974e7a6ef23d7450a5e71ef6a25..0000000000000000000000000000000000000000 --- a/rpc/tendermint/test/common.go +++ /dev/null @@ -1,74 +0,0 @@ -// Space above here matters -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package test - -import ( - "fmt" - - vm "github.com/hyperledger/burrow/manager/burrow-mint/evm" - rpc_core "github.com/hyperledger/burrow/rpc/tendermint/core" - "github.com/hyperledger/burrow/test/fixtures" -) - -// Needs to be referenced by a *_test.go file to be picked up -func TestWrapper(runner func() int) int { - fmt.Println("Running with integration TestWrapper (rpc/tendermint/test/common.go)...\n") - ffs := fixtures.NewFileFixtures("burrow") - - defer ffs.RemoveAll() - - vm.SetDebug(true) - err := initGlobalVariables(ffs) - - if err != nil { - panic(err) - } - - // start a node - ready := make(chan error) - server := make(chan *rpc_core.TendermintWebsocketServer) - defer func() { - // Shutdown -- make sure we don't hit a race on ffs.RemoveAll - tmServer := <-server - tmServer.Shutdown() - }() - - go newNode(ready, server) - err = <-ready - - if err != nil { - panic(err) - } - - return runner() -} - -// This main function exists as a little convenience mechanism for running the -// delve debugger which doesn't work well from go test yet. In due course it can -// be removed, but it's flux between pull requests should be considered -// inconsequential, so feel free to insert your own code if you want to use it -// as an application entry point for delve debugging. -func DebugMain() { - //t := &testing.T{} - TestWrapper(func() int { - //testNameReg(t, "JSONRPC") - return 0 - }) -} - -func Successor(x int) int { - return x + 1 -} diff --git a/rpc/tendermint/test/shared.go b/rpc/tendermint/test/shared.go index 5205e69368d4173a7122796ba396e16eab9a475c..3d6a7d9659052fe8d20fe8a2e5c69332d852ab0b 100644 --- a/rpc/tendermint/test/shared.go +++ b/rpc/tendermint/test/shared.go @@ -29,10 +29,10 @@ import ( core_types "github.com/hyperledger/burrow/core/types" genesis "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/logging/lifecycle" + "github.com/hyperledger/burrow/manager/burrow-mint/evm" ptypes "github.com/hyperledger/burrow/permission/types" "github.com/hyperledger/burrow/rpc/tendermint/client" edbcli "github.com/hyperledger/burrow/rpc/tendermint/client" - rpc_core "github.com/hyperledger/burrow/rpc/tendermint/core" rpc_types "github.com/hyperledger/burrow/rpc/tendermint/core/types" "github.com/hyperledger/burrow/server" "github.com/hyperledger/burrow/test/fixtures" @@ -42,6 +42,7 @@ import ( "github.com/tendermint/go-crypto" rpcclient "github.com/tendermint/go-rpc/client" "github.com/tendermint/tendermint/types" + "time" ) const chainID = "RPC_Test_Chain" @@ -61,6 +62,39 @@ var ( testCore *core.Core ) +// We use this to wrap tests +func TestWrapper(runner func() int) int { + fmt.Println("Running with integration TestWrapper (rpc/tendermint/test/shared_test.go)...") + ffs := fixtures.NewFileFixtures("burrow") + + defer func() { + // Tendermint likes to try and save to priv_validator.json after its been + // asked to shutdown so we pause to try and avoid collision + time.Sleep(time.Second) + ffs.RemoveAll() + }() + + vm.SetDebug(true) + err := initGlobalVariables(ffs) + + if err != nil { + panic(err) + } + + tmServer, err := testCore.NewGatewayTendermint(serverConfig) + defer func() { + // Shutdown -- make sure we don't hit a race on ffs.RemoveAll + tmServer.Shutdown() + testCore.Stop() + }() + + if err != nil { + panic(err) + } + + return runner() +} + // initialize config and create new node func initGlobalVariables(ffs *fixtures.FileFixtures) error { configBytes, err := config.GetConfigurationFileBytes(chainID, @@ -189,14 +223,6 @@ func genesisAccountFromPrivAccount(account *acm.PrivAccount) *genesis.GenesisAcc fmt.Sprintf("account_%X", account.Address), &ptypes.DefaultAccountPermissions) } -func newNode(ready chan error, - tmServer chan *rpc_core.TendermintWebsocketServer) { - // Run the 'tendermint' rpc server - server, err := testCore.NewGatewayTendermint(serverConfig) - ready <- err - tmServer <- server -} - func saveNewPriv() { // Save new priv_validator file. priv := &types.PrivValidator{ diff --git a/rpc/tendermint/test/common_test.go b/rpc/tendermint/test/shared_test.go similarity index 100% rename from rpc/tendermint/test/common_test.go rename to rpc/tendermint/test/shared_test.go diff --git a/test/fixtures/file_fixtures.go b/test/fixtures/file_fixtures.go index d751f55fd72af565f9488dab26d2b273d5a408cd..875e8398e5e007b4b4289f67348301689961a91b 100644 --- a/test/fixtures/file_fixtures.go +++ b/test/fixtures/file_fixtures.go @@ -73,11 +73,7 @@ func (ffs *FileFixtures) AddDir(name string) string { // Cleans up the the temporary files (with fire) func (ffs *FileFixtures) RemoveAll() { - if err := os.RemoveAll(ffs.tempDir); err != nil { - // Since we expect to be called from being deferred in a test it's - // better if we panic here so that the caller finds - panic(err) - } + os.RemoveAll(ffs.tempDir) } // Create a text file at filename with contents content diff --git a/tests/build_tool.sh b/tests/build_tool.sh deleted file mode 100755 index d6b87173002a9510ee8d837b173b7a3b02970420..0000000000000000000000000000000000000000 --- a/tests/build_tool.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash -# ---------------------------------------------------------- -# PURPOSE - -# This is the build script for the Monax stack. It will -# build the tool into docker containers in a reliable and -# predictable manner. - -# ---------------------------------------------------------- -# REQUIREMENTS - -# docker installed locally - -# ---------------------------------------------------------- -# USAGE - -# build_tool.sh - -# ---------------------------------------------------------- - -IMAGE=quay.io/monax/db -VERSION_REGEX="^v[0-9]+\.[0-9]+\.[0-9]+$" - -set -e - -if [ "$JENKINS_URL" ] || [ "$CIRCLE_BRANCH" ] || [ "$CIRCLE_TAG" ] -then - REPO=`pwd` - CI="true" -else - REPO=$GOPATH/src/github.com/hyperledger/burrow -fi - -version=$(cat $REPO/version/version.go | tail -n 1 | cut -d \ -f 4 | tr -d '"') -tag=$(git tag --points-at HEAD) - -# Only label a build as a release version when the commit is tagged -if [[ ${tag} =~ ${VERSION_REGEX} ]] ; then - echo "Building release version (tagged $tag)..." - # Fail noisily when trying to build a release version that does not match code tag - if [[ ! ${tag} = "v$version" ]]; then - echo "Build failure: version tag $tag does not match version/version.go version $version" - exit 1 - fi -else - date=$(date +"%Y%m%d") - commit=$(git rev-parse --short HEAD) - version="$version-dev-$date-$commit" - echo "Building non-release version $version..." -fi - - -# Build -mkdir -p $REPO/target/docker -docker build -t $IMAGE:build $REPO -docker run --rm --entrypoint cat $IMAGE:build /usr/local/bin/burrow > $REPO/target/docker/burrow.dockerartefact -docker run --rm --entrypoint cat $IMAGE:build /usr/local/bin/burrow-client > $REPO/target/docker/burrow-client.dockerartefact -docker build -t $IMAGE:$version -f Dockerfile.deploy $REPO - -# If provided, tag the image with the label provided -if [ "$1" ] -then - docker tag $IMAGE:$version $IMAGE:$1 - docker rmi $IMAGE:$version -fi - -# Cleanup -rm $REPO/target/docker/burrow.dockerartefact -rm $REPO/target/docker/burrow-client.dockerartefact - -# Remove build image so we don't push it when we push all tags -docker rmi -f $IMAGE:build diff --git a/util/version/cmd/main.go b/util/version/cmd/main.go new file mode 100644 index 0000000000000000000000000000000000000000..c5711e205dc6e67ac7c472afe3922e0d6714c892 --- /dev/null +++ b/util/version/cmd/main.go @@ -0,0 +1,26 @@ +// Copyright 2017 Monax Industries Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "fmt" + + "github.com/hyperledger/burrow/version" +) + +// Print the Burrow version +func main() { + fmt.Println(version.VERSION) +} diff --git a/version/version.go b/version/version.go index 449d562b15c56cc51c36208032f031397628594d..b92218bb3ac749a50cbdf4601a4455c61f0955bb 100644 --- a/version/version.go +++ b/version/version.go @@ -103,6 +103,7 @@ func MakeMinorVersionString(client string, major, minor, patch int) string { func GetVersion() (client string, major, minor, patch uint8) { return burrowVersion.GetVersion() } + func (version *VersionIdentifier) GetVersion() ( client string, major, minor, patch uint8) { return version.ClientIdentifier, version.MajorVersion, version.MinorVersion, @@ -126,8 +127,6 @@ func (version *VersionIdentifier) MatchesMinorVersion( } //------------------------------------------------------------------------------ -// Version number for tests/build_tool.sh - -// IMPORTANT: burrow version must be on the last line of this file for -// the deployment script tests/build_tool.sh to pick up the right label. +// util/version/cmd prints this when run and is used to by build_tool.sh to obtain +// Burrow version const VERSION = "0.17.0"