Skip to content

Merge pull request #2897 from PrincetonUniversity/devel #12

Merge pull request #2897 from PrincetonUniversity/devel

Merge pull request #2897 from PrincetonUniversity/devel #12

Workflow file for this run

name: Test and publish PNL release
on:
push:
tags:
- 'v*'
jobs:
create-python-dist:
runs-on: ubuntu-latest
strategy:
matrix:
# Python version in matrix for easier reference
python-version: [3.8]
environment: test-pypi
outputs:
sdist: ${{ steps.create_dist.outputs.sdist }}
wheel: ${{ steps.create_dist.outputs.wheel }}
steps:
- name: Checkout sources
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Create Python Dist files
id: create_dist
shell: bash
run: |
# We don't care about the python version used.
pip install setuptools wheel
python setup.py sdist
python setup.py bdist_wheel
cd dist
echo "sdist=$(ls *.tar.gz)" >> $GITHUB_OUTPUT
echo "wheel=$(ls *.whl)" >> $GITHUB_OUTPUT
- name: Upload Python dist files
uses: actions/upload-artifact@v4
with:
name: Python-dist-files
path: dist/
retention-days: 1
- name: Upload dist files to test PyPI
shell: bash
run: |
# Include implicit dependency on setuptools{,-rust} and preinstall wheel
pip install setuptools setuptools-rust wheel
pip install twine
# This expects TWINE_USERNAME, TWINE_PASSWORD, and TWINE_REPOSITORY_URL
# environment variables
# It's not possible to condition steps on env or secrets,
# We need an explicit check here
if [ -n "$TWINE_USERNAME" -a -n "$TWINE_PASSWORD" ]; then
twine upload dist/*
else
echo "::warning::Not uploading to test PyPI, no credentials available!"
fi
env:
TWINE_USERNAME: ${{ secrets.TWINE_TEST_USERNAME }}
TWINE_PASSWORD: ${{ secrets.TWINE_TEST_PASSWORD }}
TWINE_REPOSITORY_URL: ${{ secrets.TWINE_TEST_REPOSITORY_URL }}
test-release:
strategy:
fail-fast: false
matrix:
python-version: [3.7, 3.8, 3.9]
os: [ubuntu-latest, macos-latest, windows-latest]
dist: [wheel, sdist]
runs-on: ${{ matrix.os }}
needs: [create-python-dist]
steps:
- name: Download dist files
uses: actions/download-artifact@v4
with:
name: Python-dist-files
path: dist/
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
# The installation _could_ reuse the 'install-pnl' action,
# but actions deploys workarounds that we want to avoid here.
- name: MacOS dependencies
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install graphviz
if: startsWith(runner.os, 'macOS')
- name: Linux dependencies
run: sudo apt-get install -y graphviz
if: startsWith(runner.os, 'Linux')
- name: Windows dependencies
run: choco install --no-progress -y graphviz --version=2.38.0.20190211
if: startsWith(runner.os, 'Windows')
- name: Install wheel
shell: bash
if: matrix.dist == 'wheel'
run: pip install dist/${{ needs.create-python-dist.outputs.wheel }}[dev]
- name: Install sdist
shell: bash
if: matrix.dist == 'sdist'
run: pip install dist/${{ needs.create-python-dist.outputs.sdist }}[dev]
- name: Get tests from the repository
uses: actions/checkout@v4
- name: Run tests
shell: bash
# run only tests/. We don't care about codestyle/docstyle at this point
timeout-minutes: 80
run: |
# remove sources to prevent conflict with the isntalled package
rm -r -f psyneulink/ docs/ bin/ Matlab/
# run tests
pytest --junit-xml=tests_out.xml --verbosity=0 -n auto tests
- name: Upload test results
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.os }}-${{ matrix.python-version }}
path: tests_out.xml
retention-days: 30
if: success() || failure()
publish-pypi:
runs-on: ubuntu-latest
needs: [create-python-dist, test-release]
environment: pypi
steps:
- name: Download dist files
uses: actions/download-artifact@v4
with:
name: Python-dist-files
path: dist/
- name: Upload dist files to PyPI
shell: bash
run: |
# Include implicit dependency on setuptools{,-rust} and preinstall wheel
pip3 install --user setuptools setuptools-rust wheel
pip3 install --user twine
# This expects TWINE_USERNAME, TWINE_PASSWORD, and TWINE_REPOSITORY_URL
# environment variables
# It's not possible to condition steps on env or secrets,
# We need an explicit check here
if [ -n "$TWINE_USERNAME" -a -n "$TWINE_PASSWORD" ]; then
twine upload dist/*
else
echo "::warning::Not uploading to PyPI, no credentials available!"
fi
env:
TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }}
TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}
TWINE_REPOSITORY_URL: ${{ secrets.TWINE_REPOSITORY_URL }}
publish-github:
runs-on: ubuntu-latest
needs: [create-python-dist, test-release]
environment: gh-release
permissions:
contents: write
steps:
- name: Download dist files
uses: actions/download-artifact@v4
with:
name: Python-dist-files
path: dist/
- name: Upload dist files to release
uses: actions/github-script@v7
with:
script: |
const fs = require('fs')
tag = context.ref.split('/').pop()
console.log('running on:' + context.ref);
console.log('Looking for release for tag:' + tag);
var release
try {
release = await github.rest.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag: tag
});
console.log('Release found at: ' + release.data.html_url); // '
} catch (err) {
if (err.status == 404) {
console.log('Release not found, creating a new one');
release = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: tag,
name: 'Release ' + tag,
body: 'New features and fixed bugs'
});
} else {
throw err;
}
}
console.log('Using release upload url: ' + release['data']['upload_url']);
// Determine content-length for header to upload asset
for (asset of ['${{ needs.create-python-dist.outputs.wheel }}', '${{ needs.create-python-dist.outputs.sdist }}']) {
const file_path = 'dist/' + asset;
const file_size = file_path => fs.statSync(file_path).size;
console.log('Uploading: ' + file_path);
// Setup headers for API call, see Octokit Documentation:
// https://octokit.github.io/rest.js/#octokit-routes-repos-upload-release-asset for more information
const headers = { 'content-type': 'application/zip', 'content-length': file_size(file_path) };
// Upload a release asset
const uploadAssetResponse = await github.rest.repos.uploadReleaseAsset({
url: release.data.upload_url,
headers,
name: asset,
file: fs.readFileSync(file_path)
});
}