diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfdb8b7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.sh text eol=lf diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..6d63ee3 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +* @Paebbels + +/.github/ @Paebbels diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a86307d..8b0f354 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,10 +8,8 @@ updates: prefix: "[Dependabot]" labels: - Dependencies - reviewers: - - Paebbels schedule: - interval: "daily" # Checks on Monday trough Friday. + interval: "weekly" # Maintain GitHub Action runners - package-ecosystem: "github-actions" @@ -21,11 +19,5 @@ updates: prefix: "[Dependabot]" labels: - Dependencies - assignees: - - Paebbels - - umarcor - reviewers: - - Paebbels - - umarcor schedule: - interval: "daily" # Checks on Monday trough Friday. + interval: "weekly" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4ed2d90..46a0566 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -18,7 +18,7 @@ * tbd * tbd -# Unit Tests +# Tests * tbd * tbd diff --git a/.github/workflows/Pipeline.yml b/.github/workflows/Pipeline.yml index cd11b2e..994c75f 100644 --- a/.github/workflows/Pipeline.yml +++ b/.github/workflows/Pipeline.yml @@ -6,33 +6,43 @@ on: jobs: MikTeX: - name: Build MikTeX base-image + name: 🛳️ Build MikTeX base-image runs-on: ubuntu-24.04 outputs: - base_image_os_version: ${{ steps.variables.outputs.base_image_os_version }} - base_image_py_version: ${{ steps.variables.outputs.base_image_py_version }} - miktex_image_ns: ${{ steps.variables.outputs.miktex_image_ns }} - miktex_image_name: ${{ steps.variables.outputs.miktex_image_name }} - miktex_image_tag: ${{ steps.variables.outputs.miktex_image_tag }} - miktex_image: ${{ steps.variables.outputs.miktex_image }} + base_image_os_version: ${{ steps.variables.outputs.base_image_os_version }} + base_image_os_codename: ${{ steps.variables.outputs.base_image_os_codename }} + base_image_py_version: ${{ steps.variables.outputs.base_image_py_version }} + miktex_source_repository: ${{ steps.variables.outputs.miktex_source_repository }} + miktex_image_ns: ${{ steps.variables.outputs.miktex_image_ns }} + miktex_image_name: ${{ steps.variables.outputs.miktex_image_name }} + miktex_image_tag: ${{ steps.variables.outputs.miktex_image_tag }} + miktex_image: ${{ steps.variables.outputs.miktex_image }} + miktex_version: ${{ steps.test.outputs.miktex_version }} steps: - name: 🖉 Variables id: variables run: | base_image_name="python" - base_image_py_version="3.13" - base_image_os_version="bookworm" + base_image_os_version="13" + base_image_os_codename="Bookworm" + base_image_os_size="-slim" + base_image_py_version="3.14" + + miktex_source_repository="${base_image_os_codename,,}" image_name="miktex" image_tag="latest" tee "${GITHUB_OUTPUT}" < "${OutputFile}" - - printf "%s\n" "${ANSI_BLUE}${OutputFile}${ANSI_NOCOLOR}" - printf "%s\n" "${ANSI_BLUE}--------------------------------------------------------------------------------${ANSI_NOCOLOR}" - while IFS='' read -r line; do - printf "%s\n" " ${ANSI_CYAN}$line${ANSI_NOCOLOR}" - done < "${OutputFile}" - printf "%s\n" "${ANSI_BLUE}--------------------------------------------------------------------------------${ANSI_NOCOLOR}" + cat "${OutputFile}" | sed 's/^/ /' + printf "::endgroup::\n" } DockerImageSizeUncompressed() { docker image inspect $1 --format='{{.Size}}' | numfmt --to=iec --format '%.2f' } - printf "%s\n" "Convert 'Common.list' to 'Packages.list' ..." + printf -- "Convert 'Common.list' to 'Packages.list' ...\n" RemoveComments Common.list Packages.list - printf "%s\n" "Building docker file 'Dockerfile' ..." + printf -- "Building docker file 'Dockerfile' ...\n" docker buildx build \ --file Dockerfile \ --build-arg IMAGE=${{ steps.variables.outputs.base_image }} \ - --build-arg OS_VERSION=${{ steps.variables.outputs.base_image_os_version }} \ - --build-arg PY_VERSION=${{ steps.variables.outputs.base_image_py_version }} \ + --build-arg MIKTEX_SRC_REPO=${{ steps.variables.outputs.miktex_source_repository }} \ + --label "org.opencontainers.image.title=MikTeX on Debian ${{ steps.variables.outputs.base_image_os_version }} (${{ steps.variables.outputs.base_image_os_codename }}) + Python ${{ steps.variables.outputs.base_image_py_version }}" \ + --label "org.opencontainers.image.description=MikTeX on Debian ${{ steps.variables.outputs.base_image_os_version }} (${{ steps.variables.outputs.base_image_os_codename }}) + Python ${{ steps.variables.outputs.base_image_py_version }} image maintained by pyTooling Authors." \ + --label "org.opencontainers.image.authors=Patrick Lehmann " \ + --label "org.opencontainers.image.vendor=pyTooling" \ + --label "org.opencontainers.image.version=1.0" \ + --label "org.opencontainers.image.revison=${GITHUB_SHA}" \ + --label "org.opencontainers.image.created=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \ + --label "org.opencontainers.image.url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ + --label "org.opencontainers.image.source=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" \ + --label "org.opencontainers.image.documentation=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/blob/main/README.md" \ + --label "org.opencontainers.image.license=MIT" \ + --label "pyTooling.dockerimages.os.name=Debian" \ + --label "pyTooling.dockerimages.os.version=${{ steps.variables.outputs.base_image_os_version }}" \ + --label "pyTooling.dockerimages.os.codename=${{ steps.variables.outputs.base_image_os_codename }}" \ + --label "pyTooling.dockerimages.os.variant=" \ + --label "pyTooling.dockerimages.os.packagemanager=apt" \ + --label "pyTooling.dockerimages.os.fullname=Debian ${{ steps.variables.outputs.base_image_os_version }} (${{ steps.variables.outputs.base_image_os_codename }})" \ + --label "pyTooling.dockerimages.py.version=${{ steps.variables.outputs.base_image_py_version }}" \ + --label "pyTooling.dockerimages.application.name=MikTeX" \ --tag "${{ steps.variables.outputs.miktex_image }}" \ . 2>&1 \ | ./Docker.buildx.sh - - printf "%s\n" "Docker image '${{ steps.variables.outputs.miktex_image }}' has $(DockerImageSizeUncompressed ${{ steps.variables.outputs.miktex_image }})" + # check return codes from docker incase of error. + + printf -- "Docker image '%s' has %s\n" "${{ steps.variables.outputs.miktex_image }}" "$(DockerImageSizeUncompressed ${{ steps.variables.outputs.miktex_image }})" - name: ☑ Checking MikTeX image '${{ steps.variables.outputs.miktex_image }}' + id: test run: | - printf "%s\n" "Docker image '${{ steps.variables.outputs.miktex_image }}' has $(DockerImageSizeUncompressed ${{ steps.variables.outputs.miktex_image }})" + DockerImageSizeUncompressed() { + docker image inspect $1 --format='{{.Size}}' | numfmt --to=iec --format '%.2f' + } + + printf -- "Docker image '%s' has %s\n" "${{ steps.variables.outputs.miktex_image }}" "$(DockerImageSizeUncompressed ${{ steps.variables.outputs.miktex_image }})" + printf -- "Labels of '${{ steps.variables.outputs.miktex_image }}':\n" + docker inspect --format='{{json .Config.Labels}}' "${{ steps.variables.outputs.miktex_image }}" | jq + + docker container run --rm ${{ steps.variables.outputs.miktex_image }} bash -c 'printf "%s\n" "which pdflatex: $(which pdflatex) ($(pdflatex --version | head -n 1))"' + MIKTEX_VERSION="$(docker container run --rm ${{ steps.variables.outputs.miktex_image }} bash -c "miktex --version | head -n 1")" - docker container run --rm ${{ steps.variables.outputs.miktex_image }} 'printf "%s\n" "which pdflatex: $(which pdflatex)"' + printf -- "MikTeX version (raw): %s\n" "${MIKTEX_VERSION}" + MIKTEX_VERSION="$(echo "${MIKTEX_VERSION}" | grep -oP '\(MiKTeX \d+\.\d+\)' | grep -oP '\d+\.\d+')" + + tee "${GITHUB_OUTPUT}" < "${OutputFile}" - - printf "%s\n" "${ANSI_BLUE}${OutputFile}${ANSI_NOCOLOR}" - printf "%s\n" "${ANSI_BLUE}--------------------------------------------------------------------------------${ANSI_NOCOLOR}" - while IFS='' read -r line; do - printf "%s\n" " ${ANSI_CYAN}$line${ANSI_NOCOLOR}" - done < "${OutputFile}" - printf "%s\n" "${ANSI_BLUE}--------------------------------------------------------------------------------${ANSI_NOCOLOR}" + cat "${OutputFile}" | sed 's/^/ /' + printf "::endgroup::\n" } DockerImageSizeUncompressed() { docker image inspect $1 --format='{{.Size}}' | numfmt --to=iec --format '%.2f' } - printf "%s\n" "Convert '${{ matrix.name }}.list' to 'Packages.list' ..." + printf -- "Convert '${{ matrix.name }}.list' to 'Packages.list' ...\n" RemoveComments ${{ matrix.name }}.list Packages.list - printf "%s\n" "Building docker file 'Dockerfile' ..." + printf -- "Building docker file 'Dockerfile' ...\n" docker buildx build \ --file Dockerfile.Specific \ --build-arg "IMAGE=${{ needs.MikTeX.outputs.miktex_image }}" \ - --build-arg "BASE_VARIANT=Debian ${{ needs.MikTeX.outputs.base_image_os_version }} with Python ${{ needs.MikTeX.outputs.base_image_py_version }}" \ - --build-arg "VARIANT=${{ matrix.name }}" \ + --label "org.opencontainers.image.title=MikTeX specific for ${{ matrix.name }} on Debian ${{ steps.variables.outputs.base_image_os_version }} (${{ steps.variables.outputs.base_image_os_codename }}) + Python ${{ steps.variables.outputs.base_image_py_version }}" \ + --label "org.opencontainers.image.description=MikTeX specific for ${{ matrix.name }} on Debian ${{ steps.variables.outputs.base_image_os_version }} (${{ steps.variables.outputs.base_image_os_codename }}) + Python ${{ steps.variables.outputs.base_image_py_version }} image maintained by pyTooling Authors." \ + --label "org.opencontainers.image.authors=Patrick Lehmann " \ + --label "org.opencontainers.image.vendor=pyTooling" \ + --label "org.opencontainers.image.version=1.0" \ + --label "org.opencontainers.image.revison=${GITHUB_SHA}" \ + --label "org.opencontainers.image.created=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \ + --label "org.opencontainers.image.url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ + --label "org.opencontainers.image.source=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" \ + --label "org.opencontainers.image.documentation=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/blob/main/README.md" \ + --label "org.opencontainers.image.license=MIT" \ + --label "pyTooling.dockerimages.application.variant=${{ matrix.name }}" \ --tag "${{ steps.variables.outputs.specific_image }}" \ . 2>&1 \ | ./Docker.buildx.sh - printf "%s\n" "Docker image '${{ steps.variables.outputs.specific_image }}' has $(DockerImageSizeUncompressed ${{ steps.variables.outputs.specific_image }})" + printf -- "Docker image '%s' has %s\n" "${{ steps.variables.outputs.specific_image }}" "$(DockerImageSizeUncompressed ${{ steps.variables.outputs.specific_image }})" - name: ☑ Checking MikTeX image '${{ steps.variables.outputs.specific_image }}' run: | - printf "%s\n" "Docker image '${{ steps.variables.outputs.specific_image }}' has $(DockerImageSizeUncompressed ${{ steps.variables.outputs.specific_image }})" + DockerImageSizeUncompressed() { + docker image inspect $1 --format='{{.Size}}' | numfmt --to=iec --format '%.2f' + } + + printf -- "Docker image '%s' has %s\n" "${{ steps.variables.outputs.specific_image }}" "$(DockerImageSizeUncompressed ${{ steps.variables.outputs.specific_image }})" + printf -- "Labels of '${{ steps.variables.outputs.miktex_image }}':\n" + docker inspect --format='{{json .Config.Labels}}' "${{ steps.variables.outputs.miktex_image }}" | jq - docker container run --rm ${{ steps.variables.outputs.specific_image }} 'printf "%s\n" "which pdflatex: $(which pdflatex)"' + docker container run --rm ${{ steps.variables.outputs.specific_image }} bash -c 'xelatex --version' - name: 🔑 Login and push '${{ steps.variables.outputs.specific_image }}' to Docker Hub run: | - printf "%s\n" "Login at Docker Hub ..." + DockerImageSizeUncompressed() { + docker image inspect $1 --format='{{.Size}}' | numfmt --to=iec --format '%.2f' + } + + printf -- "Login at Docker Hub ...\n" printf "%s\n" "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u ${{ vars.DOCKERHUB_USERNAME }} --password-stdin - printf "%s\n" "Docker image '${{ steps.variables.outputs.specific_image }}' has $(DockerImageSizeUncompressed ${{ steps.variables.outputs.specific_image }})" + printf -- "Docker image '%s' has %s\n" "${{ steps.variables.outputs.specific_image }}" "$(DockerImageSizeUncompressed ${{ steps.variables.outputs.specific_image }})" docker image push ${{ steps.variables.outputs.specific_image }} diff --git a/Docker.buildx.sh b/Docker.buildx.sh index 431693b..96ba8af 100755 --- a/Docker.buildx.sh +++ b/Docker.buildx.sh @@ -20,54 +20,39 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================= - -# work around for Darwin (Mac OS) -READLINK=readlink; if [[ $(uname) == "Darwin" ]]; then READLINK=greadlink; fi +# shellcheck shell=bash # Save working directory WorkingDir=$(pwd) -ScriptDir="$($READLINK -f $(dirname $0))" -RootDir="$($READLINK -f $ScriptDir/..)" - -ANSI_ENABLE_COLOR() { - ENABLECOLOR='-c ' - ANSI_BLACK=$'\x1b[30m' - ANSI_RED=$'\x1b[31m' - ANSI_GREEN=$'\x1b[32m' - ANSI_YELLOW=$'\x1b[33m' - ANSI_BLUE=$'\x1b[34m' - ANSI_MAGENTA=$'\x1b[35m' - ANSI_CYAN=$'\x1b[36m' - ANSI_DARK_GRAY=$'\x1b[90m' - ANSI_LIGHT_GRAY=$'\x1b[37m' - ANSI_LIGHT_RED=$'\x1b[91m' - ANSI_LIGHT_GREEN=$'\x1b[92m' - ANSI_LIGHT_YELLOW=$'\x1b[93m' - ANSI_LIGHT_BLUE=$'\x1b[94m' - ANSI_LIGHT_MAGENTA=$'\x1b[95m' - ANSI_LIGHT_CYAN=$'\x1b[96m' - ANSI_WHITE=$'\x1b[97m' - ANSI_NOCOLOR=$'\x1b[0m' - - # red texts - COLORED_ERROR="${ANSI_RED}[ERROR]" - COLORED_FAILED="${ANSI_RED}[FAILED]${ANSI_NOCOLOR}" +ScriptDir="$(readlink -f "$(dirname "$0")")" +RootDir="$(readlink -f "$ScriptDir/..")" - # yellow texts - COLORED_WARNING="${ANSI_YELLOW}[WARNING]" +ANSI_BLACK=$'\x1b[30m' +ANSI_RED=$'\x1b[31m' +ANSI_GREEN=$'\x1b[32m' +ANSI_YELLOW=$'\x1b[33m' +ANSI_BLUE=$'\x1b[34m' +ANSI_MAGENTA=$'\x1b[35m' +ANSI_CYAN=$'\x1b[36m' +ANSI_DARK_GRAY=$'\x1b[90m' +ANSI_LIGHT_GRAY=$'\x1b[37m' +ANSI_LIGHT_RED=$'\x1b[91m' +ANSI_LIGHT_GREEN=$'\x1b[92m' +ANSI_LIGHT_YELLOW=$'\x1b[93m' +ANSI_LIGHT_BLUE=$'\x1b[94m' +ANSI_LIGHT_MAGENTA=$'\x1b[95m' +ANSI_LIGHT_CYAN=$'\x1b[96m' +ANSI_WHITE=$'\x1b[97m' +ANSI_NOCOLOR=$'\x1b[0m' - # green texts - COLORED_PASSED="${ANSI_GREEN}[PASSED]${ANSI_NOCOLOR}" - COLORED_DONE="${ANSI_GREEN}[DONE]${ANSI_NOCOLOR}" - COLORED_SUCCESSFUL="${ANSI_GREEN}[SUCCESSFUL]${ANSI_NOCOLOR}" -} -ANSI_ENABLE_COLOR +# red texts +COLORED_ERROR="${ANSI_RED}[ERROR]" # command line argument processing COMMAND=2 # 0-help, 1-unknown option, 2-no arg needed INDENT="" VERBOSE=0; DEBUG=0 -while [[ $# > 0 ]]; do +while [[ $# -gt 0 ]]; do key="$1" case $key in -i|--indent) @@ -125,17 +110,24 @@ Pattern_CANCELED='#[0-9]+ CANCELED' Pattern_Tagging='#[0-9]+ naming to (.*?) done' Pattern_MIKTEX='#[0-9]+ [0-9]+\.[0-9]+ Installing package' -while IFS='\n' read -r line; do +group=0 +while IFS=$'\n' read -r line; do if [[ "${line}" =~ $Pattern_FROM ]]; then - printf "%s\n" "${INDENT}${ANSI_MAGENTA}${line}${ANSI_NOCOLOR}" + printf "::group::%s\n" "${INDENT}${ANSI_MAGENTA}${line}${ANSI_NOCOLOR}" + group=1 elif [[ "${line}" =~ $Pattern_RUN ]]; then - printf "%s\n" "${INDENT}${ANSI_CYAN}${line}${ANSI_NOCOLOR}" + printf "::group::%s\n" "${INDENT}${ANSI_CYAN}${line}${ANSI_NOCOLOR}" + group=1 elif [[ "${line}" =~ $Pattern_COPY ]]; then printf "%s\n" "${INDENT}${ANSI_LIGHT_CYAN}${line}${ANSI_NOCOLOR}" elif [[ "${line}" =~ $Pattern_LABEL_ENV ]]; then printf "%s\n" "${INDENT}${ANSI_BLUE}${line}${ANSI_NOCOLOR}" elif [[ "${line}" =~ $Pattern_DONE ]]; then + if [[ $group -eq 1 ]]; then + printf "::endgroup::\n" + fi printf "%s\n" "${INDENT}${ANSI_GREEN}${line}${ANSI_NOCOLOR}" + group=0 elif [[ "${line}" =~ $Pattern_ERROR ]]; then printf "%s\n" "${INDENT}${ANSI_LIGHT_RED}${line}${ANSI_NOCOLOR}" elif [[ "${line}" =~ $Pattern_CANCELED ]]; then diff --git a/Dockerfile b/Dockerfile index 466635d..4a9fef4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,10 @@ +# check=skip=InvalidDefaultArgInFrom;error=true + ARG IMAGE -ARG OS_VERSION -ARG PY_VERSION +ARG MIKTEX_SRC_REPO FROM ${IMAGE} -ARG OS_VERSION -ARG PY_VERSION - -# Meta information -LABEL maintainer="Patrick Lehmann " -LABEL version="0.1" -LABEL description="MikTeX based on Debian ${OS_VERSION} and Python ${PY_VERSION}." +ARG MIKTEX_SRC_REPO # Install Debian packages RUN apt-get update \ @@ -20,10 +15,11 @@ RUN apt-get update \ curl \ && rm -rf /var/lib/apt/lists/* \ && apt-get clean +# && apt-get dist-clean # Install MikTeX -RUN curl -fsSL https://miktex.org/download/key | tee /usr/share/keyrings/miktex-keyring.asc > /dev/null -RUN echo "deb [signed-by=/usr/share/keyrings/miktex-keyring.asc] https://miktex.org/download/debian ${OS_VERSION} universe" | tee /etc/apt/sources.list.d/miktex.list +RUN curl -fsSL https://miktex.org/download/key | gpg --dearmor -o /usr/share/keyrings/miktex.gpg +RUN echo "deb [signed-by=/usr/share/keyrings/miktex.gpg] https://miktex.org/download/debian bookworm universe" | tee /etc/apt/sources.list.d/miktex.list RUN apt-get update \ && apt-get install -y --no-install-recommends \ ghostscript \ @@ -32,6 +28,7 @@ RUN apt-get update \ miktex \ && rm -rf /var/lib/apt/lists/* \ && apt-get clean +# && apt-get dist-clean # Install executables like lualatex into /usr/local/bin RUN miktexsetup --shared=yes finish @@ -49,4 +46,4 @@ ENV MIKTEX_USERCONFIG=/miktex/.miktex/texmfs/config ENV MIKTEX_USERDATA=/miktex/.miktex/texmfs/data ENV MIKTEX_USERINSTALL=/miktex/.miktex/texmfs/install -ENTRYPOINT /bin/bash -l +ENV MIKTEX_MAINT_GIVEUP_AFTER_DAYS=9999 diff --git a/Dockerfile.Specific b/Dockerfile.Specific index 34942d1..da1e1fe 100644 --- a/Dockerfile.Specific +++ b/Dockerfile.Specific @@ -1,15 +1,8 @@ +# check=skip=InvalidDefaultArgInFrom;error=true + ARG IMAGE -ARG BASE_VARIANT -ARG VARIANT FROM ${IMAGE} -ARG BASE_VARIANT -ARG VARIANT - -# Meta information -LABEL maintainer="Patrick Lehmann " -LABEL version="0.1" -LABEL description="MikTeX with preinstalled packages for ${VARIANT} based on ${BASE_VARIANT}." RUN --mount=type=bind,target=/context \ miktex --admin --verbose packages update-package-database \ diff --git a/README.md b/README.md index a932c20..f0dea3d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # MikTeX Docker Image -This repository is based on [Debian 12.x Bookworm (slim) with Python 3.13](https://hub.docker.com/_/python). +This repository is based on [Debian 12.x Bookworm (slim) with Python 3.14](https://hub.docker.com/_/python). + +Docker Hub: https://hub.docker.com/r/pytooling/miktex ## Usage @@ -18,7 +20,7 @@ Installed additional tools are: * MikTeX * Preinstalled packages: [Common.list](Common.list) * Perl -* Python 3.13 +* Python 3.14 ## Why another MikTeX Docker Image?