version: 2.1 orbs: slack: circleci/slack@3.4.2 references: images: middleman: &MIDDLEMAN_IMAGE docker.mirror.hashicorp.services/hashicorp/middleman-hashicorp:0.3.44 executors: go: docker: - image: docker.mirror.hashicorp.services/circleci/golang:1.16 environment: CONSUL_VERSION: 1.7.2 GOMAXPROCS: 4 GO111MODULE: "on" GOPROXY: https://proxy.golang.org/ TEST_RESULTS_DIR: &TEST_RESULTS_DIR /tmp/test-results ARTIFACTS_DIR: &ARTIFACTS_DIR /tmp/artifacts jobs: go-checks: executor: name: go steps: - checkout - run: go mod verify - run: make fmtcheck generate - run: name: verify no code was generated command: | if [[ -z $(git status --porcelain) ]]; then echo "Git directory is clean." else echo "Git is dirty. Run `make fmtcheck` and `make generate` locally and commit any formatting fixes or generated code." git status --porcelain exit 1 fi go-test: executor: name: go environment: TF_CONSUL_TEST: 1 parallelism: 4 steps: - checkout - attach_workspace: at: . - run: name: install consul command: | curl -sLo consul.zip https://releases.hashicorp.com/consul/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip unzip consul.zip mkdir -p ~/bin mv consul ~/bin echo 'export PATH="~/bin:$PATH"' - run: mkdir -p $TEST_RESULTS_DIR - run: name: Run Go Tests command: | PACKAGE_NAMES=$(go list ./... | circleci tests split --split-by=timings --timings-type=classname) echo "Running $(echo $PACKAGE_NAMES | wc -w) packages" echo $PACKAGE_NAMES gotestsum --format=short-verbose --junitfile $TEST_RESULTS_DIR/gotestsum-report.xml -- -p 2 -cover -coverprofile=cov_$CIRCLE_NODE_INDEX.part $PACKAGE_NAMES # save coverage report parts - persist_to_workspace: root: . paths: - cov_*.part - store_test_results: path: *TEST_RESULTS_DIR - store_artifacts: path: *TEST_RESULTS_DIR - slack/status: fail_only: true only_for_branches: main go-test-e2e: executor: name: go environment: TF_ACC: 1 steps: - checkout - attach_workspace: at: . - run: mkdir -p $TEST_RESULTS_DIR - run: name: Run Go E2E Tests command: | gotestsum --format=short-verbose --junitfile $TEST_RESULTS_DIR/gotestsum-report.xml -- -p 2 -cover -coverprofile=cov_e2e.part ./command/e2etest ./tools/terraform-bundle/e2etest # save coverage report parts - persist_to_workspace: root: . paths: - cov_*.part - store_test_results: path: *TEST_RESULTS_DIR - store_artifacts: path: *TEST_RESULTS_DIR - slack/status: fail_only: true only_for_branches: main # combine code coverage results from the parallel circleci executors coverage-merge: executor: name: go steps: - checkout - attach_workspace: at: . - run: mkdir -p $TEST_RESULTS_DIR - run: name: merge coverage reports command: | echo "mode: set" > coverage.out grep -h -v "mode: set" cov_*.part >> coverage.out go tool cover -html=coverage.out -o $TEST_RESULTS_DIR/coverage.html - run: name: codecov upload command: bash <(curl -s https://codecov.io/bash) -v -C $CIRCLE_SHA1 - store_artifacts: path: *TEST_RESULTS_DIR # build all distros build-distros: &build-distros executor: go environment: &build-env TF_RELEASE: 1 steps: - run: go get -u github.com/mitchellh/gox # go get gox before detecting go mod - checkout - run: ./scripts/build.sh - run: mkdir -p $ARTIFACTS_DIR - run: cp pkg/*.zip /tmp/artifacts # save dev build to CircleCI - store_artifacts: path: *ARTIFACTS_DIR # build all amd64 architecture supported OS binaries build-amd64: <<: *build-distros environment: <<: *build-env XC_OS: "darwin linux windows" XC_ARCH: "amd64" # build all arm architecture supported OS binaries build-arm: <<: *build-distros environment: <<: *build-env XC_OS: "linux" XC_ARCH: "arm" test-docker-full: executor: name: go steps: - checkout - setup_remote_docker - run: name: test docker build for 'full' image command: docker build -t test-docker-full . # Based on a similar job in terraform-website repo. website-link-check: docker: - image: *MIDDLEMAN_IMAGE steps: - checkout: path: terraform - run: name: Determine changed website files, if any working_directory: terraform command: | # Figure out what the current branch forked from. Compare against # main and the set of "vX.Y" branches, and choose whichever branch # we're the *fewest* commits ahead of. # The point here isn't to perfectly predict where this will be # merged; all we really care about is determining which commits are # *unique to this PR,* so we don't accidentally complain about # problems you had nothing to do with. PARENT_BRANCH=$( for br in $(git branch -rl --format='%(refname:short)' | grep -E '^origin/(main|v\d+\.\d+)$'); do new_commits=$(git rev-list --first-parent ^${br} HEAD | wc -l); echo "${br} ${new_commits}"; done \ | sort -n -k2 \ | head -n1 \ | awk '{print $1}'; ) echo "Checking current branch against: ${PARENT_BRANCH}" MERGE_BASE=$(git merge-base HEAD ${PARENT_BRANCH}) git diff --name-only -z --diff-filter=AMRCT ${MERGE_BASE}..HEAD -- ./website/ > /tmp/changed-website-files.txt # --name-only: Return a list of affected files but don't show the changes. # -z: Make that a null-separated list (instead of newline-separated), and # DON'T mangle non-ASCII characters. # --diff-filter=AMRCT: Only list files that were added, modified, renamed, # copied, or had their type changed (file, symlink, etc.). In # particular, we don't want to check deleted files. # ${MERGE_BASE}..HEAD: Only consider files that have # changed since this branch diverged from its parent branch. # -- ./website/: Only consider files in the website directory. echo "Changed website files:" cat /tmp/changed-website-files.txt | tr '\0' '\n' # Need to use "tr" for display because it's a null-separated list. - run: name: Exit early if there's nothing to check command: | if [ ! -s /tmp/changed-website-files.txt ]; then circleci-agent step halt fi - run: name: Check out terraform-website repo command: git clone git@github.com:hashicorp/terraform-website.git - run: name: Use local checkout for terraform submodule, instead of cloning again working_directory: terraform-website command: | # Set submodule's URL to our existing checkout. # (Using `pwd` because git's behavior with strictly relative paths is unreliable.) git config --file=.gitmodules submodule.ext/terraform.url $(pwd)/../terraform/.git # Make it so `make sync` will grab our current branch instead of stable-website. git config --file=.gitmodules submodule.ext/terraform.branch HEAD - run: name: Init/update terraform-website submodules working_directory: terraform-website command: make sync - run: name: Set up terraform-website dependencies working_directory: terraform-website/content # If this does anything interesting, then the container needs an update. command: bundle check || bundle install --path vendor/bundle --retry=3 - run: name: Run middleman in background working_directory: terraform-website/content background: true command: bundle exec middleman server - run: name: Wait for server to start command: until curl -sS http://localhost:4567/ > /dev/null; do sleep 1; done - run: name: Check links in changed pages working_directory: terraform-website/content command: cat /tmp/changed-website-files.txt | bundle exec ./scripts/check-pr-links.rb workflows: version: 2 test: jobs: - go-checks - go-test: requires: - go-checks - go-test-e2e: requires: - go-checks - coverage-merge: requires: - go-test - go-test-e2e - test-docker-full: filters: branches: only: - main - /^v\d+\.\d+$/ # v0.11, v0.12, etc. build-distros: jobs: - build-amd64 - build-arm website-test: jobs: - website-link-check