Skip to content

Commit

Permalink
Merge branch 'base' into py
Browse files Browse the repository at this point in the history
  • Loading branch information
rpatterson committed Jun 22, 2024
2 parents d16b8c3 + 104fe4e commit 61663d3
Show file tree
Hide file tree
Showing 36 changed files with 820 additions and 767 deletions.
4 changes: 2 additions & 2 deletions .env.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ PUID=${PUID}
PGID=${PGID}

# Constants specific to this project or checkout used in variable substitutions in
# `./docker-compose*.yml`. Don't change these during the ordinary course of development:
# `./compose*.yml`. Don't change these during the ordinary course of development:
# Capture the path of the checkout directory as seen by the real host running `#
# dockerd` so that following bind volumes have the correct source paths:
CHECKOUT_DIR=${CHECKOUT_DIR}
Expand All @@ -20,4 +20,4 @@ DOCKER_GID=${DOCKER_GID}
# Pin container image versions to avoid failures from external changes:
DOCKER_HADOLINT_DIGEST=@sha256:9cef74a390694cdc01dd119cbba9adac5bb6671ce67d8d79eb7ec68f497a3684
DOCKER_REUSE_DIGEST=@sha256:a0dca4eb014908af80608c06de3470b770a9c97f91041777d0c1cfbfeb8709f7
DOCKER_VALE_DIGEST=@sha256:da6a0901858421b282aa8d935e72831c84cebf716ae4e276658e9e5d382fad20
DOCKER_VALE_DIGEST=@sha256:2ae44f1276470dbf9e2f472c30caa9e8b0340f297a0ca7d02f5064d32ad6a35f
19 changes: 13 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ EMPTY=
COMMA=,
SPACE=$(EMPTY) $(EMPTY)
# Useful to update targets only one time per run including sub-makes:
export MAKE_RUN_UUID:=$(shell python3 -c "import uuid; print(uuid.uuid4())")
ifeq ($(origin MAKE_RUN_UUID), undefined)
export MAKE_RUN_UUID:=$(shell python3 -c "import uuid; print(uuid.uuid4())")
endif
# Workaround missing VCS glob wildcard matches under an editor:
# https://magit.vc/manual/magit/My-Git-hooks-work-on-the-command_002dline-but-not-inside-Magit.html
unexport GIT_LITERAL_PATHSPECS
Expand Down Expand Up @@ -236,13 +238,17 @@ export PYPI_PASSWORD
TEST_PYPI_PASSWORD?=
export TEST_PYPI_PASSWORD

# Variables related to tools managed by `./*compose*.yml`:
DOCKER_COMPOSE_UPGRADE=false

# https://www.sphinx-doc.org/en/master/usage/builders/index.html
# Run these Sphinx builders to test the correctness of the documentation:
# <!--alex disable gals-man-->
DOCS_SPHINX_BUILDERS=html dirhtml singlehtml htmlhelp qthelp epub applehelp latex man \
texinfo text gettext linkcheck xml pseudoxml
DOCS_SPHINX_ALL_FORMATS=$(DOCS_SPHINX_BUILDERS) devhelp pdf info
# <!--alex enable gals-man-->
DOCS_SPHINX_BUILD_OPTS=
# These builders report false warnings or failures:

