Repository: ESMValGroup/ESMValCore

Issue:
[Github Actions] Compress all bash shell setters into one default option per workflow
@bouweandela rightly suggested doing that so the workflow files are a bit more readable, and supplied and [example](https://github.com/dask/dask/blob/11f2b83ee034aea7837691f9a0d4ede6309d6194/.github/workflows/conda.yml#L18-L21) how that's done - cheers, bud! I'll do this as soon as possible :+1: 

Discussion:
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/ESMValGroup/ESMValCore/pull/2126?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ESMValGroup) Report
> Merging [#2126](https://app.codecov.io/gh/ESMValGroup/ESMValCore/pull/2126?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ESMValGroup) (753b4ef) into [main](https://app.codecov.io/gh/ESMValGroup/ESMValCore/commit/9d6b9630bbeb84d69f3a1a4591dbf9506f0d8b29?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ESMValGroup) (9d6b963) will **not change** coverage.
> The diff coverage is `n/a`.

```diff
@@           Coverage Diff           @@
##             main    #2126   +/-   ##
=======================================
  Coverage   93.09%   93.09%           
=======================================
  Files         237      237           
  Lines       12794    12794           
=======================================
  Hits        11910    11910           
  Misses        884      884           
```




valeriupredoi: dis ready now @bouweandela 

Patch:
diff --git a/.github/workflows/create-condalock-file.yml b/.github/workflows/create-condalock-file.yml
index 5d71fb9d2..ccdffd617 100644
--- a/.github/workflows/create-condalock-file.yml
+++ b/.github/workflows/create-condalock-file.yml
@@ -10,6 +10,11 @@ on:
   schedule:
     - cron: '0 4 */10 * *'
 
+# Required shell entrypoint to have properly configured bash shell
+defaults:
+  run:
+    shell: bash -l {0}
+
 jobs:
   create-verify-lock-file:
     name: Create and verify conda lock file for latest Python
@@ -27,7 +32,6 @@ jobs:
           miniforge-variant: Mambaforge
           use-mamba: true
       - name: Show conda config
-        shell: bash -l {0}
         run: |
           conda update -n base -c conda-forge conda
           conda info
@@ -35,45 +39,36 @@ jobs:
           conda config --show-sources
           conda config --show
       - name: Gather Python info
-        shell: bash -l {0}
         run: |
           which python
           python --version
       - name: Install conda-lock
-        shell: bash -l {0}
         run: mamba install -y conda-lock
       - name: Check version of conda-lock
-        shell: bash -l {0}
         run: conda-lock --version
       - name: Create conda lock file for linux-64
-        shell: bash -l {0}
         run: conda-lock lock --platform linux-64 -f environment.yml --mamba --kind explicit
       - name: Creating environment from lock file
-        shell: bash -l {0}
         run: conda create --name esmvaltool-fromlock --file conda-linux-64.lock
       - name: Installing pip
-        shell: bash -l {0}
         run: mamba install -y pip
       - name: Gather pip info
-        shell: bash -l {0}
         run: pip --version
       - name: Gather Python info again
-        shell: bash -l {0}
         run: |
           which python
           python --version
       - name: Show environment contents
-        shell: bash -l {0}
         run: conda list
-      - shell: bash -l {0}
+      - name: Install esmvalcore
         run: pip install -e .[develop]
-      - shell: bash -l {0}
-        run: esmvaltool --help
-      - shell: bash -l {0}
-        run: esmvaltool version
-      - shell: bash -l {0}
+      - name: Run basic commands
+        run: |
+          esmvaltool --help
+          esmvaltool version
+      - name: Run flake8
         run: flake8
-      - shell: bash -l {0}
+      - name: Run pytests
         run: pytest -n 2 -m "not installation"
       # Automated PR
       # see https://github.com/marketplace/actions/create-pull-request
diff --git a/.github/workflows/install-from-conda.yml b/.github/workflows/install-from-conda.yml
index 1548d1efd..4b9974ebe 100644
--- a/.github/workflows/install-from-conda.yml
+++ b/.github/workflows/install-from-conda.yml
@@ -29,6 +29,11 @@ on:
   schedule:
     - cron: '0 4 * * *'
 
+# Required shell entrypoint to have properly configured bash shell
+defaults:
+  run:
+    shell: bash -l {0}
+
 jobs:
   linux:
     runs-on: "ubuntu-latest"
@@ -46,20 +51,16 @@ jobs:
           miniforge-version: "latest"
           miniforge-variant: Mambaforge
           use-mamba: true
-      - shell: bash -l {0}
-        run: mkdir -p conda_install_linux_artifacts_python_${{ matrix.python-version }}
+      - run: mkdir -p conda_install_linux_artifacts_python_${{ matrix.python-version }}
       - name: Record versions
-        shell: bash -l {0}
         run: |
           mamba --version 2>&1 | tee conda_install_linux_artifacts_python_${{ matrix.python-version }}/conda_version.txt
           which conda 2>&1 | tee conda_install_linux_artifacts_python_${{ matrix.python-version }}/conda_path.txt
           which mamba 2>&1 | tee -a conda_install_linux_artifacts_python_${{ matrix.python-version }}/conda_path.txt
           python -V 2>&1 | tee conda_install_linux_artifacts_python_${{ matrix.python-version }}/python_version.txt
       - name: Install ESMValCore
-        shell: bash -l {0}
         run: mamba install esmvalcore 2>&1 | tee conda_install_linux_artifacts_python_${{ matrix.python-version }}/install.txt
       - name: Verify installation
-        shell: bash -l {0}
         run: |
           esmvaltool --help
           esmvaltool version 2>&1 | tee conda_install_linux_artifacts_python_${{ matrix.python-version }}/version.txt
@@ -84,20 +85,16 @@ jobs:
           miniforge-version: "latest"
           miniforge-variant: Mambaforge
           use-mamba: true
-      - shell: bash -l {0}
-        run: mkdir -p conda_install_osx_artifacts_python_${{ matrix.python-version }}
+      - run: mkdir -p conda_install_osx_artifacts_python_${{ matrix.python-version }}
       - name: Record versions
-        shell: bash -l {0}
         run: |
           mamba --version 2>&1 | tee conda_install_osx_artifacts_python_${{ matrix.python-version }}/conda_version.txt
           which conda 2>&1 | tee conda_install_osx_artifacts_python_${{ matrix.python-version }}/conda_path.txt
           which mamba 2>&1 | tee -a conda_install_osx_artifacts_python_${{ matrix.python-version }}/conda_path.txt
           python -V 2>&1 | tee conda_install_osx_artifacts_python_${{ matrix.python-version }}/python_version.txt
       - name: Install ESMValCore
-        shell: bash -l {0}
         run: mamba install esmvalcore 2>&1 | tee conda_install_osx_artifacts_python_${{ matrix.python-version }}/install.txt
       - name: Verify installation
-        shell: bash -l {0}
         run: |
           esmvaltool --help
           esmvaltool version 2>&1 | tee conda_install_osx_artifacts_python_${{ matrix.python-version }}/version.txt
diff --git a/.github/workflows/install-from-condalock-file.yml b/.github/workflows/install-from-condalock-file.yml
index 1e6adeaa0..d6f3d7f5f 100644
--- a/.github/workflows/install-from-condalock-file.yml
+++ b/.github/workflows/install-from-condalock-file.yml
@@ -19,6 +19,11 @@ on:
   schedule:
     - cron: '0 0 * * *'
 
+# Required shell entrypoint to have properly configured bash shell
+defaults:
+  run:
+    shell: bash -l {0}
+
 jobs:
   linux:
     runs-on: "ubuntu-latest"
@@ -36,32 +41,19 @@ jobs:
           activate-environment: esmvaltool-fromlock
           python-version: ${{ matrix.python-version }}
           channels: conda-forge
-      - shell: bash -l {0}
-        run: mkdir -p source_install_linux_artifacts_python_${{ matrix.python-version }}
-      - shell: bash -l {0}
-        run: conda --version 2>&1 | tee source_install_linux_artifacts_python_${{ matrix.python-version }}/conda_version.txt
-      - shell: bash -l {0}
-        run: which python
-      - shell: bash -l {0}
-        run: python -V 2>&1 | tee source_install_linux_artifacts_python_${{ matrix.python-version }}/python_version.txt
-      - shell: bash -l {0}
-        run: conda create --name esmvaltool-fromlock --file conda-linux-64.lock
-      - shell: bash -l {0}
-        run: conda install pip
-      - shell: bash -l {0}
-        run: which python
-      - shell: bash -l {0}
-        run: pip --version
-      - shell: bash -l {0}
-        run: pip install -e .[develop]
-      - shell: bash -l {0}
-        run: esmvaltool --help
-      - shell: bash -l {0}
-        run: esmvaltool version 2>&1 | tee source_install_linux_artifacts_python_${{ matrix.python-version }}/version.txt
-      - shell: bash -l {0}
-        run: flake8
-      - shell: bash -l {0}
-        run: pytest -n 2 -m "not installation"
+      - run: mkdir -p source_install_linux_artifacts_python_${{ matrix.python-version }}
+      - run: conda --version 2>&1 | tee source_install_linux_artifacts_python_${{ matrix.python-version }}/conda_version.txt
+      - run: which python
+      - run: python -V 2>&1 | tee source_install_linux_artifacts_python_${{ matrix.python-version }}/python_version.txt
+      - run: conda create --name esmvaltool-fromlock --file conda-linux-64.lock
+      - run: conda install pip
+      - run: which python
+      - run: pip --version
+      - run: pip install -e .[develop]
+      - run: esmvaltool --help
+      - run: esmvaltool version 2>&1 | tee source_install_linux_artifacts_python_${{ matrix.python-version }}/version.txt
+      - run: flake8
+      - run: pytest -n 2 -m "not installation"
       - name: Upload artifacts
         if: ${{ always() }}  # upload artifacts even if fail
         uses: actions/upload-artifact@v2
diff --git a/.github/workflows/install-from-pypi.yml b/.github/workflows/install-from-pypi.yml
index 76669f608..264e63c41 100644
--- a/.github/workflows/install-from-pypi.yml
+++ b/.github/workflows/install-from-pypi.yml
@@ -29,6 +29,11 @@ on:
   schedule:
     - cron: '0 0 * * *'
 
+# Required shell entrypoint to have properly configured bash shell
+defaults:
+  run:
+    shell: bash -l {0}
+
 jobs:
   linux:
     runs-on: "ubuntu-latest"
@@ -49,19 +54,15 @@ jobs:
           miniforge-version: "latest"
           miniforge-variant: Mambaforge
           use-mamba: true
-      - shell: bash -l {0}
-        run: mkdir -p pip_install_linux_artifacts_python_${{ matrix.python-version }}
+      - run: mkdir -p pip_install_linux_artifacts_python_${{ matrix.python-version }}
       - name: Record versions
-        shell: bash -l {0}
         run: |
           mamba --version 2>&1 | tee pip_install_linux_artifacts_python_${{ matrix.python-version }}/conda_version.txt
           python -V 2>&1 | tee pip_install_linux_artifacts_python_${{ matrix.python-version }}/python_version.txt
           pip -V 2>&1 | tee pip_install_linux_artifacts_python_${{ matrix.python-version }}/pip_version.txt
       - name: Install
-        shell: bash -l {0}
         run: pip install esmvalcore 2>&1 | tee pip_install_linux_artifacts_python_${{ matrix.python-version }}/install.txt
       - name: Verify installation
-        shell: bash -l {0}
         run: |
           esmvaltool --help
           esmvaltool version 2>&1 | tee pip_install_linux_artifacts_python_${{ matrix.python-version }}/version.txt
@@ -89,19 +90,15 @@ jobs:
           miniforge-version: "latest"
           miniforge-variant: Mambaforge
           use-mamba: true
-      - shell: bash -l {0}
-        run: mkdir -p pip_install_osx_artifacts_python_${{ matrix.python-version }}
+      - run: mkdir -p pip_install_osx_artifacts_python_${{ matrix.python-version }}
       - name: Record versions
-        shell: bash -l {0}
         run: |
           mamba --version 2>&1 | tee pip_install_osx_artifacts_python_${{ matrix.python-version }}/conda_version.txt
           python -V 2>&1 | tee pip_install_osx_artifacts_python_${{ matrix.python-version }}/python_version.txt
           pip -V 2>&1 | tee pip_install_osx_artifacts_python_${{ matrix.python-version }}/pip_version.txt
       - name: Install
-        shell: bash -l {0}
         run: pip install esmvalcore 2>&1 | tee pip_install_osx_artifacts_python_${{ matrix.python-version }}/install.txt
       - name: Verify installation
-        shell: bash -l {0}
         run: |
           esmvaltool --help
           esmvaltool version 2>&1 | tee pip_install_osx_artifacts_python_${{ matrix.python-version }}/version.txt
diff --git a/.github/workflows/install-from-source.yml b/.github/workflows/install-from-source.yml
index 12f7f7c60..a01af4643 100644
--- a/.github/workflows/install-from-source.yml
+++ b/.github/workflows/install-from-source.yml
@@ -27,6 +27,11 @@ on:
   schedule:
     - cron: '0 0 * * *'
 
+# Required shell entrypoint to have properly configured bash shell
+defaults:
+  run:
+    shell: bash -l {0}
+
 jobs:
   linux:
     runs-on: "ubuntu-latest"
@@ -47,18 +52,14 @@ jobs:
           miniforge-version: "latest"
           miniforge-variant: Mambaforge
           use-mamba: true
-      - shell: bash -l {0}
-        run: mkdir -p source_install_linux_artifacts_python_${{ matrix.python-version }}
+      - run: mkdir -p source_install_linux_artifacts_python_${{ matrix.python-version }}
       - name: Record versions
-        shell: bash -l {0}
         run: |
           mamba --version 2>&1 | tee source_install_linux_artifacts_python_${{ matrix.python-version }}/conda_version.txt
           python -V 2>&1 | tee source_install_linux_artifacts_python_${{ matrix.python-version }}/python_version.txt
       - name: Install
-        shell: bash -l {0}
         run: pip install -e .[develop] 2>&1 | tee source_install_linux_artifacts_python_${{ matrix.python-version }}/install.txt
       - name: Verify installation
-        shell: bash -l {0}
         run: |
           esmvaltool --help
           esmvaltool version 2>&1 | tee source_install_linux_artifacts_python_${{ matrix.python-version }}/version.txt
@@ -88,18 +89,14 @@ jobs:
           miniforge-version: "latest"
           miniforge-variant: Mambaforge
           use-mamba: true
-      - shell: bash -l {0}
-        run: mkdir -p source_install_osx_artifacts_python_${{ matrix.python-version }}
+      - run: mkdir -p source_install_osx_artifacts_python_${{ matrix.python-version }}
       - name: Record versions
-        shell: bash -l {0}
         run: |
           mamba --version 2>&1 | tee source_install_osx_artifacts_python_${{ matrix.python-version }}/conda_version.txt
           python -V 2>&1 | tee source_install_osx_artifacts_python_${{ matrix.python-version }}/python_version.txt
       - name: Install
-        shell: bash -l {0}
         run: pip install -e .[develop] 2>&1 | tee source_install_osx_artifacts_python_${{ matrix.python-version }}/install.txt
       - name: Verify installation
-        shell: bash -l {0}
         run: |
           esmvaltool --help
           esmvaltool version 2>&1 | tee source_install_osx_artifacts_python_${{ matrix.python-version }}/version.txt
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 31f3d57a8..2b01ae61c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -50,5 +50,4 @@ repos:
       - id: mypy
         additional_dependencies:
           - 'types-PyYAML'
-          - 'types-pkg_resources'
           - 'types-requests'
diff --git a/environment.yml b/environment.yml
index b18c7f341..cb066cba0 100644
--- a/environment.yml
+++ b/environment.yml
@@ -19,7 +19,7 @@ dependencies:
   - fire
   - geopy
   - humanfriendly
-  - importlib_resources
+  - importlib_metadata  # required for Python < 3.10
   - iris >=3.6.0
   - iris-esmf-regrid >=0.7.0
   - isodate
@@ -64,7 +64,6 @@ dependencies:
   # Not on conda-forge - ESMValTool_sample_data==0.0.3
   # Still for testing, MyPy library stubs
   - types-requests
-  - types-pkg_resources
   - types-PyYAML
   # Python packages needed for installing in development mode
   - codespell
diff --git a/esmvalcore/_main.py b/esmvalcore/_main.py
index 0aee610ed..da5cdd026 100755
--- a/esmvalcore/_main.py
+++ b/esmvalcore/_main.py
@@ -29,10 +29,15 @@ http://docs.esmvaltool.org. Have fun!
 # pylint: disable=import-outside-toplevel
 import logging
 import os
+import sys
 from pathlib import Path
 
+if (sys.version_info.major, sys.version_info.minor) < (3, 10):
+    from importlib_metadata import entry_points
+else:
+    from importlib.metadata import entry_points  # type: ignore
+
 import fire
-from pkg_resources import iter_entry_points
 
 # set up logging
 logger = logging.getLogger(__name__)
@@ -299,12 +304,13 @@ class ESMValTool():
         self.config = Config()
         self.recipes = Recipes()
         self._extra_packages = {}
-        if not list(iter_entry_points('esmvaltool_commands')):
+        esmvaltool_commands = entry_points(group='esmvaltool_commands')
+        if not esmvaltool_commands:
             print("Running esmvaltool executable from ESMValCore. "
                   "No other command line utilities are available "
                   "until ESMValTool is installed.")
-        for entry_point in iter_entry_points('esmvaltool_commands'):
-            self._extra_packages[entry_point.dist.project_name] = \
+        for entry_point in esmvaltool_commands:
+            self._extra_packages[entry_point.dist.name] = \
                 entry_point.dist.version
             if hasattr(self, entry_point.name):
                 logger.error('Registered command %s already exists',
diff --git a/esmvalcore/config/_config.py b/esmvalcore/config/_config.py
index aaadb955e..85f8f1f1c 100644
--- a/esmvalcore/config/_config.py
+++ b/esmvalcore/config/_config.py
@@ -5,8 +5,8 @@ import collections.abc
 import fnmatch
 import logging
 import os
-import sys
 from functools import lru_cache
+from importlib.resources import files as importlib_files
 from pathlib import Path
 
 import yaml
@@ -21,12 +21,6 @@ TASKSEP = os.sep
 
 CFG = {}
 
-if sys.version_info[:2] >= (3, 9):
-    # pylint: disable=no-name-in-module
-    from importlib.resources import files as importlib_files
-else:
-    from importlib_resources import files as importlib_files
-
 
 def _deep_update(dictionary, update):
     for key, value in update.items():
diff --git a/setup.py b/setup.py
index b93292955..092379b6b 100755
--- a/setup.py
+++ b/setup.py
@@ -39,7 +39,7 @@ REQUIREMENTS = {
         'fire',
         'geopy',
         'humanfriendly',
-        "importlib_resources;python_version<'3.9'",
+        "importlib_metadata;python_version<'3.10'",
         'isodate',
         'jinja2',
         'nc-time-axis',  # needed by iris.plot
@@ -78,7 +78,6 @@ REQUIREMENTS = {
         # MyPy library stubs
         'mypy>=0.990',
         'types-requests',
-        'types-pkg_resources',
         'types-PyYAML',
     ],
     # Documentation dependencies


Test patch:
diff --git a/.github/workflows/run-tests-comment.yml b/.github/workflows/run-tests-comment.yml
index 2351203dc..ccae9db0e 100644
--- a/.github/workflows/run-tests-comment.yml
+++ b/.github/workflows/run-tests-comment.yml
@@ -4,12 +4,17 @@ on:
     types:
       - created
 
+# Required shell entrypoint to have properly configured bash shell
+defaults:
+  run:
+    shell: bash -l {0}
+
 jobs:
   linux:
     runs-on: "ubuntu-latest"
     strategy:
       matrix:
-        python-version: ["3.9", "3.10"]
+        python-version: ["3.9", "3.10", "3.11"]
       fail-fast: false
     name: Linux Python ${{ matrix.python-version }}
     if: ${{ github.event.issue.pull_request && github.event.comment.body == '@runGAtests' }}
@@ -25,18 +30,12 @@ jobs:
           miniforge-version: "latest"
           miniforge-variant: Mambaforge
           use-mamba: true
-      - shell: bash -l {0}
-        run: mkdir -p test_linux_artifacts_python_${{ matrix.python-version }}
-      - shell: bash -l {0}
-        run: conda --version 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/conda_version.txt
-      - shell: bash -l {0}
-        run: python -V 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/python_version.txt
-      - shell: bash -l {0}
-        run: pip install -e .[develop] 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/install.txt
-      - shell: bash -l {0}
-        run: flake8
-      - shell: bash -l {0}
-        run: pytest -n 2 -m "not installation" 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/test_report.txt
+      - run: mkdir -p test_linux_artifacts_python_${{ matrix.python-version }}
+      - run: conda --version 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/conda_version.txt
+      - run: python -V 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/python_version.txt
+      - run: pip install -e .[develop] 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/install.txt
+      - run: flake8
+      - run: pytest -n 2 -m "not installation" 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/test_report.txt
       - name: Upload artifacts
         if: ${{ always() }}  # upload artifacts even if fail
         uses: actions/upload-artifact@v2
@@ -48,7 +47,7 @@ jobs:
     runs-on: "macos-latest"
     strategy:
       matrix:
-        python-version: ["3.9", "3.10"]
+        python-version: ["3.9", "3.10", "3.11"]
       fail-fast: false
     name: OSX Python ${{ matrix.python-version }}
     if: ${{ github.event.issue.pull_request && github.event.comment.body == '@runGAtests' }}
@@ -64,18 +63,12 @@ jobs:
           miniforge-version: "latest"
           miniforge-variant: Mambaforge
           use-mamba: true
-      - shell: bash -l {0}
-        run: mkdir -p test_osx_artifacts_python_${{ matrix.python-version }}
-      - shell: bash -l {0}
-        run: conda --version 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/conda_version.txt
-      - shell: bash -l {0}
-        run: python -V 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/python_version.txt
-      - shell: bash -l {0}
-        run: pip install -e .[develop] 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/install.txt
-      - shell: bash -l {0}
-        run: flake8
-      - shell: bash -l {0}
-        run: pytest -n 2 -m "not installation" 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/test_report.txt
+      - run: mkdir -p test_osx_artifacts_python_${{ matrix.python-version }}
+      - run: conda --version 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/conda_version.txt
+      - run: python -V 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/python_version.txt
+      - run: pip install -e .[develop] 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/install.txt
+      - run: flake8
+      - run: pytest -n 2 -m "not installation" 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/test_report.txt
       - name: Upload artifacts
         if: ${{ always() }}  # upload artifacts even if fail
         uses: actions/upload-artifact@v2
diff --git a/.github/workflows/run-tests-monitor.yml b/.github/workflows/run-tests-monitor.yml
index e59bb7907..6c3685dd1 100644
--- a/.github/workflows/run-tests-monitor.yml
+++ b/.github/workflows/run-tests-monitor.yml
@@ -12,6 +12,11 @@ on:
   schedule:
     - cron: '0 0 * * *'  # nightly
 
+# Required shell entrypoint to have properly configured bash shell
+defaults:
+  run:
+    shell: bash -l {0}
+
 jobs:
   linux:
     runs-on: "ubuntu-latest"
@@ -32,19 +37,12 @@ jobs:
           miniforge-version: "latest"
           miniforge-variant: Mambaforge
           use-mamba: true
-      - shell: bash -l {0}
-        run: mkdir -p test_linux_artifacts_python_${{ matrix.python-version }}
-      - shell: bash -l {0}
-        run: conda --version 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/conda_version.txt
-      - shell: bash -l {0}
-        run: python -V 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/python_version.txt
-      - shell: bash -l {0}
-        run: pip install pytest-monitor
-      - shell: bash -l {0}
-        run: pip install -e .[develop] 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/install.txt
-      - shell: bash -l {0}
-        run: pytest -n 2 -m "not installation" --db ../.pymon 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/test_report.txt
-      - shell: bash -l {0}
+      - run: mkdir -p test_linux_artifacts_python_${{ matrix.python-version }}
+      - run: conda --version 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/conda_version.txt
+      - run: python -V 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/python_version.txt
+      - run: pip install pytest-monitor
+      - run: pip install -e .[develop] 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/install.txt
+      - run: pytest -n 2 -m "not installation" --db ../.pymon 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/test_report.txt
         run: python tests/parse_pymon.py
       - name: Upload artifacts
         if: ${{ always() }}  # upload artifacts even if fail
@@ -72,20 +70,13 @@ jobs:
           miniforge-version: "latest"
           miniforge-variant: Mambaforge
           use-mamba: true
-      - shell: bash -l {0}
-        run: mkdir -p test_osx_artifacts_python_${{ matrix.python-version }}
-      - shell: bash -l {0}
-        run: conda --version 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/conda_version.txt
-      - shell: bash -l {0}
-        run: python -V 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/python_version.txt
-      - shell: bash -l {0}
-        run: pip install pytest-monitor
-      - shell: bash -l {0}
-        run: pip install -e .[develop] 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/install.txt
-      - shell: bash -l {0}
-        run: pytest -n 2 -m "not installation" --db ../.pymon 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/test_report.txt
-      - shell: bash -l {0}
-        run: python tests/parse_pymon.py
+      - run: mkdir -p test_osx_artifacts_python_${{ matrix.python-version }}
+      - run: conda --version 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/conda_version.txt
+      - run: python -V 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/python_version.txt
+      - run: pip install pytest-monitor
+      - run: pip install -e .[develop] 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/install.txt
+      - run: pytest -n 2 -m "not installation" --db ../.pymon 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/test_report.txt
+      - run: python tests/parse_pymon.py
       - name: Upload artifacts
         if: ${{ always() }}  # upload artifacts even if fail
         uses: actions/upload-artifact@v2
diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml
index d7426ecbc..aa80283eb 100644
--- a/.github/workflows/run-tests.yml
+++ b/.github/workflows/run-tests.yml
@@ -29,6 +29,11 @@ on:
   schedule:
     - cron: '0 0 * * *'  # nightly
 
+# Required shell entrypoint to have properly configured bash shell
+defaults:
+  run:
+    shell: bash -l {0}
+
 jobs:
   linux:
     runs-on: "ubuntu-latest"
@@ -49,18 +54,12 @@ jobs:
           miniforge-version: "latest"
           miniforge-variant: Mambaforge
           use-mamba: true
-      - shell: bash -l {0}
-        run: mkdir -p test_linux_artifacts_python_${{ matrix.python-version }}
-      - shell: bash -l {0}
-        run: conda --version 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/conda_version.txt
-      - shell: bash -l {0}
-        run: python -V 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/python_version.txt
-      - shell: bash -l {0}
-        run: pip install -e .[develop] 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/install.txt
-      - shell: bash -l {0}
-        run: flake8
-      - shell: bash -l {0}
-        run: pytest -n 2 -m "not installation" 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/test_report.txt
+      - run: mkdir -p test_linux_artifacts_python_${{ matrix.python-version }}
+      - run: conda --version 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/conda_version.txt
+      - run: python -V 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/python_version.txt
+      - run: pip install -e .[develop] 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/install.txt
+      - run: flake8
+      - run: pytest -n 2 -m "not installation" 2>&1 | tee test_linux_artifacts_python_${{ matrix.python-version }}/test_report.txt
       - name: Upload artifacts
         if: ${{ always() }}  # upload artifacts even if fail
         uses: actions/upload-artifact@v2
@@ -87,18 +86,12 @@ jobs:
           miniforge-version: "latest"
           miniforge-variant: Mambaforge
           use-mamba: true
-      - shell: bash -l {0}
-        run: mkdir -p test_osx_artifacts_python_${{ matrix.python-version }}
-      - shell: bash -l {0}
-        run: conda --version 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/conda_version.txt
-      - shell: bash -l {0}
-        run: python -V 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/python_version.txt
-      - shell: bash -l {0}
-        run: pip install -e .[develop] 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/install.txt
-      - shell: bash -l {0}
-        run: flake8
-      - shell: bash -l {0}
-        run: pytest -n 2 -m "not installation" 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/test_report.txt
+      - run: mkdir -p test_osx_artifacts_python_${{ matrix.python-version }}
+      - run: conda --version 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/conda_version.txt
+      - run: python -V 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/python_version.txt
+      - run: pip install -e .[develop] 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/install.txt
+      - run: flake8
+      - run: pytest -n 2 -m "not installation" 2>&1 | tee test_osx_artifacts_python_${{ matrix.python-version }}/test_report.txt
       - name: Upload artifacts
         if: ${{ always() }}  # upload artifacts even if fail
         uses: actions/upload-artifact@v2
diff --git a/tests/unit/main/test_esmvaltool.py b/tests/unit/main/test_esmvaltool.py
index 0bbe1b850..42e981511 100644
--- a/tests/unit/main/test_esmvaltool.py
+++ b/tests/unit/main/test_esmvaltool.py
@@ -178,18 +178,18 @@ def test_do_not_clean_preproc_dir(session):
     assert session._fixed_file_dir.exists()
 
 
-@mock.patch('esmvalcore._main.iter_entry_points')
+@mock.patch('esmvalcore._main.entry_points')
 def test_header(mock_entry_points, caplog):
 
     entry_point = mock.Mock()
-    entry_point.dist.project_name = 'MyEntry'
+    entry_point.dist.name = 'MyEntry'
     entry_point.dist.version = 'v42.42.42'
     entry_point.name = 'Entry name'
     mock_entry_points.return_value = [entry_point]
     with caplog.at_level(logging.INFO):
         ESMValTool()._log_header(
             'path_to_config_file',
-            ['path_to_log_file1', 'path_to_log_file2']
+            ['path_to_log_file1', 'path_to_log_file2'],
         )
 
     assert len(caplog.messages) == 8
@@ -218,8 +218,10 @@ def test_get_recipe(is_file):
 @mock.patch('os.path.isfile')
 @mock.patch('esmvalcore.config._diagnostics.DIAGNOSTICS')
 def test_get_installed_recipe(diagnostics, is_file):
+
     def encountered(path):
         return Path(path) == Path('/install_folder/recipe.yaml')
+
     is_file.side_effect = encountered
     diagnostics.recipes = Path('/install_folder')
     recipe = ESMValTool()._get_recipe('recipe.yaml')