# Copyright 2019 PrivateStorage.io, LLC # # 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. version: 2.1 aliases: - &PREPARE_VIRTUALENV run: name: "Prepare virtualenv" command: | virtualenv venv . venv/bin/activate pip install --upgrade certifi pip pip install ${PIP_REQUIREMENTS} jobs: documentation: docker: - image: "circleci/python:3.7" environment: PIP_REQUIREMENTS: "-r docs/requirements.txt" steps: - "checkout" - <<: *PREPARE_VIRTUALENV - run: name: "Sphinx Documentation Build" command: | . venv/bin/activate sphinx-build docs/source docs/build - store_artifacts: path: "docs/build" destination: "docs" macos-tests: parameters: py-version: type: "string" xcode-version: type: "string" macos: xcode: << parameters.xcode-version >> steps: - "checkout" - restore_cache: keys: # when setup.cfg changes, use increasingly general patterns to # restore cache - pip-packages-v1-{{ .Branch }}-{{ checksum "setup.cfg" }} - pip-packages-v1-{{ .Branch }}- - pip-packages-v1- - run: name: "Get Pip" command: | curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py python<< parameters.py-version >> get-pip.py - run: name: "Create Virtualenv" command: | # The CircleCI macOS Python environment has some Python libraries # in it which conflict with ZKAPAuthorizer's requirements. So # install virtualenv and use it to create an environment for # ZKAPAuthorizer so it can have all its own versions of its # dependencies. python<< parameters.py-version >> -m pip install virtualenv # Make sure virtualenv creates a Python 2 environment! virtualenv --python=python<< parameters.py-version >> venv # Get the newest pip we can because who knows what came along with # that virtualenv. venv/bin/pip install --find-links file://${PWD}/wheelhouse --upgrade pip - run: name: "Populate Wheelhouse" command: | # Get wheels for all the Python packages we depend on - either # directly via the ZKAPAuthorizer distutils configuration *or* # because some other tool depends on it. For example, pip has a # bunch of dependencies it is nice to have around, and using the # wheels depends on the wheel package. venv/bin/pip wheel --wheel-dir wheelhouse pip wheel .[test] - save_cache: paths: - "wheelhouse" key: pip-packages-v1-{{ .Branch }}-{{ checksum "setup.cfg" }} - run: name: "Install" command: | # Now we can install ZKAPAuthorizer and its dependencies and test # dependencies into the environment. venv/bin/pip install --no-index --find-links file://${PWD}/wheelhouse .[test] - run: name: "Test" command: | # The test suite might leak file descriptors. macOS defaults to a # limit of 256. This should be fixed, but not now ... ulimit -Sn 1024 # And finally we can run the tests. We'll run them with 4 jobs # because the resource class documented at # https://support.circleci.com/hc/en-us/articles/360009144794-macOS-resources # says "Medium: 4 vCPUs, 8GB RAM". venv/bin/python -m twisted.trial --jobs 4 --rterrors _zkapauthorizer environment: ZKAPAUTHORIZER_HYPOTHESIS_PROFILE: "ci" linux-tests: &LINUX_TESTS parameters: py-version: type: "string" tahoe-lafs-source: # The name of a niv source in nix/sources.json which corresponds to # a Tahoe-LAFS version. This is the version that will be declared as a # dependency of the Nix package of ZKAPAuthorizer (and therefore used # in the test run and pulled in should you install this package). type: "string" docker: # Run in a highly Nix-capable environment. We used to use `latest` but # one day someone pushed a bad revision to it and our CI broke. So now # we just pin some recent version. Who would have thought a floating # dependency would cause build instability? - image: "nixos/nix:2.5.1" # Tahoe-LAFS requires more memory than we get from the default resource # class and sometimes we have to build it. resource_class: "large" environment: # CACHIX_AUTH_TOKEN is manually set in the CircleCI web UI and allows us to push to CACHIX_NAME. CACHIX_NAME: "privatestorage-opensource" # Let us use features marked "experimental". For example, most/all of # the `nix <subcommand>` forms. NIX_CONFIG: "experimental-features = nix-command" # Pin a NixOS 21.11 revision. Most of the software involved in the # build process is pinned by nix/sources.json with niv but a few things # need to work before we get that far. This pin is for those things. # This pin has no particular bearing on what version of our dependencies # we are testing against, what version of Python we support, etc. It is # part of CI infrastructure. NIXPKGS: "https://github.com/NixOS/nixpkgs/archive/28abc4e43a24d28729509e2d83f5c4f3b3418189.tar.gz" steps: - run: # Work around a bug in the 2.5.1 Docker image that prevents it from # having any CA certificates to use to validate any certificates it # encounters (and thus makes it incapable of talking to our binary # caches). # # The work-around is from a comment on the issue # https://github.com/NixOS/nix/issues/5797 name: "Fix CA Certificates" command: | mkdir -p /etc/ssl/certs/ ln -s $NIX_SSL_CERT_FILE /etc/ssl/certs/ - run: name: "Set up Cachix" command: | nix-env -f $NIXPKGS -iA cachix bash cachix use "${CACHIX_NAME}" nix path-info --all > /tmp/store-path-pre-build - "checkout" - run: name: "Run Test Suite" command: | # Building the package has, as a side effect, running the test # suite. If the test suite fails, so does the build. # # Pass in a couple args here to control how the test suite is run # - configure Hypothesis so it can behave appropriately in a CI # environment (where resources are scarce, competetion with other # tenants is high, etc) and collect coverage information. # # Further, we want the "doc" output built as well because that's # where the coverage data ends up. nix-build tests.nix \ --argstr hypothesisProfile ci \ --arg collectCoverage true \ --argstr tahoe-lafs-source << parameters.tahoe-lafs-source >> \ --argstr python python<< parameters.py-version >> - run: name: "Push to Cachix" when: "always" command: | # Cribbed from # https://circleci.com/blog/managing-secrets-when-you-have-pull-requests-from-outside-contributors/ if [ -n "$CIRCLE_PR_NUMBER" ]; then # I'm sure you're thinking "CIRCLE_PR_NUMBER must just be the # number of the PR being built". Sorry, dear reader, you have # guessed poorly. It is also conditionally set based on whether # this is a PR from a fork or not. # # https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables echo "Skipping Cachix push for forked PR." else # https://docs.cachix.org/continuous-integration-setup/circleci.html bash -c "comm -13 <(sort /tmp/store-path-pre-build | grep -v '\.drv$') <(nix path-info --all | grep -v '\.drv$' | sort) | cachix push $CACHIX_NAME" fi - run: name: "Report Coverage" command: | ./.circleci/report-coverage.sh workflows: version: 2 everything: jobs: - "documentation" - "linux-tests": name: "Linux tests python 3.9" py-version: "39" tahoe-lafs-source: "tahoe-lafs" - "linux-tests": name: "Linux tests python 3.9, Tahoe-LAFS master" py-version: "39" # This is usually not master@HEAD because it is still pinned to a # certain revision. The intent is to update it frequently and # discover fixable incompatibilities in small groups and unfixable # incompatibilities early enough to prevent them from going into a # release. tahoe-lafs-source: "tahoe-lafs-master" # https://circleci.com/docs/2.0/testing-ios/#supported-xcode-versions - "macos-tests": name: "macOS tests python 3.8 xcode 11.7.0" py-version: "3.8" xcode-version: "11.7.0" - "macos-tests": name: "macOS tests python 3.9 xcode 12.3.0" py-version: "3.9" xcode-version: "12.3.0"