Repository: jupyterhub/jupyterhub

Issue:
migrate remaining rst docs to myst
We still have several doc pages in .rst format, while most are .md.

@consideRatio proposed migrating to myst, which I agree we should do, and it may be good to get done before the docs-reorg internship gets underway in a few weeks.

The challenge is the following open PRs (mostly from the outreachy application period last month) touch these rst files:

- [x] #4209:
  - docs/source/contributing/setup.rst
- [x] #4186:
  - docs/source/getting-started/security-basics.rst
- [x] #4127:
  - docs/source/contributing/docs.rst
- [x] #4119:
  - docs/source/contributing/tests.rst
- [x] #4094:
  - docs/source/admin/upgrading.rst
  - docs/source/getting-started/security-basics.rst
- [x] #4084:
  - docs/source/index.rst
- [ ] #4066:
  - docs/source/contributing/index.rst
  - docs/source/contributing/layout.rst
- [x] #4008:
  - docs/source/index-admin.rst
- [x] #3053:
  - docs/source/reference/index.rst
- [ ] #2726:
  - docs/source/getting-started/index.rst
  - docs/source/index.rst

<details>
<summary>PR list generated with</summary>

```python
from github import Github as GitHub

gh = GitHub()

repo = gh.get_repo("jupyterhub/jupyterhub")
for pull in repo.get_pulls(state="open"):
    pull_files = [f.filename for f in list(pull.get_files())]
    if any(f.endswith(".rst") for f in pull_files):
        print(f"- [ ] #{pull.number}:")
        for f in pull_files:
            if f.endswith(".rst"):
                print(f"  - {f}")
        continue
```

</details>

We should merge/close as many of these as we can to avoid conflicts (some that just touch an index are no big deal to resolve conflicts).





Discussion:

Resolving patch:
diff --git a/docs/generate-metrics.py b/docs/generate-metrics.py
--- a/docs/generate-metrics.py
+++ b/docs/generate-metrics.py
@@ -1,7 +1,6 @@
 import os
 
-from pytablewriter import RstSimpleTableWriter
-from pytablewriter.style import Style
+from pytablewriter import MarkdownTableWriter
 
 import jupyterhub.metrics
 
@@ -11,12 +10,11 @@
 class Generator:
     @classmethod
     def create_writer(cls, table_name, headers, values):
-        writer = RstSimpleTableWriter()
+        writer = MarkdownTableWriter()
         writer.table_name = table_name
         writer.headers = headers
         writer.value_matrix = values
         writer.margin = 1
-        [writer.set_style(header, Style(align="center")) for header in headers]
         return writer
 
     def _parse_metrics(self):
@@ -33,18 +31,17 @@ def prometheus_metrics(self):
         if not os.path.exists(generated_directory):
             os.makedirs(generated_directory)
 
-        filename = f"{generated_directory}/metrics.rst"
+        filename = f"{generated_directory}/metrics.md"
         table_name = ""
         headers = ["Type", "Name", "Description"]
         values = self._parse_metrics()
         writer = self.create_writer(table_name, headers, values)
 
-        title = "List of Prometheus Metrics"
-        underline = "============================"
-        content = f"{title}\n{underline}\n{writer.dumps()}"
         with open(filename, 'w') as f:
-            f.write(content)
-        print(f"Generated {filename}.")
+            f.write("# List of Prometheus Metrics\n\n")
+            f.write(writer.dumps())
+            f.write("\n")
+        print(f"Generated {filename}")
 
 
 def main():
diff --git a/docs/source/conf.py b/docs/source/conf.py
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -20,8 +20,6 @@
 project = "JupyterHub"
 author = "Project Jupyter Contributors"
 copyright = f"{datetime.date.today().year}, {author}"
-version = "%i.%i" % jupyterhub.version_info[:2]
-release = jupyterhub.__version__
 
 
 # -- General Sphinx configuration --------------------------------------------
@@ -39,7 +37,7 @@
     "myst_parser",
 ]
 root_doc = "index"
-source_suffix = [".md", ".rst"]
+source_suffix = [".md"]
 # default_role let's use use `foo` instead of ``foo`` in rST
 default_role = "literal"
 
@@ -48,11 +46,21 @@
 # ref: https://myst-parser.readthedocs.io/en/latest/configuration.html
 #
 myst_heading_anchors = 2
+
 myst_enable_extensions = [
+    # available extensions: https://myst-parser.readthedocs.io/en/latest/syntax/optional.html
     "colon_fence",
     "deflist",
+    "fieldlist",
+    "substitution",
 ]
 
+myst_substitutions = {
+    # date example: Dev 07, 2022
+    "date": datetime.date.today().strftime("%b %d, %Y").title(),
+    "version": jupyterhub.__version__,
+}
+
 
 # -- Custom directives to generate documentation -----------------------------
 # ref: https://myst-parser.readthedocs.io/en/latest/syntax/roles-and-directives.html


