Merge pull request #2897 from PrincetonUniversity/devel #12
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
}); | |
} |