Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 61 additions & 13 deletions .github/workflows/pcds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,34 +37,82 @@ jobs:
system-packages: ""
use-setuptools-scm: true

pip-test:
pip-test-pyside6:
strategy:
fail-fast: false
matrix:
include:
- python-version: "3.9"
deploy-on-success: true
upload-artifact: true
- python-version: "3.10"
- python-version: "3.11"
- python-version: "3.12"
- python-version: "3.13"

name: "Pip"
uses: pcdshub/pcds-ci-helpers/.github/workflows/python-pip-test.yml@master
name: "Pip test (PySide6)"
uses: ./.github/workflows/python-pip-test.yml
secrets: inherit
with:
artifact-name: "PySide6"
package-name: "qtpynodeeditor"
python-version: ${{ matrix.python-version }}
experimental: ${{ matrix.experimental || false }}
deploy-on-success: ${{ matrix.deploy-on-success || false }}
system-packages: "libegl1"
testing-extras: "PySide6"

pip-test-pyqt5:
strategy:
fail-fast: false
matrix:
include:
- python-version: "3.9"
- python-version: "3.10"
- python-version: "3.11"
- python-version: "3.12"
- python-version: "3.13"

name: "Pip test (pyqt5)"
uses: ./.github/workflows/python-pip-test.yml
secrets: inherit
with:
artifact-name: "PyQt5"
package-name: "qtpynodeeditor"
python-version: ${{ matrix.python-version }}
experimental: ${{ matrix.experimental || false }}
deploy-on-success: ${{ matrix.deploy-on-success || false }}
system-packages: ""
testing-extras: ""
testing-extras: "PyQt5"

# pip-docs:
# name: "Documentation"
# uses: pcdshub/pcds-ci-helpers/.github/workflows/python-docs.yml@master
# with:
# package-name: "qtpynodeeditor"
# python-version: "3.9"
# deploy: ${{ github.repository_owner == "klauer" && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags')) }}
# system-packages: ""
# pip-test-pyqt6:
# strategy:
# fail-fast: false
# matrix:
# include:
# - python-version: "3.9"
# deploy-on-success: true
# - python-version: "3.10"
# - python-version: "3.11"
# - python-version: "3.12"
# - python-version: "3.13"
#
# name: "Pip test (pyqt6)"
# uses: ./.github/workflows/python-pip-test.yml
# secrets: inherit
# with:
# artifact-name: "PyQt6"
# package-name: "qtpynodeeditor"
# python-version: ${{ matrix.python-version }}
# experimental: ${{ matrix.experimental || false }}
# deploy-on-success: ${{ matrix.deploy-on-success || false }}
# system-packages: ""
# testing-extras: "PyQt6"
#
# pip-docs:
# name: "Documentation"
# uses: pcdshub/pcds-ci-helpers/.github/workflows/python-docs.yml@master
# with:
# package-name: "qtpynodeeditor"
# python-version: "3.9"
# deploy: ${{ github.repository_owner == "klauer" && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags')) }}
# system-packages: ""
233 changes: 233 additions & 0 deletions .github/workflows/python-pip-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
# Borrowed from https://github.com/pcdshub/pcds-ci-helpers/blob/master/.github/workflows/python-pip-test.yml
name: Pip Build

on:
workflow_call:
inputs:
artifact-name:
description: "Artifact name"
required: true
type: string
package-name:
description: "The Python-importable package name to be tested"
required: true
type: string
python-version:
description: "The Python version to build and test with"
required: true
type: string
experimental:
description: "Mark this version as experimental and not required to pass"
required: false
default: false
type: boolean
upload-artifact:
description: "Deploy to PyPI on success (and when appropriate)"
required: false
default: false
type: boolean
deploy-on-success:
description: "Deploy to PyPI on success (and when appropriate)"
required: false
default: false
type: boolean
testing-extras:
default: ""
description: "Extra packages to be installed for testing"
required: false
type: string
ci-extras:
default: ""
description: "CI-specific packages to be installed"
required: false
type: string
system-packages:
default: ""
description: "CI-specific system packages required for installation"
required: false
type: string
outputs: {}

env:
MPLBACKEND: "agg"
QT_QPA_PLATFORM: "offscreen"

jobs:
test:
name: "Python ${{ inputs.python-version }}: pip"
runs-on: ubuntu-20.04
continue-on-error: ${{ inputs.experimental }}

defaults:
run:
# The following allows for each run step to utilize ~/.bash_profile
# for setting up the per-step initial state.
# --login: a login shell. Source ~/.bash_profile
# -e: exit on first error
# -o pipefail: piped processes are important; fail if they fail
shell: bash --login -eo pipefail {0}

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: "recursive"

- name: Check version to be built
run: |
# NOTE: If you run CI on your own fork, you may not have the right version
# number for the package. Synchronize your tags with the upstream,
# otherwise cross-dependencies may result in confusing build failure.
(echo "Package version: $(git describe --tags)" | tee "$GITHUB_STEP_SUMMARY") || \
echo "::warning::Git tags not found in repository. Build may fail!"

- name: Check environment variables for issues
run: |
echo "* Package to be built: ${{ inputs.package-name }}"
echo "* Pip 'extras' for CI testing: ${{ inputs.testing-extras }}"
echo "* General pip packages required for CI testing: ${{ inputs.ci-extras }}"

- name: Install required system packages
if: inputs.system-packages != ''
run: |
sudo apt-get update
sudo apt-get -y install ${{ inputs.system-packages }}

- name: Prepare for log files
run: |
mkdir $HOME/logs

