This quite a task and it should likely be split into smaller PRs until completed.

Breeze has the possibility of building CI and PROD images, but this one focuses only on building the CI image.

Building the image is not very straightforward, because in mulitple places the images are build differently:

* for different Python version
* with different caches
* with different build options (upgrade to newer dependencies for example) 

Also the image is multiple steps

* building base python image (if needed)
* building the CI image 

The whole story about images (both PROD and CI) is described here: 

https://github.com/apache/airflow/blob/main/IMAGES.rst

This change should end up withbuild-ci-image command that should build the image with all the possible flags.

NOTE: The old `breeze build image` command also implements complex logic to determine whether images should be pulled or whether they need to be rebuild at all. This is NOT part of this change and it will be implemented later.

Here are the current flags.

```
./breeze build-image --help
Good version of docker 20.10.7.
Build image



Detailed usage for command: build-image


breeze build-image [FLAGS]

      Builds docker image (CI or production) without entering the container. You can pass
      additional options to this command, such as:

      Choosing python version:
        '--python'

      Choosing cache option:
         '--build-cache-local' or '-build-cache-pulled', or '--build-cache-none'

      Choosing whether to force pull images or force build the image:
          '--force-build-image', '--force-pull-image'

      Checking if the base python image has been updated:
          '--check-if-base-python-image-updated'

      You can also pass '--production-image' flag to build production image rather than CI image.

      For GitHub repository, the '--github-repository' can be used to choose repository
      to pull/push images.

Flags:

-p, --python PYTHON_MAJOR_MINOR_VERSION
        Python version used for the image. This is always major/minor version.

        One of:

               3.7 3.8 3.9 3.6 

-a, --install-airflow-version INSTALL_AIRFLOW_VERSION
        Uses different version of Airflow when building PROD image.

               2.0.2 2.0.1 2.0.0 wheel sdist 

-t, --install-airflow-reference INSTALL_AIRFLOW_REFERENCE
        Installs Airflow directly from reference in GitHub when building PROD image.
        This can be a GitHub branch like main or v2-2-test, or a tag like 2.2.0rc1.

--installation-method INSTALLATION_METHOD
        Method of installing Airflow in PROD image - either from the sources ('.')
        or from package 'apache-airflow' to install from PyPI.
        Default in Breeze is to install from sources. One of:

               . apache-airflow 

--upgrade-to-newer-dependencies

        Upgrades PIP packages to latest versions available without looking at the constraints.

-I, --production-image
        Use production image for entering the environment and builds (not for tests).

-F, --force-build-images
        Forces building of the local docker images. The images are rebuilt
        automatically for the first time or when changes are detected in
        package-related files, but you can force it using this flag.

-P, --force-pull-images
        Forces pulling of images from GitHub Container Registry before building to populate cache.
        The images are pulled by default only for the first time you run the
        environment, later the locally build images are used as cache.

--check-if-base-python-image-updated
        Checks if Python base image from DockerHub has been updated vs the current python base
        image we store in GitHub Container Registry. Python images are updated regularly with
        security fixes, this switch will check if a new one has been released and will pull and
        prepare a new base python based on the latest one.

--cleanup-docker-context-files
        Removes whl and tar.gz files created in docker-context-files before running the command.
        In case there are some files there it unnecessarily increases the context size and
        makes the COPY . always invalidated - if you happen to have those files when you build your
        image.

Customization options:

-E, --extras EXTRAS
        Extras to pass to build images The default are different for CI and production images:

        CI image:
               devel_ci

        Production image:
               amazon,async,celery,cncf.kubernetes,dask,docker,elasticsearch,ftp,google,google_auth,
               grpc,hashicorp,http,ldap,microsoft.azure,mysql,odbc,pandas,postgres,redis,sendgrid,
               sftp,slack,ssh,statsd,virtualenv

--image-tag TAG
        Additional tag in the image.

--skip-installing-airflow-providers-from-sources
        By default 'pip install' in Airflow 2.0 installs only the provider packages that
        are needed by the extras. When you build image during the development (which is
        default in Breeze) all providers are installed by default from sources.
        You can disable it by adding this flag but then you have to install providers from
        wheel packages via --use-packages-from-dist flag.

--disable-pypi-when-building
        Disable installing Airflow from pypi when building. If you use this flag and want
        to install Airflow, you have to install it from packages placed in
        'docker-context-files' and use --install-from-docker-context-files flag.

--additional-extras ADDITIONAL_EXTRAS
        Additional extras to pass to build images The default is no additional extras.

--additional-python-deps ADDITIONAL_PYTHON_DEPS
        Additional python dependencies to use when building the images.

--dev-apt-command DEV_APT_COMMAND
        The basic command executed before dev apt deps are installed.

--additional-dev-apt-command ADDITIONAL_DEV_APT_COMMAND
        Additional command executed before dev apt deps are installed.

--additional-dev-apt-deps ADDITIONAL_DEV_APT_DEPS
        Additional apt dev dependencies to use when building the images.

--dev-apt-deps DEV_APT_DEPS
        The basic apt dev dependencies to use when building the images.

--additional-dev-apt-deps ADDITIONAL_DEV_DEPS
        Additional apt dev dependencies to use when building the images.

--additional-dev-apt-envs ADDITIONAL_DEV_APT_ENVS
        Additional environment variables set when adding dev dependencies.

--runtime-apt-command RUNTIME_APT_COMMAND
        The basic command executed before runtime apt deps are installed.

--additional-runtime-apt-command ADDITIONAL_RUNTIME_APT_COMMAND
        Additional command executed before runtime apt deps are installed.

--runtime-apt-deps ADDITIONAL_RUNTIME_APT_DEPS
        The basic apt runtime dependencies to use when building the images.

--additional-runtime-apt-deps ADDITIONAL_RUNTIME_DEPS
        Additional apt runtime dependencies to use when building the images.

--additional-runtime-apt-envs ADDITIONAL_RUNTIME_APT_DEPS
        Additional environment variables set when adding runtime dependencies.

Build options:

--disable-mysql-client-installation
        Disables installation of the mysql client which might be problematic if you are building
        image in controlled environment. Only valid for production image.

--disable-mssql-client-installation
        Disables installation of the mssql client which might be problematic if you are building
        image in controlled environment. Only valid for production image.

--constraints-location
        Url to the constraints file. In case of the production image it can also be a path to the
        constraint file placed in 'docker-context-files' folder, in which case it has to be
        in the form of '/docker-context-files/<NAME_OF_THE_FILE>'

--disable-pip-cache
        Disables GitHub PIP cache during the build. Useful if GitHub is not reachable during build.

--install-from-docker-context-files
        This flag is used during image building. If it is used additionally to installing
        Airflow from PyPI, the packages are installed from the .whl and .tar.gz packages placed
        in the 'docker-context-files' folder. The same flag can be used during entering the image in
        the CI image - in this case also the .whl and .tar.gz files will be installed automatically

-C, --force-clean-images
        Force build images with cache disabled. This will remove the pulled or build images
        and start building images from scratch. This might take a long time.

-r, --skip-rebuild-check
        Skips checking image for rebuilds. It will use whatever image is available locally/pulled.

-L, --build-cache-local
        Uses local cache to build images. No pulled images will be used, but results of local
        builds in the Docker cache are used instead. This will take longer than when the pulled
        cache is used for the first time, but subsequent '--build-cache-local' builds will be
        faster as they will use mostly the locally build cache.

        This is default strategy used by the Production image builds.

-U, --build-cache-pulled
        Uses images pulled from GitHub Container Registry to build images.
        Those builds are usually faster than when ''--build-cache-local'' with the exception if
        the registry images are not yet updated. The images are updated after successful merges
        to main.

        This is default strategy used by the CI image builds.

-X, --build-cache-disabled
        Disables cache during docker builds. This is useful if you want to make sure you want to
        rebuild everything from scratch.

        This strategy is used by default for both Production and CI images for the scheduled
        (nightly) builds in CI.

-g, --github-repository GITHUB_REPOSITORY
        GitHub repository used to pull, push images.
        Default: apache/airflow.

-v, --verbose
        Show verbose information about executed docker, kind, kubectl, helm commands. Useful for
        debugging - when you run breeze with --verbose flags you will be able to see the commands
        executed under the hood and copy&paste them to your terminal to debug them more easily.

        Note that you can further increase verbosity and see all the commands executed by breeze
        by running 'export VERBOSE_COMMANDS="true"' before running breeze.

--dry-run-docker
        Only show docker commands to execute instead of actually executing them. The docker
        commands are printed in yellow color.
```


dev/breeze/src/airflow_breeze/breeze.py
return __AIRFLOW_SOURCES_ROOT
def search_upwards_for_airflow_sources_root(start_from: Path) -> Optional[Path]:
    root = Path(start_from.root)
    d = start_from
    while d != root:
        attempt = d / __AIRFLOW_CFG_FILE
        if attempt.exists() and "name = apache-airflow\n" in attempt.read_text():
            return attempt.parent
        d = d.parent
    return None
def find_airflow_sources_root():
    
    airflow_sources_root = search_upwards_for_airflow_sources_root(Path.cwd())
    if not airflow_sources_root:
        
        airflow_sources_root = search_upwards_for_airflow_sources_root(Path(__file__).resolve().parent)
    global __AIRFLOW_SOURCES_ROOT
    if airflow_sources_root:
        __AIRFLOW_SOURCES_ROOT = airflow_sources_root
    else:
        console.print(f"\n[yellow]Could not find Airflow sources location. Assuming {__AIRFLOW_SOURCES_ROOT}")
    os.chdir(__AIRFLOW_SOURCES_ROOT)
@click.group()
def main():