diff --git a/.github/workflows/docker-image-build.yml b/.github/workflows/docker-image-build.yml index 0ac43426a6..6d38e12c8b 100644 --- a/.github/workflows/docker-image-build.yml +++ b/.github/workflows/docker-image-build.yml @@ -1,5 +1,5 @@ # 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 +name: Build and test ctsm-docs container # Configures this workflow to run every time a change in the Docker container setup is pushed or included in a PR on: @@ -9,7 +9,6 @@ on: paths: - 'doc/ctsm-docs_container/**' - '!doc/ctsm-docs_container/README.md' - - '.github/workflows/docker-image-ctsm-docs-build.yml' - '.github/workflows/docker-image-common.yml' pull_request: @@ -17,7 +16,6 @@ on: paths: - 'doc/ctsm-docs_container/**' - '!doc/ctsm-docs_container/README.md' - - '.github/workflows/docker-image-ctsm-docs-build.yml' - '.github/workflows/docker-image-common.yml' workflow_dispatch: diff --git a/.github/workflows/docker-image-common.yml b/.github/workflows/docker-image-common.yml index d44c14c1f8..3522069132 100644 --- a/.github/workflows/docker-image-common.yml +++ b/.github/workflows/docker-image-common.yml @@ -76,14 +76,16 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - # Try building our docs using the new container - - name: Checkout doc-builder external + # Check out all submodules because we might :literalinclude: something from one + - name: Checkout all submodules run: | - bin/git-fleximod update doc-builder + bin/git-fleximod update -o + - name: Set image tag for docs build id: set-image-tag run: | echo "IMAGE_TAG=$(echo '${{ steps.meta.outputs.tags }}' | head -n 1 | cut -d',' -f1)" >> $GITHUB_ENV + - name: Build docs using Docker (Podman has trouble on GitHub runners) id: build-docs run: | diff --git a/.github/workflows/docs-build-and-deploy.yml b/.github/workflows/docs-build-and-deploy.yml index 2c928e0ccb..1b0c0cb412 100644 --- a/.github/workflows/docs-build-and-deploy.yml +++ b/.github/workflows/docs-build-and-deploy.yml @@ -6,12 +6,14 @@ on: branches: ['master', 'release-clm5.0'] paths: - 'doc/**' + - '!doc/test/*' - '!doc/*ChangeLog*' - '!doc/*ChangeSum*' - '!doc/UpdateChangelog.pl' # Include all include::ed files outside doc/ directory! - 'src/README.unit_testing' - 'tools/README' + - 'doc/test/test_container_eq_ctsm_pylib.sh' # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -46,10 +48,14 @@ jobs: - name: Setup Pages uses: actions/configure-pages@v5 + # Check out all submodules because we might :literalinclude: something from one + - name: Checkout all submodules + run: | + bin/git-fleximod update -o + - name: Build docs using container id: build-docs run: | - bin/git-fleximod update -o cd doc ./build_docs_to_publish -d --site-root https://escomp.github.io/CTSM diff --git a/.github/workflows/docs-common.yml b/.github/workflows/docs-common.yml index 6dd8f7d53b..9c9d9f386c 100644 --- a/.github/workflows/docs-common.yml +++ b/.github/workflows/docs-common.yml @@ -26,9 +26,10 @@ jobs: fetch-depth: 0 lfs: true - - name: Checkout doc-builder external + # Check out all submodules because we might :literalinclude: something from one + - name: Checkout all submodules run: | - bin/git-fleximod update doc-builder + bin/git-fleximod update -o # Do this if not using conda # Based on https://github.com/actions/cache/blob/main/examples.md#python---pip diff --git a/.github/workflows/docs-omnibus.yml b/.github/workflows/docs-omnibus.yml index 1636150fae..1c73eb8224 100644 --- a/.github/workflows/docs-omnibus.yml +++ b/.github/workflows/docs-omnibus.yml @@ -5,29 +5,23 @@ on: # Run when a change to these files is pushed to any branch. Without the "branches:" line, for some reason this will be run whenever a tag is pushed, even if the listed files aren't changed. branches: ['*'] paths: - - 'doc/**' - - '!doc/*ChangeLog*' - - '!doc/*ChangeSum*' - - '!doc/UpdateChangelog.pl' - # Include all include::ed files outside doc/ directory! - - 'src/README.unit_testing' - - 'tools/README' + - 'doc/test/*' + - 'doc/Makefile' pull_request: # Run on pull requests that change the listed files paths: - - 'doc/**' - - '!doc/*ChangeLog*' - - '!doc/*ChangeSum*' - - '!doc/UpdateChangelog.pl' - # Include all include::ed files outside doc/ directory! - - 'src/README.unit_testing' - - 'tools/README' + - 'doc/test/*' + - 'doc/Makefile' workflow_dispatch: jobs: build-docs-omnibus-test: + # Don't run on forks, because part(s) of omnibus testing script will look for + # branch(es) that forks may not have. + if: ${{ github.repository == 'ESCOMP/CTSM' }} + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -35,9 +29,10 @@ jobs: fetch-depth: 0 lfs: true - - name: Checkout doc-builder external + # Check out all submodules because we might :literalinclude: something from one + - name: Checkout all submodules run: | - bin/git-fleximod update doc-builder + bin/git-fleximod update -o # Set up conda - name: Set up conda environment @@ -48,7 +43,6 @@ jobs: channels: conda-forge auto-activate-base: false - # TODO: Split testing.sh tests into their own steps in this job - name: Text Sphinx builds with omnibus script run: | - cd doc && ./testing.sh + cd doc/test/ && ./testing.sh diff --git a/.github/workflows/docs-ctsm_pylib.yml b/.github/workflows/docs-update-ctsm_pylib.yml similarity index 66% rename from .github/workflows/docs-ctsm_pylib.yml rename to .github/workflows/docs-update-ctsm_pylib.yml index 850f58063f..865f092f92 100644 --- a/.github/workflows/docs-ctsm_pylib.yml +++ b/.github/workflows/docs-update-ctsm_pylib.yml @@ -1,4 +1,4 @@ -name: Test building docs with ctsm_pylib +name: Docs tests to run when ctsm_pylib is updated on: push: @@ -6,13 +6,17 @@ on: branches: ['*'] paths: - 'python/conda_env_ctsm_py.txt' + - 'doc/ctsm-docs_container/requirements.txt' - '.github/workflows/docs-common.yml' + - '.github/workflows/docs-update-dependency-common.yml' pull_request: # Run on pull requests that change the listed files paths: - 'python/conda_env_ctsm_py.txt' + - 'doc/ctsm-docs_container/requirements.txt' - '.github/workflows/docs-common.yml' + - '.github/workflows/docs-update-dependency-common.yml' schedule: # 8 am every Monday UTC @@ -25,14 +29,23 @@ permissions: jobs: test-build-docs-ctsm_pylib: if: ${{ always() }} - name: With ctsm_pylib + name: Build with ctsm_pylib uses: ./.github/workflows/docs-common.yml with: use_conda: true conda_env_file: python/conda_env_ctsm_py.yml conda_env_name: ctsm_pylib - # File an issue if the docs build failed during a scheduled run + test-update-dependency: + if: ${{ always() }} + name: Docs dependency update tests + uses: ./.github/workflows/docs-update-dependency-common.yml + + # File an issue if the docs build failed during a scheduled run. + # The main thing we're concerned about in that case is something having + # changed outside the repository that's causing the ctsm_pylib setup to + # fail. Thus, we don't need this job to wait for BOTH the above jobs--- + # if one fails, they both will. file-issue-on-failure: if: | failure() && diff --git a/.github/workflows/docs-update-dependency-common.yml b/.github/workflows/docs-update-dependency-common.yml new file mode 100644 index 0000000000..a64e1a8ad5 --- /dev/null +++ b/.github/workflows/docs-update-dependency-common.yml @@ -0,0 +1,77 @@ +name: Jobs shared by docs workflows that run when a dependency is updated + +on: + workflow_call: + inputs: + # Conda is always needed for both jobs in this workflow. Here, + # we set default values for the variables in case the calling + # workflow doesn't provide them. + conda_env_file: + required: false + type: string + default: "python/conda_env_ctsm_py.yml" + conda_env_name: + required: false + type: string + default: "ctsm_pylib" + secrets: {} + +jobs: + compare-docbuilder-vs-ctsmpylib: + name: Are both methods identical? + + # Don't run on forks, because test_container_eq_ctsm_pylib.sh uses + # build_docs_to_publish, which will look for branch(es) that forks + # may not have + if: ${{ github.repository == 'ESCOMP/CTSM' }} + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + lfs: true + + # Check out all submodules because we might :literalinclude: something from one + - name: Checkout all submodules + run: | + bin/git-fleximod update -o + + - name: Set up conda environment + uses: conda-incubator/setup-miniconda@v3 + with: + activate-environment: ${{ inputs.conda_env_name }} + environment-file: ${{ inputs.conda_env_file }} + channels: conda-forge + auto-activate-base: false + + - name: Compare docs built with container vs. ctsm_pylib + run: | + cd doc/test/ + ./test_container_eq_ctsm_pylib.sh + + makefile-method: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + lfs: true + + # Check out all submodules because we might :literalinclude: something from one + - name: Checkout all submodules + run: | + bin/git-fleximod update -o + + - name: Set up conda environment + uses: conda-incubator/setup-miniconda@v3 + with: + activate-environment: ${{ inputs.conda_env_name }} + environment-file: ${{ inputs.conda_env_file }} + channels: conda-forge + auto-activate-base: false + + - name: Check that Makefile method works + run: | + cd doc/test/ + conda run -n ${{ inputs.conda_env_name }} --no-capture-output ./test_makefile_method.sh diff --git a/.github/workflows/docs-update-doc-builder.yml b/.github/workflows/docs-update-doc-builder.yml new file mode 100644 index 0000000000..0756ed94c5 --- /dev/null +++ b/.github/workflows/docs-update-doc-builder.yml @@ -0,0 +1,43 @@ +name: Docs tests to run when doc-builder is updated + +on: + push: + # Run when a change to these files is pushed to any branch. Without the "branches:" line, for some reason this will be run whenever a tag is pushed, even if the listed files aren't changed. + branches: ['*'] + paths: + - 'doc/doc-builder' + - '.github/workflows/docs-update-dependency-common.yml' + + pull_request: + # Run on pull requests that change the listed files + paths: + - 'doc/doc-builder' + - '.github/workflows/docs-update-dependency-common.yml' + + workflow_dispatch: + +permissions: + contents: read +jobs: + test-update-dependency: + + name: Tests to run when either docs dependency is updated + uses: ./.github/workflows/docs-update-dependency-common.yml + + test-rv-setup: + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + lfs: true + + # Check out all submodules because we might :literalinclude: something from one + - name: Checkout all submodules + run: | + bin/git-fleximod update -o + + - name: build_docs rv method + run: | + cd doc/test/ && ./test_build_docs_-r-v.sh docker diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 074a674ffe..362818eb90 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -7,6 +7,7 @@ on: branches: ['*'] paths: - 'doc/**' + - '!doc/test/*' - '!doc/*ChangeLog*' - '!doc/*ChangeSum*' - '!doc/UpdateChangelog.pl' @@ -14,11 +15,13 @@ on: # Include all include::ed files outside doc/ directory! - 'src/README.unit_testing' - 'tools/README' + - 'doc/test/test_container_eq_ctsm_pylib.sh' pull_request: # Run on pull requests that change the listed files paths: - 'doc/**' + - '!doc/test/*' - '!doc/*ChangeLog*' - '!doc/*ChangeSum*' - '!doc/UpdateChangelog.pl' @@ -26,6 +29,7 @@ on: # Include all include::ed files outside doc/ directory! - 'src/README.unit_testing' - 'tools/README' + - 'doc/test/test_container_eq_ctsm_pylib.sh' workflow_dispatch: @@ -49,9 +53,10 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Checkout doc-builder external + # Check out all submodules because we might :literalinclude: something from one + - name: Checkout all submodules run: | - bin/git-fleximod update doc-builder + bin/git-fleximod update -o - name: Build docs using Docker (Podman has trouble on GitHub runners) id: build-docs diff --git a/doc/ctsm-docs_container/Dockerfile b/doc/ctsm-docs_container/Dockerfile index 2ffd7a1702..5c78a0c14f 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.2c" +LABEL org.opencontainers.image.version="v1.0.2d" diff --git a/doc/source/users_guide/working-with-documentation/building-docs-multiple-versions.rst b/doc/source/users_guide/working-with-documentation/building-docs-multiple-versions.rst index dc53a2bc78..895dbf2a65 100644 --- a/doc/source/users_guide/working-with-documentation/building-docs-multiple-versions.rst +++ b/doc/source/users_guide/working-with-documentation/building-docs-multiple-versions.rst @@ -7,7 +7,7 @@ There is a menu in the lower left of the webpage that lets readers switch betwee Note that this is not necessary in order for you to contribute an update to the documentation. GitHub will test this automatically when you open a PR. But if you'd like to try, this will generate a local site for you in ``_publish/`` and then open it: -.. literalinclude:: ../../../testing.sh +.. literalinclude:: ../../../test/test_container_eq_ctsm_pylib.sh :start-at: ./build_docs_to_publish :end-before: VERSION LINKS WILL NOT RESOLVE :append: CMD _publish/index.html # where CMD is open for Mac or wslview for Windows (Ubuntu VM) diff --git a/doc/test/compose_test_cmd.sh b/doc/test/compose_test_cmd.sh new file mode 100755 index 0000000000..2b2fd3cf67 --- /dev/null +++ b/doc/test/compose_test_cmd.sh @@ -0,0 +1,13 @@ +# This should only be run locally within another shell + +if [[ "${cli_tool}" == "" ]]; then + echo "${msg} (no container)" +else + cmd="${cmd} -d" + if [[ "${cli_tool}" != "default" ]]; then + cmd="${cmd} --container-cli-tool ${cli_tool}" + fi + echo "${msg} (container: ${cli_tool})" +fi + +echo cmd diff --git a/doc/test/test_build_docs_-b.sh b/doc/test/test_build_docs_-b.sh new file mode 100755 index 0000000000..8b49e2f7aa --- /dev/null +++ b/doc/test/test_build_docs_-b.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +# Fail on any non-zero exit code +set -e + +cli_tool="$1" + +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +cd "${SCRIPT_DIR}/.." + +msg="~~~~~ Check that -b works" +cmd="./build_docs -b _build -c" + +. test/compose_test_cmd.sh +set -x +$cmd + +exit 0 diff --git a/doc/test/test_build_docs_-r-v.sh b/doc/test/test_build_docs_-r-v.sh new file mode 100755 index 0000000000..6f9415b563 --- /dev/null +++ b/doc/test/test_build_docs_-r-v.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +# Fail on any non-zero exit code +set -e + +cli_tool="$1" + +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +cd "${SCRIPT_DIR}/.." + +msg="~~~~~ Check that -r -v works" +cmd="./build_docs -r _build -v latest -c --conf-py-path doc-builder/test/conf.py --static-path ../_static --templates-path ../_templates" + +. test/compose_test_cmd.sh +set -x +$cmd + +exit 0 diff --git a/doc/test/test_container_eq_ctsm_pylib.sh b/doc/test/test_container_eq_ctsm_pylib.sh new file mode 100755 index 0000000000..729f1b723e --- /dev/null +++ b/doc/test/test_container_eq_ctsm_pylib.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Fail on any non-zero exit code +set -e + +# Compare docs built with container vs. ctsm_pylib + +cli_tool="$1" + +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +cd "${SCRIPT_DIR}/.." + +rm -rf _publish* + +# Build all docs using container +echo "~~~~~ Build all docs using container" +# Also do a custom --conf-py-path +rm -rf _build _publish +d1="$PWD/_publish_container" +./build_docs_to_publish -r _build -d --site-root "$PWD/_publish" +# VERSION LINKS WILL NOT RESOLVE IN _publish_container +cp -a _publish "${d1}" + +# Build all docs using ctsm_pylib +echo "~~~~~ Build all docs using ctsm_pylib" +rm -rf _build _publish +d2="$PWD/_publish_nocontainer" +conda run -n ctsm_pylib --no-capture-output ./build_docs_to_publish -r _build --site-root "$PWD/_publish" --conf-py-path doc-builder/test/conf.py --static-path ../_static --templates-path ../_templates +# VERSION LINKS WILL NOT RESOLVE IN _publish_nocontainer +cp -a _publish "${d2}" + +# Make sure container version is identical to no-container version +echo "~~~~~ Make sure container version is identical to no-container version" +diff -qr "${d1}" "${d2}" +echo "Successful: Docs built with container are identical to those built without" + +exit 0 diff --git a/doc/test/test_doc-builder_tests.sh b/doc/test/test_doc-builder_tests.sh new file mode 100755 index 0000000000..07cfa73ea1 --- /dev/null +++ b/doc/test/test_doc-builder_tests.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Fail on any non-zero exit code +set -e + +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +cd "${SCRIPT_DIR}" + +echo "~~~~~ Check that doc-builder tests pass" +cd ../doc-builder/test +set -x +conda run --no-capture-output -n ctsm_pylib make test + +exit 0 diff --git a/doc/test/test_makefile_method.sh b/doc/test/test_makefile_method.sh new file mode 100755 index 0000000000..b0fd80984e --- /dev/null +++ b/doc/test/test_makefile_method.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +# Fail on any non-zero exit code +set -e + +cli_tool="$1" + +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +cd "${SCRIPT_DIR}/.." + +echo "~~~~~ Check that Makefile method works" +set -x +make SPHINXOPTS="-W --keep-going" BUILDDIR=${PWD}/_build html + +exit 0 diff --git a/doc/test/testing.sh b/doc/test/testing.sh new file mode 100755 index 0000000000..2e91025e6c --- /dev/null +++ b/doc/test/testing.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# Fail on any non-zero exit code +set -e + +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +cd "${SCRIPT_DIR}/" + +# Compare docs built with container vs. ctsm_pylib +./test_container_eq_ctsm_pylib.sh + +# Check that -r -v works (Docker) +# Also do a custom --conf-py-path and other stuff +cd "${SCRIPT_DIR}/" +rm -rf _build +./test_build_docs_-r-v.sh docker + +# Check that Makefile method works +cd "${SCRIPT_DIR}/" +rm -rf _build +conda run --no-capture-output -n ctsm_pylib ./test_makefile_method.sh + +# Check that -b works +cd "${SCRIPT_DIR}/" +rm -rf _build +./test_build_docs_-b.sh docker + +# Check that doc-builder tests pass +# Don't run if on a GitHub runner; failing 🤷. Trust that doc-builder does this test. +if [[ "${GITHUB_ACTIONS}" == "" ]]; then + cd "${SCRIPT_DIR}/" + ./test_doc-builder_tests.sh +fi + +exit 0 diff --git a/doc/testing.sh b/doc/testing.sh deleted file mode 100755 index 9253df848c..0000000000 --- a/doc/testing.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash -set -e -set -x - -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -cd "${SCRIPT_DIR}" - -../bin/git-fleximod update -o -rm -rf _publish* - -# Build all docs using container -echo "~~~~~ Build all docs using container" -# Also do a custom --conf-py-path -rm -rf _build _publish -d1="$PWD/_publish_container" -./build_docs_to_publish -r _build -d --site-root "$PWD/_publish" -# VERSION LINKS WILL NOT RESOLVE IN _publish_container -cp -a _publish "${d1}" - -# Build all docs using ctsm_pylib -echo "~~~~~ Build all docs using ctsm_pylib" -rm -rf _build _publish -d2="$PWD/_publish_nocontainer" -conda run -n ctsm_pylib ./build_docs_to_publish -r _build --site-root "$PWD/_publish" --conf-py-path doc-builder/test/conf.py --static-path ../_static --templates-path ../_templates -# VERSION LINKS WILL NOT RESOLVE IN _publish_nocontainer -cp -a _publish "${d2}" - -# Make sure container version is identical to no-container version -echo "~~~~~ Make sure container version is identical to no-container version" -diff -qr "${d1}" "${d2}" - -# Check that -r -v works -echo "~~~~~ Check that -r -v works (Docker)" -# Also do a custom --conf-py-path -rm -rf _build_container -./build_docs -r _build_container -v latest -d -c --conf-py-path doc-builder/test/conf.py --static-path ../_static --templates-path ../_templates --container-cli-tool docker - -# Check that Makefile method works -echo "~~~~~ Check that Makefile method works" -rm -rf _build -conda run -n ctsm_pylib make SPHINXOPTS="-W --keep-going" BUILDDIR=${PWD}/_build html - -# Check that -b works -echo "~~~~~ Check that -b works (Podman)" -rm -rf _build_container -./build_docs -b _build_container -d -c --container-cli-tool docker - -# Check that doc-builder tests pass -# Don't run if on a GitHub runner; failing 🤷. Trust that doc-builder does this test. -if [[ "${GITHUB_ACTIONS}" == "" ]]; then - echo "~~~~~ Check that doc-builder tests pass" - cd doc-builder/test - conda run -n ctsm_pylib make test -fi - -exit 0 \ No newline at end of file