Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix CI for publishing
Browse files Browse the repository at this point in the history
chris-zen committed Jan 11, 2025
1 parent ad9d582 commit 71fb7f4
Showing 7 changed files with 225 additions and 124 deletions.
73 changes: 50 additions & 23 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -15,8 +15,8 @@ env:
PYTHON_VERSION: 3.11

jobs:
packages-build:
name: Build packages
checks:
name: Check code
runs-on: ubuntu-latest
env:
RUFF_FORMAT: github
@@ -29,25 +29,45 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Prepare virtual environment
run: make create-env
- uses: astral-sh/setup-uv@v4

- name: Check format
run: |
make check-format || true
BOLDRED=$(tput bold && tput setaf 1)
RESET=$(tput sgr0)
echo "${BOLDRED}==> We won't fail on formatting errors for the time being, but we will in the future.${RESET}"
echo "${BOLDRED}==> We won't penalise formatting errors for the time being, but we will in the future.${RESET}"
- name: Check lint
run: |
make check-lint || true
BOLDRED=$(tput bold && tput setaf 1)
RESET=$(tput sgr0)
echo "${BOLDRED}==> We won't fail on lint errors for the time being, but we will in the future.${RESET}"
echo "${BOLDRED}==> We won't enforce linting errors for the time being, but we will in the future.${RESET}"
wheels-build:
name: Build packages
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
env:
CIBW_BUILD_FRONTEND: "build[uv]"
# CIBW_REPAIR_WHEEL_COMMAND_MACOS: delocate-listdeps --all {wheel} && delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

- uses: astral-sh/setup-uv@v4

- name: Build packages
run: make build-dist
run: make build-platform-dist

- name: Upload packages
uses: actions/upload-artifact@v4
@@ -67,19 +87,24 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Prepare virtual environment
run: make create-env
- uses: astral-sh/setup-uv@v4

- name: Check Dockerfile
run: make check-docker

- name: Build Docker image
run: make build-image
run: make save-image

# TODO: Enable this when we figure out how to run it without having to download several Gigabytes of data.
# - name: Test Docker image
# run: make run-example

- name: Upload Docker image
uses: actions/upload-artifact@v4
with:
name: docker-image
path: oncodrivefml.tar

docs-build:
name: Build documentation
runs-on: ubuntu-latest
@@ -92,10 +117,9 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Prepare virtual environment
run: make create-env
- uses: astral-sh/setup-uv@v4

- name: Check version matching the tag
- name: Build the docs
shell: bash
run: make docs

@@ -110,7 +134,8 @@ jobs:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
needs:
- packages-build
- checks
- wheels-build
- docker-build
- docs-build

@@ -122,8 +147,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Prepare virtual environment
run: make create-env
- uses: astral-sh/setup-uv@v4

- name: Check version matching the tag
run: make check-version
@@ -143,13 +167,13 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Prepare virtual environment
run: make create-env
- uses: astral-sh/setup-uv@v4

- name: Download packages
uses: actions/download-artifact@v4
with:
name: python-packages
path: dist

- name: Publish to PyPI
env:
@@ -164,16 +188,19 @@ jobs:
- check-version

steps:
- if: ${{ env.DOCKER_USERNAME != '' }}
uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Prepare virtual environment
run: make create-env
- uses: astral-sh/setup-uv@v4

- name: Download Docker image
uses: actions/download-artifact@v4
with:
name: docker-image

- name: Login to DockerHub
env:
@@ -182,4 +209,4 @@ jobs:
run: make docker-login

- name: Push Docker image
run: make push-image
run: make load-image push-image
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -38,6 +38,9 @@ docs/build
# External users tests
external_checks

# VSCode
.vscode/

.ruff_cache/
.venv
data/
21 changes: 9 additions & 12 deletions CHANGELOG.rst → CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@

Changelog
=========
# Changelog

2.4.0
-----
## 2.5.0

- Adopted uv as a build tool and added a CI/CD pipeline

## 2.4.0

- The ``--no-indels`` flags only discards indels, it cannot enable their
analysis
@@ -13,19 +15,14 @@ Changelog
- Added seed as option in the configuration file
- Updated dependencies and dropped Python 3.5 support

2.3.0
-----
## 2.3.0

- Added option to set the size limit for the indels

2.2.0
-----
## 2.2.0

- Simplified signature computation using bgsignature.
Complex options should be computed externally.

- Adapted to bgparsers 0.9 that require a regions file with header.

- Simplified indels computation as assuming everything in the positive strand.

- Set by default the indels computation as substitutions.
- Set by default the indels computation as substitutions.
136 changes: 82 additions & 54 deletions Makefile
Original file line number Diff line number Diff line change
@@ -6,18 +6,24 @@ DOCS_DIR := $(ROOT_DIR)/docs
VENV_DIR := $(ROOT_DIR)/.venv

