pre-commit: install_deps> python -I -m pip install pre-commit pre-commit: freeze> python -m pip freeze --all pre-commit: cfgv==3.4.0,distlib==0.4.0,filelock==3.19.1,identify==2.6.15,nodeenv==1.9.1,pip==25.2,platformdirs==4.4.0,pre_commit==4.3.0,PyYAML==6.0.3,setuptools==80.9.0,virtualenv==20.34.0 pre-commit: commands[0]> pre-commit run --all-files --show-diff-on-failure [INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks. [INFO] Initializing environment for https://github.com/jorisroovers/gitlint. [INFO] Initializing environment for https://github.com/jorisroovers/gitlint:./gitlint-core[trusted-deps]. [INFO] Initializing environment for https://github.com/adrienverge/yamllint.git. [INFO] Initializing environment for https://github.com/pre-commit/mirrors-mypy. [INFO] Initializing environment for https://github.com/shellcheck-py/shellcheck-py. [INFO] Initializing environment for https://github.com/igorshubovych/markdownlint-cli. [INFO] Initializing environment for https://github.com/Mateusz-Grzelinski/actionlint-py. [INFO] Initializing environment for https://github.com/codespell-project/codespell. [INFO] Initializing environment for https://github.com/python-jsonschema/check-jsonschema. [INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... [INFO] Installing environment for https://github.com/adrienverge/yamllint.git. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... [INFO] Installing environment for https://github.com/pre-commit/mirrors-mypy. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... [INFO] Installing environment for https://github.com/shellcheck-py/shellcheck-py. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... [INFO] Installing environment for https://github.com/igorshubovych/markdownlint-cli. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... [INFO] Installing environment for https://github.com/Mateusz-Grzelinski/actionlint-py. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... [INFO] Installing environment for https://github.com/codespell-project/codespell. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... [INFO] Installing environment for https://github.com/python-jsonschema/check-jsonschema. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... trim trailing whitespace.................................................Passed check for added large files..............................................Passed check python ast.........................................................Passed check json...........................................(no files to check)Skipped check for merge conflicts................................................Passed check xml............................................(no files to check)Skipped check yaml...............................................................Passed debug statements (python)................................................Passed fix end of files.........................................................Passed fix requirements.txt.....................................................Passed mixed line ending........................................................Passed don't commit to branch...................................................Passed yamllint.................................................................Passed mypy.....................................................................Passed shellcheck...............................................................Passed markdownlint.............................................................Failed - hook id: markdownlint - exit code: 1 - files were modified by this hook LOCAL-TESTING-README.md:3:81 MD013/line-length Line length [Expected: 80; Actual: 160] LOCAL-TESTING-README.md:56:81 MD013/line-length Line length [Expected: 80; Actual: 88] LOCAL-TESTING-README.md:148:81 MD013/line-length Line length [Expected: 80; Actual: 112] LOCAL-TESTING-README.md:166:81 MD013/line-length Line length [Expected: 80; Actual: 104] README.md:1 MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "This project provides manuals ..."] actionlint...............................................................Passed codespell................................................................Passed Validate GitHub Actions..............................(no files to check)Skipped Validate GitHub Workflows................................................Passed Check GitHub Workflows set timeout-minutes...............................Passed Validate ReadTheDocs Config..............................................Passed pre-commit hook(s) made changes. If you are seeing this message in CI, reproduce locally with: `pre-commit run --all-files`. To run `pre-commit` as part of git workflow, use `pre-commit install`. All changes made by hooks: diff --git a/LOCAL-TESTING-README.md b/LOCAL-TESTING-README.md index 939ba5c74..a7fbc5ea8 100644 --- a/LOCAL-TESTING-README.md +++ b/LOCAL-TESTING-README.md @@ -5,6 +5,7 @@ This repository includes infrastructure for testing documentation builds locally ## Overview The setup provides a hybrid GitHub Actions workflow that work: + - **Locally with act**: Runs only the documentation build and link checking - **On GitHub/Gerrit**: Runs the full Gerrit verification workflow @@ -12,6 +13,7 @@ The setup provides a hybrid GitHub Actions workflow that work: 1. **Docker**: Required for act to run containers 2. **act**: Install from [nektos/act releases](https://github.com/nektos/act/releases) + ```bash # Example for Linux curl -s https://api.github.com/repos/nektos/act/releases/latest | \ @@ -22,19 +24,25 @@ The setup provides a hybrid GitHub Actions workflow that work: ## Quick Start ### Test Local Changes + Test your current working directory changes without submitting to Gerrit: + ```bash bash test-gerrit-local.sh --local-changes --job local-tox ``` ### Test Specific Gerrit Change + Test a specific Gerrit change request: + ```bash bash test-gerrit-local.sh --gerrit-url "https://git.opendaylight.org/gerrit/c/docs/+/117503" ``` ### Dry Run (Faster for Validation) + Add `--dry-run` to quickly validate the workflow without actually running the build: + ```bash bash test-gerrit-local.sh --local-changes --dry-run ``` @@ -42,12 +50,14 @@ bash test-gerrit-local.sh --local-changes --dry-run ## Configuration Files ### Core Files + - `.actrc` - Act configuration (Docker images, environment) - `.env.local` - Local environment variables for act - `.github/workflows/gerrit-verify.yaml` - Hybrid workflow (works locally and on GitHub) - `test-gerrit-local.sh` - Test script with URL parsing and event generation ### Generated Files + - `gerrit-verify-event.json` - Auto-generated workflow event payload ## Test Script Options @@ -67,6 +77,7 @@ Usage: test-gerrit-local.sh [options] ## How It Works ### Local Testing Flow + 1. **Script generates event JSON** with required workflow inputs 2. **Act runs workflow** using the `env.ACT='true'` environment variable 3. **Only local-tox job executes** - Gerrit jobs are skipped via conditionals @@ -75,11 +86,13 @@ Usage: test-gerrit-local.sh [options] - Link checking (`tox -e docs-linkcheck`) ### Gerrit Integration Flow + 1. **GitHub Actions triggers** on Gerrit events 2. **Full workflow executes** when `env.ACT != 'true'` 3. **Gerrit jobs run**: change info → tox verify → vote ### Key Features + - **Single workflow file** works both locally and on GitHub - **Environment-based branching** using `env.ACT` detection - **Minimal event JSON** with only required fields @@ -89,25 +102,31 @@ Usage: test-gerrit-local.sh [options] ## Troubleshooting ### Act Version Compatibility + Tested with act v0.2.80. Newer versions may have different YAML parsing behavior. ### Docker Permissions + Ensure your user can run Docker commands without sudo: + ```bash sudo usermod -aG docker $USER # Logout and login again ``` ### Missing Dependencies + If tox environments fail, ensure `docs/requirements.txt` is up to date. ### Workflow Parse Errors + - Check YAML indentation in `.github/workflows/gerrit-verify.yaml` - Validate with: `act --list --workflows .github/workflows/gerrit-verify.yaml` ## Example Workflows ### Daily Development + ```bash # Make changes to docs vim docs/some-file.rst @@ -120,6 +139,7 @@ git add . && git commit -m "Update documentation" && git review ``` ### Testing Specific Changes + ```bash # Test someone else's Gerrit change bash test-gerrit-local.sh --gerrit-url "https://git.opendaylight.org/gerrit/c/docs/+/117503" @@ -131,6 +151,7 @@ bash test-gerrit-local.sh --gerrit-url "https://git.opendaylight.org/gerrit/c/do ## Files Added/Modified ### New Files + - `.actrc` - Act runner configuration - `.env.local` - Local environment variables - `test-gerrit-local.sh` - Main test script @@ -138,6 +159,7 @@ bash test-gerrit-local.sh --gerrit-url "https://git.opendaylight.org/gerrit/c/do - `.pre-commit-config.yaml` - Pre-commit hooks for code quality ### Modified Files + - `.github/workflows/gerrit-verify.yaml` - Enhanced with local testing support - `docs/index.rst` - Test change (can be reverted) pre-commit: exit 1 (52.78 seconds) /w/workspace/docs-tox-verify-vanadium> pre-commit run --all-files --show-diff-on-failure pid=3337 pre-commit: FAIL ✖ in 55.79 seconds docs: install_deps> python -I -m pip install -r docs/requirements.txt docs: freeze> python -m pip freeze --all docs: alabaster==1.0.0,attrs==25.4.0,babel==2.17.0,blockdiag==3.0.0,certifi==2025.10.5,charset-normalizer==3.4.3,contourpy==1.3.3,cycler==0.12.1,defusedxml==0.7.1,docutils==0.21.2,fonttools==4.60.1,funcparserlib==2.0.0a0,future==1.0.0,idna==3.10,imagesize==1.4.1,Jinja2==3.1.6,jira==3.10.5,jsonschema==3.2.0,kiwisolver==1.4.9,lfdocs-conf==0.9.0,MarkupSafe==3.0.3,matplotlib==3.10.6,numpy==2.3.3,nwdiag==3.0.0,oauthlib==3.3.1,packaging==25.0,pillow==11.3.0,pip==25.2,Pygments==2.19.2,pyparsing==3.2.5,pyrsistent==0.20.0,python-dateutil==2.9.0.post0,PyYAML==6.0.3,requests==2.32.5,requests-file==1.5.1,requests-oauthlib==2.0.0,requests-toolbelt==1.0.0,roman-numerals-py==3.1.0,seqdiag==3.0.0,setuptools==80.9.0,six==1.17.0,snowballstemmer==3.0.1,Sphinx==8.2.3,sphinx-bootstrap-theme==0.8.1,sphinx-data-viewer==0.1.5,sphinx-rtd-theme==3.0.2,sphinx-tabs==3.4.7,sphinxcontrib-applehelp==2.0.0,sphinxcontrib-blockdiag==3.0.0,sphinxcontrib-devhelp==2.0.0,sphinxcontrib-htmlhelp==2.1.0,sphinxcontrib-jquery==4.1,sphinxcontrib-jsmath==1.0.1,sphinxcontrib-needs==0.7.9,sphinxcontrib-nwdiag==2.0.0,sphinxcontrib-plantuml==0.31,sphinxcontrib-qthelp==2.0.0,sphinxcontrib-seqdiag==3.0.0,sphinxcontrib-serializinghtml==2.0.0,sphinxcontrib-swaggerdoc==0.1.7,typing_extensions==4.15.0,urllib3==2.5.0,webcolors==24.11.1 docs: commands[0]> sphinx-build -q -j auto -W --keep-going -b html -n -d /w/workspace/docs-tox-verify-vanadium/.tox/docs/tmp/doctrees ./docs/ /w/workspace/docs-tox-verify-vanadium/docs/_build/html docs: OK ✔ in 1 minute 9.2 seconds docs-linkcheck: install_deps> python -I -m pip install -r docs/requirements.txt docs-linkcheck: freeze> python -m pip freeze --all docs-linkcheck: alabaster==1.0.0,attrs==25.4.0,babel==2.17.0,blockdiag==3.0.0,certifi==2025.10.5,charset-normalizer==3.4.3,contourpy==1.3.3,cycler==0.12.1,defusedxml==0.7.1,docutils==0.21.2,fonttools==4.60.1,funcparserlib==2.0.0a0,future==1.0.0,idna==3.10,imagesize==1.4.1,Jinja2==3.1.6,jira==3.10.5,jsonschema==3.2.0,kiwisolver==1.4.9,lfdocs-conf==0.9.0,MarkupSafe==3.0.3,matplotlib==3.10.6,numpy==2.3.3,nwdiag==3.0.0,oauthlib==3.3.1,packaging==25.0,pillow==11.3.0,pip==25.2,Pygments==2.19.2,pyparsing==3.2.5,pyrsistent==0.20.0,python-dateutil==2.9.0.post0,PyYAML==6.0.3,requests==2.32.5,requests-file==1.5.1,requests-oauthlib==2.0.0,requests-toolbelt==1.0.0,roman-numerals-py==3.1.0,seqdiag==3.0.0,setuptools==80.9.0,six==1.17.0,snowballstemmer==3.0.1,Sphinx==8.2.3,sphinx-bootstrap-theme==0.8.1,sphinx-data-viewer==0.1.5,sphinx-rtd-theme==3.0.2,sphinx-tabs==3.4.7,sphinxcontrib-applehelp==2.0.0,sphinxcontrib-blockdiag==3.0.0,sphinxcontrib-devhelp==2.0.0,sphinxcontrib-htmlhelp==2.1.0,sphinxcontrib-jquery==4.1,sphinxcontrib-jsmath==1.0.1,sphinxcontrib-needs==0.7.9,sphinxcontrib-nwdiag==2.0.0,sphinxcontrib-plantuml==0.31,sphinxcontrib-qthelp==2.0.0,sphinxcontrib-seqdiag==3.0.0,sphinxcontrib-serializinghtml==2.0.0,sphinxcontrib-swaggerdoc==0.1.7,typing_extensions==4.15.0,urllib3==2.5.0,webcolors==24.11.1 docs-linkcheck: commands[0]> sphinx-build -q -b linkcheck -d /w/workspace/docs-tox-verify-vanadium/.tox/docs-linkcheck/tmp/doctrees ./docs/ /w/workspace/docs-tox-verify-vanadium/docs/_build/linkcheck docs-linkcheck: OK ✔ in 3 minutes 12.58 seconds spelling: install_deps> python -I -m pip install PyEnchant sphinxcontrib-spelling -r docs/requirements.txt spelling: freeze> python -m pip freeze --all spelling: alabaster==1.0.0,attrs==25.4.0,babel==2.17.0,blockdiag==3.0.0,certifi==2025.10.5,charset-normalizer==3.4.3,contourpy==1.3.3,cycler==0.12.1,defusedxml==0.7.1,docutils==0.21.2,fonttools==4.60.1,funcparserlib==2.0.0a0,future==1.0.0,idna==3.10,imagesize==1.4.1,Jinja2==3.1.6,jira==3.10.5,jsonschema==3.2.0,kiwisolver==1.4.9,lfdocs-conf==0.9.0,MarkupSafe==3.0.3,matplotlib==3.10.6,numpy==2.3.3,nwdiag==3.0.0,oauthlib==3.3.1,packaging==25.0,pillow==11.3.0,pip==25.2,pyenchant==3.3.0,Pygments==2.19.2,pyparsing==3.2.5,pyrsistent==0.20.0,python-dateutil==2.9.0.post0,PyYAML==6.0.3,requests==2.32.5,requests-file==1.5.1,requests-oauthlib==2.0.0,requests-toolbelt==1.0.0,roman-numerals-py==3.1.0,seqdiag==3.0.0,setuptools==80.9.0,six==1.17.0,snowballstemmer==3.0.1,Sphinx==8.2.3,sphinx-bootstrap-theme==0.8.1,sphinx-data-viewer==0.1.5,sphinx-rtd-theme==3.0.2,sphinx-tabs==3.4.7,sphinxcontrib-applehelp==2.0.0,sphinxcontrib-blockdiag==3.0.0,sphinxcontrib-devhelp==2.0.0,sphinxcontrib-htmlhelp==2.1.0,sphinxcontrib-jquery==4.1,sphinxcontrib-jsmath==1.0.1,sphinxcontrib-needs==0.7.9,sphinxcontrib-nwdiag==2.0.0,sphinxcontrib-plantuml==0.31,sphinxcontrib-qthelp==2.0.0,sphinxcontrib-seqdiag==3.0.0,sphinxcontrib-serializinghtml==2.0.0,sphinxcontrib-spelling==8.0.1,sphinxcontrib-swaggerdoc==0.1.7,typing_extensions==4.15.0,urllib3==2.5.0,webcolors==24.11.1 spelling: commands[0]> sh -c 'command enchant>/dev/null || command enchant-2 -v>/dev/null || (sudo apt-get -qq update && sudo apt-get --yes install enchant-2) || sudo yum -y install enchant || (echo "enchant command not found - please install it (e.g. sudo apt-get install enchant | yum install enchant )" >&2 && exit 1)' Reading package lists... Building dependency tree... Reading state information... The following additional packages will be installed: aspell aspell-en dictionaries-common hunspell-en-us libaspell15 libenchant-2-2 libhunspell-1.7-0 Suggested packages: aspell-doc spellutils wordlist hunspell openoffice.org-hunspell | openoffice.org-core libenchant-2-voikko The following NEW packages will be installed: aspell aspell-en dictionaries-common enchant-2 hunspell-en-us libaspell15 libenchant-2-2 libhunspell-1.7-0 0 upgraded, 8 newly installed, 0 to remove and 35 not upgraded. Need to get 1416 kB of archives. After this operation, 5448 kB of additional disk space will be used. Get:1 http://nova.clouds.archive.ubuntu.com/ubuntu jammy/main amd64 libaspell15 amd64 0.60.8-4build1 [325 kB] Get:2 http://nova.clouds.archive.ubuntu.com/ubuntu jammy/main amd64 dictionaries-common all 1.28.14 [185 kB] Get:3 http://nova.clouds.archive.ubuntu.com/ubuntu jammy/main amd64 aspell amd64 0.60.8-4build1 [87.7 kB] Get:4 http://nova.clouds.archive.ubuntu.com/ubuntu jammy/main amd64 aspell-en all 2018.04.16-0-1 [299 kB] Get:5 http://nova.clouds.archive.ubuntu.com/ubuntu jammy/main amd64 hunspell-en-us all 1:2020.12.07-2 [280 kB] Get:6 http://nova.clouds.archive.ubuntu.com/ubuntu jammy/main amd64 libhunspell-1.7-0 amd64 1.7.0-4build1 [175 kB] Get:7 http://nova.clouds.archive.ubuntu.com/ubuntu jammy/main amd64 libenchant-2-2 amd64 2.3.2-1ubuntu2 [50.9 kB] Get:8 http://nova.clouds.archive.ubuntu.com/ubuntu jammy/main amd64 enchant-2 amd64 2.3.2-1ubuntu2 [13.0 kB] Fetched 1416 kB in 1s (1573 kB/s) Selecting previously unselected package libaspell15:amd64. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 190232 files and directories currently installed.) Preparing to unpack .../0-libaspell15_0.60.8-4build1_amd64.deb ... Unpacking libaspell15:amd64 (0.60.8-4build1) ... Selecting previously unselected package dictionaries-common. Preparing to unpack .../1-dictionaries-common_1.28.14_all.deb ... Adding 'diversion of /usr/share/dict/words to /usr/share/dict/words.pre-dictionaries-common by dictionaries-common' Unpacking dictionaries-common (1.28.14) ... Selecting previously unselected package aspell. Preparing to unpack .../2-aspell_0.60.8-4build1_amd64.deb ... Unpacking aspell (0.60.8-4build1) ... Selecting previously unselected package aspell-en. Preparing to unpack .../3-aspell-en_2018.04.16-0-1_all.deb ... Unpacking aspell-en (2018.04.16-0-1) ... Selecting previously unselected package hunspell-en-us. Preparing to unpack .../4-hunspell-en-us_1%3a2020.12.07-2_all.deb ... Unpacking hunspell-en-us (1:2020.12.07-2) ... Selecting previously unselected package libhunspell-1.7-0:amd64. Preparing to unpack .../5-libhunspell-1.7-0_1.7.0-4build1_amd64.deb ... Unpacking libhunspell-1.7-0:amd64 (1.7.0-4build1) ... Selecting previously unselected package libenchant-2-2:amd64. Preparing to unpack .../6-libenchant-2-2_2.3.2-1ubuntu2_amd64.deb ... Unpacking libenchant-2-2:amd64 (2.3.2-1ubuntu2) ... Selecting previously unselected package enchant-2. Preparing to unpack .../7-enchant-2_2.3.2-1ubuntu2_amd64.deb ... Unpacking enchant-2 (2.3.2-1ubuntu2) ... Setting up dictionaries-common (1.28.14) ... debconf: unable to initialize frontend: Dialog debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.) debconf: falling back to frontend: Readline Setting up libaspell15:amd64 (0.60.8-4build1) ... Setting up aspell (0.60.8-4build1) ... debconf: unable to initialize frontend: Dialog debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.) debconf: falling back to frontend: Readline Setting up hunspell-en-us (1:2020.12.07-2) ... Setting up libhunspell-1.7-0:amd64 (1.7.0-4build1) ... Setting up libenchant-2-2:amd64 (2.3.2-1ubuntu2) ... Setting up aspell-en (2018.04.16-0-1) ... debconf: unable to initialize frontend: Dialog debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.) debconf: falling back to frontend: Readline Setting up enchant-2 (2.3.2-1ubuntu2) ... Processing triggers for libc-bin (2.35-0ubuntu3.10) ... Processing triggers for man-db (2.10.2-1) ... Processing triggers for dictionaries-common (1.28.14) ... debconf: unable to initialize frontend: Dialog debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.) debconf: falling back to frontend: Readline aspell-autobuildhash: processing: en [en-common]. aspell-autobuildhash: processing: en [en-variant_0]. aspell-autobuildhash: processing: en [en-variant_1]. aspell-autobuildhash: processing: en [en-variant_2]. aspell-autobuildhash: processing: en [en-w_accents-only]. aspell-autobuildhash: processing: en [en-wo_accents-only]. aspell-autobuildhash: processing: en [en_AU-variant_0]. aspell-autobuildhash: processing: en [en_AU-variant_1]. aspell-autobuildhash: processing: en [en_AU-w_accents-only]. aspell-autobuildhash: processing: en [en_AU-wo_accents-only]. aspell-autobuildhash: processing: en [en_CA-variant_0]. aspell-autobuildhash: processing: en [en_CA-variant_1]. aspell-autobuildhash: processing: en [en_CA-w_accents-only]. aspell-autobuildhash: processing: en [en_CA-wo_accents-only]. aspell-autobuildhash: processing: en [en_GB-ise-w_accents-only]. aspell-autobuildhash: processing: en [en_GB-ise-wo_accents-only]. aspell-autobuildhash: processing: en [en_GB-ize-w_accents-only]. aspell-autobuildhash: processing: en [en_GB-ize-wo_accents-only]. aspell-autobuildhash: processing: en [en_GB-variant_0]. aspell-autobuildhash: processing: en [en_GB-variant_1]. aspell-autobuildhash: processing: en [en_US-w_accents-only]. aspell-autobuildhash: processing: en [en_US-wo_accents-only]. Running kernel seems to be up-to-date. No services need to be restarted. No containers need to be restarted. No user sessions are running outdated binaries. No VM guests are running outdated hypervisor (qemu) binaries on this host. spelling: commands[1]> sphinx-build -q -W --keep-going -b spelling -d /w/workspace/docs-tox-verify-vanadium/.tox/spelling/tmp/doctrees ./docs/ /w/workspace/docs-tox-verify-vanadium/docs/_build/spelling spelling: OK ✔ in 1 minute 36.02 seconds gitlint: install_deps> python -I -m pip install gitlint gitlint: freeze> python -m pip freeze --all gitlint: arrow==1.2.3,click==8.1.3,gitlint==0.19.1,gitlint-core==0.19.1,pip==25.2,python-dateutil==2.9.0.post0,setuptools==80.9.0,sh==1.14.3,six==1.17.0 gitlint: commands[0]> gitlint pre-commit: FAIL code 1 (55.79=setup[3.01]+cmd[52.78] seconds) docs: OK (69.19=setup[23.06]+cmd[46.13] seconds) docs-linkcheck: OK (192.57=setup[19.68]+cmd[172.89] seconds) spelling: OK (96.02=setup[21.08]+cmd[19.18,55.76] seconds) gitlint: OK (4.56=setup[4.40]+cmd[0.16] seconds) evaluation failed :( (418.16 seconds)