How to pre-install pre commit into hooks into docker
Asked Answered
F

2

8

As I understand the documentation, whenever I add these lines to the config:

repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v2.1.0
    hooks:
    -   id: trailing-whitespace

it makes pre-commit to download the hooks code from this repo and execute it. Is it possible to pre-install all the hooks somehow into a Docker image. So when I call pre-commit run no network is used?

I found this section of the documentation describing how pre-commit caches all the repositories. They are stored in ~/.cache/pre-commit and this could be configured by updating PRE_COMMIT_HOME env variable.

However, the caching only works when I do pre-commit run. But I want to pre-install everything w/o running the checks. Is it possible?

Fabiolafabiolas answered 12/8, 2021 at 9:28 Comment(3)
Would there be an advantage to mounting the ~/.cache/pre-commit directory, allowing you to maintain/retain the cache outside the container?Shoreless
@Shoreless No. The idea is that you can pre-install stuff into the container, and then use it on different machines, in e.g. Jenkins. without network access. With the mounting approach, each Jenkins agent would need to download things on their own.Fabiolafabiolas
Makes perfect sense. I had a different use case, and this question/answers helped me solve my problems. Thanks!Shoreless
P
20

you're looking for the pre-commit install-hooks command

at the least you need something like this to cache the pre-commit environments:

COPY .pre-commit-config.yaml .
RUN git init . && pre-commit install-hooks

disclaimer: I created pre-commit

Plague answered 12/8, 2021 at 14:4 Comment(3)
When using in a a devcontainer in VSCode, I want the actual Git repository to be copied in, so I added an && rm -rf .git to make it clear the repository initialized in the image is just throwaway. In the postAttach script, I then am doing a pre-commit install to install the hook scripts on the repository.Betthezul
@AidanFeldman Since it only needs to run once, shouldn't ´pre-commit install` go in postCreateCommand and not postAttachCommand?Gaziantep
You could also run pre-commit install --install-hooks to install the hook environments at the same time.Gaziantep
U
2

Snippet provided by @anthony-sottile works like charm. It helps utilize docker cache. Here is a working variation for it from django world.

ARG PYTHON_VERSION=3.9-buster

# define an alias for the specfic python version used in this file.
FROM python:${PYTHON_VERSION} as python

# Python build stage
FROM python as python-build-stage

ARG BUILD_ENVIRONMENT=test

# Install apt packages
RUN apt-get update && apt-get install --no-install-recommends -y \
  # dependencies for building Python packages
  build-essential \
  # psycopg2 dependencies
  libpq-dev

# Requirements are installed here to ensure they will be cached.
COPY ./requirements .

# Create Python Dependency and Sub-Dependency Wheels.
RUN pip wheel --wheel-dir /usr/src/app/wheels  \
  -r ${BUILD_ENVIRONMENT}.txt


# Python 'run' stage
FROM python as python-run-stage

ARG BUILD_ENVIRONMENT=test
ARG APP_HOME=/app

ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
ENV BUILD_ENV ${BUILD_ENVIRONMENT}

WORKDIR ${APP_HOME}

# Install required system dependencies
RUN apt-get update && apt-get install --no-install-recommends -y \
  # psycopg2 dependencies
  libpq-dev \
  # Translations dependencies
  gettext \
  # cleaning up unused files
  && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
  && rm -rf /var/lib/apt/lists/*

# All absolute dir copies ignore workdir instruction. All relative dir copies are wrt to the workdir instruction
# copy python dependency wheels from python-build-stage
COPY --from=python-build-stage /usr/src/app/wheels  /wheels/

# use wheels to install python dependencies
RUN pip install --no-cache-dir --no-index --find-links=/wheels/ /wheels/* \
    && rm -rf /wheels/

COPY ./compose/test/django/entrypoint /entrypoint
RUN chmod +x /entrypoint

COPY .pre-commit-config.yaml .
RUN git init . && pre-commit install-hooks

# copy application code to WORKDIR
COPY . ${APP_HOME}

ENTRYPOINT ["/entrypoint"]

then you can fire pre-commit checks in similar fashion:

docker-compose -p project_name -f test.yml run --rm django pre-commit run --all-files
Utu answered 23/11, 2021 at 18:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.