define version
$(shell $(VENV_DIR)/bin/python -c 'from oncodrivefml import __version__; print(__version__)')
$(shell uv run python -c "from oncodrivefml import __version__; print(__version__)")
endef

define git_tag_or_sha
$(shell git describe --tags --exact-match 2>/dev/null || git rev-parse --short HEAD)
endef

define image
bbglab/oncodrivefml:$(version)
bbglab/oncodrivefml:$(call version)
endef

GIT_TAG_OR_SHA = $(shell git describe --tags --exact-match 2>/dev/null || git rev-parse --short HEAD)
IMAGE_FILE := oncodrivefml.tar

BOLDRED := $(shell tput bold && tput setaf 1)
BOLDGREEN := $(shell tput bold && tput setaf 2)
BOLDYELLOW := $(shell tput bold && tput setaf 3)
BOLDBLUE := $(shell tput bold && tput setaf 4)
LIGHTBLUE := $(shell tput setaf 6)
WHITE := $(shell tput sgr0 && tput setaf 7)
RESET := $(shell tput sgr0)

@@ -32,9 +38,6 @@ help:
@echo "$(BOLDGREEN) check-docker $(WHITE)-> Check the Dockerfile"
@echo "$(BOLDGREEN) format $(WHITE)-> Format source code"
@echo "$(BOLDGREEN) build-dist $(WHITE)-> Build source and wheel distribution files"
@echo "$(BOLDGREEN) install-dev $(WHITE)-> Install the packages in editable mode"
@echo "$(BOLDGREEN) create-env $(WHITE)-> Create a virtual environment"
@echo "$(BOLDGREEN) remove-env $(WHITE)-> Remove the virtual environment"
@echo "$(BOLDGREEN) build-image $(WHITE)-> Build the Docker image"
@echo "$(BOLDGREEN) docker-login $(WHITE)-> Log in to DockerHub"
@echo "$(BOLDGREEN) push-image $(WHITE)-> Push the Docker image into DockerHub"
@@ -43,25 +46,47 @@ help:
@echo "$(BOLDGREEN) clean $(WHITE)-> Clean the working directory (build files, virtual environments, caches)"
@echo "$(RESET)"

$(VENV_DIR):
@echo "$(BOLDYELLOW)Preparing virtual environment ...$(RESET)"
python -m venv $(VENV_DIR)
$(VENV_DIR)/bin/pip install -U pip ruff setuptools wheel build twine
@echo "$(BOLDGREEN)==> Success!$(RESET)"
.PHONY: uv-installed
uv-installed:
@if ! which uv > /dev/null; then \
echo "$(BOLDRED)This project build is managed by $(BOLDYELLOW)uv$(BOLDRED), which is not installed.$(RESET)"; \
echo "$(LIGHTBLUE)Please follow these instructions to install it:$(RESET)"; \
echo "$(LIGHTBLUE)--> $(BOLDBLUE)https://docs.astral.sh/uv/#getting-started$(RESET)"; \
exit 1; \
fi

.PHONY: ruff-installed
ruff-installed: uv-installed
@if ! which ruff > /dev/null; then \
echo "$(BOLDRED)This project requires $(BOLDYELLOW)ruff$(BOLDRED), which is not installed.$(RESET)"; \
echo "$(LIGHTBLUE)Installing it with $(BOLDYELLOW)uv tool install ruff$(RESET)"; \
uv tool install ruff; \
ruff --version; \
fi

.PHONY: sphinx-installed
sphinx-installed: uv-installed
@if ! uv pip show sphinx > /dev/null; then \
echo "$(BOLDRED)This project requires $(BOLDYELLOW)sphinx$(BOLDRED), which is not installed.$(RESET)"; \
echo "$(LIGHTBLUE)Installing it with $(BOLDYELLOW)uv pip install --requirements optional-requirements.txt$(RESET)"; \
uv venv; \
uv pip install --requirements optional-requirements.txt; \
uv run sphinx-build --version; \
fi

.PHONY: checks
checks: check-format check-lint check-docker

.PHONY: check-format
check-format: $(VENV_DIR)
check-format: ruff-installed
@echo "$(BOLDGREEN)Checking code format ...$(RESET)"
$(VENV_DIR)/bin/ruff format --check
ruff format --check
@echo "$(BOLDGREEN)==> Success!$(RESET)"

.PHONY: check-lint
check-lint: $(VENV_DIR)
check-lint: ruff-installed
@echo "$(BOLDGREEN)Checking lint ...$(RESET)"
$(VENV_DIR)/bin/ruff check
ruff check
@echo "$(BOLDGREEN)==> Success!$(RESET)"

