Skip to content

Commit

Permalink
Upgrading versions and adding Continuous Integration and Delivery
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-zen committed Dec 7, 2024
1 parent 2b3842e commit 1d61fd2
Show file tree
Hide file tree
Showing 15 changed files with 1,548 additions and 100 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.venv/
dist/
example/
oncodriveclustl.egg-info/
167 changes: 167 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
name: Build and Publish

on:
push:
tags:
- "**"
branches:
- "**"

permissions:
contents: read

env:
TERM: xterm

jobs:
packages-build:
name: Build packages
runs-on: ubuntu-latest
env:
RUFF_FORMAT: github

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"

- 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 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 enforce linting errors for the time being, but we will in the future.${RESET}"
- name: Build packages
run: make build-dist

- name: Upload packages
uses: actions/upload-artifact@v4
with:
name: python-packages
path: dist

docker-build:
name: Build Docker image
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"

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

- name: Check Dockerfile
run: make check-docker

- name: Build Docker 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: oncodriveclustl.tar

check-version:
name: Check version
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
needs:
- packages-build
- docker-build

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"

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

- name: Check version matching the tag
run: make check-version

packages-publish:
name: Publish packages
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
needs:
- check-version

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"

- 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:
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
if: ${{ env.PYPI_TOKEN != '' }}
run: make publish-dist

docker-push:
name: Push Docker image
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
needs:
- check-version

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

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"

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

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

- name: Login to DockerHub
if: ${{ env.DOCKER_USERNAME != '' }}
run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin

- name: Push Docker image
if: ${{ env.DOCKER_USERNAME != '' }}
run: make load-image push-image
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ dataset_randomizator.py
Distance_mutations.ipynb
oncodriveclustl/count_mutations.py
oncodriveclustl/mutations_intogen_local.txt
example/output
oncodriveclustl.tar

# Singularity images
*.simg
Expand All @@ -34,8 +36,14 @@ oncodriveclustl/mutations_intogen_local.txt
# gEdit temporal files
*~

# vscode
.vscode/

# Python bytecode
__pycache__
*.pyc
*.egg-info/
dist/

# uv files
.venv/
2 changes: 2 additions & 0 deletions .hadolint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ignored:
- DL3003
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.12.4
10 changes: 10 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM python:3.12-slim

# hadolint ignore=DL3042
RUN --mount=type=cache,target=/root/.cache/pip \
--mount=type=bind,target=/project,rw \
cd /project && pip install .

RUN oncodriveclustl --help

ENTRYPOINT [ "/usr/local/bin/oncodriveclustl" ]
4 changes: 0 additions & 4 deletions MANIFEST.in

This file was deleted.

150 changes: 150 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
ROOT_DIR := $(shell echo $(dir $(lastword $(MAKEFILE_LIST))) | sed 's|/*$$||')

SHELL := /bin/bash

define version
$(shell uv run python -c "from oncodriveclustl 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/oncodriveclustl:$(call version)
endef

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)


.PHONY: help
help:
@echo "$(BOLDYELLOW)Available targets:$(RESET)"
@echo
@echo "$(BOLDGREEN) checks $(WHITE)-> Run all the checks (format and lint)"
@echo "$(BOLDGREEN) check-format $(WHITE)-> Check for formatting errors"
@echo "$(BOLDGREEN) check-lint $(WHITE)-> Check for lint errors"
@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) build-image $(WHITE)-> Build the Docker image"
@echo "$(BOLDGREEN) push-image $(WHITE)-> Push the Docker image into DockerHub"
@echo "$(BOLDGREEN) run-example $(WHITE)-> Run the included example using the Docker image"
@echo "$(BOLDGREEN) clean $(WHITE)-> Clean the working directory (build files, virtual environments, caches)"
@echo "$(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: checks
checks: check-format check-lint check-docker

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

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

.PHONY: check-docker
check-docker:
@echo "$(BOLDGREEN)Checking Dockerfile ...$(RESET)"
docker run --rm -i \
-v $$(pwd):/project \
hadolint/hadolint hadolint \
--config /project/.hadolint.yaml \
/project/Dockerfile
@echo "$(BOLDGREEN)==> Success!$(RESET)"

.PHONY: check-version
check-version: uv-installed
@echo "$(BOLDGREEN)Checking that the version matches the tag ...$(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: ruff-installed
@echo "$(BOLDGREEN)Formatting code ...$(RESET)"
ruff format

.PHONY: build-dist
build-dist: uv-installed
@echo "$(BOLDGREEN)Building packages ...$(RESET)"
uv build

.PHONY: publish-dist
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
uv publish --token $(PYPI_TOKEN)

.PHONY: build-image
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 oncodriveclustl.tar $(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 oncodriveclustl.tar
@echo "$(BOLDGREEN)==> Success!$(RESET)"

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

.PHONY: run-example
run-example: uv-installed
@echo "$(BOLDGREEN)Running example ...$(RESET)"
uv run oncodriveclustl \
-i example/PAAD.tsv.gz -r example/cds.hg19.regions.gz -o example/output \
-sw 15 -cw 15 -simw 35 -sim region_restricted --concatenate --clustplot -e KRAS
@echo "$(BOLDGREEN)==> Success!$(RESET)"

.PHONY: clean
clean:
@echo "$(BOLDGREEN)Cleaning the repository ...$(RESET)"
rm -rf ./oncodriveclustl.egg-info ./dist ./.ruff_cache ./.venv oncodriveclustl.tar
find . -name "__pycache__" -type d -exec rm -r {} +
Loading

0 comments on commit 1d61fd2

Please sign in to comment.