# Override variable values if present in `./.env` and if not overridden on the
Expand Down Expand Up @@ -324,7 +330,7 @@ $(DOCS_SPHINX_BUILDERS:%=build-docs-%): ./.tox/$(PYTHON_HOST_ENV)/.tox-info.json
build-docs-pdf: build-docs-latex
# TODO: Switch to a TeX Live container for SVG support.
$(MAKE) -C "./build/docs/$(<:build-docs-%=%)/" \
LATEXMKOPTS="-f -interaction=nonstopmode" all-pdf || true
LATEXMKOPTS="-f -interaction=nonstopmode" all-pdf
.PHONY: build-docs-info
## Render the Texinfo documentation into a `*.info` file.
build-docs-info: build-docs-texinfo
Expand Down Expand Up @@ -643,7 +649,7 @@ devel-upgrade:
touch ./requirements/*.txt.in "./.env.in.~prereq~" "./.vale.ini" ./styles/*.ini
$(MAKE) PIP_COMPILE_ARGS="--upgrade" DOCKER_COMPOSE_UPGRADE=true \
$(PYTHON_ENVS:%=build-requirements-%) devel-upgrade-pre-commit \
devel-upgrade-js "./var/log/vale-rule-levels.log"
devel-upgrade-js "./.env.~out~" "./var/log/vale-rule-levels.log"
.PHONY: devel-upgrade-pre-commit
## Update VCS integration from remotes to the most recent tag.
devel-upgrade-pre-commit: ./.tox/build/.tox-info.json
Expand Down Expand Up @@ -754,15 +760,16 @@ $(foreach python_env,$(PYTHON_ENVS),\
$(MAKE) "$(HOST_TARGET_DOCKER)" "./.env.~out~"
mkdir -pv "$(dir $(@))"
# Workaround broken interactive session detection:
docker compose pull --quiet "vale" | tee -a "$(@)"
docker compose run --rm -T --entrypoint "true" vale | tee -a "$(@)"
docker compose pull --quiet "vale"
# Create the Docker compose network a single time under parallel make:
docker compose run --rm -T --entrypoint "date" vale | tee -a "$(@)"

# Local environment variables and secrets from a template:
./.env.in.~prereq~:
touch "$(@)"
./.env.in: ./.env.in.~prereq~
ifeq ($(DOCKER_COMPOSE_UPGRADE),true)
# Define the image tag to track in `./docker-compose*.yml` in the default values for the
# Define the image tag to track in `./compose*.yml` in the default values for the
# `${DOCKER_*_DIGEST}` environment variables and track the locked/frozen image digests
# in `./.env.in` in VCS:
#
Expand Down
109 changes: 60 additions & 49 deletions build-host/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,19 @@
## Container image in which to build, test, and release projects.

FROM docker:cli
# Defensive shell options:
SHELL ["/bin/ash", "-eu", "-c"]

# Least volatile layers first:

# Project constants:
ARG PROJECT_NAMESPACE=rpatterson
ARG PROJECT_NAME=project-structure

# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys
LABEL org.opencontainers.image.url="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}"
LABEL org.opencontainers.image.documentation="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}/-/blob/develop/build-host/README.rst"
LABEL org.opencontainers.image.source="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}/-/blob/develop/build-host/Dockerfile"
LABEL org.opencontainers.image.title="Project Structure Build Host"
LABEL org.opencontainers.image.description="Container image in which to build, test, and release projects."
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.authors="Ross Patterson <me@rpatterson.net>"
LABEL org.opencontainers.image.vendor="rpatterson.net"
LABEL org.opencontainers.image.base.name="docker.io/library/docker:latest"
# Build-time labels:
LABEL org.opencontainers.image.version=1.0.0

ENV PROJECT_NAMESPACE="${PROJECT_NAMESPACE}"
ENV PROJECT_NAME="${PROJECT_NAME}"
# Find the same home directory even when run as another user, for example `root`:
ENV HOME="/home/runner"
ENV PATH="${HOME}/.local/bin:${PATH}"
# Render template targets without user input:
ENV TEMPLATE_IGNORE_EXISTING=true
# Prevent Node Version Manager (NVM) installing into `/bin/versions/**`:
ENV NVM_DIR="${HOME}/.nvm"
# Node.js releases compatible with Alpine Linux based on musl libc:
# https://github.com/nvm-sh/nvm/issues/1102#issuecomment-550572252
ENV NVM_NODEJS_ORG_MIRROR="https://unofficial-builds.nodejs.org/download/release"
# Limit Python versions to the version installed into the image:
ENV PYTHON_MINORS="3.12"

ENTRYPOINT [ "docker-entrypoint.sh", "init-job.sh", "entrypoint.sh" ]
CMD [ "make", "-e", "build-docker" ]

# More volatile layers and layers with longer build times last:
# Avoid long re-build times, longest running layers first:

# Install the operating system packages needed to use the `./Makefile`. Also install
# any operating system packages the `./Makefile` might install to optimize build times:
# hadolint ignore=DL3018
RUN \
apk add --no-cache \
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
apk add \
"shadow" \
"coreutils" \
"diffutils" \
"make" \
"bash" \
"su-exec" \
Expand All @@ -63,30 +29,75 @@ RUN \
"curl" \
"imagemagick" \
"librsvg" \
"texlive-luatex" \
"texmf-dist-binextra" \
"texinfo" \
"texlive-full" \
"texmf-dist-latex" \
"texmf-dist-lang" \
"texmf-dist-latexrecommended" \
"texmf-dist-fontsrecommended" \
"texmf-dist-latexextra" \
"github-cli" \
&& groupdel "docker" \
&& apk del --no-cache "shadow" \
&& rm -rf /var/cache/apk/*
&& apk del "shadow"

# Bake external build dependencies into the image:
# Node.js releases compatible with Alpine Linux based on musl libc:
# https://github.com/nvm-sh/nvm/issues/1102#issuecomment-550572252
ENV NVM_NODEJS_ORG_MIRROR="https://unofficial-builds.nodejs.org/download/release"
# Prevent Node Version Manager (NVM) installing into `/bin/versions/**`:
ENV HOME="/home/runner"
ENV NVM_DIR="${HOME}/.nvm"
# hadolint ignore=DL3042,DL4006,SC1091
RUN --mount=type=cache,target=/root/.cache,sharing=locked \
pipx install "tox==4.11.3" && \
wget -qO- "https://github.com/raw/nvm-sh/nvm/v0.39.5/install.sh" | \
bash && \
echo 'nvm_get_arch() { nvm_echo x64-musl; }' >>"${HOME}/.nvm/nvm.sh" && \
. "${HOME}/.nvm/nvm.sh" || true && \
nvm install "20" && \
mkdir -pv "${HOME}/.local/state/${PROJECT_NAME}/log/"
echo 'nvm_get_arch() { nvm_echo x64-musl; }' >>"${HOME}/.nvm/nvm.sh" && set +u && \
. "${HOME}/.nvm/nvm.sh" || true && set -u && \
nvm install "20"

# Layers that don't vary between projects next:

# Find the same home directory even when run as another user, for example `root`:
ENV PATH="${HOME}/.local/bin:${PATH}"
# Render template targets without user input:
ENV TEMPLATE_IGNORE_EXISTING=true

ENTRYPOINT [ "docker-entrypoint.sh", "init-job.sh", "entrypoint.sh" ]
CMD [ "make", "-j", "release-all" ]

# More volatile, project-specific layers last:

# Project constants:
ARG PROJECT_NAMESPACE=rpatterson
ARG PROJECT_NAME=project-structure

# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys
LABEL org.opencontainers.image.url="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}"
LABEL org.opencontainers.image.documentation="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}/-/blob/develop/build-host/README.rst"
LABEL org.opencontainers.image.source="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}/-/blob/develop/build-host/Dockerfile"
LABEL org.opencontainers.image.title="Project Structure Build Host"
LABEL org.opencontainers.image.description="Container image in which to build, test, and release projects."
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.authors="Ross Patterson <me@rpatterson.net>"
LABEL org.opencontainers.image.vendor="rpatterson.net"
LABEL org.opencontainers.image.base.name="docker.io/library/docker:cli"
# Build-time labels:
LABEL org.opencontainers.image.version=2.0.0

ENV PROJECT_NAMESPACE="${PROJECT_NAMESPACE}"
ENV PROJECT_NAME="${PROJECT_NAME}"
# Limit Python versions to the version installed into the image:
ENV PYTHON_MINORS="3.12"

# Configure the VCS client for the image user:
ARG USER_SIGNINGKEY
RUN --mount=type=cache,target=/root/.cache,sharing=locked \
RUN \
git config -f "${HOME}/.gitconfig" "user.name" "CI Runner" && \
git config -f "${HOME}/.gitconfig" "user.email" \
"runner@build-host.${PROJECT_NAMESPACE:-rpatterson}.localhost" && \
git config --global user.signingkey "${USER_SIGNINGKEY}"
git config --global user.signingkey "${USER_SIGNINGKEY}" && \
mkdir -pv "${HOME}/.local/state/${PROJECT_NAME}/log/"

COPY [ "./bin/init-job.sh", "./bin/entrypoint.sh", "/usr/local/bin/" ]
72 changes: 32 additions & 40 deletions docker-compose.override.yml → compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,56 @@
#
# SPDX-License-Identifier: MIT

# Common configuration shared between services:

x-volume-checkout-service: &volume-checkout-service
type: "volume"
source: "checkout"
target: "/usr/local/src/project-structure"

x-service: &service
user: "${PUID:-1000}:${PGID:-${PUID:-1000}}"
environment:
TZ: "${TZ:-Etc/UTC}"
volumes:
- <<: *volume-checkout-service
working_dir: "/usr/local/src/project-structure${WORKTREE_REL:-}"

x-service-linter: &service-linter
<<: *service
profiles:
- "lint"

# Override `$ docker compose` configuration for development or testing here in this
# repository checkout. Put everything used outside this checkout in
# `./docker-compose.yml`.
# `./compose.yml`.
services:
reuse:
<<: *service-linter
image: "docker.io/fsfe/reuse${DOCKER_REUSE_DIGEST:-:latest-debian}"
command: >-
lint
# https://github.com/hadolint/hadolint#how-to-use
hadolint:
<<: *service-linter
# For this and other development tools in container images, define the image tag to
# follow when upgrading as the default and `./.env` controls the specific digest
# used currently:
image: "ghcr.io/hadolint/hadolint${DOCKER_HADOLINT_DIGEST:-:latest-debian}"
profiles:
- "lint"
environment:
TZ: "${TZ:-Etc/UTC}"
volumes:
- type: "volume"
source: "checkout"
target: "/usr/local/src/project-structure"
working_dir: "/usr/local/src/project-structure${WORKTREE_REL:-}"
command: >-
hadolint "./build-host/Dockerfile"
reuse:
image: "docker.io/fsfe/reuse${DOCKER_REUSE_DIGEST:-:latest-debian}"
profiles:
- "lint"
user: "${PUID:-1000}:${PGID:-${PUID:-1000}}"
environment:
TZ: "${TZ:-Etc/UTC}"
volumes:
- type: "volume"
source: "checkout"
target: "/usr/local/src/project-structure"
working_dir: "/usr/local/src/project-structure${WORKTREE_REL:-}"
command: >-
lint
vale:
<<: *service-linter
image: "docker.io/jdkato/vale${DOCKER_VALE_DIGEST:-:latest}"
profiles:
- "lint"
user: "${PUID:-1000}:${PGID:-${PUID:-1000}}"
environment:
TZ: "${TZ:-Etc/UTC}"
volumes:
- type: "volume"
source: "checkout"
target: "/usr/local/src/project-structure"
working_dir: "/usr/local/src/project-structure${WORKTREE_REL:-}"
command: >-
.
## Containers for simulating CI/CD:

build-host:
<<: *service
image: "${DOCKER_NAMESPACE:-merpatterson}/project-structure:build-host"
profiles:
- "ci"
Expand All @@ -70,9 +65,7 @@ services:
privileged: true
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- type: "volume"
source: "checkout"
target: "/usr/local/src/project-structure"
- <<: *volume-checkout-service
- "${CHECKOUT_DIR:-.}${WORKTREE_REL:-}/build-host/bin/init-job.sh\
:/usr/local/bin/init-job.sh"
- "${CHECKOUT_DIR:-.}${WORKTREE_REL:-}/build-host/bin/entrypoint.sh\
Expand All @@ -83,17 +76,16 @@ services:
:${SSH_AUTH_SOCK:-/run/user/${PUID:-1000}/ssh/agent.socket}"
- "~/.gnupg/:/home/runner/.gnupg/"
- "/run/user/${PUID:-1000}/gnupg/S.gpg-agent:/home/runner/.gnupg/S.gpg-agent"
working_dir: "/usr/local/src/project-structure${WORKTREE_REL:-}"
env_file: "./.env"
environment:
TZ: "${TZ:-Etc/UTC}"
PUID: "${PUID:-1000}"
PGID: "${DOCKER_GID:-${PGID:-${PUID:-1000}}}"
SSH_AUTH_SOCK: "${SSH_AUTH_SOCK:-/run/user/${PUID:-1000}/ssh/agent.socket}"
# Pass the bind volume source paths along as seen from the host `# dockerd`:
CHECKOUT_DIR: "${CHECKOUT_DIR:-.}"
WORKTREE_REL: "${WORKTREE_REL:-}"
# DEBUG: "true"
user: "0:0"
command: >-
make -j -O release-all
Expand Down
File renamed without changes.
1 change: 0 additions & 1 deletion docs/_static/logo-120.svg

This file was deleted.

3 changes: 0 additions & 3 deletions docs/_static/logo-120.svg.license

This file was deleted.

1 change: 0 additions & 1 deletion docs/_static/logo-32.svg

This file was deleted.

3 changes: 0 additions & 3 deletions docs/_static/logo-32.svg.license

This file was deleted.

1 change: 0 additions & 1 deletion docs/_static/logo.svg

This file was deleted.

1 change: 0 additions & 1 deletion docs/_static/logo.svg.license

This file was deleted.

2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
autoapi_keep_files = True

# -- Other formats -----------------------------------------------------------
latex_logo = './_static/logo.svg'
latex_logo = './_static/logo.png'
# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-applehelp_bundle_id
applehelp_bundle_id = 'net.rpatterson.project-structure'
# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-applehelp_disable_external_tools
Expand Down
Loading

0 comments on commit 61663d3

Please sign in to comment.