From 67bfa6a84b9dbb82e5f154e44f0e5f775806f1a2 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 10:31:57 -0600 Subject: [PATCH 01/13] ctsm-docs build/publish workflow now includes version tag. --- .../workflows/docker-image-build-publish.yml | 11 +++++++- doc/ctsm-docs_container/Dockerfile | 3 ++- doc/ctsm-docs_container/get_version.sh | 26 +++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100755 doc/ctsm-docs_container/get_version.sh diff --git a/.github/workflows/docker-image-build-publish.yml b/.github/workflows/docker-image-build-publish.yml index b52be7f031..ae40f262d8 100644 --- a/.github/workflows/docker-image-build-publish.yml +++ b/.github/workflows/docker-image-build-publish.yml @@ -44,6 +44,13 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + # Get version label from Dockerfile using a shell script. + - name: Extract version from Dockerfile + id: version + run: | + VERSION="$(doc/ctsm-docs_container/get_version.sh)" + echo "version=$VERSION" >> $GITHUB_OUTPUT + # Uses the `docker/login-action` action to log in to the Container registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. - name: Log in to the Container registry uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 @@ -70,7 +77,9 @@ jobs: platforms: linux/amd64,linux/arm64 push: true load: false - tags: ${{ env.IMAGE_TAG }} + tags: | + ${{ env.IMAGE_TAG }} + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }} labels: "" # This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see [Using artifact attestations to establish provenance for builds](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds). diff --git a/doc/ctsm-docs_container/Dockerfile b/doc/ctsm-docs_container/Dockerfile index 90e3a6160e..f1844248d2 100644 --- a/doc/ctsm-docs_container/Dockerfile +++ b/doc/ctsm-docs_container/Dockerfile @@ -28,4 +28,5 @@ WORKDIR /home/user CMD ["/bin/bash", "-l"] LABEL org.opencontainers.image.title="Container for building CTSM documentation" -LABEL org.opencontainers.image.source=https://github.com/ESCOMP/CTSM \ No newline at end of file +LABEL org.opencontainers.image.source=https://github.com/ESCOMP/CTSM +LABEL org.opencontainers.image.version="v1.0.1" diff --git a/doc/ctsm-docs_container/get_version.sh b/doc/ctsm-docs_container/get_version.sh new file mode 100755 index 0000000000..485e720eff --- /dev/null +++ b/doc/ctsm-docs_container/get_version.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -e +cd doc/ctsm-docs_container + +# Extract version from Dockerfile +version="$(grep "org.opencontainers.image.version" Dockerfile | cut -d'"' -f2 | sort |uniq)" +n_found=$(echo $version | wc -w) + +# Error if anything other than exactly one version tag was found +if [[ ${n_found} -gt 1 ]]; then + echo -e "Multiple version tags found:\n${version}" >&2 + exit 2 +elif [[ ${n_found} -lt 1 ]]; then + echo "Expected 1 but found 0 version tags" >&2 + exit -1 +fi + +# Error if version doesn't start with v +if [[ "${version}" != "v"* ]]; then + echo "Version '${version}' doesn't start with v" >&2 + exit 22 +fi + +echo ${version} + +exit 0 From 51974c9d2ec88164f98ee1e8d7e26404e6e1dae8 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 10:44:07 -0600 Subject: [PATCH 02/13] ctsm-docs container build/publish workflow: Include "latest" tag. We should avoid relying on the "latest" tag for anything, but it's good practice to have one. --- .github/workflows/docker-image-build-publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/docker-image-build-publish.yml b/.github/workflows/docker-image-build-publish.yml index ae40f262d8..064d136e67 100644 --- a/.github/workflows/docker-image-build-publish.yml +++ b/.github/workflows/docker-image-build-publish.yml @@ -68,6 +68,7 @@ jobs: # This step uses the `docker/build-push-action` action to build the image, based on the ctsm-docs `Dockerfile`. # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see [Usage](https://github.com/docker/build-push-action#usage) in the README of the `docker/build-push-action` repository. # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. + # Note that we should avoid relying on the "latest" tag for anything, but it's good practice to have one. # v6.15.0 - name: Push Docker image id: push @@ -79,6 +80,7 @@ jobs: load: false tags: | ${{ env.IMAGE_TAG }} + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }} labels: "" From 0fe1e87c92be88dd548c0a7df058d8b55882d17f Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 10:47:53 -0600 Subject: [PATCH 03/13] ctsm-docs container: Fail publish if version tag exists. Requires updating version to v1.0.2, even though the container won't actually change. --- .github/workflows/docker-image-build-publish.yml | 9 +++++++-- doc/ctsm-docs_container/Dockerfile | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-image-build-publish.yml b/.github/workflows/docker-image-build-publish.yml index 064d136e67..dc3960fe01 100644 --- a/.github/workflows/docker-image-build-publish.yml +++ b/.github/workflows/docker-image-build-publish.yml @@ -49,7 +49,12 @@ jobs: id: version run: | VERSION="$(doc/ctsm-docs_container/get_version.sh)" - echo "version=$VERSION" >> $GITHUB_OUTPUT + VERSION_TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${VERSION}" + if docker manifest inspect $VERSION_TAG >/dev/null 2>&1; then + echo "Tag $VERSION_TAG already exists!" + exit 1 + fi + echo "version_tag=$VERSION_TAG" >> $GITHUB_OUTPUT # Uses the `docker/login-action` action to log in to the Container registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. - name: Log in to the Container registry @@ -81,7 +86,7 @@ jobs: tags: | ${{ env.IMAGE_TAG }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }} + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version_tag }} labels: "" # This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see [Using artifact attestations to establish provenance for builds](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds). diff --git a/doc/ctsm-docs_container/Dockerfile b/doc/ctsm-docs_container/Dockerfile index f1844248d2..1a0ae0c9f8 100644 --- a/doc/ctsm-docs_container/Dockerfile +++ b/doc/ctsm-docs_container/Dockerfile @@ -29,4 +29,4 @@ CMD ["/bin/bash", "-l"] LABEL org.opencontainers.image.title="Container for building CTSM documentation" LABEL org.opencontainers.image.source=https://github.com/ESCOMP/CTSM -LABEL org.opencontainers.image.version="v1.0.1" +LABEL org.opencontainers.image.version="v1.0.2" From 6b2c83c86573b92fd46dcee2261c0363263540db Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 10:54:45 -0600 Subject: [PATCH 04/13] Don't trigger Docker image workflows if only README changes. --- .github/workflows/docker-image-build-publish.yml | 6 +++--- .github/workflows/docker-image-build.yml | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-image-build-publish.yml b/.github/workflows/docker-image-build-publish.yml index dc3960fe01..2f26131bdf 100644 --- a/.github/workflows/docker-image-build-publish.yml +++ b/.github/workflows/docker-image-build-publish.yml @@ -2,12 +2,12 @@ name: Build and publish ctsm-docs Docker image on: - # Run this whenever something gets pushed to master + # Run this whenever a change to certain files gets pushed to master push: branches: ['master'] paths: - - 'doc/ctsm-docs_container/Dockerfile' - - 'doc/ctsm-docs_container/requirements.txt' + - 'doc/ctsm-docs_container/**' + - '!doc/ctsm-docs_container/README.md' # Run this whenever it's manually called workflow_dispatch: diff --git a/.github/workflows/docker-image-build.yml b/.github/workflows/docker-image-build.yml index e013b888a7..b3b8076bf2 100644 --- a/.github/workflows/docker-image-build.yml +++ b/.github/workflows/docker-image-build.yml @@ -6,12 +6,14 @@ on: push: paths: - 'doc/ctsm-docs_container/**' + - '!doc/ctsm-docs_container/README.md' - '.github/workflows/docker-image-ctsm-docs-build.yml' - '.github/workflows/docker-image-build-common.yml' pull_request: paths: - 'doc/ctsm-docs_container/**' + - '!doc/ctsm-docs_container/README.md' - '.github/workflows/docker-image-ctsm-docs-build.yml' - '.github/workflows/docker-image-build-common.yml' From 63cb052eb4d4fb309ce27a3923190988a02b387b Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 10:55:11 -0600 Subject: [PATCH 05/13] Correct a comment in a GH workflow. --- .github/workflows/docker-image-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image-build.yml b/.github/workflows/docker-image-build.yml index b3b8076bf2..b5779e78cc 100644 --- a/.github/workflows/docker-image-build.yml +++ b/.github/workflows/docker-image-build.yml @@ -1,7 +1,7 @@ # Modified from https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#publishing-a-package-using-an-action (last accessed 2025-05-09) name: Test building ctsm-docs Docker image and using it to build the docs -# Configures this workflow to run every time a change in the Docker container setup is pushed to the master branch +# Configures this workflow to run every time a change in the Docker container setup is pushed or included in a PR on: push: paths: From dd730c2ba45c72ccee11959ed5d535d8bf5cfe5f Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 12:09:40 -0600 Subject: [PATCH 06/13] Check version in Dockerfile as part of docker-image-common.yml. --- .../workflows/docker-image-build-publish.yml | 15 +---- .github/workflows/docker-image-common.yml | 11 ++++ .../workflows/docker-image-get-version.yml | 58 +++++++++++++++++++ 3 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/docker-image-get-version.yml diff --git a/.github/workflows/docker-image-build-publish.yml b/.github/workflows/docker-image-build-publish.yml index 2f26131bdf..bb221221ca 100644 --- a/.github/workflows/docker-image-build-publish.yml +++ b/.github/workflows/docker-image-build-publish.yml @@ -32,6 +32,7 @@ jobs: REGISTRY: ${{ needs.build-image-and-test-docs.outputs.REGISTRY }} IMAGE_NAME: ${{ needs.build-image-and-test-docs.outputs.IMAGE_NAME }} IMAGE_TAG: ${{ needs.build-image-and-test-docs.outputs.image_tag }} + VERSION_TAG: ${{ needs.build-image-and-test-docs.outputs.version_tag }} # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. permissions: @@ -44,18 +45,6 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - # Get version label from Dockerfile using a shell script. - - name: Extract version from Dockerfile - id: version - run: | - VERSION="$(doc/ctsm-docs_container/get_version.sh)" - VERSION_TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${VERSION}" - if docker manifest inspect $VERSION_TAG >/dev/null 2>&1; then - echo "Tag $VERSION_TAG already exists!" - exit 1 - fi - echo "version_tag=$VERSION_TAG" >> $GITHUB_OUTPUT - # Uses the `docker/login-action` action to log in to the Container registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. - name: Log in to the Container registry uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 @@ -86,7 +75,7 @@ jobs: tags: | ${{ env.IMAGE_TAG }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version_tag }} + ${{ env.VERSION_TAG }} labels: "" # This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see [Using artifact attestations to establish provenance for builds](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds). diff --git a/.github/workflows/docker-image-common.yml b/.github/workflows/docker-image-common.yml index 40cbd90ac3..257f078620 100644 --- a/.github/workflows/docker-image-common.yml +++ b/.github/workflows/docker-image-common.yml @@ -12,6 +12,9 @@ on: image_tag: description: "First image tag" value: ${{ jobs.build-image-and-test-docs.outputs.image_tag }} + version_tag: + description: "Version tag from Dockerfile" + value: ${{ jobs.check-version.outputs.VERSION_TAG }} # Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. env: @@ -81,3 +84,11 @@ jobs: id: build-docs run: | cd doc && ./build_docs -b ${PWD}/_build -c -d -i $IMAGE_TAG + + + check-version: + needs: build-image-and-test-docs + uses: ./.github/workflows/docker-image-get-version.yml + with: + registry: ${{ needs.build-image-and-test-docs.outputs.REGISTRY }} + image_name: ${{ needs.build-image-and-test-docs.outputs.IMAGE_NAME }} diff --git a/.github/workflows/docker-image-get-version.yml b/.github/workflows/docker-image-get-version.yml new file mode 100644 index 0000000000..480502bef2 --- /dev/null +++ b/.github/workflows/docker-image-get-version.yml @@ -0,0 +1,58 @@ +name: Get and check version specified in a Dockerfile + +on: + workflow_call: + inputs: + registry: + required: true # Require any workflows calling this one to provide input + type: string + default: 'ghcr.io' # Provide default so this workflow works standalone too + image_name: + required: true # Require any workflows calling this one to provide input + type: string + default: 'escomp/ctsm/ctsm-docs' # Provide default so this workflow works standalone too + outputs: + VERSION_TAG: + description: "Tag to be pushed to container registry" + value: ${{ jobs.get-check-version.outputs.VERSION_TAG }} + +# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. +jobs: + get-check-version: + name: Get version number from Dockerfile and check it + runs-on: ubuntu-latest + outputs: + VERSION_TAG: ${{ steps.get-check-version.outputs.version_tag }} + # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + permissions: + contents: read + packages: read + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Get version number from Dockerfile and check it + id: get-check-version + run: | + set -e + set -o pipefail + set -u + VERSION="$(doc/ctsm-docs_container/get_version.sh)" + VERSION_TAG="${{ inputs.registry }}/${{ inputs.image_name }}:${VERSION}" + + # Store the manifest inspect result and output + set +e + INSPECT_RESULT="$(docker manifest inspect "$VERSION_TAG" 2>&1)" + INSPECT_STATUS=$? + set -e + + if [[ "${INSPECT_RESULT}" == *"schemaVersion"* ]]; then + echo "Tag $VERSION_TAG already exists!" >&2 + exit 123 + elif [[ "${INSPECT_RESULT}" != "manifest unknown" ]]; then + # "manifest unknown" means the tag doesn't exist, which is what we want + echo -e "Error checking manifest for $VERSION_TAG:\n${INSPECT_RESULT}" >&2 + exit 2 + fi + echo "version_tag=$VERSION_TAG" >> $GITHUB_OUTPUT From fd6d7c9e462edb0669dd2570e1cd318028e3b36c Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 13:06:25 -0600 Subject: [PATCH 07/13] Ensure repo in IMAGE_NAME is always lowercase, per Docker rule. --- .github/workflows/docker-image-common.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-image-common.yml b/.github/workflows/docker-image-common.yml index 257f078620..7fc2f134de 100644 --- a/.github/workflows/docker-image-common.yml +++ b/.github/workflows/docker-image-common.yml @@ -19,7 +19,8 @@ on: # Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. env: REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }}/ctsm-docs + IMAGE_BASENAME: ctsm-docs + REPO: ${{ github.repository }} # There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. jobs: @@ -28,7 +29,7 @@ jobs: # Variables that might be needed by the calling workflow outputs: REGISTRY: ${{ env.REGISTRY }} - IMAGE_NAME: ${{ env.IMAGE_NAME }} + IMAGE_NAME: ${{ steps.set-image-name.outputs.IMAGE_NAME }} image_tag: ${{ steps.set-image-tag.outputs.IMAGE_TAG }} # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. permissions: @@ -42,6 +43,14 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + # Ensure that the repository part of IMAGE_NAME is lowercase. This is needed because Docker requires image names to be entirely lowercase. Note that the *image name* part, set as IMAGE_BASENAME in the env block above, is *not* converted. This will cause the check-version job to fail if the IMAGE_BASENAME contains capitals. We don't want to silently fix that here; rather, we require the user to specify a lowercase IMAGE_BASENAME. + - name: Get image name with lowercase repo + id: set-image-name + run: | + lowercase_repo=$(echo $REPO | tr '[:upper:]' '[:lower:]') + echo "IMAGE_NAME=${lowercase_repo}/${IMAGE_BASENAME}" >> $GITHUB_ENV + echo "IMAGE_NAME=${lowercase_repo}/${IMAGE_BASENAME}" >> $GITHUB_OUTPUT + # Uses the `docker/login-action` action to log in to the Container registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. - name: Log in to the Container registry uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 @@ -55,7 +64,7 @@ jobs: id: meta uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + images: ${{ env.REGISTRY }}/${{ steps.set-image-name.outputs.IMAGE_NAME }} # This step uses the `docker/build-push-action` action to build the image, based on the ctsm-docs `Dockerfile`. # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see [Usage](https://github.com/docker/build-push-action#usage) in the README of the `docker/build-push-action` repository. From c591a7c6da3391f18f553cae8f28c3cfb85e2e60 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 13:54:55 -0600 Subject: [PATCH 08/13] docker-image-get-version: Enable running on workflow dispatch. --- .github/workflows/docker-image-get-version.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/docker-image-get-version.yml b/.github/workflows/docker-image-get-version.yml index 480502bef2..d5ab6e2107 100644 --- a/.github/workflows/docker-image-get-version.yml +++ b/.github/workflows/docker-image-get-version.yml @@ -15,6 +15,18 @@ on: VERSION_TAG: description: "Tag to be pushed to container registry" value: ${{ jobs.get-check-version.outputs.VERSION_TAG }} + workflow_dispatch: + inputs: + registry: + description: 'Container registry' + required: false + type: string + default: 'ghcr.io' + image_name: + description: 'Image name' + required: false + type: string + default: 'escomp/ctsm/ctsm-docs' # There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. jobs: From 5e07fd56319f2bb5c43a9c93db6a0fdb5f796e69 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 15:31:51 -0600 Subject: [PATCH 09/13] docker-image-get-version.yml: Minor improvements. --- .github/workflows/docker-image-get-version.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-image-get-version.yml b/.github/workflows/docker-image-get-version.yml index d5ab6e2107..1a4ceb87b0 100644 --- a/.github/workflows/docker-image-get-version.yml +++ b/.github/workflows/docker-image-get-version.yml @@ -52,19 +52,21 @@ jobs: set -u VERSION="$(doc/ctsm-docs_container/get_version.sh)" VERSION_TAG="${{ inputs.registry }}/${{ inputs.image_name }}:${VERSION}" - + # Store the manifest inspect result and output set +e INSPECT_RESULT="$(docker manifest inspect "$VERSION_TAG" 2>&1)" INSPECT_STATUS=$? set -e - + if [[ "${INSPECT_RESULT}" == *"schemaVersion"* ]]; then echo "Tag $VERSION_TAG already exists!" >&2 exit 123 elif [[ "${INSPECT_RESULT}" != "manifest unknown" ]]; then # "manifest unknown" means the tag doesn't exist, which is what we want echo -e "Error checking manifest for $VERSION_TAG:\n${INSPECT_RESULT}" >&2 - exit 2 + exit $INSPECT_STATUS fi + + echo "Setting version_tag to $VERSION_TAG" echo "version_tag=$VERSION_TAG" >> $GITHUB_OUTPUT From fcc56645c696d2639b480f2008a54c0f97b9174d Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 15:45:28 -0600 Subject: [PATCH 10/13] Avoid tagging container with IMAGE_TAG (e.g., "master"). --- .github/workflows/docker-image-build-publish.yml | 2 -- .github/workflows/docker-image-common.yml | 2 -- 2 files changed, 4 deletions(-) diff --git a/.github/workflows/docker-image-build-publish.yml b/.github/workflows/docker-image-build-publish.yml index bb221221ca..9096434946 100644 --- a/.github/workflows/docker-image-build-publish.yml +++ b/.github/workflows/docker-image-build-publish.yml @@ -31,7 +31,6 @@ jobs: env: REGISTRY: ${{ needs.build-image-and-test-docs.outputs.REGISTRY }} IMAGE_NAME: ${{ needs.build-image-and-test-docs.outputs.IMAGE_NAME }} - IMAGE_TAG: ${{ needs.build-image-and-test-docs.outputs.image_tag }} VERSION_TAG: ${{ needs.build-image-and-test-docs.outputs.version_tag }} # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. @@ -73,7 +72,6 @@ jobs: push: true load: false tags: | - ${{ env.IMAGE_TAG }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest ${{ env.VERSION_TAG }} labels: "" diff --git a/.github/workflows/docker-image-common.yml b/.github/workflows/docker-image-common.yml index 7fc2f134de..0a0bbad9f7 100644 --- a/.github/workflows/docker-image-common.yml +++ b/.github/workflows/docker-image-common.yml @@ -30,7 +30,6 @@ jobs: outputs: REGISTRY: ${{ env.REGISTRY }} IMAGE_NAME: ${{ steps.set-image-name.outputs.IMAGE_NAME }} - image_tag: ${{ steps.set-image-tag.outputs.IMAGE_TAG }} # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. permissions: contents: read @@ -88,7 +87,6 @@ jobs: id: set-image-tag run: | echo "IMAGE_TAG=$(echo '${{ steps.meta.outputs.tags }}' | cut -d',' -f1)" >> $GITHUB_ENV - echo "IMAGE_TAG=$(echo '${{ steps.meta.outputs.tags }}' | cut -d',' -f1)" >> $GITHUB_OUTPUT - name: Build docs using container id: build-docs run: | From de2609f401fe1b22ff436710aabd79405edf33d9 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 17:00:40 -0600 Subject: [PATCH 11/13] ctsm-docs container README: Add auto-publishing info. --- doc/ctsm-docs_container/README.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/doc/ctsm-docs_container/README.md b/doc/ctsm-docs_container/README.md index bdd4eb3fa7..b502beb7e8 100644 --- a/doc/ctsm-docs_container/README.md +++ b/doc/ctsm-docs_container/README.md @@ -21,7 +21,26 @@ ghcr.io/escomp/ctsm/ctsm-docs latest ab51446519a4 3 seconds ago 233M To test, you can tell `build_docs` to use your new version by adding `--docker-image IMAGE_ID` to your call, where in the example above `IMAGE_ID` is `ab51446519a4`. -## Publishing +## Publishing automatically + +The `docker-image-build-publish.yml` workflow makes it so that new versions of the workflow will be published to the GitHub Container Registry whenever changes to the container setup are merged to CTSM's `master` branch. This will fail (as will a similar, no-publish workflow that happens on PRs) unless you specify exactly one new version number in the Dockerfile. This version number will be used as a tag that can be referenced by, e.g., doc-builder. + +Lots of Docker instructions tell you to use the `latest` tag, and indeed the workflow will add that tag automatically. However, actually _using_ `latest` can lead to support headaches as users think they have the right version but actually don't. Instead, you'll make a new version number incremented from the [previous one](https://github.com/ESCOMP/CTSM/pkgs/container/ctsm%2Fctsm-docs/versions), in the `vX.Y.Z` format. + +Here's where you need to specify the version number in the Dockerfile: +```docker +LABEL org.opencontainers.image.version="vX.Y.Z" +``` +The string there can technically be anything as long as (a) it starts with a lowercase `v` and (b) it hasn't yet been used on a published version of the container. + +You can check the results of the automatic publication on the [container's GitHub page](https://github.com/ESCOMP/CTSM/pkgs/container/ctsm%2Fctsm-docs). + +### Updating doc-builder +After the new version of the container is published, you will probably want to tell [doc-builder](https://github.com/ESMCI/doc-builder) to use the new one. Open a PR where you change the tag (the part after the colon) in the definition of `DEFAULT_DOCKER_IMAGE` in `doc_builder/build_commands.py`. Remember, **use the version number**, not "latest". + +## Publishing manually (NOT recommended) + +It's vastly preferable to let GitHub build and publish the new repo using the `docker-image-build-publish.yml` workflow as described above. However, if you need to publish manually for some reason, here's how. ### Pushing to GitHub Container Registry If you want to publish the container, you first need a [GitHub Personal Access Token (Classic)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#personal-access-tokens-classic) with the `write:packages` permissions. You can see your existing PAT(C)s [here](https://github.com/settings/tokens). If you don't have one with the right permissions, [this link](https://github.com/settings/tokens/new?scopes=write:packages) should start the setup process for you. @@ -49,7 +68,7 @@ docker push ghcr.io/escomp/ctsm/ctsm-docs:vX.Y.Z Then browse to the [container's GitHub page](https://github.com/ESCOMP/CTSM/pkgs/container/ctsm%2Fctsm-docs) to make sure this all worked and the image is public. ### Updating doc-builder -Since you've updated the container, you will probably want to tell [doc-builder](https://github.com/ESMCI/doc-builder) to use the new one. Open a PR where you change the tag (the part after the colon) in the definition of `DEFAULT_DOCKER_IMAGE` in `doc_builder/build_commands.py`. Remember, **use the version number**, not "latest". +See "Updating doc-builder" in the "Publishing automatically" section above. ## See also From 5fc502269af2d3bf0d9ce529a200bcf2d09316d2 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 17:02:27 -0600 Subject: [PATCH 12/13] ctsm-docs container README: Minor improvements. --- doc/ctsm-docs_container/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ctsm-docs_container/README.md b/doc/ctsm-docs_container/README.md index b502beb7e8..0af0ae71c0 100644 --- a/doc/ctsm-docs_container/README.md +++ b/doc/ctsm-docs_container/README.md @@ -7,7 +7,7 @@ This Readme tells you how to update the ctsm-docs Docker container if a need to ## Building -If you actually want to build the container, make sure Docker is running. In the Docker Desktop settings, make sure you've enabled the [`continerd` image store](https://docs.docker.com/desktop/features/containerd/), which allows multi-platform builds. Then do: +If you actually want to build the container, make sure Docker is running. In the Docker Desktop settings, make sure you've enabled the [`containerd` image store](https://docs.docker.com/desktop/features/containerd/), which allows multi-platform builds. Then do: ```shell docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/escomp/ctsm/ctsm-docs . ``` @@ -50,7 +50,7 @@ Once you have a PAT(C), you can authenticate in your shell session like so: ```shell echo YOUR_PERSONAL_ACCESS_TOKEN_CLASSIC | docker login ghcr.io -u YOUR_USERNAME --password-stdin ``` -The leading spaces are intended to prevent this command, which contains your secret PAT(C), from being written to your shell's history file. That at least works in bash... sometimes. To be extra safe, in bash you can do `history -c` and it will clear the session's history entirely. +The leading spaces are intended to prevent this command, which contains your secret PAT(C), from being written to your shell's history file. That at least works in bash... sometimes. To be extra safe, in bash you can do `history -c` and it will clear your entire bash history. That can be pretty disruptive, but fortunately you should only need to authenticate once. ### Tagging You'll next need to tag the image. Lots of Docker instructions tell you to use the `latest` tag, and Docker may actually do that for you. However, `latest` can lead to support headaches as users think they have the right version but actually don't. Instead, you'll make a new version number incremented from the [previous one](https://github.com/ESCOMP/CTSM/pkgs/container/ctsm%2Fctsm-docs/versions), in the `vX.Y.Z` format. From 5536915a770df4cc6e04530467b18172d32135df Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 13 May 2025 17:04:58 -0600 Subject: [PATCH 13/13] Update a Workflow comment. --- .github/workflows/docker-image-common.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image-common.yml b/.github/workflows/docker-image-common.yml index 0a0bbad9f7..94eb60c5f4 100644 --- a/.github/workflows/docker-image-common.yml +++ b/.github/workflows/docker-image-common.yml @@ -16,7 +16,7 @@ on: description: "Version tag from Dockerfile" value: ${{ jobs.check-version.outputs.VERSION_TAG }} -# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. +# Defines custom environment variables for the workflow. env: REGISTRY: ghcr.io IMAGE_BASENAME: ctsm-docs