mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-26 02:43:43 +03:00
Merge branch 'packages'
This commit is contained in:
commit
06c3c3a557
88
.appveyor/packages.yml
Normal file
88
.appveyor/packages.yml
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
version : 2.x.{build}
|
||||||
|
|
||||||
|
clone_folder: C:\Project
|
||||||
|
|
||||||
|
# We use the configuration to specify the package name
|
||||||
|
configuration:
|
||||||
|
- psycopg2
|
||||||
|
- psycopg2-binary
|
||||||
|
|
||||||
|
environment:
|
||||||
|
matrix:
|
||||||
|
# For Python versions available on Appveyor, see
|
||||||
|
# https://www.appveyor.com/docs/windows-images-software/#python
|
||||||
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019, PY_VER: "39", PY_ARCH: "32"}
|
||||||
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019, PY_VER: "39", PY_ARCH: "64"}
|
||||||
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "38", PY_ARCH: "32"}
|
||||||
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "38", PY_ARCH: "64"}
|
||||||
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "37", PY_ARCH: "32"}
|
||||||
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "37", PY_ARCH: "64"}
|
||||||
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "36", PY_ARCH: "32"}
|
||||||
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "36", PY_ARCH: "64"}
|
||||||
|
|
||||||
|
WORKFLOW: packages
|
||||||
|
|
||||||
|
OPENSSL_VERSION: "1_1_1h"
|
||||||
|
POSTGRES_VERSION: "13_0"
|
||||||
|
|
||||||
|
PSYCOPG2_TESTDB: psycopg2_test
|
||||||
|
PSYCOPG2_TESTDB_USER: postgres
|
||||||
|
PSYCOPG2_TESTDB_HOST: localhost
|
||||||
|
|
||||||
|
PGUSER: postgres
|
||||||
|
PGPASSWORD: Password12!
|
||||||
|
PGSSLMODE: require
|
||||||
|
|
||||||
|
# Add CWD to perl library path for PostgreSQL build on VS2019
|
||||||
|
PERL5LIB: .
|
||||||
|
|
||||||
|
# Select according to the service enabled
|
||||||
|
POSTGRES_DIR: C:\Program Files\PostgreSQL\9.6\
|
||||||
|
|
||||||
|
# The python used in the build process, not the one packages are built for
|
||||||
|
PYEXE: C:\Python36\python.exe
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
fast_finish: false
|
||||||
|
|
||||||
|
services:
|
||||||
|
# Note: if you change this service also change POSTGRES_DIR
|
||||||
|
- postgresql96
|
||||||
|
|
||||||
|
cache:
|
||||||
|
# Rebuild cache if following file changes
|
||||||
|
# (See the file to zap the cache manually)
|
||||||
|
- C:\Others -> scripts\appveyor.cache_rebuild
|
||||||
|
|
||||||
|
# Script called before repo cloning
|
||||||
|
# init:
|
||||||
|
|
||||||
|
# Repository gets cloned, Cache is restored
|
||||||
|
|
||||||
|
install:
|
||||||
|
- "%PYEXE% scripts\\appveyor.py install"
|
||||||
|
|
||||||
|
# PostgreSQL server starts now
|
||||||
|
|
||||||
|
build: off
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- "%PYEXE% scripts\\appveyor.py build_script"
|
||||||
|
|
||||||
|
after_build:
|
||||||
|
- "%PYEXE% scripts\\appveyor.py after_build"
|
||||||
|
|
||||||
|
before_test:
|
||||||
|
- "%PYEXE% scripts\\appveyor.py before_test"
|
||||||
|
|
||||||
|
test_script:
|
||||||
|
- "%PYEXE% scripts\\appveyor.py test_script"
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
- path: dist\psycopg2-*\*.whl
|
||||||
|
name: wheel
|
||||||
|
- path: dist\psycopg2-*\*.exe
|
||||||
|
name: exe
|
||||||
|
|
||||||
|
|
||||||
|
# vim: set ts=4 sts=4 sw=4:
|
|
@ -3,11 +3,6 @@ version : 2.x.{build}
|
||||||
clone_folder: C:\Project
|
clone_folder: C:\Project
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
global:
|
|
||||||
# MSVC Express 2008's setenv.cmd failes if /E:ON and /V:ON are not
|
|
||||||
# enabled in the batch script interpreter
|
|
||||||
CMD_IN_ENV: cmd /E:ON /V:ON /C .\appveyor\run_with_env.cmd
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
# For Python versions available on Appveyor, see
|
# For Python versions available on Appveyor, see
|
||||||
# https://www.appveyor.com/docs/windows-images-software/#python
|
# https://www.appveyor.com/docs/windows-images-software/#python
|
||||||
|
@ -20,6 +15,8 @@ environment:
|
||||||
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "36", PY_ARCH: "32"}
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "36", PY_ARCH: "32"}
|
||||||
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "36", PY_ARCH: "64"}
|
- {APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015, PY_VER: "36", PY_ARCH: "64"}
|
||||||
|
|
||||||
|
WORKFLOW: tests
|
||||||
|
|
||||||
OPENSSL_VERSION: "1_1_1h"
|
OPENSSL_VERSION: "1_1_1h"
|
||||||
POSTGRES_VERSION: "13_0"
|
POSTGRES_VERSION: "13_0"
|
||||||
|
|
87
.github/workflows/packages.yml
vendored
87
.github/workflows/packages.yml
vendored
|
@ -50,3 +50,90 @@ jobs:
|
||||||
--health-interval 10s
|
--health-interval 10s
|
||||||
--health-timeout 5s
|
--health-timeout 5s
|
||||||
--health-retries 5
|
--health-retries 5
|
||||||
|
|
||||||
|
|
||||||
|
build-manylinux_2_24:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- platform: manylinux_2_24_x86_64
|
||||||
|
- platform: manylinux_2_24_i686
|
||||||
|
- platform: manylinux_2_24_aarch64
|
||||||
|
- platform: manylinux_2_24_ppc64le
|
||||||
|
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout repos
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up QEMU for multi-arch build
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
|
- name: Build packages
|
||||||
|
run: >-
|
||||||
|
docker run --rm
|
||||||
|
-e PLAT=${{ matrix.platform }}
|
||||||
|
-e PACKAGE_NAME=psycopg2-binary
|
||||||
|
-e PYVERS="cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310"
|
||||||
|
-e PSYCOPG2_TESTDB=postgres
|
||||||
|
-e PSYCOPG2_TESTDB_HOST=172.17.0.1
|
||||||
|
-e PSYCOPG2_TESTDB_USER=postgres
|
||||||
|
-e PSYCOPG2_TESTDB_PASSWORD=password
|
||||||
|
-e PSYCOPG2_TEST_FAST=1
|
||||||
|
-v `pwd`:/src
|
||||||
|
--workdir /src
|
||||||
|
quay.io/pypa/${{ matrix.platform }}
|
||||||
|
./scripts/build/build_manylinux_2_24.sh
|
||||||
|
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: packages_${{ matrix.platform }}
|
||||||
|
path: |
|
||||||
|
dist/*/*${{ matrix.platform }}.whl
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgresql:
|
||||||
|
image: postgres:13
|
||||||
|
env:
|
||||||
|
POSTGRES_PASSWORD: password
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
# Set health checks to wait until postgres has started
|
||||||
|
options: >-
|
||||||
|
--health-cmd pg_isready
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 5
|
||||||
|
|
||||||
|
|
||||||
|
build-macos:
|
||||||
|
runs-on: macos-10.15
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
python-version: ['3.6', '3.7', '3.8', '3.9']
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repos
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python-version }}
|
||||||
|
|
||||||
|
- name: Build packages
|
||||||
|
run: ./scripts/build/build_macos.sh
|
||||||
|
env:
|
||||||
|
PACKAGE_NAME: psycopg2-binary
|
||||||
|
PSYCOPG2_TESTDB: postgres
|
||||||
|
PSYCOPG2_TEST_FAST: 1
|
||||||
|
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: packages_macos
|
||||||
|
path: |
|
||||||
|
dist/*/*${{ matrix.platform }}.whl
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -14,3 +14,4 @@ env?
|
||||||
.vscode/
|
.vscode/
|
||||||
/rel
|
/rel
|
||||||
/wheels
|
/wheels
|
||||||
|
/packages
|
||||||
|
|
9
NEWS
9
NEWS
|
@ -4,7 +4,6 @@ Current release
|
||||||
What's new in psycopg 2.9
|
What's new in psycopg 2.9
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
- Dropped support for Python 2.7, 3.4, 3.5 (:tickets:`#1198, #1000, #1197`).
|
|
||||||
- ``with connection`` starts a transaction on autocommit transactions too
|
- ``with connection`` starts a transaction on autocommit transactions too
|
||||||
(:ticket:`#941`).
|
(:ticket:`#941`).
|
||||||
- Escape table and column names in `~cursor.copy_from()` and
|
- Escape table and column names in `~cursor.copy_from()` and
|
||||||
|
@ -12,6 +11,14 @@ What's new in psycopg 2.9
|
||||||
- Connection exceptions with sqlstate ``08XXX`` reclassified as
|
- Connection exceptions with sqlstate ``08XXX`` reclassified as
|
||||||
`~psycopg2.OperationalError` (a subclass of the previously used
|
`~psycopg2.OperationalError` (a subclass of the previously used
|
||||||
`~psycopg2.DatabaseError`) (:ticket:`#1148`).
|
`~psycopg2.DatabaseError`) (:ticket:`#1148`).
|
||||||
|
- Include library dirs required from libpq to work around MacOS build problems
|
||||||
|
(:ticket:`#1200`).
|
||||||
|
|
||||||
|
Other changes:
|
||||||
|
|
||||||
|
- Dropped support for Python 2.7, 3.4, 3.5 (:tickets:`#1198, #1000, #1197`).
|
||||||
|
- Build system for Linux/MacOS binary packages moved to GitHub action, now
|
||||||
|
providing :pep:`600`\-style wheels packages.
|
||||||
|
|
||||||
|
|
||||||
What's new in psycopg 2.8.7
|
What's new in psycopg 2.8.7
|
||||||
|
|
|
@ -15,24 +15,12 @@ How to make a psycopg2 release
|
||||||
|
|
||||||
$ export VERSION=2.8.4
|
$ export VERSION=2.8.4
|
||||||
|
|
||||||
- In the `Travis settings`__ you may want to be sure that the variables
|
- Push psycopg2 to master or to the maint branch. Make sure tests on `GitHub
|
||||||
``TEST_PAST`` and ``TEST_FUTURE`` are set to 1 to check all
|
Actions`__ and AppVeyor__ pass.
|
||||||
the supported postgres version.
|
|
||||||
|
|
||||||
.. __: https://travis-ci.org/psycopg/psycopg2/settings
|
.. __: https://github.com/psycopg/psycopg2/actions/workflows/tests.yml
|
||||||
|
|
||||||
- Push psycopg2 to master or to the maint branch. Make sure tests on Travis__
|
|
||||||
and AppVeyor__ pass.
|
|
||||||
|
|
||||||
.. __: https://travis-ci.org/psycopg/psycopg2
|
|
||||||
.. __: https://ci.appveyor.com/project/psycopg/psycopg2
|
.. __: https://ci.appveyor.com/project/psycopg/psycopg2
|
||||||
|
|
||||||
- For an extra test merge or rebase the `test_i686`__ branch on the commit to
|
|
||||||
release and push it too: this will test with Python 32 bits and debug
|
|
||||||
versions.
|
|
||||||
|
|
||||||
.. __: https://github.com/psycopg/psycopg2/tree/test_i686
|
|
||||||
|
|
||||||
- Create a signed tag with the content of the relevant NEWS bit and push it.
|
- Create a signed tag with the content of the relevant NEWS bit and push it.
|
||||||
E.g.::
|
E.g.::
|
||||||
|
|
||||||
|
@ -49,34 +37,31 @@ How to make a psycopg2 release
|
||||||
- Fixed bug blah (:ticket:`#42`).
|
- Fixed bug blah (:ticket:`#42`).
|
||||||
...
|
...
|
||||||
|
|
||||||
- Update the `psycopg2-wheels`_ submodule to the tag version and push. This
|
- Create the packages:
|
||||||
will build the packages on `Travis CI`__ and `AppVeyor`__ and upload them to
|
|
||||||
https://upload.psycopg.org/.
|
|
||||||
|
|
||||||
.. _psycopg2-wheels: https://github.com/psycopg/psycopg2-wheels
|
- On GitHub Actions run manually a `package build workflow`__.
|
||||||
.. __: https://travis-ci.org/psycopg/psycopg2-wheels
|
|
||||||
.. __: https://ci.appveyor.com/project/psycopg/psycopg2-wheels
|
|
||||||
|
|
||||||
- Download the packages generated (this assumes ssh configured properly)::
|
- On Appveyor change the `build settings`__ and replace the custom
|
||||||
|
configuration file name from ``.appveyor/tests.yml`` to
|
||||||
|
``.appveyor/packages.yml`` (yeah, that sucks a bit. Remember to put it
|
||||||
|
back to testing).
|
||||||
|
|
||||||
$ rsync -arv psycopg-upload:psycopg2-${VERSION} .
|
.. __: https://github.com/psycopg/psycopg2/actions/workflows/packages.yml
|
||||||
|
.. __: https://ci.appveyor.com/project/psycopg/psycopg2/settings
|
||||||
|
|
||||||
- Sign the packages and upload the signatures back::
|
- When the workflows have finished download the packages using the
|
||||||
|
``download_packages.py`` and ``download_packages_appveyor.py`` scripts from
|
||||||
$ for f in psycopg2-${VERSION}/*.{exe,tar.gz,whl}; do \
|
the ``scripts/build`` directory. They will be saved in a
|
||||||
gpg --armor --detach-sign $f;
|
``psycopg2-${VERSION}`` directory.
|
||||||
done
|
|
||||||
|
|
||||||
$ rsync -arv psycopg2-${VERSION} psycopg-upload:
|
|
||||||
|
|
||||||
- Remove the ``.exe`` from the dir, because we don't want to upload them on
|
- Remove the ``.exe`` from the dir, because we don't want to upload them on
|
||||||
PyPI::
|
PyPI::
|
||||||
|
|
||||||
$ rm -v psycopg2-${VERSION}/*.exe{,.asc}
|
$ rm -v psycopg2-${VERSION}/*.exe
|
||||||
|
|
||||||
- Only for stable packages: upload the packages and signatures on PyPI::
|
- Only for stable packages: upload the signed packages on PyPI::
|
||||||
|
|
||||||
$ twine upload psycopg2-${VERSION}/*
|
$ twine upload -s psycopg2-${VERSION}/*
|
||||||
|
|
||||||
- Create a release and release notes in the psycopg website, announce to
|
- Create a release and release notes in the psycopg website, announce to
|
||||||
psycopg and pgsql-announce mailing lists.
|
psycopg and pgsql-announce mailing lists.
|
||||||
|
@ -89,7 +74,7 @@ Releasing test packages
|
||||||
|
|
||||||
Test packages may be uploaded on the `PyPI testing site`__ using::
|
Test packages may be uploaded on the `PyPI testing site`__ using::
|
||||||
|
|
||||||
$ twine upload -r testpypi psycopg2-${VERSION}/*
|
$ twine upload -s -r testpypi psycopg2-${VERSION}/*
|
||||||
|
|
||||||
assuming `proper configuration`__ of ``~/.pypirc``.
|
assuming `proper configuration`__ of ``~/.pypirc``.
|
||||||
|
|
||||||
|
|
|
@ -699,13 +699,8 @@ class Options:
|
||||||
@property
|
@property
|
||||||
def is_wheel(self):
|
def is_wheel(self):
|
||||||
"""Are we building the wheel packages or just the extension?"""
|
"""Are we building the wheel packages or just the extension?"""
|
||||||
project_name = os.environ['APPVEYOR_PROJECT_NAME']
|
workflow = os.environ["WORKFLOW"]
|
||||||
if project_name == 'psycopg2':
|
return workflow == "packages"
|
||||||
return False
|
|
||||||
elif project_name == 'psycopg2-wheels':
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
raise Exception(f"unexpected project name: {project_name}")
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def py_dir(self):
|
def py_dir(self):
|
||||||
|
@ -801,12 +796,7 @@ class Options:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def package_dir(self):
|
def package_dir(self):
|
||||||
"""
|
return self.clone_dir
|
||||||
The directory containing the psycopg code checkout dir.
|
|
||||||
|
|
||||||
Building psycopg it is clone_dir, building the wheels it is a submodule.
|
|
||||||
"""
|
|
||||||
return self.clone_dir / 'psycopg2' if self.is_wheel else self.clone_dir
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dist_dir(self):
|
def dist_dir(self):
|
||||||
|
|
77
scripts/build/build_macos.sh
Executable file
77
scripts/build/build_macos.sh
Executable file
|
@ -0,0 +1,77 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Create macOS wheels for psycopg2
|
||||||
|
#
|
||||||
|
# Following instructions from https://github.com/MacPython/wiki/wiki/Spinning-wheels
|
||||||
|
# Cargoculting pieces of implementation from https://github.com/matthew-brett/multibuild
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
set -x
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
PRJDIR="$( cd "${DIR}/../.." && pwd )"
|
||||||
|
|
||||||
|
brew install gnu-sed postgresql@13
|
||||||
|
|
||||||
|
# Start the database for testing
|
||||||
|
brew services start postgresql
|
||||||
|
|
||||||
|
for i in $(seq 10 -1 0); do
|
||||||
|
eval pg_isready && break
|
||||||
|
if [ $i == 0 ]; then
|
||||||
|
echo "PostgreSQL service not ready, giving up"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "PostgreSQL service not ready, waiting a bit, attempts left: $i"
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
|
||||||
|
# Find psycopg version
|
||||||
|
VERSION=$(grep -e ^PSYCOPG_VERSION "${PRJDIR}/setup.py" | gsed "s/.*'\(.*\)'/\1/")
|
||||||
|
# A gratuitous comment to fix broken vim syntax file: '")
|
||||||
|
DISTDIR="${PRJDIR}/dist/psycopg2-$VERSION"
|
||||||
|
mkdir -p "$DISTDIR"
|
||||||
|
|
||||||
|
# Install required python packages
|
||||||
|
pip install -U pip wheel delocate
|
||||||
|
|
||||||
|
# Replace the package name
|
||||||
|
gsed -i "s/^setup(name=\"psycopg2\"/setup(name=\"${PACKAGE_NAME}\"/" \
|
||||||
|
"${PRJDIR}/setup.py"
|
||||||
|
|
||||||
|
# Build the wheels
|
||||||
|
WHEELDIR="${PRJDIR}/wheels"
|
||||||
|
pip wheel -w ${WHEELDIR} .
|
||||||
|
delocate-listdeps ${WHEELDIR}/*.whl
|
||||||
|
|
||||||
|
# Check where is the libpq. I'm gonna kill it for testing
|
||||||
|
if [[ -z "${LIBPQ:-}" ]]; then
|
||||||
|
export LIBPQ=$(delocate-listdeps ${WHEELDIR}/*.whl | grep libpq)
|
||||||
|
fi
|
||||||
|
|
||||||
|
delocate-wheel ${WHEELDIR}/*.whl
|
||||||
|
# https://github.com/MacPython/wiki/wiki/Spinning-wheels#question-will-pip-give-me-a-broken-wheel
|
||||||
|
delocate-addplat --rm-orig -x 10_9 -x 10_10 ${WHEELDIR}/*.whl
|
||||||
|
cp ${WHEELDIR}/*.whl ${DISTDIR}
|
||||||
|
|
||||||
|
# kill the libpq to make sure tests don't depend on it
|
||||||
|
mv "$LIBPQ" "${LIBPQ}-bye"
|
||||||
|
|
||||||
|
# Install and test the built wheel
|
||||||
|
pip install ${PACKAGE_NAME} --no-index -f "$DISTDIR"
|
||||||
|
|
||||||
|
# Print psycopg and libpq versions
|
||||||
|
python -c "import psycopg2; print(psycopg2.__version__)"
|
||||||
|
python -c "import psycopg2; print(psycopg2.__libpq_version__)"
|
||||||
|
python -c "import psycopg2; print(psycopg2.extensions.libpq_version())"
|
||||||
|
|
||||||
|
# fail if we are not using the expected libpq library
|
||||||
|
# Disabled as we just use what's available on the system on macOS
|
||||||
|
# if [[ "${WANT_LIBPQ:-}" ]]; then
|
||||||
|
# python -c "import psycopg2, sys; sys.exit(${WANT_LIBPQ} != psycopg2.extensions.libpq_version())"
|
||||||
|
# fi
|
||||||
|
|
||||||
|
python -c "import tests; tests.unittest.main(defaultTest='tests.test_suite')"
|
||||||
|
|
||||||
|
# just because I'm a boy scout
|
||||||
|
mv "${LIBPQ}-bye" "$LIBPQ"
|
75
scripts/build/build_manylinux_2_24.sh
Executable file
75
scripts/build/build_manylinux_2_24.sh
Executable file
|
@ -0,0 +1,75 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Create manylinux_2_24 wheels for psycopg2
|
||||||
|
#
|
||||||
|
# Look at the .github/workflows/packages.yml file for hints about how to use it.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
set -x
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
PRJDIR="$( cd "${DIR}/../.." && pwd )"
|
||||||
|
|
||||||
|
# Build all the available versions, or just the ones specified in PYVERS
|
||||||
|
if [ ! "${PYVERS:-}" ]; then
|
||||||
|
PYVERS="$(ls /opt/python/)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Find psycopg version
|
||||||
|
VERSION=$(grep -e ^PSYCOPG_VERSION "${PRJDIR}/setup.py" | sed "s/.*'\(.*\)'/\1/")
|
||||||
|
# A gratuitous comment to fix broken vim syntax file: '")
|
||||||
|
DISTDIR="${PRJDIR}/dist/psycopg2-$VERSION"
|
||||||
|
|
||||||
|
# Replace the package name
|
||||||
|
if [[ "${PACKAGE_NAME:-}" ]]; then
|
||||||
|
sed -i "s/^setup(name=\"psycopg2\"/setup(name=\"${PACKAGE_NAME}\"/" \
|
||||||
|
"${PRJDIR}/setup.py"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install prerequisite libraries
|
||||||
|
curl -s https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
|
||||||
|
echo "deb http://apt.postgresql.org/pub/repos/apt stretch-pgdg main" \
|
||||||
|
> /etc/apt/sources.list.d/pgdg.list
|
||||||
|
apt-get -y update
|
||||||
|
apt-get install -y libpq-dev
|
||||||
|
|
||||||
|
# Create the wheel packages
|
||||||
|
for PYVER in $PYVERS; do
|
||||||
|
PYBIN="/opt/python/${PYVER}/bin"
|
||||||
|
"${PYBIN}/pip" wheel "${PRJDIR}" -w "${PRJDIR}/dist/"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Bundle external shared libraries into the wheels
|
||||||
|
for WHL in "${PRJDIR}"/dist/*.whl; do
|
||||||
|
auditwheel repair "$WHL" -w "$DISTDIR"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Make sure the libpq is not in the system
|
||||||
|
for f in $(find /usr/lib /usr/lib64 -name libpq\*) ; do
|
||||||
|
mkdir -pv "/libpqbak/$(dirname $f)"
|
||||||
|
mv -v "$f" "/libpqbak/$(dirname $f)"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Install packages and test
|
||||||
|
cd "${PRJDIR}"
|
||||||
|
for PYVER in $PYVERS; do
|
||||||
|
PYBIN="/opt/python/${PYVER}/bin"
|
||||||
|
"${PYBIN}/pip" install ${PACKAGE_NAME} --no-index -f "$DISTDIR"
|
||||||
|
|
||||||
|
# Print psycopg and libpq versions
|
||||||
|
"${PYBIN}/python" -c "import psycopg2; print(psycopg2.__version__)"
|
||||||
|
"${PYBIN}/python" -c "import psycopg2; print(psycopg2.__libpq_version__)"
|
||||||
|
"${PYBIN}/python" -c "import psycopg2; print(psycopg2.extensions.libpq_version())"
|
||||||
|
|
||||||
|
# Fail if we are not using the expected libpq library
|
||||||
|
if [[ "${WANT_LIBPQ:-}" ]]; then
|
||||||
|
"${PYBIN}/python" -c "import psycopg2, sys; sys.exit(${WANT_LIBPQ} != psycopg2.extensions.libpq_version())"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"${PYBIN}/python" -c "import tests; tests.unittest.main(defaultTest='tests.test_suite')"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Restore the libpq packages
|
||||||
|
for f in $(cd /libpqbak/ && find . -not -type d); do
|
||||||
|
mv -v "/libpqbak/$f" "/$f"
|
||||||
|
done
|
77
scripts/build/download_packages.py
Executable file
77
scripts/build/download_packages.py
Executable file
|
@ -0,0 +1,77 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""Download packages from github actions artifacts
|
||||||
|
"""
|
||||||
|
|
||||||
|
import io
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
|
from zipfile import ZipFile
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s"
|
||||||
|
)
|
||||||
|
|
||||||
|
REPOS = "psycopg/psycopg2"
|
||||||
|
WORKFLOW_NAME = "Build packages"
|
||||||
|
|
||||||
|
|
||||||
|
class ScriptError(Exception):
|
||||||
|
"""Controlled exception raised by the script."""
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
token = os.environ["GITHUB_TOKEN"]
|
||||||
|
except KeyError:
|
||||||
|
raise ScriptError("please set a GITHUB_TOKEN to download artifacts")
|
||||||
|
|
||||||
|
s = requests.Session()
|
||||||
|
s.headers["Accept"] = "application/vnd.github.v3+json"
|
||||||
|
s.headers["Authorization"] = f"token {token}"
|
||||||
|
|
||||||
|
logger.info("looking for recent runs")
|
||||||
|
resp = s.get(f"https://api.github.com/repos/{REPOS}/actions/runs?per_page=10")
|
||||||
|
resp.raise_for_status()
|
||||||
|
for run in resp.json()["workflow_runs"]:
|
||||||
|
if run["name"] == WORKFLOW_NAME:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise ScriptError(f"couldn't find {WORKFLOW_NAME!r} in recent runs")
|
||||||
|
|
||||||
|
logger.info(f"looking for run {run['id']} artifacts")
|
||||||
|
resp = s.get(f"{run['url']}/artifacts")
|
||||||
|
resp.raise_for_status()
|
||||||
|
artifacts = resp.json()["artifacts"]
|
||||||
|
|
||||||
|
dest = Path("packages")
|
||||||
|
if not dest.exists():
|
||||||
|
logger.info(f"creating dir {dest}")
|
||||||
|
dest.mkdir()
|
||||||
|
|
||||||
|
for artifact in artifacts:
|
||||||
|
logger.info(f"downloading {artifact['name']} archive")
|
||||||
|
zip_url = artifact["archive_download_url"]
|
||||||
|
resp = s.get(zip_url)
|
||||||
|
with ZipFile(io.BytesIO(resp.content)) as zf:
|
||||||
|
logger.info("extracting archive content")
|
||||||
|
zf.extractall(dest)
|
||||||
|
|
||||||
|
logger.info(f"now you can run: 'twine upload -s {dest}/*'")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
sys.exit(main())
|
||||||
|
|
||||||
|
except ScriptError as e:
|
||||||
|
logger.error("%s", e)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
logger.info("user interrupt")
|
||||||
|
sys.exit(1)
|
77
scripts/build/download_packages_appveyor.py
Executable file
77
scripts/build/download_packages_appveyor.py
Executable file
|
@ -0,0 +1,77 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""Download packages from github actions artifacts
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
|
||||||
|
|
||||||
|
API_URL = "https://ci.appveyor.com/api"
|
||||||
|
REPOS = "psycopg/psycopg2"
|
||||||
|
WORKFLOW_NAME = "Build packages"
|
||||||
|
|
||||||
|
|
||||||
|
class ScriptError(Exception):
|
||||||
|
"""Controlled exception raised by the script."""
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
token = os.environ["APPVEYOR_TOKEN"]
|
||||||
|
except KeyError:
|
||||||
|
raise ScriptError("please set a APPVEYOR_TOKEN to download artifacts")
|
||||||
|
|
||||||
|
s = requests.Session()
|
||||||
|
s.headers["Content-Type"] = "application/json"
|
||||||
|
s.headers["Authorization"] = f"Bearer {token}"
|
||||||
|
|
||||||
|
logger.info("fetching last run")
|
||||||
|
resp = s.get(f"{API_URL}/projects/{REPOS}/")
|
||||||
|
resp.raise_for_status()
|
||||||
|
data = resp.json()
|
||||||
|
jobs = data["build"]["jobs"]
|
||||||
|
for job in jobs:
|
||||||
|
if job["status"] != "success":
|
||||||
|
raise ScriptError("status for job {job['jobId']} is {job['status']}")
|
||||||
|
|
||||||
|
logger.info(f"fetching artifacts info for {job['name']}")
|
||||||
|
resp = s.get(f"{API_URL}/buildjobs/{job['jobId']}/artifacts/")
|
||||||
|
resp.raise_for_status()
|
||||||
|
afs = resp.json()
|
||||||
|
for af in afs:
|
||||||
|
fn = af["fileName"]
|
||||||
|
if fn.startswith("dist/"):
|
||||||
|
fn = fn.split("/", 1)[1]
|
||||||
|
dest = Path("packages") / fn
|
||||||
|
logger.info(f"downloading {dest}")
|
||||||
|
resp = s.get(
|
||||||
|
f"{API_URL}/buildjobs/{job['jobId']}/artifacts/{af['fileName']}"
|
||||||
|
)
|
||||||
|
resp.raise_for_status()
|
||||||
|
if not dest.parent.exists():
|
||||||
|
dest.parent.mkdir()
|
||||||
|
|
||||||
|
with dest.open("wb") as f:
|
||||||
|
f.write(resp.content)
|
||||||
|
|
||||||
|
logger.info("now you can run: 'twine upload -s packages/*'")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
sys.exit(main())
|
||||||
|
|
||||||
|
except ScriptError as e:
|
||||||
|
logger.error("%s", e)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
logger.info("user interrupt")
|
||||||
|
sys.exit(1)
|
||||||
|
|
10
setup.py
10
setup.py
|
@ -376,6 +376,16 @@ For further information please check the 'doc/src/install.rst' file (also at
|
||||||
self.library_dirs.append(pg_config_helper.query("libdir"))
|
self.library_dirs.append(pg_config_helper.query("libdir"))
|
||||||
self.include_dirs.append(pg_config_helper.query("includedir"))
|
self.include_dirs.append(pg_config_helper.query("includedir"))
|
||||||
self.include_dirs.append(pg_config_helper.query("includedir-server"))
|
self.include_dirs.append(pg_config_helper.query("includedir-server"))
|
||||||
|
|
||||||
|
# add includedirs from cppflags, libdirs from ldflags
|
||||||
|
for token in pg_config_helper.query("ldflags").split():
|
||||||
|
if token.startswith("-L"):
|
||||||
|
self.library_dirs.append(token[2:])
|
||||||
|
|
||||||
|
for token in pg_config_helper.query("cppflags").split():
|
||||||
|
if token.startswith("-I"):
|
||||||
|
self.include_dirs.append(token[2:])
|
||||||
|
|
||||||
pgversion = pg_config_helper.query("version").split()[1]
|
pgversion = pg_config_helper.query("version").split()[1]
|
||||||
|
|
||||||
verre = re.compile(
|
verre = re.compile(
|
||||||
|
|
|
@ -178,7 +178,10 @@ class ConnectingTestCase(unittest.TestCase):
|
||||||
if libname is None and platform.system() == 'Windows':
|
if libname is None and platform.system() == 'Windows':
|
||||||
raise self.skipTest("can't import libpq on windows")
|
raise self.skipTest("can't import libpq on windows")
|
||||||
|
|
||||||
|
try:
|
||||||
rv = ConnectingTestCase._libpq = ctypes.pydll.LoadLibrary(libname)
|
rv = ConnectingTestCase._libpq = ctypes.pydll.LoadLibrary(libname)
|
||||||
|
except OSError as e:
|
||||||
|
raise self.skipTest("couldn't open libpq for testing: %s" % e)
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user