1. Allow build, lint, test & bash with the celery container using `make` commands.
2. Added CI to build the docker image to make sure it doesn't get broken in a future PR without knowing.
3. Default to Python 3.11 in the Dockerfile if not set otherwise via .python-version (pyenv).

For example running `make docker-lint` from the `celery` repo root:
```bash
make docker-lint

[+] Creating 4/0
 ✔ Container docker-azurite-1   Running                                                                                                                                           0.0s
 ✔ Container docker-rabbit-1    Running                                                                                                                                           0.0s
 ✔ Container docker-dynamodb-1  Running                                                                                                                                           0.0s
 ✔ Container docker-redis-1     Running                                                                                                                                           0.0s
ROOT: will run in automatically provisioned tox, host /home/developer/.pyenv/versions/3.11.5/bin/python3.11 is missing [requires (has)]: tox-gh-actions
ROOT: recreate env because python changed version_info=[3, 9, 13, 'final', 0]->[3, 11, 5, 'final', 0] | executable='/Users/nusnus/.pyenv/versions/3.9.13/bin/python3.9'->'/home/developer/.pyenv/versions/3.11.5/bin/python3.11' | virtualenv version='20.24.4'->'20.24.5'
ROOT: remove tox env folder /home/developer/celery/.tox/.tox
ROOT: install_deps> python -I -m pip install tox tox-gh-actions
ROOT: provision> .tox/.tox/bin/python -m tox -e lint
ROOT: tox-gh-actions won't override envlist because tox is not running in GitHub Actions
.pkg: _optional_hooks> python /home/developer/celery/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
.pkg: get_requires_for_build_editable> python /home/developer/celery/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
.pkg: build_editable> python /home/developer/celery/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
lint: install_package> python -I -m pip install --force-reinstall --no-deps /home/developer/celery/.tox/.tmp/package/17/celery-5.3.4-0.editable-py3-none-any.whl
lint: commands[0]> pre-commit run --all-files --show-diff-on-failure
[INFO] Initializing environment for https://github.com/asottile/pyupgrade.
[INFO] Initializing environment for https://github.com/PyCQA/flake8.
[INFO] Initializing environment for https://github.com/asottile/yesqa.
[INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Initializing environment for https://github.com/pycqa/isort.
[INFO] Initializing environment for https://github.com/pre-commit/mirrors-mypy.
[INFO] Installing environment for https://github.com/asottile/pyupgrade.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[INFO] Installing environment for https://github.com/PyCQA/flake8.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[INFO] Installing environment for https://github.com/asottile/yesqa.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[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/pycqa/isort.
[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...
pyupgrade................................................................Passed
flake8...................................................................Passed
Strip unnecessary `# noqa`s..............................................Passed
check for merge conflicts................................................Passed
check toml...............................................................Passed
check yaml...............................................................Passed
mixed line ending........................................................Passed
isort....................................................................Passed
mypy.....................................................................Passed
.pkg: _exit> python /home/developer/celery/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
  lint: OK (35.25=setup[3.34]+cmd[31.92] seconds)
  congratulations :) (37.49 seconds)
```


The `make help` is also modified:
```bash
make help
docs                 - Build documentation.
test-all             - Run tests for all supported python versions.
distcheck ---------- - Check distribution for problems.
  test               - Run unittests using current python.
  lint ------------  - Check codebase for problems.
    apicheck         - Check API reference coverage.
    configcheck      - Check configuration reference coverage.
    readmecheck      - Check README.rst encoding.
    contribcheck     - Check CONTRIBUTING.rst encoding
    flakes --------  - Check code for syntax and style errors.
      flakecheck     - Run flake8 on the source code.
      flakepluscheck - Run flakeplus on the source code.
readme               - Regenerate README.rst file.
contrib              - Regenerate CONTRIBUTING.rst file
clean-dist --------- - Clean all distribution build artifacts.
  clean-git-force    - Remove all uncommitted files.
  clean ------------ - Non-destructive clean
    clean-pyc        - Remove .pyc/__pycache__ files
    clean-docs       - Remove documentation build artifacts.
    clean-build      - Remove setup artifacts.
bump                 - Bump patch version number.
bump-minor           - Bump minor version number.
bump-major           - Bump major version number.
release              - Make PyPI release.

Docker-specific commands:
  docker-build			- Build celery docker container.
  docker-lint        		- Run tox -e lint on docker container.
  docker-unit-tests		- Run unit tests on docker container, use '-- -k <TEST NAME>' for specific test run.
  docker-bash        		- Get a bash shell inside the container.
