version: 2.1 workflows: version: 2 test_build_deploy: jobs: - pipenv_install_36: filters: tags: only: /.*/ - pip_install_36: filters: tags: only: /.*/ - pipenv_install_37: filters: tags: only: /.*/ - pip_install_37: filters: tags: only: /.*/ - contracts: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - pip_install_36 - pipenv_install_36 - pip_install_37 - pipenv_install_37 - crypto: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - pip_install_36 - pipenv_install_36 - pip_install_37 - pipenv_install_37 - network: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - pip_install_36 - pipenv_install_36 - pip_install_37 - pipenv_install_37 - keystore: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - pip_install_36 - pipenv_install_36 - pip_install_37 - pipenv_install_37 - blockchain: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - pip_install_36 - pipenv_install_36 - pip_install_37 - pipenv_install_37 - character: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - crypto - network - keystore - agents: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - blockchain # - contracts (Removed dependency to speed up overall workflow execution) - actors: context: "NuCypher Tests" filters: tags: only: /.*/ requires: # (Prioritizing this task given that it's awfully slow) - pip_install_36 - pipenv_install_36 - pip_install_37 - pipenv_install_37 # - blockchain # - contracts - deployers: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - blockchain # - contracts (Removed dependency to speed up overall workflow execution) - config: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - blockchain - crypto - network - keystore - cli: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - agents - actors - deployers - config - character - ursula_command: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - agents - actors - deployers - config - character - heartbeat_demo: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - cli - ursula_command - mypy: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - cli - ursula_command - estimate_gas: context: "NuCypher Tests" filters: tags: only: /.*/ requires: - cli - ursula_command - build_docs: filters: tags: only: /.*/ requires: - cli - ursula_command - test_build: filters: tags: only: /.*/ requires: - cli - ursula_command - build_docs - build_docker: filters: tags: only: /v[0-9]+.*/ branches: ignore: /.*/ requires: - cli - ursula_command - test_deploy: context: "NuCypher PyPI" requires: - test_build filters: tags: only: /v[0-9]+.*/ branches: ignore: /.*/ - request_publication_approval: type: approval requires: - test_deploy - build_docker filters: tags: only: /v[0-9]+.*/ branches: ignore: /.*/ - publish_pypi: context: "NuCypher PyPI" requires: - request_publication_approval filters: tags: only: /v[0-9]+.*/ branches: ignore: /.*/ - publish_docker: context: "NuCypher Docker" requires: - request_publication_approval filters: tags: only: /v[0-9]+.*/ branches: ignore: /.*/ python_36_base: &python_36_base parallelism: 1 working_directory: ~/nucypher docker: - image: circleci/python:3.6 python_37_base: &python_37_base parallelism: 1 working_directory: ~/nucypher docker: - image: circleci/python:3.7 commands: pipenv_install: description: "Install Python dependencies with Pipenv" steps: - checkout - run: name: Install Python Dependencies with Pipenv command: pipenv sync --dev - run: name: Install Solidity Compiler (Pipenv Entrypoint) command: pipenv run install-solc - run: name: Check NuCypher Python API Entrypoint command: pipenv run python3 -c "import nucypher; print(nucypher.__version__)" - run: name: Check NuCypher CLI Entrypoint command: pipenv run nucypher --help check_nucypher_entrypoints: description: "Ensure both the python API and CLI entrypoints are usable" steps: - run: name: Check NuCypher Python API Entrypoint command: python3 -c "import nucypher; print(nucypher.__version__)" - run: name: Check NuCypher CLI Entrypoint command: | export PATH=~/.local/bin:$PATH source ~/.bashrc nucypher --help pip_install: description: "Install Python dependencies with Pip" steps: - checkout - run: name: Install Python Dependencies with Pip command: pip3 install --user . - run: name: Install Python Development Dependencies with Pip command: pip3 install --user .[development] - run: name: Install Solidity Compiler command: ./scripts/install_solc.sh - check_nucypher_entrypoints prepare_environment: description: "Checkout application code and Attach the Workspace" steps: - checkout - attach_workspace: at: ~/.local/share/virtualenvs/ - run: name: "Create directory for test reports" command: mkdir reports coveralls: description: "Upload Coverage Report To Coveralls.io" steps: - run: name: Upload Coverage Report command: | echo -e "COVERALLS_REPO_TOKEN=$COVERALLS_REPO_TOKEN" >> .env pipenv run coveralls capture_test_results: description: "Store and Upload test results; Follow-up step for tests" steps: - coveralls - store_test_results: path: reports jobs: # Python 3.6 pip_install_36: <<: *python_36_base steps: - pip_install pipenv_install_36: <<: *python_36_base steps: - pipenv_install - persist_to_workspace: root: ~/.local/share/virtualenvs/ paths: - nucypher-* # Python 3.7 pip_install_37: <<: *python_37_base steps: - pip_install pipenv_install_37: <<: *python_37_base steps: - pipenv_install blockchain: <<: *python_36_base parallelism: 2 steps: - prepare_environment - run: name: Blockchain Interface Tests command: pipenv run pytest tests/blockchain/eth/interfaces - capture_test_results agents: <<: *python_36_base parallelism: 4 steps: - prepare_environment - run: name: Blockchain Agent Tests command: | pipenv run pytest $(circleci tests glob tests/blockchain/eth/entities/agents/**/*.py | circleci tests split --split-by=timings) - capture_test_results actors: <<: *python_36_base parallelism: 2 steps: - prepare_environment - run: name: Blockchain Actor Tests command: | pipenv run pytest $(circleci tests glob tests/blockchain/eth/entities/actors/**/*.py | circleci tests split --split-by=timings) - capture_test_results deployers: <<: *python_36_base parallelism: 4 steps: - prepare_environment - run: name: Contract Deployer Tests command: | pipenv run pytest $(circleci tests glob tests/blockchain/eth/entities/deployers/test_*.py | circleci tests split --split-by=timings) - capture_test_results contracts: <<: *python_36_base parallelism: 5 steps: - prepare_environment - run: name: Ethereum Contract Unit Tests command: | pipenv run pytest $(circleci tests glob tests/blockchain/eth/contracts/**/**/test_*.py | circleci tests split --split-by=timings) - store_test_results: path: reports config: <<: *python_36_base parallelism: 2 steps: - prepare_environment - run: name: Node Configuration Tests command: | pipenv run pytest $(circleci tests glob tests/config/**/test_*.py | circleci tests split --split-by=timings) - capture_test_results crypto: <<: *python_36_base steps: - prepare_environment - run: name: Crypto Character Tests command: pipenv run pytest tests/crypto - capture_test_results network: <<: *python_36_base steps: - prepare_environment - run: name: Network Tests command: | pipenv run pytest $(circleci tests glob tests/network/**/test_*.py | circleci tests split --split-by=timings) - capture_test_results keystore: <<: *python_36_base parallelism: 2 steps: - prepare_environment - run: name: Keystore Tests command: | pipenv run pytest $(circleci tests glob tests/keystore/**/test_*.py | circleci tests split --split-by=timings) - capture_test_results character: <<: *python_36_base parallelism: 4 steps: - prepare_environment - run: name: Character Tests command: | pipenv run pytest $(circleci tests glob tests/characters/**/test_*.py | circleci tests split --split-by=timings) - capture_test_results learning: <<: *python_36_base steps: - prepare_environment - run: name: Learner Tests command: pipenv run pytest tests/learning - capture_test_results heartbeat_demo: <<: *python_36_base steps: - checkout - pip_install - run: name: Run demo Ursula fleet, Alicia and the Doctor command: | mkdir /tmp/ursulas-logs export PATH=~/.local/bin:$PATH source ~/.bashrc export NUCYPHER_SENTRY_LOGS=0 export NUCYPHER_FILE_LOGS=0 python3 examples/run_lonely_demo_ursula.py > /tmp/ursulas-logs/ursula-11500.txt 2>&1 & sleep 15 nucypher ursula run --dev --debug --federated-only --teacher-uri localhost:11500 --rest-port 11501 > /tmp/ursulas-logs/ursula-11501.txt 2>&1 & sleep 15 nucypher ursula run --dev --debug --federated-only --teacher-uri localhost:11500 --rest-port 11502 > /tmp/ursulas-logs/ursula-11502.txt 2>&1 & sleep 15 python3 examples/heartbeat_demo/alicia.py python3 examples/heartbeat_demo/doctor.py - store_artifacts: path: /tmp/ursulas-logs cli: <<: *python_36_base parallelism: 6 steps: - prepare_environment - run: name: Nucypher CLI Tests command: | pipenv run pytest $(circleci tests glob tests/cli/**/test_*.py | circleci tests split --split-by=timings) - store_test_results: path: reports ursula_command: <<: *python_36_base steps: - prepare_environment - run: name: Ursula Command Tests command: pipenv run pytest tests/cli/protocol - store_test_results: path: reports mypy: <<: *python_36_base steps: - prepare_environment - run: name: Install mypy command: | pipenv run pip install lxml pipenv run pip install mypy - run: name: Run Mypy Static Type Checks (Always Succeed) command: | mkdir ./mypy_reports ./mypy_results export MYPYPATH=./nucypher pipenv run mypy ./nucypher --config-file=mypy.ini --xslt-html-report ./mypy_reports/html/ --linecount-report ./mypy_reports/linecount || true - store_artifacts: path: ./mypy_reports estimate_gas: <<: *python_36_base steps: - checkout - attach_workspace: at: ~/.local/share/virtualenvs/ - run: name: Estimate Gas command: | pipenv run python tests/metrics/estimate_gas.py - store_artifacts: path: tests/metrics/results/ build_docs: <<: *python_36_base steps: - checkout - attach_workspace: at: ~/.local/share/virtualenvs/ - run: name: Install Documentation Build Dependencies command: pip3 install --user sphinx recommonmark sphinx-rtd-theme - run: name: Build Sphinx Documentation command: | cd docs make html - store_artifacts: path: docs/build test_build: <<: *python_36_base steps: - checkout - pip_install - run: name: Install Twine command: pip install --user twine - run: name: Build Python Distribution Wheel command: | pipenv run python setup.py sdist pipenv run python setup.py bdist_wheel build_docker: working_directory: ~/nucypher docker: - image: docker:18.06.1-ce-git steps: - checkout - setup_remote_docker - restore_cache: keys: - v1-{{ .Branch }} paths: - ~/docker/nucypher.tar - run: name: Load Docker Image Layer Cache command: | set +o pipefail docker load -i ~/docker/nucypher.tar | true - run: name: Build Docker Image command: | docker build -f deploy/docker/Dockerfile --cache-from=nucypher -t nucypher/nucypher:$CIRCLE_TAG . - run: name: Save Docker Image Layer Cache command: | mkdir -p ~/docker docker save -o ~/docker/nucypher.tar nucypher/nucypher:$CIRCLE_TAG - save_cache: key: v1-{{ .Branch }}-{{ epoch }} paths: - ~/docker/nucypher.tar test_deploy: <<: *python_36_base steps: - checkout - pip_install - run: name: Install Twine command: pip3 install --user twine - run: name: Verify git tag == __version__ (Test Deploy) command: python setup.py verify - run: name: Initialize .pypirc (Test Deploy) command: | echo -e "[distutils]" >> ~/.pypirc echo -e "index-servers = " >> ~/.pypirc echo -e " pypi" >> ~/.pypirc echo -e " testpypi" >> ~/.pypirc echo -e "" >> ~/.pypirc echo -e "[testpypi]" >> ~/.pypirc echo -e "repository: https://test.pypi.org/legacy/" >> ~/.pypirc echo -e "username: $TEST_PYPI_USERNAME" >> ~/.pypirc echo -e "password: $TEST_PYPI_PASSWORD" >> ~/.pypirc - run: name: Build Python Wheel (Test Deploy) command: | python3 setup.py sdist python3 setup.py bdist_wheel - run: name: upload to TestPyPI command: python3 -m twine upload --repository testpypi dist/* --verbose - run: name: pip install from TestPyPI command: | pip3 install --user --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple nucypher --verbose python3 -c "import nucypher; print(nucypher.__version__)" publish_pypi: <<: *python_36_base steps: - checkout - pip_install - run: name: Install Twine command: pip3 install --user twine - run: name: Verify git tag == __version__ command: python3 setup.py verify - run: name: Initialize .pypirc command: | echo -e "[distutils]" >> ~/.pypirc echo -e "index-servers = " >> ~/.pypirc echo -e " pypi" >> ~/.pypirc echo -e "" >> ~/.pypirc echo -e "[pypi]" >> ~/.pypirc echo -e "username = $PYPI_USERNAME" >> ~/.pypirc echo -e "password = $PYPI_PASSWORD" >> ~/.pypirc - run: name: Build Python Wheel command: | python3 setup.py sdist python3 setup.py bdist_wheel - deploy: name: Upload to PyPI command: python3 -m twine upload dist/* --verbose publish_docker: working_directory: ~/nucypher docker: - image: docker:18.06.1-ce-git steps: - checkout - setup_remote_docker - restore_cache: keys: - v1-{{ .Branch }} paths: - ~/docker/nucypher.tar - run: name: Load Docker Image Layer Cache command: | set +o pipefail docker load -i ~/docker/nucypher.tar | true - deploy: name: Push NuCypher Docker Image command: | echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin docker push nucypher/nucypher:$CIRCLE_TAG