diff --git a/dev_tools/packaging/produce-package.sh b/dev_tools/packaging/produce-package.sh new file mode 100755 index 0000000..bec6cb2 --- /dev/null +++ b/dev_tools/packaging/produce-package.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +# Copyright 2018 The OpenFermion Developers +# +# 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 +# +# https://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. + +################################################################################ +# Produces wheels that can be uploaded to the pypi package repository. +# +# First argument must be the output directory. Second argument is an optional +# version specifier. If not set, the version from `_version.py` is used. If set, +# it overwrites `_version.py`. +# +# Usage: +# dev_tools/packaging/produce-package.sh output_dir [version] +################################################################################ + +PROJECT_NAME=openfermionpyscf + +set -e + +if [ -z "${1}" ]; then + echo -e "\e[31mNo output directory given.\e[0m" + exit 1 +fi +out_dir=$(realpath "${1}") + +SPECIFIED_VERSION="${2}" + +# Get the working directory to the repo root. +cd "$( dirname "${BASH_SOURCE[0]}" )" +repo_dir=$(git rev-parse --show-toplevel) +cd ${repo_dir} + +# Make a clean copy of HEAD, without files ignored by git (but potentially kept by setup.py). +if [ ! -z "$(git status --short)" ]; then + echo -e "\e[31mWARNING: You have uncommitted changes. They won't be included in the package.\e[0m" +fi +tmp_git_dir=$(mktemp -d "/tmp/produce-package-git.XXXXXXXXXXXXXXXX") +trap "{ rm -rf ${tmp_git_dir}; }" EXIT +cd "${tmp_git_dir}" +git init --quiet +git fetch ${repo_dir} HEAD --quiet --depth=1 +git checkout FETCH_HEAD -b work --quiet +if [ ! -z "${SPECIFIED_VERSION}" ]; then + echo '__version__ = "'"${SPECIFIED_VERSION}"'"' > "${tmp_git_dir}/${PROJECT_NAME}/_version.py" +fi + +# Python wheel. +echo "Producing python package files..." +python3 setup.py -q sdist -d "${out_dir}" + +ls "${out_dir}" diff --git a/dev_tools/packaging/publish-dev-package.sh b/dev_tools/packaging/publish-dev-package.sh new file mode 100755 index 0000000..f693688 --- /dev/null +++ b/dev_tools/packaging/publish-dev-package.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash + +# Copyright 2018 The OpenFermion Developers +# +# 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 +# +# https://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. + +################################################################################ +# Produces and uploads dev-version wheels to a pypi package repository. Uploads +# to the test pypi repository unless the --prod switch is added. +# +# The pypi credentials given to twine are specified via environment variables. +# +# Usage: +# export TEST_TWINE_USERNAME=... +# export TEST_TWINE_PASSWORD=... +# export PROD_TWINE_USERNAME=... +# export PROD_TWINE_PASSWORD=... +# dev_tools/packaging/publish-dev-package.sh EXPECTED_VERSION [--test|--prod] +# +# The uploaded package can be installed with pip, but if it's the test version +# then the requirements must be installed separately first (because they do not +# all exist on test pypi). +# +# Prod installation: +# +# pip install openfermionpyscf==VERSION_YOU_UPLOADED +# +# Test installation: +# +# pip install -r requirements.txt +# pip install --index-url https://test.pypi.org/simple/ openfermionpyscf==VERSION_YOU_UPLOADED +################################################################################ + +PROJECT_NAME=openfermionpyscf +set -e +trap "{ echo -e '\e[31mFAILED\e[0m'; }" ERR + +EXPECTED_VERSION=$1 +PROD_SWITCH=$2 + +if [ -z "${EXPECTED_VERSION}" ]; then + echo -e "\e[31mFirst argument must be the expected version.\e[0m" + exit 1 +fi +if [[ "${EXPECTED_VERSION}" != *dev* ]]; then + echo -e "\e[31mExpected version must include 'dev'.\e[0m" + exit 1 +fi +ACTUAL_VERSION_LINE=$(cat "${PROJECT_NAME}/_version.py" | tail -n 1) +if [ "${ACTUAL_VERSION_LINE}" != '__version__ = "'"${EXPECTED_VERSION}"'"' ]; then + echo -e "\e[31mExpected version (${EXPECTED_VERSION}) didn't match the one in ${PROJECT_NAME}/_version.py (${ACTUAL_VERSION_LINE}).\e[0m" + exit 1 +fi + +if [ -z "${PROD_SWITCH}" ] || [ "${PROD_SWITCH}" = "--test" ]; then + PYPI_REPOSITORY_FLAG="--repository-url=https://test.pypi.org/legacy/" + PYPI_REPO_NAME="TEST" + USERNAME="${TEST_TWINE_USERNAME}" + PASSWORD="${TEST_TWINE_PASSWORD}" + if [ -z "${USERNAME}" ]; then + echo -e "\e[31mTEST_TWINE_USERNAME environment variable must be set.\e[0m" + exit 1 + fi + if [ -z "${PASSWORD}" ]; then + echo -e "\e[31mTEST_TWINE_PASSWORD environment variable must be set.\e[0m" + exit 1 + fi +elif [ "${PROD_SWITCH}" = "--prod" ]; then + PYPI_REPOSITORY_FLAG='' + PYPI_REPO_NAME="PROD" + USERNAME="${PROD_TWINE_USERNAME}" + PASSWORD="${PROD_TWINE_PASSWORD}" + if [ -z "${USERNAME}" ]; then + echo -e "\e[31mPROD_TWINE_USERNAME environment variable must be set.\e[0m" + exit 1 + fi + if [ -z "${PASSWORD}" ]; then + echo -e "\e[31mPROD_TWINE_PASSWORD environment variable must be set.\e[0m" + exit 1 + fi +else + echo -e "\e[31mSecond argument must be empty, '--test' or '--prod'.\e[0m" + exit 1 +fi + + +UPLOAD_VERSION="${EXPECTED_VERSION}$(date "+%Y%m%d%H%M%S")" +echo -e "Producing package with version \e[33m\e[100m${UPLOAD_VERSION}\e[0m to upload to \e[33m\e[100m${PYPI_REPO_NAME}\e[0m pypi repository" + +# Get the working directory to the repo root. +cd "$( dirname "${BASH_SOURCE[0]}" )" +cd "$(git rev-parse --show-toplevel)" + +# Temporary workspace. +tmp_package_dir=$(mktemp -d "/tmp/publish-dev-package_package.XXXXXXXXXXXXXXXX") +trap "{ rm -rf ${tmp_package_dir}; }" EXIT + +# Produce packages. +dev_tools/packaging/produce-package.sh "${tmp_package_dir}" "${UPLOAD_VERSION}" +twine upload --username="${USERNAME}" --password="${PASSWORD}" ${PYPI_REPOSITORY_FLAG} "${tmp_package_dir}/*" + +echo -e "\e[32mUploaded package with version ${UPLOAD_VERSION} to ${PYPI_REPO_NAME} pypi repository\e[0m" diff --git a/dev_tools/packaging/verify-published-package.sh b/dev_tools/packaging/verify-published-package.sh new file mode 100755 index 0000000..74f7bfe --- /dev/null +++ b/dev_tools/packaging/verify-published-package.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +# Copyright 2018 The OpenFermion Developers +# +# 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 +# +# https://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. + +################################################################################ +# Downloads and tests openfermionpyscf wheels from the pypi package repository. Uses the +# prod pypi repository unless the --test switch is added. +# +# CAUTION: when targeting the test pypi repository, this script assumes that the +# local version of openfermionpyscf has the same dependencies as the remote one (because the +# dependencies must be installed from the non-test pypi repository). If the +# dependencies disagree, the tests can spuriously fail. +# +# Usage: +# dev_tools/packaging/verify-published-package.sh PACKAGE_VERSION [--test|--prod] +################################################################################ + +set -e +trap "{ echo -e '\e[31mFAILED\e[0m'; }" ERR + + +PROJECT_NAME=openfermionpyscf +PROJECT_VERSION=$1 +PROD_SWITCH=$2 + +if [ -z "${PROJECT_VERSION}" ]; then + echo -e "\e[31mFirst argument must be the package version to test.\e[0m" + exit 1 +fi + +if [ "${PROD_SWITCH}" = "--test" ]; then + PYPI_REPOSITORY_FLAG="--index-url=https://test.pypi.org/simple/" + PYPI_REPO_NAME="TEST" +elif [ -z "${PROD_SWITCH}" ] || [ "${PROD_SWITCH}" = "--prod" ]; then + PYPI_REPOSITORY_FLAG='' + PYPI_REPO_NAME="PROD" +else + echo -e "\e[31mSecond argument must be empty, '--prod' or '--test'.\e[0m" + exit 1 +fi + +# Find the repo root. +cd "$( dirname "${BASH_SOURCE[0]}" )" +REPO_ROOT="$(git rev-parse --show-toplevel)" + +# Temporary workspace. +tmp_dir=$(mktemp -d "/tmp/verify-published-package.XXXXXXXXXXXXXXXX") +cd "${tmp_dir}" +trap "{ rm -rf ${tmp_dir}; }" EXIT + +# Test both the python 2 and python 3 versions. +for PYTHON_VERSION in python2 python3; do + # Prepare. + RUNTIME_DEPS_FILE="${REPO_ROOT}/requirements.txt" + echo -e "\n\e[32m${PYTHON_VERSION}\e[0m" + echo "Working in a fresh virtualenv at ${tmp_dir}/${PYTHON_VERSION}" + virtualenv --quiet "--python=/usr/bin/${PYTHON_VERSION}" "${tmp_dir}/${PYTHON_VERSION}" + + # Install package. + if [ "${PYPI_REPO_NAME}" == "TEST" ]; then + echo "Pre-installing dependencies since they don't all exist in TEST pypi" + "${tmp_dir}/${PYTHON_VERSION}/bin/pip" install --quiet -r "${RUNTIME_DEPS_FILE}" + fi + echo Installing "${PROJECT_NAME}==${PROJECT_VERSION} from ${PYPI_REPO_NAME} pypi" + "${tmp_dir}/${PYTHON_VERSION}/bin/pip" install --quiet ${PYPI_REPOSITORY_FLAG} "${PROJECT_NAME}==${PROJECT_VERSION}" + + # Run tests. + echo Installing pytest + "${tmp_dir}/${PYTHON_VERSION}/bin/pip" install --quiet pytest + PY_VER=$(ls "${tmp_dir}/${PYTHON_VERSION}/lib") + echo Running tests + "${tmp_dir}/${PYTHON_VERSION}/bin/pytest" --quiet --disable-pytest-warnings "${tmp_dir}/${PYTHON_VERSION}/lib/${PY_VER}/site-packages/${PROJECT_NAME}" +done + +echo +echo -e '\e[32mVERIFIED\e[0m' diff --git a/openfermionpyscf/_version.py b/openfermionpyscf/_version.py index b89ff0f..7e5facc 100644 --- a/openfermionpyscf/_version.py +++ b/openfermionpyscf/_version.py @@ -11,4 +11,4 @@ # limitations under the License. """Define version number here and read it from setup.py automatically""" -__version__ = "0.3" +__version__ = "0.4.dev"