.PHONY: check-docker
@@ -75,51 +100,39 @@ check-docker:
@echo "$(BOLDGREEN)==> Success!$(RESET)"

.PHONY: check-version
check-version: $(VENV_DIR)
check-version: uv-installed
@echo "$(BOLDGREEN)Checking that the version matches the tag ...$(RESET)"
@if [ "$(version)" != "$(GIT_TAG_OR_SHA)" ]; then \
echo "$(BOLDRED)==> Version $(BOLDYELLOW)$(version)$(BOLDRED) doesn't match the git tag $(BOLDYELLOW)$(GIT_TAG_OR_SHA)$(BOLDRED) !!!$(RESET)"; \
@if [ "$(call version)" != "$(call git_tag_or_sha)" ]; then \
echo "$(BOLDRED)==> Version $(BOLDYELLOW)$(call version)$(BOLDRED) doesn't match the git tag $(BOLDYELLOW)$(call git_tag_or_sha)$(BOLDRED) !!!$(RESET)"; \
echo "$(BOLDRED)==> Please update the $(BOLDYELLOW)__version__$(BOLDRED) in $(BOLDYELLOW)oncodrivefml/__init__.py$(BOLDRED) and re-create the tag.$(RESET)"; \
exit 1; \
fi
@echo "$(BOLDGREEN)==> Success!$(RESET)"

.PHONY: format
format: $(VENV_DIR)
format: ruff-installed
@echo "$(BOLDGREEN)Formatting code ...$(RESET)"
$(VENV_DIR)/bin/ruff format
ruff format

.PHONY: build-dist
build-dist: $(VENV_DIR)
build-dist: uv-installed
@echo "$(BOLDGREEN)Building packages ...$(RESET)"
$(VENV_DIR)/bin/python -m build
uv build

.PHONY: build-platform-dist
build-platform-dist: uv-installed
uv venv
uv pip install cibuildwheel
uv run cibuildwheel --output-dir dist

