From cdab53b8bd8e4f5eef58a18a58201cbb9d249d3f Mon Sep 17 00:00:00 2001 From: clintval Date: Thu, 8 Aug 2024 08:57:47 -0700 Subject: [PATCH 01/11] chore: update the release process to leverage GitHub Actions --- .github/workflows/publish.yml | 132 ++++++++++++++++++++++++++++ .github/workflows/pythonpackage.yml | 93 -------------------- .github/workflows/tests.yml | 104 ++++++++++++++++++++++ .github/workflows/wheels.yml | 31 ++++--- pyproject.toml | 30 +++++++ 5 files changed, 281 insertions(+), 109 deletions(-) create mode 100644 .github/workflows/publish.yml delete mode 100644 .github/workflows/pythonpackage.yml create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..a1321ca --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,132 @@ +name: publish + +on: + push: + tags: '\d+.\d+.\d+' + +env: + POETRY_VERSION: 1.6 + +jobs: + on-main-branch-check: + runs-on: ubuntu-latest + outputs: + on_main: ${{ steps.contains_tag.outputs.retval }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: rickstaa/action-contains-tag@v1 + id: contains_tag + with: + reference: "main" + tag: "${{ github.ref_name }}" + + tests: + name: tests + needs: on-main-branch-check + if: ${{ needs.on-main-branch-check.outputs.on_main == 'true' }} + uses: "./.github/workflows/tests.yml" + + build-wheels: + name: build wheels + needs: tests + uses: "./.github/workflows/wheels.yml" + + build-sdist: + name: build source distribution + needs: tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true + + - uses: actions/setup-python@v5 + with: + python-version: 3.12 + + - name: Install poetry + run: | + python -m pip install --upgrade pip + python -m pip install poetry==${{env.POETRY_VERSION}} + + - name: Configure poetry + shell: bash + run: poetry config virtualenvs.in-project true + + - name: Install dependencies + run: poetry install --no-interaction --no-root --without=dev + + - name: Install project + run: poetry install --no-interaction --without=dev + + - name: Build package + run: poetry build --format=sdist + + - uses: actions/upload-artifact@v4 + with: + name: pybedlite-sdist + path: dist/*.tar.gz + + publish-to-pypi: + runs-on: ubuntu-latest + needs: [build-wheels, build-sdist] + environment: pypi + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v4 + with: + path: packages + pattern: 'pybedlite-*' + merge-multiple: true + + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: packages/ + skip-existing: true + verbose: true + + make-changelog: + runs-on: ubuntu-latest + needs: publish-to-pypi + outputs: + release_body: ${{ steps.git-cliff.outputs.content }} + steps: + - name: Checkout the Repository at the Tagged Commit + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.ref_name }} + + - name: Generate a Changelog + uses: orhun/git-cliff-action@v3 + id: git-cliff + with: + config: pyproject.toml + args: --latest --verbose + env: + GITHUB_REPO: ${{ github.repository }} + + make-github-release: + runs-on: ubuntu-latest + environment: github + permissions: + contents: write + pull-requests: read + needs: make-changelog + steps: + - name: Create Draft Release + id: create_release + uses: softprops/action-gh-release@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + name: ${{ github.ref_name }} + body: | + ${{ needs.draft-changelog.outputs.release_body }} + draft: false + prerelease: false diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml deleted file mode 100644 index fe3b9cc..0000000 --- a/.github/workflows/pythonpackage.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Python package - -on: [push] -env: - POETRY_VERSION: 1.6.1 - -jobs: - testing: - runs-on: ubuntu-20.04 - environment: github-action-ci - strategy: - matrix: - PYTHON_VERSION: ["3.8", "3.9", "3.10", "3.11"] - steps: - - uses: actions/checkout@v2 - with: - submodules: 'true' - - - name: Set up Python ${{matrix.PYTHON_VERSION}} - uses: actions/setup-python@v4 - with: - python-version: ${{matrix.PYTHON_VERSION}} - - - name: Get full Python version - id: full-python-version - shell: bash - run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") - - - name: Install poetry - shell: bash - run: | - pip install poetry==${{env.POETRY_VERSION}} - - - name: Configure poetry - shell: bash - run: poetry config virtualenvs.in-project true - - - name: Set up cache - uses: actions/cache@v2 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }} - - - name: Ensure cache is healthy - if: steps.cache.outputs.cache-hit == 'true' - shell: bash - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - - name: Install deps - shell: bash - run: | - poetry install --only dev - poetry build - poetry install --extras docs - - - name: Run pytest - shell: bash - run: | - poetry run python -m pytest --cov=pybedlite --cov-report=xml --cov-branch - - - name: Style checking - shell: bash - run: | - poetry run black --line-length 99 --check pybedlite - - - name: Import sorting - shell: bash - run: | - poetry run isort --force-single-line-imports --profile black --check pybedlite - - - name: Run lint - shell: bash - run: | - poetry run flake8 --config=ci/flake8.cfg pybedlite - - - name: Run mypy - shell: bash - run: | - poetry run mypy -p pybedlite --config=ci/mypy.ini - - - name: Run docs - shell: bash - run: | - set -euo pipefail - pushd docs - poetry run make html - popd - - - name: Upload code coverage - uses: codecov/codecov-action@v4.5.0 - with: - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..425e112 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,104 @@ +name: tests + +on: + push: + branches: + - "**" + tags: + - "!**" + workflow_call: + +env: + POETRY_VERSION: 1.6 + +jobs: + unit-tests: + runs-on: ubuntu-latest + environment: github-action-ci + strategy: + matrix: + PYTHON_VERSION: ["3.8", "3.9", "3.10", "3.11"] + + steps: + - uses: actions/checkout@v4 + with: + submodules: "true" + + - name: Set up Python ${{ matrix.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.PYTHON_VERSION }} + + - name: Get full Python version + id: full-python-version + shell: bash + run: echo "version=$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")" >> $GITHUB_OUTPUT + + - name: Install poetry + run: | + python -m pip install --upgrade pip + python -m pip install poetry==${{env.POETRY_VERSION}} + + - name: Configure poetry + shell: bash + run: poetry config virtualenvs.in-project true + + - name: Set up cache + uses: actions/cache@v4 + id: cache + with: + path: .venv + key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }} + + - name: Ensure cache is healthy + if: steps.cache.outputs.cache-hit == 'true' + shell: bash + run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv + + - name: Test the lock file is up to date + run: python -m poetry check --lock + + - name: Install dependencies and package + shell: bash + run: | + poetry install --only dev + poetry build + poetry install --extras docs + + - name: Run pytest + shell: bash + run: | + poetry run python -m pytest --cov=pybedlite --cov-report=xml --cov-branch + + - name: Style checking + shell: bash + run: | + poetry run black --line-length 99 --check pybedlite + + - name: Import sorting + shell: bash + run: | + poetry run isort --force-single-line-imports --profile black --check pybedlite + + - name: Run lint + shell: bash + run: | + poetry run flake8 --config=ci/flake8.cfg pybedlite + + - name: Run mypy + shell: bash + run: | + poetry run mypy -p pybedlite --config=ci/mypy.ini + + - name: Run docs + shell: bash + run: | + set -euo pipefail + pushd docs + poetry run make html + popd + + - name: Upload code coverage + uses: codecov/codecov-action@v4.5.0 + with: + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index f555d6c..3cfa839 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -1,12 +1,12 @@ -name: Build wheels for multiple platforms +name: build wheels on: - push: - branches: [main] + pull_request: + workflow_call: workflow_dispatch: jobs: - build_wheels: + build-wheels: name: Build wheels for ${{ matrix.python }}-${{ matrix.platform.target }}_${{ matrix.platform.arch }} on ${{ matrix.platform.os }} runs-on: ${{ matrix.platform.os }} strategy: @@ -22,12 +22,12 @@ jobs: # These don't work right now - they just hang while pulling the build image from quay. # If this doesn't resolve itself, we could try to configure different images: # https://cibuildwheel.readthedocs.io/en/stable/options/. - #- os: ubuntu-latest - # target: manylinux - # arch: aarch64 - #- os: ubuntu-latest - # target: musllinux - # arch: aarch64 + # - os: ubuntu-latest + # target: manylinux + # arch: aarch64 + # - os: ubuntu-latest + # target: musllinux + # arch: aarch64 - os: macos-latest target: macosx arch: x86_64 @@ -40,13 +40,12 @@ jobs: with: submodules: "true" - # Used to host cibuildwheel - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: - python-version: 3.8 + python-version: 3.12 - name: Install cibuildwheel - run: python -m pip install cibuildwheel==2.15.0 + run: python -m pip install cibuildwheel==2.20.0 - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse @@ -55,8 +54,8 @@ jobs: CIBW_BUILD: ${{ matrix.python }}-${{ matrix.platform.target }}_${{ matrix.platform.arch }} CIBW_BUILD_VERBOSITY: 1 - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: - name: wheels + name: pybedlite-wheels-${{ matrix.python }}-${{ matrix.platform.target }}_${{ matrix.platform.arch }} path: ./wheelhouse/*.whl if-no-files-found: error diff --git a/pyproject.toml b/pyproject.toml index 06402b2..cb5ec11 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,3 +50,33 @@ generate-setup-file = true [build-system] requires = ["poetry-core", "setuptools", "cython"] build-backend = "poetry.core.masonry.api" + +[tool.git-cliff.changelog] +header = "" +trim = true +body = """ +{% for group, commits in commits | group_by(attribute="group") %} + ## {{ group | upper_first }} + {% for commit in commits %} + - {{ commit.message | upper_first }} ({{ commit.id | truncate(length=8, end="") }})\ + {% endfor %} +{% endfor %}\n +""" + +[tool.git-cliff.git] +conventional_commits = true +commit_parsers = [ + { message = "^.+!:*", group = "Breaking"}, + { message = "^feat*", group = "Features"}, + { message = "^fix*", group = "Bug Fixes"}, + { message = "^[cC]i*", group = "CI/CD"}, + { message = "^docs*", group = "Documentation"}, + { message = "^perf*", group = "Performance"}, + { message = "^refactor*", group = "Refactor"}, + { message = "^style*", group = "Styling"}, + { message = "^test*", group = "Testing"}, + { message = "^chore\\(release\\):*", skip = true}, + { message = "^chore*", group = "Miscellaneous Tasks"}, + { body = ".*security", group = "Security"} +] +filter_commits = false From 8db28b6e32a12e789d972da807edc8674b238b29 Mon Sep 17 00:00:00 2001 From: clintval Date: Thu, 8 Aug 2024 09:20:23 -0700 Subject: [PATCH 02/11] chore: downgrade cibuildwheel --- .github/workflows/wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 3cfa839..f4c403b 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -45,7 +45,7 @@ jobs: python-version: 3.12 - name: Install cibuildwheel - run: python -m pip install cibuildwheel==2.20.0 + run: python -m pip install cibuildwheel==2.15.0 - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse From d80ef903a0c20dd8092d38367d2682cf93871aa1 Mon Sep 17 00:00:00 2001 From: clintval Date: Thu, 8 Aug 2024 09:20:46 -0700 Subject: [PATCH 03/11] chore: downgrade Python for building wheels --- .github/workflows/wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index f4c403b..fb8b8cf 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -42,7 +42,7 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: 3.12 + python-version: 3.8 - name: Install cibuildwheel run: python -m pip install cibuildwheel==2.15.0 From 83c859276b55245ec78e8f5b980917e669e2a26c Mon Sep 17 00:00:00 2001 From: clintval Date: Thu, 8 Aug 2024 09:22:37 -0700 Subject: [PATCH 04/11] chore: try removing the environment to make less noisy --- .github/workflows/tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 425e112..b85287d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,6 @@ env: jobs: unit-tests: runs-on: ubuntu-latest - environment: github-action-ci strategy: matrix: PYTHON_VERSION: ["3.8", "3.9", "3.10", "3.11"] From 3f92a96dceb24e0f7f012770b1b8f00e1e28402e Mon Sep 17 00:00:00 2001 From: clintval Date: Thu, 8 Aug 2024 09:44:41 -0700 Subject: [PATCH 05/11] chore: address @nh13 review --- .github/workflows/publish.yml | 2 -- .github/workflows/tests.yml | 2 +- .github/workflows/wheels.yml | 2 +- README.md | 9 ++++++--- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a1321ca..6888582 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -122,8 +122,6 @@ jobs: - name: Create Draft Release id: create_release uses: softprops/action-gh-release@v2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: name: ${{ github.ref_name }} body: | diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b85287d..b8a68a5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - PYTHON_VERSION: ["3.8", "3.9", "3.10", "3.11"] + PYTHON_VERSION: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index fb8b8cf..39bf75c 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.platform.os }} strategy: matrix: - python: [cp38, cp39, cp310, cp311] + python: [cp38, cp39, cp310, cp311, cp312] platform: - os: ubuntu-latest target: manylinux diff --git a/README.md b/README.md index cfc230e..8c3db64 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ --- -[![Python package][python-package-badge]][python-package-link] +[![Unit tests][tests-badge]][tests-link] +[![Python versions][python-version-badge]](https://github.com/fulcrumgenomics/python-template) [![PyPI version][pypi-badge]][pypi-link] [![PyPI download total][pypi-downloads-badge]][pypi-downloads-link] @@ -26,12 +27,14 @@ [code-coverage-link]: https://codecov.io/gh/fulcrumgenomics/pybedlite [license-badge]: http://img.shields.io/badge/license-MIT-blue.svg [license-link]: https://github.com/fulcrumgenomics/pybedlite/blob/main/LICENSE -[python-package-badge]: https://github.com/fulcrumgenomics/pybedlite/workflows/Python%20package/badge.svg -[python-package-link]: https://github.com/fulcrumgenomics/pybedlite/actions?query=workflow%3A%22Python+package%22 [pypi-badge]: https://badge.fury.io/py/pybedlite.svg [pypi-link]: https://pypi.python.org/pypi/pybedlite [pypi-downloads-badge]: https://img.shields.io/pypi/dm/pybedlite [pypi-downloads-link]: https://pypi.python.org/pypi/pybedlite +[python-version-badge]: https://img.shields.io/badge/python-3.8_|_3.9_|_3.10_|_3.11_|_3.12-blue +[python-version-link]: https://codecov.io/gh/fulcrumgenomics/pybedlite +[tests-badge]: https://github.com/fulcrumgenomics/pybedlite/workflows/tests/badge.svg +[tests-link]: https://github.com/fulcrumgenomics/pybedlite/actions/workflows/tests.yml?query=branch%3Amain # pybedlite From 6a41783a4ea5fdb569860e1dfa54c59352f311a7 Mon Sep 17 00:00:00 2001 From: clintval Date: Thu, 8 Aug 2024 09:50:21 -0700 Subject: [PATCH 06/11] chore: silence false positive flake8 lint --- pybedlite/tests/test_overlap_detector.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pybedlite/tests/test_overlap_detector.py b/pybedlite/tests/test_overlap_detector.py index 4208fe2..4bc801e 100644 --- a/pybedlite/tests/test_overlap_detector.py +++ b/pybedlite/tests/test_overlap_detector.py @@ -213,7 +213,7 @@ def test_construction_from_ucsc_with_strand(strand: str) -> None: `Interval.from_ucsc()` should correctly parse UCSC position-formatted strings with strands. """ expected_interval = Interval("chr1", 100, 200, negative=(strand == "-")) - assert Interval.from_ucsc(f"chr1:101-200({strand})") == expected_interval + assert Interval.from_ucsc(f"chr1:101-200({strand})") == expected_interval # noqa: E231 # false positive lint with flake8 @pytest.mark.parametrize( @@ -223,7 +223,7 @@ def test_construction_from_ucsc_other_contigs(contig: str) -> None: """ `Interval.from_ucsc()` should accommodate non-human, decoy, custom, and other contig names. """ - assert Interval.from_ucsc(f"{contig}:101-200") == Interval(contig, 100, 200) + assert Interval.from_ucsc(f"{contig}:101-200") == Interval(contig, 100, 200) # noqa: E231 # false positive lint with flake8 def test_that_overlap_detector_allows_generic_parameterization() -> None: From 39fc70d17ee3fe7e3c0b2ed6049f3b2ff6890d14 Mon Sep 17 00:00:00 2001 From: clintval Date: Thu, 8 Aug 2024 09:52:09 -0700 Subject: [PATCH 07/11] chore: style code --- pybedlite/tests/test_overlap_detector.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pybedlite/tests/test_overlap_detector.py b/pybedlite/tests/test_overlap_detector.py index 4bc801e..4aed439 100644 --- a/pybedlite/tests/test_overlap_detector.py +++ b/pybedlite/tests/test_overlap_detector.py @@ -213,7 +213,9 @@ def test_construction_from_ucsc_with_strand(strand: str) -> None: `Interval.from_ucsc()` should correctly parse UCSC position-formatted strings with strands. """ expected_interval = Interval("chr1", 100, 200, negative=(strand == "-")) - assert Interval.from_ucsc(f"chr1:101-200({strand})") == expected_interval # noqa: E231 # false positive lint with flake8 + assert ( + Interval.from_ucsc(f"chr1:101-200({strand})") == expected_interval + ) # noqa: E231 # false positive lint with flake8 @pytest.mark.parametrize( @@ -223,7 +225,9 @@ def test_construction_from_ucsc_other_contigs(contig: str) -> None: """ `Interval.from_ucsc()` should accommodate non-human, decoy, custom, and other contig names. """ - assert Interval.from_ucsc(f"{contig}:101-200") == Interval(contig, 100, 200) # noqa: E231 # false positive lint with flake8 + assert Interval.from_ucsc(f"{contig}:101-200") == Interval( + contig, 100, 200 + ) # noqa: E231 # false positive lint with flake8 def test_that_overlap_detector_allows_generic_parameterization() -> None: From 0779fd5ae169e94f5f026dc29b44f5b09a031851 Mon Sep 17 00:00:00 2001 From: clintval Date: Thu, 8 Aug 2024 09:54:52 -0700 Subject: [PATCH 08/11] chore: appease black and flake8 at the same time --- pybedlite/tests/test_overlap_detector.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pybedlite/tests/test_overlap_detector.py b/pybedlite/tests/test_overlap_detector.py index 4aed439..dcaac58 100644 --- a/pybedlite/tests/test_overlap_detector.py +++ b/pybedlite/tests/test_overlap_detector.py @@ -212,10 +212,9 @@ def test_construction_from_ucsc_with_strand(strand: str) -> None: """ `Interval.from_ucsc()` should correctly parse UCSC position-formatted strings with strands. """ + # false positive lint with flake8 below expected_interval = Interval("chr1", 100, 200, negative=(strand == "-")) - assert ( - Interval.from_ucsc(f"chr1:101-200({strand})") == expected_interval - ) # noqa: E231 # false positive lint with flake8 + assert Interval.from_ucsc(f"chr1:101-200({strand})") == expected_interval # noqa: E231 @pytest.mark.parametrize( @@ -225,9 +224,8 @@ def test_construction_from_ucsc_other_contigs(contig: str) -> None: """ `Interval.from_ucsc()` should accommodate non-human, decoy, custom, and other contig names. """ - assert Interval.from_ucsc(f"{contig}:101-200") == Interval( - contig, 100, 200 - ) # noqa: E231 # false positive lint with flake8 + # false positive lint with flake8 below + assert Interval.from_ucsc(f"{contig}:101-200") == Interval(contig, 100, 200) # noqa: E231 def test_that_overlap_detector_allows_generic_parameterization() -> None: From 6e7c52b93f078060e021c268408877219167531a Mon Sep 17 00:00:00 2001 From: clintval Date: Thu, 8 Aug 2024 15:24:30 -0700 Subject: [PATCH 09/11] chore: document the release process in a CONTRIBUTING.md --- CONTRIBUTING.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 47 ++++----------------------------- pyproject.toml | 2 +- 3 files changed, 75 insertions(+), 43 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e204371 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,69 @@ +# Contributing to pybedlite + +## Getting Setup for Development Work + +Clone the repository to your local machine. +Note that pybedlite includes [cgranges][cgranges-link] as a submodule, so you must use the `--recurse-submodules` option: + +``` +git clone --recurse-submodules https://github.com/fulcrumgenomics/pybedlite.git +``` + +[Poetry][poetry-link] is used to manage the python development environment. + +A simple way to create an environment with the desired version of python and poetry is to use [conda][conda-link]. E.g.: + +```bash +conda create -n pybedlite python=3.8 poetry=1.6 +conda activate pybedlite +poetry install +``` + +If the methods listed above do not work try the following: + +```bash +mamba create -n pybedlite -c conda-forge "python=3.9.16" "poetry=1.6.1" +mamba activate pybedlite +poetry install +``` + +[poetry-link]: https://github.com/python-poetry/poetry +[conda-link]: https://docs.conda.io/en/latest/miniconda.html +[cgranges-link]: https://github.com/lh3/cgranges + +## Checking the Build + +Check the library with: + +```bash +poetry run ./ci/check.sh +``` + +## Building the Documentation + +Build the documentation with: + +```bash +(cd docs/ && poetry run make html) +``` + +## Creating a Release on PyPi + +1. Clone the repository recursively and ensure you are on the `main` (un-dirty) branch +2. Checkout a new branch to prepare the library for release +3. Bump the version of the library to the desired SemVer with `poetry version #.#.#` +4. Commit the version bump changes with a Git commit message like `chore(release): bump to #.#.#` +5. Push the commit to the upstream remote, open a PR, ensure tests pass, and seek reviews +6. Squash merge the PR +7. Tag the new commit on the main branch of the repository with the new SemVer + +GitHub Actions will take care of the remainder of the deploy and release process with: + +1. Unit tests will be run for safety-sake +2. A source distribution will be built +3. Many multi-arch multi-Python binary distributions will be built +4. Assets will be deployed to PyPi with the new SemVer +5. A [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/)-aware changelog will be drafted +6. A GitHub release will be created with the new SemVer and the drafted changelog + +Consider editing the changelog if there are any errors or necessary enhancements. diff --git a/README.md b/README.md index 8c3db64..b9722ec 100644 --- a/README.md +++ b/README.md @@ -40,58 +40,21 @@ See documentation on [pybedlite.readthedocs.org][rtd-link]. -``` +```bash pip install pybedlite ``` OR -``` +```bash conda install -c bioconda pybedlite ``` OR -``` +```bash conda create -n pybedlite pybedlite conda activate pybedlite ``` [rtd-link]: http://pybedlite.readthedocs.org/en/stable -**Requires python 3.8+** (for python < 3.8, please use pybedlite <= 0.0.3) - -# Getting Setup for Development Work - -Clone the repository to your local machine. Note that pybedlite >= 0.0.4 includes [cgranges][cgranges-link] as a submodule, so you must use the `--recurse-submodules` option: -``` -git clone --recurse-submodules https://github.com/fulcrumgenomics/pybedlite.git -``` - -[Poetry][poetry-link] is used to manage the python development environment. - -A simple way to create an environment with the desired version of python and poetry is to use [conda][conda-link]. E.g.: +## Development and Testing -```bash -conda create -n pybedlite python=3.8 poetry -conda activate pybedlite -poetry install -``` - -If the methods listed above do not work try the following: -```bash -mamba create -n pybedlite -c conda-forge "python=3.9.16" "poetry=1.6.1" -mamba activate pybedlite -poetry install -``` - -If, during `poetry install` on Mac OS X errors are encountered running gcc/clang to build `pybedtools` or other packages with native code, try setting the following and re-running `poetry install`: -```bash -export CFLAGS="-stdlib=libc++" -``` - -[poetry-link]: https://github.com/python-poetry/poetry -[conda-link]: https://docs.conda.io/en/latest/miniconda.html -[cgranges-link]: https://github.com/lh3/cgranges - -## Checking the Build -### Run all checks with: -```bash -./ci/check.sh -``` +See the [contributing guide](./CONTRIBUTING.md) for more information. diff --git a/pyproject.toml b/pyproject.toml index cb5ec11..dda9687 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,7 @@ classifiers = [ "Topic :: Software Development :: Documentation", "Topic :: Software Development :: Libraries :: Python Modules", ] -include = ["LICENSE"] +include = ["LICENSE", "CONTRIBUTING.md"] packages = [{ include = "pybedlite" }, { include = "cgranges" }] [tool.poetry.dependencies] From 69c8340b9e19c67bfb28d0f60970240c848595ed Mon Sep 17 00:00:00 2001 From: clintval Date: Thu, 8 Aug 2024 15:25:41 -0700 Subject: [PATCH 10/11] chore: remove temp CI group --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index dda9687..c45af0f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,7 +69,6 @@ commit_parsers = [ { message = "^.+!:*", group = "Breaking"}, { message = "^feat*", group = "Features"}, { message = "^fix*", group = "Bug Fixes"}, - { message = "^[cC]i*", group = "CI/CD"}, { message = "^docs*", group = "Documentation"}, { message = "^perf*", group = "Performance"}, { message = "^refactor*", group = "Refactor"}, From b949f6d3fe88875b93cd8373f16c974a38ee11f0 Mon Sep 17 00:00:00 2001 From: clintval Date: Wed, 18 Sep 2024 13:54:29 -0700 Subject: [PATCH 11/11] chore: make the workflow named pybedlite-specific --- .github/workflows/{publish.yml => publish_pybedlite.yml} | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) rename .github/workflows/{publish.yml => publish_pybedlite.yml} (97%) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish_pybedlite.yml similarity index 97% rename from .github/workflows/publish.yml rename to .github/workflows/publish_pybedlite.yml index 6888582..f85d1d7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish_pybedlite.yml @@ -1,4 +1,4 @@ -name: publish +name: publish pybedlite on: push: @@ -124,7 +124,6 @@ jobs: uses: softprops/action-gh-release@v2 with: name: ${{ github.ref_name }} - body: | - ${{ needs.draft-changelog.outputs.release_body }} + body: ${{ needs.make-changelog.outputs.release_body }} draft: false prerelease: false