Simplify the version bump process. ### Description

Simplify the version bump process.

- Use substitution hook in docs to update CDN URL.
  - In `dev` or `prerelease` versions, it will point to `dev` url
  - In `stable` versions, it will point it `vX.Y.Z` url
- Introduce a version bump script `tools/bump_version.py`.


~- Use `bump2version` to bump Python versions (continuing from #2460)~
~- Use `npm version` to bump JS versions~
~- Update `run_docker` script to use latest deployed pre-built docker image when `--pre-built` option is specified.~

### Checklists

- [x] Add new / update outdated documentation

# setup: import pandas as pd ; import numpy ; N = 1000000 ; df1 = pd.DataFrame(numpy.random.randint(0, 10, size=(N, 3)), columns=["col1", "col2", "col3"]) ; df2 = pd.DataFrame(numpy.random.randint(0, 10, size=(N, 3)), columns=["col4", "col5", "col6"])
# run: join_df(df1, df2)


def join_df(df1, df2):
    return df1.join(df2, how="outer")

# setup: import pandas as pd ; import numpy ; N = 1000000 ; df1 = pd.DataFrame(numpy.random.randint(0, 10, size=(N, 3)), columns=["col1", "col2", "col3"]) ; df2 = pd.DataFrame(numpy.random.randint(0, 10, size=(N, 3)), columns=["col4", "col5", "col6"])
# run: join_df(df1, df2)


def join_df(df1, df2):
    return df1.join(df2, how="outer")