- uses: actions/setup-python@v5
with:
python-version: "${{ inputs.python-version }}"

- name: Upgrade pip
run: |
pip install --upgrade pip

- name: Build wheel and source distribution
run: |
python -m pip install twine build
export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
echo "Source date epoch set to ${SOURCE_DATE_EPOCH} for reproducible build"
# See: https://github.com/python/cpython/pull/5200
# And: https://reproducible-builds.org/docs/source-date-epoch/
# (I learned about this from DLS)
python -m build --sdist --wheel --outdir ./dist

- name: Check the source distribution
run: |
python -m venv test-source-env
source test-source-env/bin/activate

python -m pip install ./dist/*.gz
if [ ! -z "${{ inputs.testing-extras }}" ]; then
python -m pip install ${{ inputs.testing-extras }}
fi
python -c "import ${{ inputs.package-name }}; print('Imported ${{ inputs.package-name }} successfully')"

- name: Use the wheel for testing
run: |
python -m venv test-wheel-env
source test-wheel-env/bin/activate

python -m pip install ./dist/*.whl
if [ ! -z "${{ inputs.testing-extras }}" ]; then
python -m pip install ${{ inputs.testing-extras }}
fi
python -c "import ${{ inputs.package-name }}; print('Imported ${{ inputs.package-name }} successfully')"

- name: Installing CI extras and testing extras
run: |
# 1. escape '<' so the user doesn't have to
# 2. escape '>' so the user doesn't have to
# 3. allow conda/pip to use the same requirements spec;
# conda expects pkg=ver but pip expects pkg==ver; using a basic
# (not =<>)=(not =) to avoid incompatibility with macOS sed not supporting
# '=\+'
input_requirements=$(
echo "${{ inputs.ci-extras }} ${{ inputs.testing-extras }}" |
sed -e "s/</\</g" |
sed -e "s/>/\>/g" |
sed -e 's/\([^=<>]\)=\([^=]\)/\1==\2/g'
)

declare -a test_requirements=()
for req in $input_requirements; do
test_requirements+=( "$req" )
done

set -x
if [[ ${#test_requirements[@]} -gt 0 ]]; then
echo "CI extras: ${{ inputs.ci-extras }}"
echo "Testing extras: ${{ inputs.testing-extras }}"
pip install "${test_requirements[@]}" .[test]
else
echo "No extras to install."
pip install .[test]
fi

- name: Check the pip packages in the test env
run: |
pip list

- name: Run tests
run: |
pytest -v \
--log-file="$HOME/logs/debug_log.txt" \
--log-format='%(asctime)s.%(msecs)03d %(module)-15s %(levelname)-8s %(threadName)-10s %(message)s' \
--log-file-date-format='%H:%M:%S' \
--log-level=DEBUG \
2>&1 | tee "$HOME/logs/pytest_log.txt"

- name: After failure
if: ${{ failure() }}
run: |
# On failure:
# * Include the pip package details
# * Include the pytest log in the step summary (but not in the step output as it's available in the previous step)
# * Include the debug log in the step output (but not the step summary as it's too verbose)
(
echo "### Pip list"
echo "<details>"
echo ""
echo '```'
pip list | egrep -v -e "^#"
echo '```'
echo "</details>"

echo ""
echo "### Pytest log"
echo '```python'
cat "$HOME/logs/pytest_log.txt" || echo "# Pytest log not found?"
echo '```'
) >> "$GITHUB_STEP_SUMMARY"

echo "## Debug log"
cat "$HOME/logs/debug_log.txt" || echo "Debug logfile not found?"

# - name: Upload log file artifacts
# if: ${{ always() }}
# uses: actions/upload-artifact@v4
# with:
# name: Python ${{ inputs.python-version }} - ${{ inputs.artifact-name }} - testing log
# path: "~/logs"

- name: Upload the package as an artifact
if: ${{ inputs.upload-artifact }}
uses: actions/upload-artifact@v4
with:
name: Python ${{ inputs.python-version }} - ${{ inputs.artifact-name }} - package
path: dist

- name: PyPI deployment
if: inputs.deploy-on-success && github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: |
if [ -z "$TWINE_PASSWORD" ]; then
echo "# No PYPI_TOKEN secret in job!" | tee -a "$GITHUB_STEP_SUMMARY"
exit 1
fi
twine upload --verbose dist/*
3 changes: 0 additions & 3 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@ include AUTHORS.rst
include CONTRIBUTING.rst
include LICENSE
include README.rst
include requirements.txt
include dev-requirements.txt

recursive-exclude * __pycache__
recursive-exclude * *.py[co]

recursive-include docs *.rst conf.py Makefile make.bat

include versioneer.py
include qtpynodeeditor/_version.py
include qtpynodeeditor/DefaultStyle.json
6 changes: 4 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ qtpynodeeditor may also be installed using pip from PyPI.

::

$ python -m pip install qtpynodeeditor pyqt5
$ python -m pip install qtpynodeeditor[pyqt5]
$ python -m pip install qtpynodeeditor[pyqt6]
$ python -m pip install qtpynodeeditor[pyside]


Running the Tests
Expand All @@ -63,5 +65,5 @@ Tests must be run with pytest and pytest-qt.

::

$ pip install -r dev-requirements.txt
$ pip install .[pyqt5,test]
$ pytest -v qtpynodeeditor/tests
6 changes: 0 additions & 6 deletions dev-requirements.txt

This file was deleted.

6 changes: 0 additions & 6 deletions docs-requirements.txt

This file was deleted.

Loading