From 26ef06cc2759fc8ba8f61ff1f919c0f5e090cff2 Mon Sep 17 00:00:00 2001 From: Laurent Sorber Date: Wed, 29 Nov 2023 15:40:12 +0000 Subject: [PATCH 1/5] feat: update GitLab CI/CD to use the Dev Container CLI --- .github/workflows/test.yml | 14 +- .../.github/workflows/deploy.yml | 6 +- .../.github/workflows/publish.yml | 2 +- .../.github/workflows/test.yml | 10 +- .../.gitlab-ci.yml | 184 +++++++++--------- .../Dockerfile | 20 -- .../README.md | 1 - 7 files changed, 105 insertions(+), 132 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 34dee4bc..a4e106b9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: template @@ -34,16 +34,14 @@ jobs: cruft create --no-input --extra-context '{"package_name": "My Package", "python_version": "3.8", "docker_image":"radixai/python-gpu:$PYTHON_VERSION-cuda11.8", "with_fastapi_api": "1", "with_typer_cli": "1"}' ./template/ - name: Set up Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 21 - name: Install @devcontainers/cli - run: npm install --location=global @devcontainers/cli@0.41.0 + run: npm install --location=global @devcontainers/cli@0.54.0 - name: Start Dev Container with Python ${{ matrix.python-version }} - env: - DOCKER_BUILDKIT: 1 run: | git config --global init.defaultBranch main git init @@ -59,13 +57,13 @@ jobs: run: devcontainer exec --workspace-folder my-package poe test - name: Build ci Docker image - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v5 with: context: ./my-package/ target: ci - name: Build app Docker image - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v5 with: build-args: | SOURCE_BRANCH=${{ env.GITHUB_REF }} diff --git a/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/deploy.yml b/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/deploy.yml index bd08cdb1..8771a41c 100644 --- a/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/deploy.yml +++ b/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/deploy.yml @@ -30,10 +30,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Log in to the Docker registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: {% raw %}${{ env.DOCKER_REGISTRY }}{% endraw %} username: {% raw %}${{ github.actor }}{% endraw %} @@ -43,7 +43,7 @@ jobs: run: echo "GIT_TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV - name: Build and push Docker image - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v5 with: context: . push: true diff --git a/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/publish.yml b/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/publish.yml index 1d342e9c..546af45e 100644 --- a/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/publish.yml +++ b/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/publish.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 diff --git a/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/test.yml b/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/test.yml index dbb7e1ed..22148393 100644 --- a/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/test.yml +++ b/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/test.yml @@ -20,19 +20,17 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 21 - name: Install @devcontainers/cli - run: npm install --location=global @devcontainers/cli@0.41.0 + run: npm install --location=global @devcontainers/cli@0.54.0 - name: Start Dev Container - env: - DOCKER_BUILDKIT: 1 run: | git config --global init.defaultBranch main PYTHON_VERSION={% raw %}${{{% endraw %} matrix.python-version }} devcontainer up --workspace-folder . diff --git a/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml b/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml index 8f9a7199..58c6a284 100644 --- a/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml +++ b/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml @@ -1,103 +1,74 @@ stages: - - prebuild - build - test - {% if cookiecutter.with_fastapi_api|int or cookiecutter.with_streamlit_app|int %}deploy{% else %}publish{% endif %} -Compute CI image hash: - stage: prebuild - script: - - export DOCKER_IMAGE_SHA="$(sha1sum Dockerfile poetry.lock pyproject.toml | sha1sum | cut -c 1-12)" - - echo "CI_IMAGE_SHA=$DOCKER_IMAGE_SHA" >> .env - artifacts: - reports: - dotenv: .env +variables: + DOCKER_TLS_CERTDIR: "/certs" + +.parallel: + parallel: + matrix: + - PYTHON_VERSION: [{{ cookiecutter.python_version }}] -# Base Docker build script. -.docker: - image: docker:stable +# Build the Dev Container. +Build: + extends: .parallel + stage: build + image: docker:latest services: - - docker:stable-dind - variables: - DOCKER_REGISTRY: $CI_REGISTRY - DOCKER_REGISTRY_USER: $CI_REGISTRY_USER - DOCKER_REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD + - docker:dind script: - | - echo "$DOCKER_REGISTRY_PASSWORD" | docker login --username "$DOCKER_REGISTRY_USER" --password-stdin "$DOCKER_REGISTRY" - DOCKER_PUSH=${DOCKER_PUSH:-$(timeout 2s docker pull "$DOCKER_IMAGE":"$DOCKER_IMAGE_SHA" >/dev/null 2>&1 && echo $? || echo $?)} - if [ "$DOCKER_PUSH" -ne 1 ]; then - echo "$DOCKER_IMAGE:$DOCKER_IMAGE_SHA exists, skipping this job..." + # Log in to the Docker registry. + echo "$CI_REGISTRY_PASSWORD" | docker login --username "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY" + + # Install the Dev Container CLI. + apk add --update npm + npm install --location=global @devcontainers/cli@0.54.0 + + # Compute a hash for the Dev Container image. + export CI_IMAGE_SHA="$(sha1sum Dockerfile poetry.lock pyproject.toml | sha1sum | cut -c 1-8)" + echo "CI_IMAGE_SHA=$CI_IMAGE_SHA" >> .env + + # Build and push the Dev Container image, unless it already exists. + IMAGE_NAME="$CI_REGISTRY_IMAGE/devcontainer:$PYTHON_VERSION-$CI_IMAGE_SHA" + IMAGE_EXISTS=${IMAGE_EXISTS:-$(timeout 2s docker pull "$IMAGE_NAME" >/dev/null 2>&1 && echo $? || echo $?)} + if [ "$IMAGE_EXISTS" -ne 1 ]; then + echo "$IMAGE_NAME exists, skipping this job..." else - # Compile a list of image tags consisting of a hash of its contents, the latest tag if this - # pipeline is running for the default branch, and the Git tag if this commit is tagged. - DOCKER_TAGS="$DOCKER_IMAGE_SHA" - if [ "$CI_COMMIT_BRANCH" = "$CI_DEFAULT_BRANCH" ]; then DOCKER_TAGS="$DOCKER_TAGS latest"; fi - if [ -n "$CI_COMMIT_TAG" ]; then DOCKER_TAGS="$DOCKER_TAGS $CI_COMMIT_TAG"; fi - if [ -n "$CI_ENVIRONMENT_NAME" ]; then DOCKER_TAGS="$DOCKER_TAGS $CI_ENVIRONMENT_NAME"; fi - DOCKER_TAGS_JOINED="" - for DOCKER_TAG in $DOCKER_TAGS; do - DOCKER_TAGS_JOINED="$DOCKER_TAGS_JOINED --tag $DOCKER_IMAGE:$DOCKER_TAG" - done - - # Build the Docker image with all of the selected tags. {%- if cookiecutter.private_package_repository_name %} echo "[http-basic.{{ cookiecutter.private_package_repository_name|slugify }}]" >> auth.toml echo "username = \"gitlab-ci-token\"" >> auth.toml echo "password = \"$CI_JOB_TOKEN\"" >> auth.toml + export $POETRY_AUTH_TOML_PATH=$(pwd)/auth.toml {%- endif %} - DOCKER_BUILDKIT=1 docker build \ - --cache-from "$CI_REGISTRY_IMAGE/ci:$CI_IMAGE_SHA" \ - {%- if cookiecutter.private_package_repository_name %} - --secret id=poetry_auth,src=auth.toml \ - {%- endif %} - --target "$DOCKER_TARGET" \ - --pull \ - $DOCKER_TAGS_JOINED \ - . - - # Push all the tagged images. - for DOCKER_TAG in $DOCKER_TAGS; do - docker push "$DOCKER_IMAGE:$DOCKER_TAG" - done + devcontainer build --image-name "$IMAGE_NAME" --workspace-folder . + docker push "$IMAGE_NAME" fi - rules: - - if: $CI_PIPELINE_SOURCE != "merge_request_event" - - if: $CI_PIPELINE_SOURCE == "merge_request_event" - changes: - - Dockerfile - - poetry.lock - - pyproject.toml - -# Build CI Docker image. -Build CI image: - extends: - - .docker - stage: build - variables: - DOCKER_IMAGE: $CI_REGISTRY_IMAGE/ci - DOCKER_IMAGE_SHA: $CI_IMAGE_SHA - DOCKER_TARGET: ci + artifacts: + reports: + dotenv: .env # Lint and test the package. Test: + extends: .parallel stage: test - image: $CI_REGISTRY_IMAGE/ci:$CI_IMAGE_SHA - cache: - key: $CI_COMMIT_REF_SLUG - paths: - - .mypy_cache/ - - .pytest_cache/ + image: docker:latest + services: + - docker:dind script: - {%- if cookiecutter.private_package_repository_name %} - - poetry config http-basic.{{ cookiecutter.private_package_repository_name|slugify }} "gitlab-ci-token" "$CI_JOB_TOKEN" - {%- endif %} - - poe lint - - poe test + - | + apk add --update npm + npm install --location=global @devcontainers/cli@0.54.0 + devcontainer up --cache-from "type=registry,ref=$CI_REGISTRY_IMAGE/devcontainer:$PYTHON_VERSION-$CI_IMAGE_SHA" --workspace-folder . + devcontainer exec --workspace-folder . git config --global --add safe.directory /workspaces/{{ cookiecutter.__package_name_kebab_case }} + devcontainer exec --workspace-folder . poe lint + devcontainer exec --workspace-folder . poe test coverage: '/^TOTAL.*\s+(\d+(?:\.\d+)?)%/' artifacts: reports: - coverage_report: + coverage_report: coverage_format: cobertura path: reports/coverage.xml junit: @@ -107,10 +78,10 @@ Test: when: always {% if not cookiecutter.with_fastapi_api|int and not cookiecutter.with_streamlit_app|int -%} -# Publish this package version to a (private) package repository. +# Publish this package version to {% if cookiecutter.private_package_repository_name %}a private package repository{% else %}PyPI{% endif %}. Publish: stage: publish - image: $CI_REGISTRY_IMAGE/ci:$CI_IMAGE_SHA + image: $CI_REGISTRY_IMAGE/devcontainer:{{ cookiecutter.python_version }}-$CI_IMAGE_SHA script: {%- if cookiecutter.private_package_repository_name %} - poetry config repositories.private "{{ cookiecutter.private_package_repository_url.replace('simple/', '').replace('simple', '') }}" @@ -123,21 +94,48 @@ Publish: only: - tags {%- else -%} -# Build the application as a Docker image and push it to the GitLab registry. -.deploy: - extends: - - .docker +# Deploy the application to the Docker registry. +Deploy: stage: deploy - variables: - DOCKER_IMAGE: $CI_REGISTRY_IMAGE - DOCKER_IMAGE_SHA: ${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA} - DOCKER_PUSH: 1 - DOCKER_TARGET: app + image: docker:latest + services: + - docker:dind + script: + - | + # Log in to the Docker registry. + echo "$CI_REGISTRY_PASSWORD" | docker login --username "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY" + + # Compile a list of tags for the image. + DOCKER_TAGS="" + if [ "$CI_COMMIT_BRANCH" = "$CI_DEFAULT_BRANCH" ]; then DOCKER_TAGS="$DOCKER_TAGS latest"; fi + if [ -n "$CI_COMMIT_TAG" ]; then DOCKER_TAGS="$DOCKER_TAGS $CI_COMMIT_TAG"; fi + if [ -n "$CI_ENVIRONMENT_NAME" ]; then DOCKER_TAGS="$DOCKER_TAGS $CI_ENVIRONMENT_NAME"; fi + DOCKER_TAGS_JOINED="" + for DOCKER_TAG in $DOCKER_TAGS; do + DOCKER_TAGS_JOINED="$DOCKER_TAGS_JOINED --tag $CI_REGISTRY_IMAGE:$DOCKER_TAG" + done + + # Build the app image. + {%- if cookiecutter.private_package_repository_name %} + echo "[http-basic.{{ cookiecutter.private_package_repository_name|slugify }}]" >> auth.toml + echo "username = \"gitlab-ci-token\"" >> auth.toml + echo "password = \"$CI_JOB_TOKEN\"" >> auth.toml + {%- endif %} + docker build \ + --cache-from "type=registry,ref=$CI_REGISTRY_IMAGE/devcontainer:{{ cookiecutter.python_version }}-$CI_IMAGE_SHA" \ + --pull \ + {%- if cookiecutter.private_package_repository_name %} + --secret id=poetry-auth,src=auth.toml \ + {%- endif %} + --target app \ + $DOCKER_TAGS_JOINED \ + . + + # Push the tags to the Docker registry. + for DOCKER_TAG in $DOCKER_TAGS; do + docker push "$CI_REGISTRY_IMAGE:$DOCKER_TAG" + done + only: + - tags when: manual -{% for environment in ["feature", "development", "test", "acceptance", "production"] %} -Deploy ({{ environment }}): - extends: - - .deploy - environment: {{ environment }} -{% endfor %} {%- endif %} \ No newline at end of file diff --git a/{{ cookiecutter.__package_name_kebab_case }}/Dockerfile b/{{ cookiecutter.__package_name_kebab_case }}/Dockerfile index 2ee279c3..4ee75c7b 100644 --- a/{{ cookiecutter.__package_name_kebab_case }}/Dockerfile +++ b/{{ cookiecutter.__package_name_kebab_case }}/Dockerfile @@ -64,26 +64,6 @@ RUN --mount=type=cache,uid=$UID,gid=$GID,target=/home/user/.cache/pypoetry/ \ -FROM poetry as ci - -# Allow CI to run as root. -USER root - -# Install git so we can run pre-commit. -RUN --mount=type=cache,target=/var/cache/apt/ \ - --mount=type=cache,target=/var/lib/apt/ \ - apt-get update && \ - apt-get install --no-install-recommends --yes git - -# Install the CI/CD Python dependencies in the virtual environment. -RUN --mount=type=cache,target=/root/.cache/pypoetry/ \ - {%- if cookiecutter.private_package_repository_name %} - --mount=type=secret,id=poetry-auth,target=/root/.config/pypoetry/auth.toml \ - {%- endif %} - poetry install --only main,test --no-interaction - - - FROM poetry as dev # Install development tools: curl, git, gpg, ssh, starship, sudo, vim, and zsh. diff --git a/{{ cookiecutter.__package_name_kebab_case }}/README.md b/{{ cookiecutter.__package_name_kebab_case }}/README.md index 230422d0..02398cdc 100644 --- a/{{ cookiecutter.__package_name_kebab_case }}/README.md +++ b/{{ cookiecutter.__package_name_kebab_case }}/README.md @@ -47,7 +47,6 @@ _Python application_: to serve this {% if cookiecutter.with_fastapi_api|int %}RE 1. [Install Docker Desktop](https://www.docker.com/get-started). - Enable _Use Docker Compose V2_ in Docker Desktop's preferences window. - _Linux only_: - - [Configure Docker to use the BuildKit build system](https://docs.docker.com/build/buildkit/#getting-started). On macOS and Windows, BuildKit is enabled by default in Docker Desktop. - Export your user's user id and group id so that [files created in the Dev Container are owned by your user](https://github.com/moby/moby/issues/3206): ```sh cat << EOF >> ~/.bashrc From 6df314cffb70844c2e3eecdaede00f31623baf00 Mon Sep 17 00:00:00 2001 From: Laurent Sorber Date: Wed, 29 Nov 2023 15:45:02 +0000 Subject: [PATCH 2/5] fix: remove ci stage from tests --- .github/workflows/test.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a4e106b9..262ea3fc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -56,12 +56,6 @@ jobs: - name: Test package run: devcontainer exec --workspace-folder my-package poe test - - name: Build ci Docker image - uses: docker/build-push-action@v5 - with: - context: ./my-package/ - target: ci - - name: Build app Docker image uses: docker/build-push-action@v5 with: From b767313b5d3c435fa5fbca83adfcdf60fe6f705d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Go=C3=A1s=20Aguililla?= Date: Fri, 1 Dec 2023 12:03:06 +0100 Subject: [PATCH 3/5] fix: use double quotes around Python version --- {{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml b/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml index 58c6a284..a92b488e 100644 --- a/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml +++ b/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml @@ -9,7 +9,8 @@ variables: .parallel: parallel: matrix: - - PYTHON_VERSION: [{{ cookiecutter.python_version }}] + - PYTHON_VERSION: ["{{ cookiecutter.python_version }}"] + # Build the Dev Container. Build: From 8a23f88051c10e26d3f6797ff2cab3cb060eec6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Go=C3=A1s=20Aguililla?= Date: Fri, 1 Dec 2023 13:35:50 +0100 Subject: [PATCH 4/5] chore: simplify devcontainers install --- .../.dockerignore | 3 ++- .../.gitlab-ci.yml | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/{{ cookiecutter.__package_name_kebab_case }}/.dockerignore b/{{ cookiecutter.__package_name_kebab_case }}/.dockerignore index 191381ee..c79fc345 100644 --- a/{{ cookiecutter.__package_name_kebab_case }}/.dockerignore +++ b/{{ cookiecutter.__package_name_kebab_case }}/.dockerignore @@ -1 +1,2 @@ -.git \ No newline at end of file +.git +.*_cache \ No newline at end of file diff --git a/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml b/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml index a92b488e..4e8c783f 100644 --- a/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml +++ b/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml @@ -11,6 +11,15 @@ variables: matrix: - PYTHON_VERSION: ["{{ cookiecutter.python_version }}"] +.install_devcontainers_cli: &install_devcontainers_cli + cache: + paths: + - .apk_cache + - .npm_cache + before_script: + # Install the Dev Container CLI. + - mkdir -p .apk_cache && apk add --update-cache --cache-dir .apk_cache nodejs npm + - npm install --global --cache .npm_cache --prefer-offline @devcontainers/cli@0.54.0 # Build the Dev Container. Build: @@ -23,11 +32,7 @@ Build: - | # Log in to the Docker registry. echo "$CI_REGISTRY_PASSWORD" | docker login --username "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY" - - # Install the Dev Container CLI. - apk add --update npm - npm install --location=global @devcontainers/cli@0.54.0 - + # Compute a hash for the Dev Container image. export CI_IMAGE_SHA="$(sha1sum Dockerfile poetry.lock pyproject.toml | sha1sum | cut -c 1-8)" echo "CI_IMAGE_SHA=$CI_IMAGE_SHA" >> .env @@ -50,6 +55,7 @@ Build: artifacts: reports: dotenv: .env + <<: *install_devcontainers_cli # Lint and test the package. Test: @@ -60,8 +66,6 @@ Test: - docker:dind script: - | - apk add --update npm - npm install --location=global @devcontainers/cli@0.54.0 devcontainer up --cache-from "type=registry,ref=$CI_REGISTRY_IMAGE/devcontainer:$PYTHON_VERSION-$CI_IMAGE_SHA" --workspace-folder . devcontainer exec --workspace-folder . git config --global --add safe.directory /workspaces/{{ cookiecutter.__package_name_kebab_case }} devcontainer exec --workspace-folder . poe lint @@ -77,6 +81,7 @@ Test: - reports/pytest.xml untracked: true when: always + <<: *install_devcontainers_cli {% if not cookiecutter.with_fastapi_api|int and not cookiecutter.with_streamlit_app|int -%} # Publish this package version to {% if cookiecutter.private_package_repository_name %}a private package repository{% else %}PyPI{% endif %}. From c512d1298b59e557de5790e82f0bb4056b77d5a7 Mon Sep 17 00:00:00 2001 From: Laurent Sorber Date: Tue, 19 Dec 2023 13:41:21 +0000 Subject: [PATCH 5/5] refactor: simplify GitLab CI/CD script --- .github/workflows/test.yml | 2 +- .../.dockerignore | 7 +++++-- .../.github/workflows/test.yml | 2 +- .../.gitlab-ci.yml | 19 ++++++++++--------- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 262ea3fc..bed85160 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -39,7 +39,7 @@ jobs: node-version: 21 - name: Install @devcontainers/cli - run: npm install --location=global @devcontainers/cli@0.54.0 + run: npm install --location=global @devcontainers/cli@0.55.0 - name: Start Dev Container with Python ${{ matrix.python-version }} run: | diff --git a/{{ cookiecutter.__package_name_kebab_case }}/.dockerignore b/{{ cookiecutter.__package_name_kebab_case }}/.dockerignore index c79fc345..c17c79a6 100644 --- a/{{ cookiecutter.__package_name_kebab_case }}/.dockerignore +++ b/{{ cookiecutter.__package_name_kebab_case }}/.dockerignore @@ -1,2 +1,5 @@ -.git -.*_cache \ No newline at end of file +# Caches +.*_cache/ + +# Git +.git/ diff --git a/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/test.yml b/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/test.yml index 22148393..bc676f1f 100644 --- a/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/test.yml +++ b/{{ cookiecutter.__package_name_kebab_case }}/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: node-version: 21 - name: Install @devcontainers/cli - run: npm install --location=global @devcontainers/cli@0.54.0 + run: npm install --location=global @devcontainers/cli@0.55.0 - name: Start Dev Container run: | diff --git a/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml b/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml index 4e8c783f..112a02d4 100644 --- a/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml +++ b/{{ cookiecutter.__package_name_kebab_case }}/.gitlab-ci.yml @@ -6,24 +6,25 @@ stages: variables: DOCKER_TLS_CERTDIR: "/certs" -.parallel: +.python_matrix: parallel: matrix: - PYTHON_VERSION: ["{{ cookiecutter.python_version }}"] -.install_devcontainers_cli: &install_devcontainers_cli +.install_devcontainers_cli: cache: paths: - .apk_cache - .npm_cache before_script: - # Install the Dev Container CLI. - - mkdir -p .apk_cache && apk add --update-cache --cache-dir .apk_cache nodejs npm - - npm install --global --cache .npm_cache --prefer-offline @devcontainers/cli@0.54.0 + - mkdir -p .apk_cache && apk add --cache-dir .apk_cache npm + - npm install --cache .npm_cache --global --prefer-offline @devcontainers/cli@0.55.0 # Build the Dev Container. Build: - extends: .parallel + extends: + - .python_matrix + - .install_devcontainers_cli stage: build image: docker:latest services: @@ -55,11 +56,12 @@ Build: artifacts: reports: dotenv: .env - <<: *install_devcontainers_cli # Lint and test the package. Test: - extends: .parallel + extends: + - .python_matrix + - .install_devcontainers_cli stage: test image: docker:latest services: @@ -81,7 +83,6 @@ Test: - reports/pytest.xml untracked: true when: always - <<: *install_devcontainers_cli {% if not cookiecutter.with_fastapi_api|int and not cookiecutter.with_streamlit_app|int -%} # Publish this package version to {% if cookiecutter.private_package_repository_name %}a private package repository{% else %}PyPI{% endif %}.