version: 2.1 references: # environment specific references - aim to avoid conflicts go-machine-image: &go_machine_image circleci/classic:201808-01 go-machine-recent-image: &go_machine_recent_image ubuntu-1604:201903-01 go-windows-image: &go_windows_image windows-server-2019-vs2019:stable # common references common_envs: &common_envs GOMAXPROCS: 1 NOMAD_SLOW_TEST: 1 GOTESTSUM_JUNITFILE: /tmp/test-reports/results.xml GOTESTSUM_JSONFILE: /tmp/test-reports/testjsonfile.json # disable implicit git paging. CircleCI runs commands with in a tty # making git assume it's an interactive session. PAGER: cat GIT_PAGER: cat commands: install-buf: steps: - run: name: install buf command: | sudo ./scripts/vagrant-linux-priv-buf.sh install-vault: parameters: version: type: string default: 1.2.4 steps: - run: name: Install Vault command: | set -x case "${OSTYPE}" in linux*) os="linux" ;; darwin*) os="darwin" ;; msys*) os="windows" ;; *) echo "unknown os: ${OSTYPE}"; exit 1 ;; esac curl -SL --fail -o /tmp/vault.zip https://releases.hashicorp.com/vault/"<< parameters.version >>"/vault_"<< parameters.version >>"_"${os}"_amd64.zip if [[ "${os}" != "windows" ]]; then sudo unzip -d /usr/local/bin /tmp/vault.zip rm -rf /tmp/vault* else rm -rf c:\Windows\vault.exe unzip /tmp/vault.zip -d "/c/Windows" rm -rf /tmp/vault* fi install-consul: parameters: version: type: string default: 1.8.3 steps: - run: name: Install Consul << parameters.version >> command: | curl -SL --fail -o /tmp/consul.zip https://releases.hashicorp.com/consul/<< parameters.version >>/consul_<< parameters.version >>_linux_amd64.zip sudo unzip -d /usr/local/bin /tmp/consul.zip rm -rf /tmp/consul* install-golang: parameters: target_directory: type: string default: /usr/local steps: - run: name: Install golang command: | set -x echo installing golang ${GOLANG_VERSION} case "${OSTYPE}" in linux*) os="linux" ;; darwin*) os="darwin" ;; msys*) os="windows" ;; *) echo "unknown os: ${OSTYPE}"; exit 1 ;; esac if [[ "${os}" != "windows" ]] then sudo rm -rf << parameters.target_directory >>/go sudo mkdir -p << parameters.target_directory >> curl -SL --fail -o /tmp/golang.tar.gz https://dl.google.com/go/go${GOLANG_VERSION}.${os}-amd64.tar.gz sudo tar -C << parameters.target_directory >> -xzf /tmp/golang.tar.gz rm -rf /tmp/golang.tar.gz else rm -rf << parameters.target_directory >>/go mkdir -p <> curl -SL --fail -o /tmp/go.zip https://dl.google.com/go/go${GOLANG_VERSION}.windows-amd64.zip unzip -q -o /tmp/go.zip -d << parameters.target_directory >> rm -rf /tmp/go.zip fi install-circleci-local-cli: parameters: version: type: string default: 0.1.5879 sha256: type: string default: f178ea62c781aec06267017404f87983c87f171fd0e66ef3737916246ae66dd6 steps: - run: name: Install CircleCI CLI << parameters.version >> command: | CCI_VERSION="<< parameters.version >>" CCI_SHA256="<< parameters.sha256 >>" URL="https://github.com/CircleCI-Public/circleci-cli/releases/download/v${CCI_VERSION}/circleci-cli_${CCI_VERSION}_linux_amd64.tar.gz" mkdir -p /tmp/circleci-cli/ curl --fail --show-error --location \ -o /tmp/circleci-cli/cli.tar.gz "${URL}" echo "$CCI_SHA256 /tmp/circleci-cli/cli.tar.gz" | sha256sum -c tar -xz --strip-components=1 \ -C /tmp/circleci-cli \ -f /tmp/circleci-cli/cli.tar.gz \ "circleci-cli_${CCI_VERSION}_linux_amd64/circleci" sudo cp /tmp/circleci-cli/circleci /usr/bin/circleci-local-cli circleci-local-cli version run-tests: steps: - run: name: Running Nomad Tests no_output_timeout: 20m command: | if [ -z $GOTEST_PKGS_EXCLUDE ]; then unset GOTEST_PKGS_EXCLUDE else unset GOTEST_PKGS fi if [ ! -z $GOTESTARCH ]; then export GOARCH="$GOTESTARCH"; fi mkdir -p /tmp/test-reports sudo -E PATH="$GOPATH/bin:/usr/local/go/bin:$PATH" make generate-structs if [ ! -z $GOTEST_MOD ]; then sudo -E PATH="$GOPATH/bin:/usr/local/go/bin:$PATH" make test-nomad-module else sudo -E PATH="$GOPATH/bin:/usr/local/go/bin:$PATH" make test-nomad fi jobs: website-docker-image: docker: - image: docker.mirror.hashicorp.services/circleci/buildpack-deps shell: /usr/bin/env bash -euo pipefail -c steps: - checkout - run: name: Skip building if nothing changed command: | # There is an edge case that would cause an issue here - if dependencies are updated to an exact copy # of a previous version, for example if packge-lock.json is reverted, we need to manually push the new # image to the "latest" tag # Ignore job if running an enterprise build IMAGE_TAG=$(cat website/Dockerfile website/package-lock.json | sha256sum | awk '{print $1;}') echo "Using $IMAGE_TAG" if [ "$CIRCLE_REPOSITORY_URL" != "git@github.com:hashicorp/nomad.git" ]; then echo "Not Nomad OSS Repo, not building website docker image" circleci-agent step halt elif curl https://hub.docker.com/v2/repositories/hashicorp/nomad-website/tags/$IMAGE_TAG -fsL > /dev/null; then echo "Dependencies have not changed, not building a new website docker image." circleci-agent step halt fi - setup_remote_docker - run: name: Build Docker Image command: | IMAGE_TAG=$(cat website/Dockerfile website/package-lock.json | sha256sum | awk '{print $1;}') echo "Using $IMAGE_TAG" cd website/ docker build -t hashicorp/nomad-website:$IMAGE_TAG . docker tag hashicorp/nomad-website:$IMAGE_TAG hashicorp/nomad-website:latest docker login -u $WEBSITE_DOCKER_USER -p $WEBSITE_DOCKER_PASS docker push hashicorp/nomad-website test-windows: executor: go-windows steps: - run: git config --global core.autocrlf false - checkout - run: name: Setup command: | mkdir -p $GOBIN mkdir -p $GOTESTSUM_PATH - install-golang: target_directory: "c:" - run: go version - install-vault: version: $VAULT_VERSION - run: vault version - run: choco install make - run: name: Install golang dependencies command: | export PATH=$PATH:/c/go/bin:/c/gopath/bin make deps - run: name: Pre-download docker test image command: docker pull docker.mirror.hashicorp.services/hashicorpnomad/busybox-windows:server2016-0.1 - run: name: Build nomad command: | export PATH=$PATH:/c/go/bin:/c/gopath/bin go build -o $GOBIN\nomad.exe - run: name: Run tests with gotestsum command: | # Only test docker driver tests for now export PATH=$PATH:/c/go/bin:/c/gopath/bin gotestsum --format=short-verbose \ --junitfile $GOTESTSUM_PATH/results.xml \ github.com/hashicorp/nomad/drivers/docker \ github.com/hashicorp/nomad/client/lib/fifo \ github.com/hashicorp/nomad/client/logmon - store_test_results: path: c:\tmp\test-reports - store_artifacts: path: c:\tmp\test-reports test-ui: docker: - image: docker.mirror.hashicorp.services/circleci/node:12-browsers environment: # See https://git.io/vdao3 for details. JOBS: 2 steps: - checkout - restore_cache: keys: - v3-deps-{{ checksum "ui/yarn.lock" }} - run: name: yarn install command: cd ui && yarn install --frozen-lockfile - save_cache: key: v3-deps-{{ checksum "ui/yarn.lock" }} paths: - ./ui/node_modules - run: name: lint:js command: cd ui && yarn run lint:js - run: name: lint:hbs command: cd ui && yarn run lint:hbs - run: name: Ember tests command: mkdir -p /tmp/test-reports && cd ui && yarn test - store_test_results: path: /tmp/test-reports - store_artifacts: path: /tmp/test-reports test-machine: executor: "<< parameters.executor >>" parameters: test_packages: type: string default: "" test_module: type: string default: "" exclude_packages: type: string default: "" executor: type: string default: "go-machine-recent" goarch: type: string default: "amd64" environment: GOTEST_PKGS_EXCLUDE: "<< parameters.exclude_packages >>" GOTEST_PKGS: "<< parameters.test_packages >>" GOTEST_MOD: "<< parameters.test_module >>" GOTESTARCH: "<< parameters.goarch >>" steps: - checkout - install-golang - install-buf - install-consul - install-vault - run: name: Install 32bit gcc libs command: | if [ ! -z $GOTESTARCH ] && [ $GOTESTARCH == "386" ]; then sudo apt-get update sudo apt-get install -y gcc-multilib else echo "Skipping 32bit lib installation while building for not 386" fi - run: PATH="$GOPATH/bin:/usr/local/go/bin:$PATH" make bootstrap - run-tests - store_test_results: path: /tmp/test-reports - store_artifacts: path: /tmp/test-reports test-e2e: executor: go steps: - checkout - run: apt-get update; apt-get install -y sudo unzip # e2e tests require privileged mount/umount permissions when running as root # TODO: switch to using machine executor and run as root to test e2e path - run: name: prepare non-root user command: | groupadd --gid 3434 circleci useradd --uid 3434 --gid circleci --shell /bin/bash --create-home circleci echo 'circleci ALL=NOPASSWD: ALL' >> /etc/sudoers.d/50-circleci echo 'Defaults env_keep += "DEBIAN_FRONTEND"' >> /etc/sudoers.d/env_keep chown -R circleci:circleci /go - run: sudo -E -H -u circleci PATH=${PATH} make deps - run: sudo -E -H -u circleci PATH=${PATH} make integration-test - run: sudo -E -H -u circleci PATH=${PATH} make e2e-test test-container: executor: go parameters: test_packages: type: string default: "" exclude_packages: type: string default: "" goarch: type: string default: "amd64" environment: GOTEST_PKGS: "<< parameters.test_packages >>" GOTEST_PKGS_EXCLUDE: "<< parameters.exclude_packages >>" GOTESTARCH: "<< parameters.goarch >>" steps: - checkout - run: apt-get update; apt-get install -y shellcheck sudo unzip - run: make deps - install-buf - install-consul - install-vault - run-tests - store_test_results: path: /tmp/test-reports - store_artifacts: path: /tmp/test-reports lint-go: executor: go steps: - checkout - run: apt-get update; apt-get install -y shellcheck sudo unzip - install-buf - install-circleci-local-cli - run: make deps lint-deps - run: make check - run: make checkscripts - run: mkdir -p ui/dist && make generate-all static-assets build-darwin-binaries: executor: go-macos steps: - checkout - run: name: configure PATH command: echo 'export PATH="${GOPATH}/bin:${HOME}/goinstall/go/bin:$PATH"' >> ${BASH_ENV} - install-golang: target_directory: ~/goinstall - run: source ${BASH_ENV} && make deps - run: brew install protobuf - run: PATH="$GOPATH/bin:${HOME}/goinstall/go/bin:$PATH" make generate-structs - run: name: prepare ui cache command: git log -n 1 --pretty=format:%H ui > /tmp/ui-sha - restore_cache: name: restore compiled ui assets keys: - v1-binary-ui-assets-darwin-{{ checksum "/tmp/ui-sha" }} - run: name: prepare ui command: | if [[ -f ~/caches/ui-assets/bindata_assetfs.go ]]; then cp ~/caches/ui-assets/bindata_assetfs.go ./command/agent/bindata_assetfs.go exit 0 fi ./scripts/vagrant-linux-unpriv-ui.sh export PATH="$GOPATH/bin:/usr/local/go/bin:$PATH" source ${BASH_ENV} . ~/.nvm/nvm.sh cd ui && yarn install --frozen-lockfile && cd .. JOBS=2 make ember-dist static-assets mkdir -p ~/caches/ui-assets cp ./command/agent/bindata_assetfs.go ~/caches/ui-assets/bindata_assetfs.go - save_cache: name: save compiled ui assets key: v1-binary-ui-assets-darwin-{{ checksum "/tmp/ui-sha" }} paths: - ~/caches/ui-assets - run: name: build binaries command: | source ${BASH_ENV} export GO_TAGS="ui $(grep -e '^GO_TAGS ?=' ./GNUmakefile | cut -d= -f2)" make pkg/darwin_amd64.zip - store_artifacts: path: pkg/darwin_amd64.zip destination: /builds/nomad_darwin_amd64.zip build-binaries: executor: go steps: - checkout - run: apt-get update; apt-get install -y sudo unzip zip - run: make deps - install-buf - run: sudo -E PATH="$GOPATH/bin:/usr/local/go/bin:$PATH" make generate-structs - run: name: prepare ui cache command: git log -n 1 --pretty=format:%H ui > /tmp/ui-sha - restore_cache: name: restore compiled ui assets keys: - v1-binary-ui-assets-linux-{{ checksum "/tmp/ui-sha" }} - run: name: prepare ui command: | if [[ -f /tmp/ui-assets/bindata_assetfs.go ]]; then cp /tmp/ui-assets/bindata_assetfs.go ./command/agent/bindata_assetfs.go exit 0 fi ./scripts/vagrant-linux-unpriv-ui.sh export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" export PATH="$GOPATH/bin:/usr/local/go/bin:$PATH" . ~/.nvm/nvm.sh cd ui && yarn install --frozen-lockfile && cd .. JOBS=2 make ember-dist static-assets mkdir -p /tmp/ui-assets cp ./command/agent/bindata_assetfs.go /tmp/ui-assets/bindata_assetfs.go - save_cache: name: save compiled ui assets key: v1-binary-ui-assets-linux-{{ checksum "/tmp/ui-sha" }} paths: - /tmp/ui-assets - run: name: build binaries command: | export GO_TAGS="ui $(grep -e '^GO_TAGS ?=' ./GNUmakefile | cut -d= -f2)" make pkg/windows_amd64.zip pkg/linux_amd64.zip - store_artifacts: path: pkg destination: /builds - store_artifacts: path: /tmp/ui-assets destination: /ui-assets algolia_index: docker: - image: docker.mirror.hashicorp.services/node:12 steps: - checkout - run: name: Push content to Algolia Index command: | if [ "$CIRCLE_REPOSITORY_URL" != "git@github.com:hashicorp/nomad.git" ]; then echo "Not Nomad OSS Repo, not indexing Algolia" exit 0 fi cd website/ npm install node scripts/index_search_content.js executors: go: working_directory: /go/src/github.com/hashicorp/nomad docker: - image: docker.mirror.hashicorp.services/golang:1.15.6 environment: <<: *common_envs GOPATH: /go go-machine: working_directory: ~/go/src/github.com/hashicorp/nomad machine: image: *go_machine_image environment: &machine_env <<: *common_envs GOPATH: /home/circleci/go GOLANG_VERSION: 1.15.6 # uses a more recent image with unattended upgrades disabled properly # but seems to break docker builds go-machine-recent: working_directory: ~/go/src/github.com/hashicorp/nomad machine: image: *go_machine_recent_image environment: *machine_env go-macos: working_directory: ~/go/src/github.com/hashicorp/nomad macos: xcode: 11.3.1 environment: <<: *common_envs GOPATH: /Users/distiller/go GOLANG_VERSION: 1.15.6 go-windows: machine: image: *go_windows_image resource_class: windows.medium shell: bash --login -eo pipefail working_directory: c:\gopath\src\github.com\hashicorp\nomad environment: GOPATH: c:\gopath GOBIN: c:\gopath\bin GOTESTSUM_PATH: c:\tmp\test-reports GOLANG_VERSION: 1.15.6 GOTESTSUM_VERSION: 0.4.2 VAULT_VERSION: 1.4.1 workflows: build-test: jobs: - build-binaries: # almost always build binaries as they may be needed # for e2e tests filters: branches: ignore: - stable-website - /^.-ui\b.*/ - lint-go: # check branches are almost all the backend branches filters: &backend_check_branches_filter branches: ignore: - /^.-ui\b.*/ - /^docs-.*/ - stable-website # Note: comment-out this job in ENT - build-darwin-binaries: filters: *backend_check_branches_filter - test-e2e: filters: *backend_check_branches_filter - test-ui: filters: branches: ignore: - stable-website - /^docs-.*/ - /^e2e-.*/ # Note: comment-out this job in ENT - test-windows: filters: branches: ignore: - /^.-ui\b.*/ - /^docs-.*/ - /^e2e-.*/ - stable-website - test-machine: name: "test-client" test_packages: "./client/..." # test branches are the branches that can impact unit tests filters: &backend_test_branches_filter branches: ignore: - /^.-ui\b.*/ - /^docs-.*/ - /^e2e-.*/ - stable-website - test-machine: name: "test-nomad" test_packages: "./nomad/..." filters: *backend_test_branches_filter - test-machine: # API Tests run in a VM rather than container due to the FS tests # requiring `mount` priviliges. name: "test-api" test_module: "api" filters: *backend_test_branches_filter - test-container: name: "test-devices" test_packages: "./devices/..." filters: *backend_test_branches_filter - test-machine: name: "test-other" exclude_packages: "./api|./client|./drivers/docker|./drivers/exec|./drivers/shared/executor|./nomad|./devices|./e2e" filters: *backend_test_branches_filter - test-machine: name: "test-docker" test_packages: "./drivers/docker" # docker is misbehaving in docker-machine-recent image # and we get unexpected failures # e.g. https://circleci.com/gh/hashicorp/nomad/3854 executor: go-machine filters: *backend_test_branches_filter - test-machine: name: "test-exec" test_packages: "./drivers/exec" filters: *backend_test_branches_filter - test-machine: name: "test-shared-exec" test_packages: "./drivers/shared/executor" filters: *backend_test_branches_filter - test-machine: name: "test-32bit" # Currently we only explicitly test fingerprinting on 32bit # architectures. test_packages: "./client/fingerprint" goarch: "386" filters: *backend_test_branches_filter website: when: equal: [ "https://github.com/hashicorp/nomad", << pipeline.project.git_url >> ] jobs: - website-docker-image: context: static-sites filters: branches: only: - master - algolia_index: context: static-sites filters: branches: only: - stable-website