From de022f577d32c4cd04f23696209de9631a042446 Mon Sep 17 00:00:00 2001 From: Tobias Schottdorf Date: Fri, 30 Sep 2016 15:50:28 -0400 Subject: [PATCH] build: RIP CircleCI --- build/circle-deps.sh | 186 ------------------------- build/circle-local.sh | 6 - build/circle-test.sh | 173 ----------------------- build/circle-trigger-osx-build-push.sh | 17 --- circle.yml | 75 ---------- 5 files changed, 457 deletions(-) delete mode 100755 build/circle-deps.sh delete mode 100755 build/circle-local.sh delete mode 100755 build/circle-test.sh delete mode 100755 build/circle-trigger-osx-build-push.sh delete mode 100644 circle.yml diff --git a/build/circle-deps.sh b/build/circle-deps.sh deleted file mode 100755 index fbfe99027b5c..000000000000 --- a/build/circle-deps.sh +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env bash - -set -euxo pipefail - -CIRCLE_NODE_INDEX="${CIRCLE_NODE_INDEX-0}" -CIRCLE_NODE_TOTAL="${CIRCLE_NODE_TOTAL-1}" - -function is_shard() { - test $(($1 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" -} - -function fetch_docker() { - local user="$1" - local repo="${2}" - local tag="${3}" - local name="${user}/${repo}" - local ref="${name}:${tag}" - if ! docker images --format '{{.Repository}}:{{.Tag}}' | grep -q "${ref}"; then - # If we have a saved image, load it. - imgcache="${builder_dir}/${user}.${repo}.tar" - if [[ -e "${imgcache}" ]]; then - time docker load -i "${imgcache}" - fi - - # If we still don't have the tag we want: pull it and save it. - if ! docker images --format '{{.Repository}}:{{.Tag}}' | grep -q "${ref}"; then - time docker pull "${ref}" - time docker save -o "${imgcache}" "${ref}" - fi - fi -} - -# This is mildly tricky: This script runs itself recursively. The -# first time it is run it does not take the if-branch below and -# executes on the host computer. As a final step it uses the -# builder.sh script to run itself inside of docker passing "docker" as -# the argument causing the commands in the if-branch to be executed -# within the docker container. -if [ "${1-}" = "docker" ]; then - # Fetch glock without -u: glock will update itself (and once - # glock has updated itself, "go get -u" no longer works because - # the clone's head is detached). - go get github.com/robfig/glock - glock sync -n < GLOCKFILE - - # Be careful to keep the dependencies built for each shard in sync - # with the dependencies used by each shard in circle-test.sh. - - # Note the ordering here and later in this script of the shard tests - # is a bit odd. We perform the tests in this order to maintain the - # same build order as the pre-parallel deps script. - - if is_shard 2; then - make -C ui jspm.installed - - # TODO(pmattis): This works around the problem seen in - # https://github.com/cockroachdb/cockroach/issues/4013 where - # certain checks and code generation tools rely on compiled - # packages. In particular, `stringer` definitely relies on - # compiled packages for imports and it appears `go vet` is - # similar. Would be nice to find a different solution, but simply - # removing the out of date packages does not fix the problem (it - # causes `stringer` to complain). - time make build - fi - - if is_shard 1; then - time go test -race -v -i ./... - # We need go2xunit on both shards that run go tests. - time go install -v github.com/tebeka/go2xunit - fi - - if is_shard 0; then - time make install - time go test -v -i ./... - time go test -v -c -tags acceptance ./acceptance - fi - - exit 0 -fi - -shard1_done="${HOME}/shard1" -shard2_done="${HOME}/shard2" - -function notify() { - if is_shard 1; then - if ! is_shard 0; then - time ssh node0 touch "${shard1_done}" - else - touch "${shard1_done}" - fi - fi - - if is_shard 2; then - if ! is_shard 0; then - time ssh node0 touch "${shard2_done}" - else - touch "${shard2_done}" - fi - fi -} - -# Notify shard 0 that shard's 1 and 2 are done if they exit for any -# reason. This prevents shard 0 from spinning forever. -trap "notify" EXIT - -# `~/builder` is cached by circle-ci. -builder_dir=~/builder -mkdir -p "${builder_dir}" -du -sh "${builder_dir}" -ls -lah "${builder_dir}" - -fetch_docker "cockroachdb" "builder" "$("$(dirname "${0}")"/builder.sh version)" - -if is_shard 0; then - # See the comment in build/builder.sh about this awk line. - postgresTestTag=$(awk -F\" '/postgresTestTag *=/ {print $2}' \ - "$(dirname "${0}")"/../acceptance/util_test.go) - if [ -z "${postgresTestTag}" ]; then - echo "unable to determine postgres-test tag" - exit 1 - fi - # Dockerfile at: https://github.com/cockroachdb/postgres-test - fetch_docker "cockroachdb" "postgres-test" "${postgresTestTag}" -fi - -# Recursively invoke this script inside the builder docker container, -# passing "docker" as the first argument. -"$(dirname "${0}")"/builder.sh "${0}" docker - -# According to -# https://discuss.circleci.com/t/cache-save-restore-algorithm/759, the -# cache is only collected from container (shard) 0. We work around -# this limitation by copying the build output from shards 1 and 2 over -# to shard 0. On shard 0 we wait for this remote data to be copied. - -gopath0="${GOPATH%%:*}" - -if is_shard 2; then - # We might already be on shard 0 if we're running without - # parallelism. Avoid deleting our build output in that case. - if ! is_shard 0; then - for dir in "${HOME}/.jspm" "${HOME}/.npm"; do - time rsync -a --delete "${dir}/" node0:"${dir}" - done - - cmds=$(grep '^cmd ' GLOCKFILE | grep -v glock | awk '{print $2}' | awk -F/ '{print $NF}') - path="${gopath0}/bin/docker_amd64" - time ssh node0 mkdir -p "$path" - (time cd "$path" && rsync ${cmds} node0:"${path}") - fi -fi - -if is_shard 1; then - # We might already be on shard 0 if we're running without - # parallelism. Avoid deleting our build output in that case. - if ! is_shard 0; then - dir="${gopath0}/pkg/docker_amd64_race" - time rsync -a --delete "${dir}/" node0:"${dir}" - fi -fi - -# Need to notify before exit in case we're running without -# parallelism. -notify - -if is_shard 0; then - set +x - start=$(date +%s) - while :; do - if [ -e "${shard1_done}" ] && [ -e "${shard2_done}" ]; then - break - fi - sleep 1 - done - echo "waited $(($(date +%s) - start)) secs" - - # Sync the go packages from the node which built the commands. We - # have to do this as a pull instead of as a push because node 0 is - # building an overlapping set of packages. - if ! is_shard 2; then - node=$((2 % CIRCLE_NODE_TOTAL)) - dir="${gopath0}/pkg/docker_amd64" - time rsync -au node${node}:"${dir}/" "${dir}" - fi -fi diff --git a/build/circle-local.sh b/build/circle-local.sh deleted file mode 100755 index 618582c1834d..000000000000 --- a/build/circle-local.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -"$(dirname "${0}")"/circle-deps.sh -"$(dirname "${0}")"/circle-test.sh diff --git a/build/circle-test.sh b/build/circle-test.sh deleted file mode 100755 index 1ef037b68549..000000000000 --- a/build/circle-test.sh +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -CIRCLE_NODE_INDEX="${CIRCLE_NODE_INDEX-0}" -CIRCLE_NODE_TOTAL="${CIRCLE_NODE_TOTAL-1}" - -if [ -n "${CIRCLE_ARTIFACTS-}" ]; then - outdir="${CIRCLE_ARTIFACTS}" -elif [ -n "${TMPDIR-}" ]; then - outdir="${TMPDIR}" -else - outdir="/tmp" -fi - -builder="$(dirname "${0}")"/builder.sh -match='^F[0-9]+|^panic|^[Gg]oroutine [0-9]+|(read|write) by.*goroutine|DATA RACE|Too many goroutines running after tests' - -prepare_artifacts() { - # Friendly but stern reminder: Never ever move this or put anything above it. - ret=$? - # Show each action taken so we can trace if things go awry here. - set -x - - # Translate the log output to xml to integrate with CircleCI - # better. - if [ -n "${CIRCLE_TEST_REPORTS-}" ]; then - if [ -f "${outdir}/test.log" ]; then - mkdir -p "${CIRCLE_TEST_REPORTS}/test" - ${builder} go2xunit --fail-on-race < "${outdir}/test.log" \ - > "${CIRCLE_TEST_REPORTS}/test/test.xml" - fi - if [ -f "${outdir}/testrace.log" ]; then - mkdir -p "${CIRCLE_TEST_REPORTS}/race" - ${builder} go2xunit --fail-on-race < "${outdir}/testrace.log" \ - > "${CIRCLE_TEST_REPORTS}/race/testrace.xml" - fi - if [ -f "${outdir}/check.log" ]; then - mkdir -p "${CIRCLE_TEST_REPORTS}/check" - ${builder} go2xunit --fail-on-race < "${outdir}/check.log" \ - > "${CIRCLE_TEST_REPORTS}/check/check.xml" - fi - if [ -f "${outdir}/acceptance.log" ]; then - mkdir -p "${CIRCLE_TEST_REPORTS}/acceptance" - - # Because we do not run `go test acceptance/...`, we don't get - # the package-level summary line, which breaks go2xunit. The - # `echo` below fakes that. It turns out go2xunit doesn't actually - # care about the content of this line, so long as it matches the - # correct format. - # We have the choice between 'ok' and 'FAIL', but since excerpt.txt - # greps this for failures, 'ok' is easier to handle. - echo 'ok github.com/cockroachdb/cockroach/acceptance 1337s' \ - >> "${outdir}/acceptance.log" - - ${builder} go2xunit --fail-on-race < "${outdir}/acceptance.log" \ - > "${CIRCLE_TEST_REPORTS}/acceptance/acceptance.xml" - fi - fi - - # Generate the slow test output. - # We use `tail` below (instead of `sort -r | head` ) to work around - # the fact that `set -o pipefail` doesn't like it if `sort` exits - # with a SIGPIPE error code (which piping to `head` can cause). - find "${outdir}" -name 'test*.log' -type f -exec \ - grep -F ': Test' {} ';' | \ - sed -E 's/(--- PASS: |\(|\))//g' | \ - awk '{ print $2, $1 }' | sort -n | tail -n 10 \ - > "${outdir}/slow.txt" - - # Generate the excerpt output and fail if it is non-empty. - find "${outdir}" -name '*.log' -type f -exec \ - grep -B 5 -A 10 -E "^\-{0,3} *FAIL|${match}" {} ';' > "${outdir}/excerpt.txt" - - if [ -s "${outdir}/excerpt.txt" ]; then - ret=1 - - echo "FAIL: excerpt.txt is not empty (${outdir}/excerpt.txt)" - echo - head -n 100 "${outdir}/excerpt.txt" - fi - - if [ "${ret}" -ne 0 ] && - [ -n "${GITHUB_API_TOKEN-}" ] && - ([ "${CIRCLE_BRANCH-}" = "master" ] || [ "${CIRCLE_BRANCH-}" = "develop" ]) - then - function post() { - curl -X POST -H "Authorization: token ${GITHUB_API_TOKEN}" \ - "https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/$1" \ - -d "${2}" - } - - echo "Posting an issue" - # Generate string of failed tests: 'TestRaftRemoveRace TestChaos TestHoneyBooBoo' - FAILEDTESTS=$(grep -oh '^--- FAIL: \w*' "${outdir}/excerpt.txt" | sed -e 's/--- FAIL: //' | tr '\n' ' ' || true) - if [ -z "${FAILEDTESTS}" ] && [ -n "${CIRCLE_TEST_REPORTS-}" ]; then - # If we generated XML reports and the simple grep didn't find - # anything (which happens for timeouts and panics), parse the - # XML for more robust results. - FAILEDTESTS=$(python3 -c 'import sys, xml.etree.ElementTree as ET; [print(t.attrib["name"]) for filename in sys.argv[1:] for t in ET.parse(filename).findall(".//failure/..")]' "$(find "${CIRCLE_TEST_REPORTS}" -type f -iname '*.xml')") - fi - - # JSON monster to post the issue. - post issues "{ \"title\": \"circleci: failed tests: ${FAILEDTESTS}\", \"body\": \"The following test appears to have failed:\n\n[#${CIRCLE_BUILD_NUM}](https://circleci.com/gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/${CIRCLE_BUILD_NUM}):\n\n\`\`\`\n$(python -c 'import json,sys; print json.dumps(sys.stdin.read()[:30000]).strip("\"")' < ${outdir}/excerpt.txt)\n\`\`\`\nPlease assign, take a look and update the issue accordingly.\", \"labels\": [\"test-failure\", \"Robot\"], \"milestone\": 4 }" > /dev/null - echo "Found test/race failures in test logs, see excerpt.log and the newly created issue on our issue tracker" - fi - - exit $ret -} - -trap prepare_artifacts EXIT - -function is_shard() { - test $(($1 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" -} - -# Note that the order of the is_shard tests is a bit odd. It would be -# more natural to check shard 0, then 1, and then 2. The odd ordering -# is done so that the tests are performed in the pre-parallel order -# when parallelism is disabled. That is, we get a good ordering when -# only a single container is running the tests (CIRCLE_NODE_INDEX == -# 1). - -if is_shard 2; then - # Run "make check" to verify coding guidelines. - echo "make check" - time ${builder} make check | tee "${outdir}/check.log" - - # Verify that "go generate" was run. - echo "verifying generated files" - time ${builder} go generate ./... - time ${builder} /bin/bash -c '! git status --porcelain | read || (git status; git diff -a; exit 1)' | tee "${outdir}"/generate.log -fi - -if is_shard 0; then - # Run "make test". - echo "make test" - time ${builder} make test \ - TESTFLAGS='-v --verbosity=1 --vmodule=monitor=2,tracer=2' | \ - tr -d '\r' | tee "${outdir}/test.log" | \ - grep -E "^\--- (PASS|FAIL)|^(FAIL|ok)|${match}" | - awk '{print "test:", $0}' - - # Run the acceptance tests (only on Linux). We can run the - # acceptance tests on the Mac's, but circle-deps.sh only built the - # acceptance tests for Linux. - if [ "$(uname)" = "Linux" ]; then - # Make a place for the containers to write their logs. - mkdir -p ${outdir}/acceptance - - # Note that this test requires 2>&1 but the others don't because - # this one runs outside the builder container (and inside the - # container, something is already combining stdout and stderr). - time "$(dirname "${0}")"/../acceptance.test -nodes 3 -l ${outdir}/acceptance \ - -test.v -test.timeout 10m \ - --verbosity=1 --vmodule=monitor=2 2>&1 | \ - tr -d '\r' | tee "${outdir}/acceptance.log" | \ - grep -E "^\--- (PASS|FAIL)|^(FAIL|ok)|${match}" | - awk '{print "acceptance:", $0}' - else - echo "skipping acceptance tests on $(uname): use 'make acceptance' instead" - fi -fi - -if is_shard 1; then - # Run "make testrace". - echo "make testrace" - time ${builder} make testrace \ - TESTFLAGS='-v --verbosity=1 --vmodule=monitor=2' | \ - tr -d '\r' | tee "${outdir}/testrace.log" | \ - grep -E "^\--- (PASS|FAIL)|^(FAIL|ok)|${match}" | - awk '{print "race:", $0}' -fi diff --git a/build/circle-trigger-osx-build-push.sh b/build/circle-trigger-osx-build-push.sh deleted file mode 100755 index 2fe7b9a27519..000000000000 --- a/build/circle-trigger-osx-build-push.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -if [ $# -ne 2 ]; then - cat < -EOF - exit 2 -fi - -REV="${2}" -echo "Triggering ${REV}" -curl -X POST --header 'Content-Type: application/json' \ - -d ' { "build_parameters": { "BUILD_OSX": "true" } }' \ - "https://circleci.com/api/v1/project/cockroachdb/cockroach/tree/${REV}?circle-token=${1}" diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 25707f988c31..000000000000 --- a/circle.yml +++ /dev/null @@ -1,75 +0,0 @@ -machine: - pre: - - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0 - - environment: - # Used by https://godoc.org/github.com/docker/docker/client#NewEnvClient. - # Matches the docker daemon version in use. - # See https://docs.docker.com/engine/reference/api/docker_remote_api/ - DOCKER_API_VERSION: v1.22 - - services: - - docker - -checkout: - post: - # git tags are used to generate build info which is baked into the - # CockroachDB binary; unfortunately, it is not possible to fetch all tags - # without also unshallowing the checkout, so we must do both. - - git fetch --unshallow --tags - # GOPATH is cached, so we need to clean out the version from the previous - # run or the subsequent `mv` will fail. We put our checkout in the correct - # location for the OSX build step. - - rm -rf "${GOPATH%%:*}/src/github.com/cockroachdb/cockroach" - - mkdir -p "${GOPATH%%:*}/src/github.com/cockroachdb/" - - mv ~/cockroach "${GOPATH%%:*}/src/github.com/cockroachdb/" - - ln -s "${GOPATH%%:*}/src/github.com/cockroachdb/cockroach" ~/cockroach - -dependencies: - override: - - build/circle-deps.sh: - parallel: true - cache_directories: - - ~/.jspm - - ~/.npm - - ~/builder - -test: - override: - - build/circle-test.sh: - parallel: true - -deployment: - release: - tag: /beta-[0-9]+/ - commands: - - sed "s//$DOCKER_EMAIL/;s//$DOCKER_AUTH/" < "resource/deploy_templates/.dockercfg.template" > ~/.dockercfg - - build/builder.sh build/build-static-binaries.sh static-tests.tar.gz - - | - export VERSION=$CIRCLE_TAG - echo "Deploying ${VERSION}..." - if [ -n "$DOCKER_EMAIL" ]; then - build/push-docker-deploy.sh - fi - - aws configure set region us-east-1 - - build/build-osx.sh - - build/push-tagged-aws.sh - datarace: - branch: data-race - commands: - - aws configure set region us-east-1 - - build/builder.sh build/build-race-binaries.sh - - build/push-one-binary.sh "${CIRCLE_SHA1-$(git rev-parse HEAD)}" cockroach cockroach.race - stdmalloc: - branch: stdmalloc - commands: - - aws configure set region us-east-1 - - build/builder.sh build/build-static-binaries.sh static-tests.malloc.tar.gz stdmalloc - - build/push-one-binary.sh "${CIRCLE_SHA1-$(git rev-parse HEAD)}" cockroach cockroach.stdmalloc - - build/push-one-binary.sh "${CIRCLE_SHA1-$(git rev-parse HEAD)}" static-tests.stdmalloc.tar.gz - beta: - branch: /branch-beta-[0-9]+/ - commands: - - aws configure set region us-east-1 - - build/builder.sh build/build-static-binaries.sh static-tests.tar.gz - - build/push-one-binary.sh "${CIRCLE_SHA1-$(git rev-parse HEAD)}" cockroach cockroach.beta