Skip to content

chore: use Pixi for improved CI/CD and update project configuration #82

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 26, 2025
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
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# SCM syntax highlighting & preventing 3-way merges
pixi.lock merge=binary linguist-language=YAML linguist-generated=true
31 changes: 12 additions & 19 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,27 @@ jobs:
release-type: python
package-name: snakemake-interface-executor-plugins

publish:
publish-pypi:
runs-on: ubuntu-latest
needs: release-please
if: ${{ needs.release-please.outputs.release_created }}
steps:
- uses: actions/checkout@v3

- uses: actions/setup-python@v2
with:
python-version: "3.11"

- name: Install poetry
run: pip install poetry

- name: Determine dependencies
run: poetry lock
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v4
- name: Install Pixi
uses: prefix-dev/[email protected]
with:
python-version: "3.11"
cache: poetry
environments: publish
pixi-version: v0.42.1

- name: Install Dependencies using Poetry
- name: Build source and wheel distribution + check build
# this will build the source and wheel into the dist/ directory
run: |
poetry install
pixi run --environment publish check-build

- name: Publish to PyPi
- name: Publish distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
env:
PYPI_USERNAME: __token__
PYPI_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: poetry publish --build --username $PYPI_USERNAME --password $PYPI_PASSWORD
102 changes: 33 additions & 69 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,88 +7,52 @@ on:
pull_request:
branches-ignore: []

permissions:
contents: read
checks: write
issues: write
pull-requests: write

jobs:
formatting:
quality-control:
runs-on: ubuntu-latest
steps:
- name: Check out the code
uses: actions/checkout@v3

- uses: actions/setup-python@v4
with:
python-version: "3.11"

- name: Install poetry
run: pip install poetry

- name: Determine dependencies
run: poetry lock

- uses: actions/setup-python@v4
with:
python-version: "3.11"
cache: poetry
uses: actions/checkout@v4

- name: Install Dependencies using Poetry
run: poetry install

- name: Check formatting
run: poetry run black --check .

linting:
runs-on: ubuntu-latest
steps:
- name: Check out the code
uses: actions/checkout@v3

- uses: actions/setup-python@v4
- name: Install Pixi
uses: prefix-dev/[email protected]
with:
python-version: "3.11"

- name: Install poetry
run: pip install poetry
environments: dev
pixi-version: v0.42.1

- name: Determine dependencies
run: poetry lock

- uses: actions/setup-python@v4
with:
python-version: "3.11"
cache: poetry
- name: Ruff Format
if: always()
run: |
pixi run --environment dev format --check

- name: Install Dependencies using Poetry
run: poetry install
- name: Ruff lint
if: always()
run: |
pixi run --environment dev lint --diff
# - name: Mypy
# if: always()
# run: |
# pixi run --environment dev type-check

- name: Check code
run: poetry run flake8
- name: Collect QC
run: echo "All quality control checks passed"

testing:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: actions/setup-python@v4
- name: Install Pixi
uses: prefix-dev/[email protected]
with:
python-version: "3.11"

- name: Install poetry
run: pip install poetry

- name: Determine dependencies
run: poetry lock

- uses: actions/setup-python@v4
with:
python-version: "3.11"
cache: poetry

- name: Install dependencies
run: |
pip install connection-pool # because it is incompatible with poetry
poetry install

- name: Run pytest
run: poetry run coverage run -m pytest tests/tests.py
environments: dev
pixi-version: v0.42.1

- name: Run Coverage
run: poetry run coverage report -m
- name: Run tests
run: pixi run --environment dev test --show-capture=all -s -vv
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,8 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

poetry.lock
poetry.lock
# pixi environments
.pixi
*.egg-info
pixi.lock
86 changes: 65 additions & 21 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
[tool.poetry]
authors = ["Johannes Köster <[email protected]>"]
description = "This package provides a stable interface for interactions between Snakemake and its executor plugins."
license = "MIT"
[project]
name = "snakemake-interface-executor-plugins"
packages = [{include = "snakemake_interface_executor_plugins"}]
readme = "README.md"
version = "9.3.3"

[tool.poetry.dependencies]
argparse-dataclass = "^2.0.0"
python = "^3.11"
throttler = "^1.2.2"
snakemake-interface-common = "^1.17.4"

[tool.poetry.dev-dependencies]
black = "^24.0.0"
coverage = {extras = ["toml"], version = "^6.3.1"}
flake8 = "^4.0.1"
flake8-bugbear = "^22.1.11"
pytest = "^7.0"
snakemake = {git="https://github.com/snakemake/snakemake.git"}
snakemake-executor-plugin-cluster-generic = {git = "https://github.com/snakemake/snakemake-executor-plugin-cluster-generic.git"}
description = "This package provides a stable interface for interactions between Snakemake and its executor plugins."
authors = [{ name = "Johannes Köster", email = "[email protected]" }]
license = { text = "MIT" }
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"snakemake-interface-common>=1.17.4",
"throttler>=1.2.2",
"argparse-dataclass>=2.0.0",
]

[tool.coverage.run]
omit = [".*", "*/site-packages/*"]
Expand All @@ -31,3 +21,57 @@ fail_under = 63
[build-system]
build-backend = "poetry.core.masonry.api"
requires = ["poetry-core"]

[tool.pixi.project]
channels = ["conda-forge"]
platforms = ["osx-arm64", "linux-64"]

[tool.pixi.pypi-dependencies]

[tool.pixi.tasks]

[tool.pixi.environments]
dev = { features = ["dev"] }
publish = { features = ["publish"] }

[tool.pixi.feature.dev.pypi-dependencies]
snakemake-interface-executor-plugins = { path = ".", editable = true }
snakemake = { git = "https://github.com/snakemake/snakemake.git" }
snakemake-executor-plugin-cluster-generic = { git = "https://github.com/snakemake/snakemake-executor-plugin-cluster-generic.git" }

[tool.pixi.feature.dev.tasks.test]
cmd = [
"pytest",
"--cov=snakemake_interface_executor_plugins",
"--cov-report=xml:coverage-report/coverage.xml",
"--cov-report=term-missing",
"tests/tests.py"
]
description = "Run tests and generate coverage report"


[tool.pixi.feature.dev.dependencies]
pytest = ">=8.3.5,<9"
ruff = ">=0.10.0,<0.11"
mypy = ">=1.15.0,<2"
pytest-cov = ">=6.0.0,<7"

[tool.pixi.feature.dev.tasks]
format = "ruff format snakemake_interface_executor_plugins"
lint = "ruff check"
type-check = "mypy snakemake_interface_executor_plugins/"
qc = { depends-on = ["format", "lint", "type-check"] }

[tool.mypy]
ignore_missing_imports = true

# Publish
[tool.pixi.feature.publish.dependencies]
twine = ">=6.1.0,<7"
python-build = ">=1.2.2,<2"

[tool.pixi.feature.publish.tasks]
build = { cmd = "python -m build", description = "Build the package into the dist/ directory" }
check-build = { cmd = "python -m twine check dist/*", depends-on = [
"build",
], description = "Check that the package can be uploaded" }
3 changes: 2 additions & 1 deletion snakemake_interface_executor_plugins/executors/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ def isdigit(i):
for resource, value in job.resources.items()
if isinstance(value, int)
# need to check bool seperately because bool is a subclass of int
and isdigit(value) and resource not in excluded_resources
and isdigit(value)
and resource not in excluded_resources
}

def get_resource_declarations(self, job: JobExecutorInterface):
Expand Down