Test patch:
diff --git a/docs/source/contributing/tests.md b/docs/source/contributing/tests.md
new file mode 100644
--- /dev/null
+++ b/docs/source/contributing/tests.md
@@ -0,0 +1,130 @@
+(contributing-tests)=
+
+# Testing JupyterHub and linting code
+
+Unit testing helps to validate that JupyterHub works the way we think it does,
+and continues to do so when changes occur. They also help communicate
+precisely what we expect our code to do.
+
+JupyterHub uses [pytest](https://pytest.org) for all the tests. You
+can find them under the [jupyterhub/tests](https://github.com/jupyterhub/jupyterhub/tree/main/jupyterhub/tests) directory in the git repository.
+
+## Running the tests
+
+1. Make sure you have completed {ref}`contributing/setup`.
+   Once you are done, you would be able to run `jupyterhub` from the command line and access it from your web browser.
+   This ensures that the dev environment is properly set up for tests to run.
+
+2. You can run all tests in JupyterHub
+
+   ```bash
+   pytest -v jupyterhub/tests
+   ```
+
+   This should display progress as it runs all the tests, printing
+   information about any test failures as they occur.
+
+   If you wish to confirm test coverage the run tests with the `--cov` flag:
+
+   ```bash
+   pytest -v --cov=jupyterhub jupyterhub/tests
+   ```
+
+3. You can also run tests in just a specific file:
+
+   ```bash
+   pytest -v jupyterhub/tests/<test-file-name>
+   ```
+
+4. To run a specific test only, you can do:
+
+   ```bash
+   pytest -v jupyterhub/tests/<test-file-name>::<test-name>
+   ```
+
+   This runs the test with function name `<test-name>` defined in
+   `<test-file-name>`. This is very useful when you are iteratively
+   developing a single test.
+
+   For example, to run the test `test_shutdown` in the file `test_api.py`,
+   you would run:
+
+   ```bash
+   pytest -v jupyterhub/tests/test_api.py::test_shutdown
+   ```
+
+   For more details, refer to the [pytest usage documentation](https://pytest.readthedocs.io/en/latest/usage.html).
+
+## Test organisation
+
+The tests live in `jupyterhub/tests` and are organized roughly into:
+
+1. `test_api.py` tests the REST API
+2. `test_pages.py` tests loading the HTML pages
+
+and other collections of tests for different components.
+When writing a new test, there should usually be a test of
+similar functionality already written and related tests should
+be added nearby.
+
+The fixtures live in `jupyterhub/tests/conftest.py`. There are
+fixtures that can be used for JupyterHub components, such as:
+
+- `app`: an instance of JupyterHub with mocked parts
+- `auth_state_enabled`: enables persisting auth_state (like authentication tokens)
+- `db`: a sqlite in-memory DB session
+- `` io_loop` ``: a Tornado event loop
+- `event_loop`: a new asyncio event loop
+- `user`: creates a new temporary user
+- `admin_user`: creates a new temporary admin user
+- single user servers
+  \- `cleanup_after`: allows cleanup of single user servers between tests
+- mocked service
+  \- `MockServiceSpawner`: a spawner that mocks services for testing with a short poll interval
+  \- `` mockservice` ``: mocked service with no external service url
+  \- `mockservice_url`: mocked service with a url to test external services
+
+And fixtures to add functionality or spawning behavior:
+
+- `admin_access`: grants admin access
+- `` no_patience` ``: sets slow-spawning timeouts to zero
+- `slow_spawn`: enables the SlowSpawner (a spawner that takes a few seconds to start)
+- `never_spawn`: enables the NeverSpawner (a spawner that will never start)
+- `bad_spawn`: enables the BadSpawner (a spawner that fails immediately)
+- `slow_bad_spawn`: enables the SlowBadSpawner (a spawner that fails after a short delay)
+
+Refer to the [pytest fixtures documentation](https://pytest.readthedocs.io/en/latest/fixture.html) to learn how to use fixtures that exists already and to create new ones.
+
+## Troubleshooting Test Failures
+
+### All the tests are failing
+
+Make sure you have completed all the steps in {ref}`contributing/setup` successfully, and are able to access JupyterHub from your browser at <http://localhost:8000> after starting `jupyterhub` in your command line.
+
+## Code formatting and linting
+
+JupyterHub automatically enforces code formatting. This means that pull requests
+with changes breaking this formatting will receive a commit from pre-commit.ci
+automatically.
+
+To automatically format code locally, you can install pre-commit and register a
+_git hook_ to automatically check with pre-commit before you make a commit if
+the formatting is okay.
+
+```bash
+pip install pre-commit
+pre-commit install --install-hooks
+```
+
+To run pre-commit manually you would do:
+
+```bash
+# check for changes to code not yet committed
+pre-commit run
+
+# check for changes also in already committed code
+pre-commit run --all-files
+```
+
+You may also install [black integration](https://github.com/psf/black#editor-integration)
+into your text editor to format code automatically.
diff --git a/docs/source/contributing/tests.rst b/docs/source/contributing/tests.rst
deleted file mode 100644
--- a/docs/source/contributing/tests.rst
+++ /dev/null
@@ -1,138 +0,0 @@
-.. _contributing/tests:
-
-===================================
-Testing JupyterHub and linting code
-===================================
-
-Unit testing helps to validate that JupyterHub works the way we think it does,
-and continues to do so when changes occur. They also help communicate
-precisely what we expect our code to do. 
-
-JupyterHub uses `pytest <https://pytest.org>`_ for all the tests. You
-can find them under the `jupyterhub/tests <https://github.com/jupyterhub/jupyterhub/tree/main/jupyterhub/tests>`_ directory in the git repository.
-
-Running the tests
-==================
-
-#. Make sure you have completed :ref:`contributing/setup`.
-   Once you are done, you would be able to run ``jupyterhub`` from the command line and access it from your web browser.
-   This ensures that the dev environment is properly set up for tests to run.
-
-#. You can run all tests in JupyterHub
-
-   .. code-block:: bash
-
-      pytest -v jupyterhub/tests
-
-   This should display progress as it runs all the tests, printing
-   information about any test failures as they occur.
-
-   If you wish to confirm test coverage the run tests with the `--cov` flag:
-
-   .. code-block:: bash
-
-      pytest -v --cov=jupyterhub jupyterhub/tests
-
-#. You can also run tests in just a specific file:
-
-   .. code-block:: bash
-
-      pytest -v jupyterhub/tests/<test-file-name>
-
-#. To run a specific test only, you can do:
-
-   .. code-block:: bash
-
-      pytest -v jupyterhub/tests/<test-file-name>::<test-name>
-
-   This runs the test with function name ``<test-name>`` defined in
-   ``<test-file-name>``. This is very useful when you are iteratively
-   developing a single test.
-
-   For example, to run the test ``test_shutdown`` in the file ``test_api.py``,
-   you would run:
-
-   .. code-block:: bash
-
-      pytest -v jupyterhub/tests/test_api.py::test_shutdown
-
-   For more details, refer to the `pytest usage documentation <https://pytest.readthedocs.io/en/latest/usage.html>`_.
-
-Test organisation
-=================
-
-The tests live in ``jupyterhub/tests`` and are organized roughly into:
-
-#. ``test_api.py`` tests the REST API
-#. ``test_pages.py`` tests loading the HTML pages
-
-and other collections of tests for different components.
-When writing a new test, there should usually be a test of
-similar functionality already written and related tests should
-be added nearby.
-
-The fixtures live in ``jupyterhub/tests/conftest.py``. There are
-fixtures that can be used for JupyterHub components, such as:
-
-- ``app``: an instance of JupyterHub with mocked parts
-- ``auth_state_enabled``: enables persisting auth_state (like authentication tokens)
-- ``db``: a sqlite in-memory DB session
-- ``io_loop```: a Tornado event loop
-- ``event_loop``: a new asyncio event loop
-- ``user``: creates a new temporary user
-- ``admin_user``: creates a new temporary admin user
-- single user servers
-  - ``cleanup_after``: allows cleanup of single user servers between tests
-- mocked service
-  - ``MockServiceSpawner``: a spawner that mocks services for testing with a short poll interval
-  - ``mockservice```: mocked service with no external service url
-  - ``mockservice_url``: mocked service with a url to test external services
-
-And fixtures to add functionality or spawning behavior:
-
-- ``admin_access``: grants admin access
-- ``no_patience```: sets slow-spawning timeouts to zero
-- ``slow_spawn``: enables the SlowSpawner (a spawner that takes a few seconds to start)
-- ``never_spawn``: enables the NeverSpawner (a spawner that will never start)
-- ``bad_spawn``: enables the BadSpawner (a spawner that fails immediately)
-- ``slow_bad_spawn``: enables the SlowBadSpawner (a spawner that fails after a short delay)
-
-Refer to the `pytest fixtures documentation <https://pytest.readthedocs.io/en/latest/fixture.html>`_  to learn how to use fixtures that exists already and to create new ones.
-
-Troubleshooting Test Failures
-=============================
-
-All the tests are failing
--------------------------
-
-Make sure you have completed all the steps in :ref:`contributing/setup` successfully, and are able to access JupyterHub from your browser at http://localhost:8000 after starting ``jupyterhub`` in your command line.
-
-
-Code formatting and linting
-===========================
-
-JupyterHub automatically enforces code formatting. This means that pull requests
-with changes breaking this formatting will receive a commit from pre-commit.ci
-automatically.
-
-To automatically format code locally, you can install pre-commit and register a
-*git hook* to automatically check with pre-commit before you make a commit if
-the formatting is okay.
-
-.. code:: bash
-
-   pip install pre-commit
-   pre-commit install --install-hooks
-
-To run pre-commit manually you would do:
-
-.. code:: bash
-
-   # check for changes to code not yet committed
-   pre-commit run
-
-   # check for changes also in already committed code
-   pre-commit run --all-files
-
-You may also install `black integration <https://github.com/psf/black#editor-integration>`_
-into your text editor to format code automatically.