Newer
Older
# 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.
aliases:
- &PREPARE_VIRTUALENV
run:
name: "Prepare virtualenv"
command: |
virtualenv venv
. venv/bin/activate
pip install --upgrade certifi pip
pip install ${PIP_REQUIREMENTS}
documentation:
docker:
- image: "circleci/python:3.7"
environment:
PIP_REQUIREMENTS: "-r docs/requirements.txt"
steps:
- "checkout"
- <<: *PREPARE_VIRTUALENV
- run:
name: "Sphinx Documentation Build"
command: |
sphinx-build docs/source docs/build
- store_artifacts:
path: "docs/build"
destination: "docs"
parameters:
py-version:
type: "string"
xcode-version:
type: "string"
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: |
# The CircleCI macOS environment has curl and Python but does not
# have pip. So, for starters, use curl and Python to get pip.
if [ "<< parameters.py-version >>" == "2.7" ]; then
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py
else
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
fi
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
- 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"
# Run in a highly Nix-capable environment.
- image: "nixorg/nix:circleci"
environment:
# Specify a revision of PrivateStorageio/nixpkgs to run against. This
# essentially pins the majority of the software involved in the build.
# This revision is selected arbitrarily (it's just new enough to define
# all of the PrivateStorage stuff that ZKAPAuthorizer depends on). It's
# somewhat current as of the time of this comment. We can bump it to a
# newer version when that makes sense. Meanwhile, the platform won't
# shift around beneath us unexpectedly.
NIXPKGS_REV: "730129887a84a8f84f3b78ffac7add72aeb551b6"
- run:
# Get NIX_PATH set for the rest of the job so that the revision of
# nixpkgs we selected will be used everywhere Nix pulls in software.
# There is no way to set an environment variable containing the
# value of another environment variable on CircleCI except to use
# the `BASE_ENV` feature as we do here.
name: "Setup NIX_PATH Environment Variable"
command: |
echo "export NIX_PATH=nixpkgs=https://github.com/PrivateStorageio/nixpkgs/archive/$NIXPKGS_REV.tar.gz" >> $BASH_ENV
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
- "run":
# CircleCI won't let us interpolate NIXPKGS_REV into a cache key.
# Only CircleCI's own environment variables or variables set via the
# web interface in a "context" can be interpolated into cache keys.
# However, we can interpolate the checksum of a file... Since we
# don't care about the exact revision, we just care that a new
# revision gives us a new string, we can write the revision to a
# file and then put the checksum of that file into the cache key.
# This way, we don't have to maintain the nixpkgs revision in two
# places and risk having them desynchronize.
name: "Prepare For Cache Key"
command: |
echo "${NIXPKGS_REV}" > nixpkgs.rev
- restore_cache:
# Get all of Nix's state relating to the particular revision of
# nixpkgs we're using. It will always be the same. CircleCI
# artifacts and nixpkgs store objects are probably mostly hosted in
# the same place (S3) so there's not a lot of difference for
# anything that's pre-built. For anything we end up building
# ourselves, though, this saves us all of the build time (less the
# download time).
#
# Read about caching dependencies: https://circleci.com/docs/2.0/caching/
name: "Restore Nix Store Paths"
keys:
# Construct cache keys that allow sharing as long as nixpkgs
# revision is unchanged.
#
# If nixpkgs changes then potentially a lot of cached packages for
# the base system will be invalidated so we may as well drop them
# and make a new cache with the new packages.
- zkapauthorizer-nix-store-v4-{{ checksum "nixpkgs.rev" }}-ourdeps
- zkapauthorizer-nix-store-v4-{{ checksum "nixpkgs.rev" }}-
- zkapauthorizer-nix-store-v4-
- run:
name: "Build challenge-bypass-ristretto"
command: |
# Pre-build this because doing so is somewhat memory intensive and
# we want to turn off concurrency for this part. We want to be
# able to leave concurrency on for the rest of the build, though,
# where it doesn't cause problems and speeds things up.
nix-build --cores 1 --max-jobs 1 \
--arg callPackage '(import <nixpkgs> { }).callPackage' \
./python-challenge-bypass-ristretto.nix
- save_cache:
name: "Cache Nix Store Paths"
key: zkapauthorizer-nix-store-v4-{{ checksum "nixpkgs.rev" }}
paths:
- "/nix"
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 \
--argstr hypothesisProfile ci \
--arg collectCoverage true \
--attr doc
- save_cache:
name: "Cache Nix Store Paths"
key: zkapauthorizer-nix-store-v4-{{ checksum "nixpkgs.rev" }}-ourdeps
paths:
- "/nix"
name: "Report Coverage"
command: |
./.circleci/report-coverage.sh
# A variation of linux-tests that is only run once a week and is given
# enough resources that it can build not only ZKAPAuthorizer but all its
# dependencies within the limited time period imposed by CircleCI.
linux-tests-big:
# Everything is the same as the linux-tests job ...
<<: *LINUX_TESTS
# ... except more resources from the platform.
resource_class: "xlarge"
workflows:
version: 2
everything:
jobs:
- "macos-tests":
matrix:
parameters:
py-version:
- "2.7"
xcode-version:
# https://circleci.com/docs/2.0/testing-ios/#supported-xcode-versions
- "12.3.0"
- "11.7.0"
refresh-cache:
jobs:
- "linux-tests-big"
triggers:
- schedule:
# Run the job once a week. CircleCI caches expired after 15 days so
# this should always keep the latest version of our cache fresh and
# prevent us from actually having to rebuild it very often.
#
# https://circleci.com/docs/2.0/workflows/#specifying-a-valid-schedule
filters:
branches:
only:
- "master"