.PHONY: publish-dist
publish-dist: $(VENV_DIR)
@echo "$(BOLDGREEN)Publishing OncodriveFML $(BOLDYELLOW)$(version)$(BOLDGREEN) to PyPI ...$(RESET)"
@if [[ -z "$(PYPI_TOKEN)" ]]; then \
echo "$(BOLDRED)==> Missing PYPI_TOKEN !!!$(RESET)"; \
publish-dist: uv-installed
@echo "$(BOLDGREEN)Publishing OncodriveCLUSTL $(BOLDYELLOW)$(call version)$(BOLDGREEN) to PyPI ...$(RESET)"
@if [ -z "$(PYPI_TOKEN)" ]; then \
echo "$(BOLDRED)==> Missing PyPI token !!!$(RESET)"; \
exit 1; \
fi
@$(VENV_DIR)/bin/twine upload --username __token__ --password $(PYPI_TOKEN) dist/*

.PHONY: install
install-dev: $(VENV_DIR)
$(VENV_DIR)/bin/pip install -e .

.PHONY: create-env
create-env: $(VENV_DIR)

.PHONY: remove-env
remove-env:
@echo "$(BOLDGREEN)Removing virtual environment ...$(RESET)"
rm -rf $(VENV_DIR)

.PHONY: build-image
build-image: $(VENV_DIR)
@echo "$(BOLDGREEN)Building Docker image $(BOLDYELLOW)$(image)$(BOLDGREEN) ...$(RESET)"
docker build --progress=plain -t $(image) .
@echo "$(BOLDGREEN)==> Success!$(RESET)"
uv publish --token $(PYPI_TOKEN)

.PHONY: docker-login
docker-login:
@@ -131,20 +144,35 @@ docker-login:
@(echo "$(DOCKER_PASSWORD)" | docker login -u $(DOCKER_USERNAME) --password-stdin) || (echo "$(BOLDRED)==> Failed to log in !!!$(RESET)"; exit 1)

.PHONY: build-image
push-image: $(VENV_DIR)
build-image: uv-installed
@echo "$(BOLDGREEN)Building Docker image $(BOLDYELLOW)$(call image)$(BOLDGREEN) ...$(RESET)"
docker build --progress=plain -t $(call image) .
@echo "$(BOLDGREEN)==> Success!$(RESET)"

.PHONY: save-image
save-image: build-image
@echo "$(BOLDGREEN)Saving Docker image $(BOLDYELLOW)$(call image)$(BOLDGREEN) ...$(RESET)"
docker save -o $(IMAGE_FILE) $(call image)
@echo "$(BOLDGREEN)==> Success!$(RESET)"

.PHONY: load-image
load-image: uv-installed
@echo "$(BOLDGREEN)Loading Docker image $(BOLDYELLOW)$(call image)$(BOLDGREEN) ...$(RESET)"
docker load -i $(IMAGE_FILE)
@echo "$(BOLDGREEN)==> Success!$(RESET)"

.PHONY: build-image
push-image: uv-installed
@echo "$(BOLDGREEN)Pushing the Docker image into the DockerHub ...$(RESET)"
docker push $(image)
docker push $(call image)
@echo "$(BOLDGREEN)==> Success!$(RESET)"

.PHONY: docs
docs: $(VENV_DIR)
@if ! which $(VENV_DIR)/bin/sphinx-build > /dev/null; then \
$(VENV_DIR)/bin/pip install -r optional-requirements.txt; \
fi
(source $(VENV_DIR)/bin/activate; make -C $(DOCS_DIR) html)
docs: sphinx-installed
(source .venv/bin/activate; make -C $(DOCS_DIR) html)

.PHONY: run-example
run-example:
run-example: build-image
@echo "$(BOLDGREEN)Running example ...$(RESET)"
docker run --rm -i \
-v $${BGDATA_LOCAL:-$${HOME}/.bgdata}:/root/.bgdata \
@@ -156,6 +184,6 @@ run-example:
.PHONY: clean
clean:
@echo "$(BOLDGREEN)Cleaning the repository ...$(RESET)"
rm -rf ./oncodrivefml.egg-info ./dist $(VENV_DIR) ./.ruff_cache ./.eggs $(DOCS_DIR)/build
rm -rf ./oncodrivefml.egg-info ./dist ./.ruff_cache ./.eggs $(DOCS_DIR)/build ./.venv
find oncodrivefml \( -name '*.c' -o -name '*.so' \) -type f -exec rm {} +
find . -name "__pycache__" -type d -exec rm -r {} +
2 changes: 1 addition & 1 deletion oncodrivefml/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__logger_name__ = 'oncodrivefml'
__version__ = "2.5.0"
__version__ = "2.5.0rc1"
80 changes: 80 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
[project]
name = "oncodrivefml"
dynamic = ["version"]
description = "Identify signals of positive selection in somatic mutations"
readme = "README.md"
license = {file = "LICENSE"}
authors = [
{ name = "BBGLab (Barcelona Biomedical Genomics Lab)", email = "bbglab@irbbarcelona.org" },
]
requires-python = ">=3.8.0,<3.12.0"
dependencies = [
"ago==0.0.93",
"bgcache==0.1",
"bgconfig==0.10",
"bgdata>=2.0.4",
"bglogs==0.6",
"bgparsers==0.10",
"bgreference==0.6",
"bgsignature==0.2",
"bokeh==1.4.0",
"click==8.0.4",
"intervaltree==3.1.0",
"Jinja2==3.0.3",
"numpy==1.24.4",
"matplotlib==3.6.3",
"pandas==1.5.3",
"pytabix==0.1",
"scipy==1.10.1",
"statsmodels==0.14.0",
]

[project.scripts]
oncodrivefml = "oncodrivefml.main:cmdline"

[project.urls]
Download = "https://pypi.org/project/oncodrivefml/#history"
Homepage = "https://github.com/bbglab/oncodrivefml"

# [build-system]
# requires = ["setuptools>=74.1", "Cython==0.29.37"]
# build-backend = "setuptools.build_meta"

# [tool.setuptools]
# ext-modules = [
# { name = "oncodrivefml.walker_cython", sources = ["oncodrivefml/walker_cython.pyx"] }
# ]

# [tool.setuptools.packages]
# find = {}

# [tool.setuptools.package-data]
# oncodrivefml = ["*.txt.gz", "*.conf.template", "*.conf.template.spec", "*.pyx", "*.json.gz"]

[build-system]
requires = ["hatchling", "Cython==0.29.37", "cibuildwheel==2.22.0"]
build-backend = "hatchling.build"

[tool.hatch.version]
path = "oncodrivefml/__init__.py"

[tool.hatch.build.targets.sdist]
include = ["/oncodrivefml"]
exclude = ["*.c", "*.so"]

[tool.hatch.build.targets.wheel]
packages = ["extra", "oncodrivefml"]
exclude = ["*.c", "*.so"]
include = [
"oncodrivefml/*.txt.gz",
"oncodrivefml/*.conf.template",
"oncodrivefml/*.conf.template.spec",
"oncodrivefml/*.pyx",
"oncodrivefml/*.json.gz"
]

[tool.hatch.build.targets.wheel.hooks.cython]
dependencies = ["hatch-cython"]

[tool.hatch.build.targets.wheel.hooks.cython.options]
src = ["oncodrivefml/walker_cython.pyx"]
34 changes: 0 additions & 34 deletions setup.py

This file was deleted.

0 comments on commit 71fb7f4

Please sign in to comment.