```
Celery Docker Upgrades. 1. Allow build, lint, test & bash with the celery container using `make` commands.
2. Added CI to build the docker image to make sure it doesn't get broken in a future PR without knowing.
3. Default to Python 3.11 in the Dockerfile if not set otherwise via .python-version (pyenv).

For example running `make docker-lint` from the `celery` repo root:
```bash
make docker-lint

[+] Creating 4/0
 ✔ Container docker-azurite-1   Running                                                                                                                                           0.0s
 ✔ Container docker-rabbit-1    Running                                                                                                                                           0.0s
 ✔ Container docker-dynamodb-1  Running                                                                                                                                           0.0s
 ✔ Container docker-redis-1     Running                                                                                                                                           0.0s
ROOT: will run in automatically provisioned tox, host /home/developer/.pyenv/versions/3.11.5/bin/python3.11 is missing [requires (has)]: tox-gh-actions
ROOT: recreate env because python changed version_info=[3, 9, 13, 'final', 0]->[3, 11, 5, 'final', 0] | executable='/Users/nusnus/.pyenv/versions/3.9.13/bin/python3.9'->'/home/developer/.pyenv/versions/3.11.5/bin/python3.11' | virtualenv version='20.24.4'->'20.24.5'
ROOT: remove tox env folder /home/developer/celery/.tox/.tox
ROOT: install_deps> python -I -m pip install tox tox-gh-actions
ROOT: provision> .tox/.tox/bin/python -m tox -e lint
ROOT: tox-gh-actions won't override envlist because tox is not running in GitHub Actions
.pkg: _optional_hooks> python /home/developer/celery/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
.pkg: get_requires_for_build_editable> python /home/developer/celery/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
.pkg: build_editable> python /home/developer/celery/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
lint: install_package> python -I -m pip install --force-reinstall --no-deps /home/developer/celery/.tox/.tmp/package/17/celery-5.3.4-0.editable-py3-none-any.whl
lint: commands[0]> pre-commit run --all-files --show-diff-on-failure
[INFO] Initializing environment for https://github.com/asottile/pyupgrade.
[INFO] Initializing environment for https://github.com/PyCQA/flake8.
[INFO] Initializing environment for https://github.com/asottile/yesqa.
[INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Initializing environment for https://github.com/pycqa/isort.
[INFO] Initializing environment for https://github.com/pre-commit/mirrors-mypy.
[INFO] Installing environment for https://github.com/asottile/pyupgrade.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[INFO] Installing environment for https://github.com/PyCQA/flake8.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[INFO] Installing environment for https://github.com/asottile/yesqa.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[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/pycqa/isort.
[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...
pyupgrade................................................................Passed
flake8...................................................................Passed
Strip unnecessary `# noqa`s..............................................Passed
check for merge conflicts................................................Passed
check toml...............................................................Passed
check yaml...............................................................Passed
mixed line ending........................................................Passed
isort....................................................................Passed
mypy.....................................................................Passed
.pkg: _exit> python /home/developer/celery/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
  lint: OK (35.25=setup[3.34]+cmd[31.92] seconds)
  congratulations :) (37.49 seconds)
```


The `make help` is also modified:
```bash
make help
docs                 - Build documentation.
test-all             - Run tests for all supported python versions.
distcheck ---------- - Check distribution for problems.
  test               - Run unittests using current python.
  lint ------------  - Check codebase for problems.
    apicheck         - Check API reference coverage.
    configcheck      - Check configuration reference coverage.
    readmecheck      - Check README.rst encoding.
    contribcheck     - Check CONTRIBUTING.rst encoding
    flakes --------  - Check code for syntax and style errors.
      flakecheck     - Run flake8 on the source code.
      flakepluscheck - Run flakeplus on the source code.
readme               - Regenerate README.rst file.
contrib              - Regenerate CONTRIBUTING.rst file
clean-dist --------- - Clean all distribution build artifacts.
  clean-git-force    - Remove all uncommitted files.
  clean ------------ - Non-destructive clean
    clean-pyc        - Remove .pyc/__pycache__ files
    clean-docs       - Remove documentation build artifacts.
    clean-build      - Remove setup artifacts.
bump                 - Bump patch version number.
bump-minor           - Bump minor version number.
bump-major           - Bump major version number.
release              - Make PyPI release.

Docker-specific commands:
  docker-build			- Build celery docker container.
  docker-lint        		- Run tox -e lint on docker container.
  docker-unit-tests		- Run unit tests on docker container, use '-- -k <TEST NAME>' for specific test run.
  docker-bash        		- Get a bash shell inside the container.
```
from time import sleep

from tasks import identity_task, mul, wait_for_revoke, xsum
from visitors import MonitoringIdStampingVisitor

from celery.canvas import Signature, chain, chord, group
from celery.result import AsyncResult


def create_canvas(n: int) -> Signature:
    """Creates a canvas to calculate: n * sum(1..n) * 10
    For example, if n = 3, the result is 3 * (1 + 2 + 3) * 10 = 180
    """
    canvas = chain(
        group(identity_task.s(i) for i in range(1, n+1)) | xsum.s(),
        chord(group(mul.s(10) for _ in range(1, n+1)), xsum.s()),
    )

    return canvas


def revoke_by_headers(result: AsyncResult, terminate: bool) -> None:
    """Revokes the last task in the workflow by its stamped header

    Arguments:
        result (AsyncResult): Can be either a frozen or a running result
        terminate (bool): If True, the revoked task will be terminated
    """
    result.revoke_by_stamped_headers({'mystamp': 'I am a stamp!'}, terminate=terminate)


def prepare_workflow() -> Signature:
    """Creates a canvas that waits "n * sum(1..n) * 10" in seconds,
    with n = 3.

    The canvas itself is stamped with a unique monitoring id stamp per task.
    The waiting task is stamped with different consistent stamp, which is used
    to revoke the task by its stamped header.
    """
    canvas = create_canvas(n=3)
    canvas = canvas | wait_for_revoke.s()
    canvas.stamp(MonitoringIdStampingVisitor())
    return canvas


def run_then_revoke():
    """Runs the workflow and lets the waiting task run for a while.
    Then, the waiting task is revoked by its stamped header.

    The expected outcome is that the canvas will be calculated to the end,
    but the waiting task will be revoked and terminated *during its run*.

    See worker logs for more details.
    """
    canvas = prepare_workflow()
    result = canvas.delay()
    print('Wait 5 seconds, then revoke the last task by its stamped header: "mystamp": "I am a stamp!"')
    sleep(5)
    print('Revoking the last task...')
    revoke_by_headers(result, terminate=True)


def revoke_then_run():
    """Revokes the waiting task by its stamped header before it runs.
    Then, run the workflow, which will not run the waiting task that was revoked.

    The expected outcome is that the canvas will be calculated to the end,
    but the waiting task will not run at all.

    See worker logs for more details.
    """
    canvas = prepare_workflow()
    result = canvas.freeze()
    revoke_by_headers(result, terminate=False)
    result = canvas.delay()

from time import sleep

from tasks import identity_task, mul, wait_for_revoke, xsum
from visitors import MonitoringIdStampingVisitor

from celery.canvas import Signature, chain, chord, group
from celery.result import AsyncResult


def create_canvas(n: int) -> Signature:
    """Creates a canvas to calculate: n * sum(1..n) * 10
    For example, if n = 3, the result is 3 * (1 + 2 + 3) * 10 = 180
    """
    canvas = chain(
        group(identity_task.s(i) for i in range(1, n+1)) | xsum.s(),
        chord(group(mul.s(10) for _ in range(1, n+1)), xsum.s()),
    )

    return canvas


def revoke_by_headers(result: AsyncResult, terminate: bool) -> None:
    """Revokes the last task in the workflow by its stamped header

    Arguments:
        result (AsyncResult): Can be either a frozen or a running result
        terminate (bool): If True, the revoked task will be terminated
    """
    result.revoke_by_stamped_headers({'mystamp': 'I am a stamp!'}, terminate=terminate)


def prepare_workflow() -> Signature:
    """Creates a canvas that waits "n * sum(1..n) * 10" in seconds,
    with n = 3.

    The canvas itself is stamped with a unique monitoring id stamp per task.
    The waiting task is stamped with different consistent stamp, which is used
    to revoke the task by its stamped header.
    """
    canvas = create_canvas(n=3)
    canvas = canvas | wait_for_revoke.s()
    canvas.stamp(MonitoringIdStampingVisitor())
    return canvas


def run_then_revoke():
    """Runs the workflow and lets the waiting task run for a while.
    Then, the waiting task is revoked by its stamped header.

    The expected outcome is that the canvas will be calculated to the end,
    but the waiting task will be revoked and terminated *during its run*.

    See worker logs for more details.
    """
    canvas = prepare_workflow()
    result = canvas.delay()
    print('Wait 5 seconds, then revoke the last task by its stamped header: "mystamp": "I am a stamp!"')
    sleep(5)
    print('Revoking the last task...')
    revoke_by_headers(result, terminate=True)


def revoke_then_run():
    """Revokes the waiting task by its stamped header before it runs.
    Then, run the workflow, which will not run the waiting task that was revoked.

    The expected outcome is that the canvas will be calculated to the end,
    but the waiting task will not run at all.

    See worker logs for more details.
    """
    canvas = prepare_workflow()
    result = canvas.freeze()
    revoke_by_headers(result, terminate=False)
    result = canvas.delay()
