diff --git a/.github/workflows/release-github.yml b/.github/workflows/release-github.yml new file mode 100644 index 0000000..4aa1a41 --- /dev/null +++ b/.github/workflows/release-github.yml @@ -0,0 +1,163 @@ +name: Release on GitHub + +on: + workflow_call: + secrets: + PAT_TOKEN: + description: "GitHub Personal Access Token" + required: true + +env: + TAG: ${{ github.ref_name }} + +defaults: + run: + shell: bash {0} + +jobs: + prepare-release: + if: ${{ ! contains(github.ref, 'rc') }} + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + ref: main + + - name: Update CHANGELOG + run: | + wget https://raw.githubusercontent.com/scikit-package/release-scripts/v0/.github/workflows/update-changelog.py + python update-changelog.py "$TAG" + rm update-changelog.py + + - name: Commit updated CHANGELOG.rst + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add . + if ! git diff --cached --quiet; then + git commit -m "update changelog for $TAG" + git push origin main + else + echo "No CHANGELOG.rst changes" + fi + + - name: New tag + run: | + git fetch --tags + git tag -d "$TAG" 2>/dev/null || true + git push origin ":$TAG" 2>/dev/null || true + git tag "$TAG" + git push origin "$TAG" + + - name: Get CHANGELOG.txt + run: | + wget https://raw.githubusercontent.com/scikit-package/release-scripts/v0/.github/workflows/get-latest-changelog.py + python get-latest-changelog.py "$TAG" + rm get-latest-changelog.py + + - name: Upload changelog.txt + uses: actions/upload-artifact@v4 + with: + name: changelog + path: CHANGELOG.txt + + release: + needs: [prepare-release] + if: always() + runs-on: ubuntu-latest + env: + REPO_FULL: ${{ github.repository }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} + steps: + - name: Check prepare release + run: | + if [[ ${{ needs.prepare-release.result }} != 'success' && "$TAG" != *rc* ]]; then + echo "::error::Skipping release job because prepare-release failed" + exit 78 + fi + echo "Continuing with release job" + + - name: Download built wheels + uses: actions/download-artifact@v4 + with: + path: dist/ + + - name: Download changelog + if: ${{ needs.prepare-release.result == 'success' }} + uses: actions/download-artifact@v4 + with: + name: changelog + path: . + + - name: Download instructions + uses: actions/download-artifact@v4 + with: + name: instructions + path: . + + - name: Zip wheels and instructions into dist/srxplanar-$TAG-wheels.zip + run: | + mkdir -p dist + find dist -type f -name '*.whl' | zip -j dist/srxplanar-"$TAG"-wheels.zip -@ + zip -j dist/srxplanar-"$TAG"-wheels.zip INSTRUCTIONS.txt + + - name: Prepare release metadata + id: meta + run: | + if [[ "$TAG" == *rc* ]]; then + PRERELEASE=true + TITLE="Pre-release $TAG" + BODY_RAW="Changelog: https://github.com/$REPO_FULL/commits/$TAG" + else + PRERELEASE=false + TITLE="Release $TAG" + BODY_RAW=$( payload.json + + echo "Release metadata:" + cat payload.json + + - name: Create GitHub Release + id: create_release + run: | + set -euo pipefail + + HTTP_STATUS=$( + curl --silent --output resp.json --write-out "%{http_code}" \ + -X POST "https://api.github.com/repos/$REPO_FULL/releases" \ + -H "Accept: application/vnd.github+json" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $PAT_TOKEN" \ + --data @payload.json + ) + if [[ "$HTTP_STATUS" -ne 201 ]]; then + echo "::error::Failed to create release (status $HTTP_STATUS)" + exit 1 + fi + + UPLOAD_URL=$(jq -r .upload_url resp.json | sed 's/{.*}//') + echo "upload_url=$UPLOAD_URL" >> $GITHUB_OUTPUT + + - name: Upload srxplanar-$TAG-wheels.zip + if: steps.create_release.outputs.upload_url != '' + run: | + FILE=dist/srxplanar-$TAG-wheels.zip + echo "Uploading asset: $FILE" + curl --silent --fail --data-binary @"$FILE" \ + -H "Content-Type: application/zip" \ + -H "Authorization: Bearer $PAT_TOKEN" \ + "${{ steps.create_release.outputs.upload_url }}?name=$(basename "$FILE")" diff --git a/.github/workflows/tests-on-pr-no-codecov.yml b/.github/workflows/tests-on-pr-no-codecov.yml new file mode 100644 index 0000000..0dd0735 --- /dev/null +++ b/.github/workflows/tests-on-pr-no-codecov.yml @@ -0,0 +1,17 @@ +name: Tests on PR + +on: + pull_request: + workflow_dispatch: + +jobs: + tests-on-pr: + uses: scikit-package/release-scripts/.github/workflows/_tests-on-pr-no-codecov.yml@v0 + with: + project: diffpy.srxplanar + c_extension: false + headless: false + python_version: "3.13" + run: | + conda install pre-commit + pre-commit run --all-files diff --git a/.gitignore b/.gitignore index c717e59..099e294 100644 --- a/.gitignore +++ b/.gitignore @@ -1,45 +1,93 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ *.py[cod] +*$py.class # C extensions *.so -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -temp -develop-eggs +# Distribution / packaging +.Python +env/ +build/ +_build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +venv/ +*.egg-info/ .installed.cfg -lib -lib64 -tags +*.egg +bin/ +temp/ +tags/ errors.err +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + # Installer logs pip-log.txt +pip-delete-this-directory.txt MANIFEST # Unit test / coverage reports +htmlcov/ +.tox/ .coverage -.tox +.coverage.* +.cache nosetests.xml +coverage.xml +*,cover +.hypothesis/ # Translations *.mo +*.pot # Mr Developer .mr.developer.cfg .project .pydevproject -.settings -# version information -setup.cfg -/diffpy/srxplanar/version.cfg -/diffpy/confutils/version.cfg +# Django stuff: +*.log + +# Sphinx documentation +docs/build/ +docs/source/generated/ + +# pytest +.pytest_cache/ + +# PyBuilder +target/ + +# Editor files +# mac +.DS_Store +*~ + +# vim +*.swp +*.swo + +# pycharm +.idea/ + +# VSCode +.vscode/ + +# Ipython Notebook +.ipynb_checkpoints diff --git a/pyproject.toml b/pyproject.toml index 8dcd94a..9c39af5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ maintainers = [ description = "Distance Printer, calculate the inter atomic distances. Part of xPDFsuite" keywords = ['diffpy', 'pdf', 'data interpretation'] readme = "README.rst" -requires-python = ">=3.12, <3.15" +requires-python = ">=3.11, <3.14" classifiers = [ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', diff --git a/src/diffpy/srxplanar/srxplanar_app.py b/src/diffpy/srxplanar/srxplanar_app.py new file mode 100644 index 0000000..4c6e49d --- /dev/null +++ b/src/diffpy/srxplanar/srxplanar_app.py @@ -0,0 +1,34 @@ +import argparse + +from diffpy.srxplanar.version import __version__ # noqa + + +def main(): + parser = argparse.ArgumentParser( + prog="diffpy.srxplanar", + description=( + "Distance Printer, calculate the inter atomic distances." + " Part of xPDFsuite\n\n" + "For more information, visit: " + "https://github.com/diffpy/diffpy.srxplanar/" + ), + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + + parser.add_argument( + "--version", + action="store_true", + help="Show the program's version number and exit", + ) + + args = parser.parse_args() + + if args.version: + print(f"diffpy.srxplanar {__version__}") + else: + # Default behavior when no arguments are given + parser.print_help() + + +if __name__ == "__main__": + main()