diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 4b4036d7..71873240 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -144,3 +144,52 @@ jobs: path: dist/*.tar.gz if-no-files-found: error retention-days: 90 + docker-image-test: + runs-on: ubuntu-latest + # set a dependency sequence to occur after build job completion + needs: build + env: + version: ${{ needs.build.outputs.version }} + sdist_filename: pycytominer-${{ needs.build.outputs.version}}.tar.gz + sdist_extracted_name: pycytominer-${{ needs.build.outputs.version}} + steps: + # checks out selected files for docker image build testing + - name: Checkout selected files + uses: actions/checkout@v4 + with: + sparse-checkout: | + build/docker/Dockerfile + tests + sparse-checkout-cone-mode: false + - name: Download sdist artifact + uses: actions/download-artifact@v4 + with: + name: sdist + # gather the sdist tar.gz name (which varies) + # unzips the sdist + - name: Extract sdist + run: | + tar -xzvf "${{ env.sdist_filename}}" + # note: roughly follows Docker documentation on GitHub Actions usage + # found on the following https://github.com/docker/build-push-action + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + # attempts to build a test image for observing test behavior + # and modeling a production image build. Version label + # assumes pwd of, for example: pycytominer-1.0.1.post37.dev0+55690e4, + # where we attempt to use 1.0.1.post37.dev0+55690e4 as a version label. + - name: Build docker image for testing + run: | + cd "${{ env.sdist_extracted_name }}" && \ + cp -r ../tests . && \ + docker build -f ../build/docker/Dockerfile \ + -t pycytominer:testing \ + --label version="${{ env.version }}" \ + --target testing \ + . + # runs pytest for pycytominer within a docker container based on the image above + - name: Run tests through docker image + run: | + docker run pycytominer:testing pytest diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ee168710..89385f49 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,3 +18,7 @@ repos: rev: v1.6.26 hooks: - id: actionlint + - repo: https://github.com/hadolint/hadolint + rev: v2.12.1-beta + hooks: + - id: hadolint-docker diff --git a/Makefile b/Makefile index b97de95f..b184c7bd 100644 --- a/Makefile +++ b/Makefile @@ -18,3 +18,8 @@ help: # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +# note: presumes the existence of docker daemon to receive docker commands +test_docker_build: + docker build -f build/docker/Dockerfile -t pycytominer:latest . && \ + docker run pycytominer:latest poetry run pytest diff --git a/build/docker/Dockerfile b/build/docker/Dockerfile new file mode 100644 index 00000000..9948094a --- /dev/null +++ b/build/docker/Dockerfile @@ -0,0 +1,37 @@ +FROM python:3.11 as base + +# set various metadata, loosely following biocontainers standards from: +# https://biocontainers-edu.readthedocs.io/en/latest/what_is_biocontainers.html +LABEL base_image="python:3.11" +LABEL software="pycytominer" +LABEL about.summary="Python package for processing image-based profiling data" +LABEL about.home="https://github.com/cytomining/pycytominer" +LABEL about.documentation="https://pycytominer.readthedocs.io/en/stable/" +LABEL about.license_file="https://github.com/cytomining/pycytominer/blob/main/LICENSE.md" +LABEL about.license="SPDX:BSD-3-Clause" + +# set the workdir to /app +WORKDIR /app + +# configures poetry to install dependencies without virtualenvs +# see: https://python-poetry.org/docs/configuration/#virtualenvscreate +ENV POETRY_VIRTUALENVS_CREATE=false + +# install poetry and poetry dynamic versioning +# hadolint ignore=DL3013 +RUN pip install --no-cache-dir poetry + +# create stage for production build (no dev or non-essential deps) +FROM base as production + +# copy the pycytominer source into image +COPY . . + +# install pycytominer using poetry root dependencies and all extras +RUN poetry install --all-extras -v --no-interaction + +# create stage for production build (no dev or non-essential deps) +FROM production as testing + +# install pycytominer from poetry with group deps and all extras for testing +RUN poetry install --with dev --all-extras -v --no-interaction diff --git a/pyproject.toml b/pyproject.toml index e8d8dcfd..49b73e47 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,6 +39,7 @@ license = "BSD-3-Clause" readme = "README.md" homepage = "https://pycytominer.readthedocs.io/" repository = "https://github.com/cytomining/pycytominer" +include = [{ path = "poetry.lock", format = "sdist" }] [tool.poetry.dependencies] python = ">=3.8,<4.0"