Skip to content

Commit

Permalink
Push CI image using new Python Breeze (#22888)
Browse files Browse the repository at this point in the history
Fixes: #22821
  • Loading branch information
potiuk authored Apr 10, 2022
1 parent 81bbb55 commit 7c64b92
Show file tree
Hide file tree
Showing 17 changed files with 249 additions and 181 deletions.
30 changes: 12 additions & 18 deletions .github/workflows/build-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ env:
secrets.CONSTRAINTS_GITHUB_REPOSITORY || 'apache/airflow' }}
# This token is WRITE one - pull_request_target type of events always have the WRITE token
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
AIRFLOW_LOGIN_TO_GITHUB_REGISTRY: "true"
LOGIN_TO_GITHUB_REGISTRY: "true"
IMAGE_TAG_FOR_THE_BUILD: "${{ github.event.pull_request.head.sha || github.sha }}"

concurrency:
Expand Down Expand Up @@ -224,24 +224,19 @@ jobs:
- run: python -m pip install --editable ./dev/breeze/
- name: "Free space"
run: airflow-freespace
- name: "Build CI image ${{ matrix.python-version }}:${{ env.IMAGE_TAG_FOR_THE_BUILD }}"
run: breeze build-image
env:
GITHUB_REGISTRY_PULL_IMAGE_TAG: "latest"
GITHUB_REGISTRY_PUSH_IMAGE_TAG: ${{ env.IMAGE_TAG_FOR_THE_BUILD }}
UPGRADE_TO_NEWER_DEPENDENCIES: ${{ needs.build-info.outputs.upgradeToNewerDependencies }}
DOCKER_CACHE: ${{ needs.build-info.outputs.cacheDirective }}
- name: "Push CI image ${{ matrix.python-version }}:${{ env.IMAGE_TAG_FOR_THE_BUILD }}"
run: ./scripts/ci/images/ci_push_ci_images.sh
env:
GITHUB_REGISTRY_PUSH_IMAGE_TAG: ${{ env.IMAGE_TAG_FOR_THE_BUILD }}
- name: "Build/Push CI image ${{ matrix.python-version }}:${{ env.IMAGE_TAG_FOR_THE_BUILD }}"
run: >
breeze build-image --push-image
--upgrade-to-newer-dependencies "${{ needs.build-info.outputs.upgradeToNewerDependencies }}"
--docker-cache "${{ needs.build-info.outputs.cacheDirective }}"
--image-tag "${{ env.IMAGE_TAG_FOR_THE_BUILD }}"
- name: >
Push empty CI images to finish waiting jobs:
${{ matrix.python-version }}:${{ env.IMAGE_TAG_FOR_THE_BUILD }}"
if: failure() || cancelled()
run: ./scripts/ci/images/ci_push_empty_ci_images.sh
env:
GITHUB_REGISTRY_PUSH_IMAGE_TAG: ${{ env.IMAGE_TAG_FOR_THE_BUILD }}
run: >
breeze build-image --push-image --empty-image
--github-registry-push-image-tag "${{ env.IMAGE_TAG_FOR_THE_BUILD }}"
- name: "Candidates for pip resolver backtrack triggers: ${{ matrix.python-version }}"
if: failure() || cancelled()
run: airflow-find-newer-dependencies --max-age 1 --python "${{ matrix.python-version }}"
Expand Down Expand Up @@ -339,6 +334,5 @@ jobs:
Push empty PROD images to finish waiting jobs:
${{ matrix.python-version }}:${{ env.IMAGE_TAG_FOR_THE_BUILD }}"
if: failure() || cancelled()
run: ./scripts/ci/images/ci_push_empty_prod_images.sh
env:
GITHUB_REGISTRY_PUSH_IMAGE_TAG: ${{ env.IMAGE_TAG_FOR_THE_BUILD }}
run: >
breeze build-prod-image --push-image --empty-image --image-tag "${{ env.IMAGE_TAG_FOR_THE_BUILD }}"
20 changes: 7 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ env:
secrets.CONSTRAINTS_GITHUB_REPOSITORY || 'apache/airflow' }}
# In builds from forks, this token is read-only. For scheduler/direct push it is WRITE one
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
AIRFLOW_LOGIN_TO_GITHUB_REGISTRY: "true"
LOGIN_TO_GITHUB_REGISTRY: "true"
ENABLE_TEST_COVERAGE: "${{ github.event_name == 'push' }}"
IMAGE_TAG_FOR_THE_BUILD: "${{ github.event.pull_request.head.sha || github.sha }}"

Expand Down Expand Up @@ -328,19 +328,13 @@ jobs:
- name: "Free space"
run: airflow-freespace
if: needs.build-info.outputs.inWorkflowBuild == 'true'
- name: "Build CI image ${{ matrix.python-version }}:${{ env.IMAGE_TAG_FOR_THE_BUILD }}"
run: breeze build-image
if: needs.build-info.outputs.inWorkflowBuild == 'true'
env:
GITHUB_REGISTRY_PULL_IMAGE_TAG: "latest"
GITHUB_REGISTRY_PUSH_IMAGE_TAG: ${{ env.IMAGE_TAG_FOR_THE_BUILD }}
UPGRADE_TO_NEWER_DEPENDENCIES: ${{ needs.build-info.outputs.upgradeToNewerDependencies }}
DOCKER_CACHE: ${{ needs.build-info.outputs.cacheDirective }}
- name: "Push CI image ${{ matrix.python-version }}:${{ env.IMAGE_TAG_FOR_THE_BUILD }}"
run: ./scripts/ci/images/ci_push_ci_images.sh
- name: "Build/Push CI image ${{ matrix.python-version }}:${{ env.IMAGE_TAG_FOR_THE_BUILD }}"
run: >
breeze build-image --push-image
--upgrade-to-newer-dependencies "${{ needs.build-info.outputs.upgradeToNewerDependencies }}"
--docker-cache "${{ needs.build-info.outputs.cacheDirective }}"
--image-tag "${{ env.IMAGE_TAG_FOR_THE_BUILD }}"
if: needs.build-info.outputs.inWorkflowBuild == 'true'
env:
GITHUB_REGISTRY_PUSH_IMAGE_TAG: ${{ env.IMAGE_TAG_FOR_THE_BUILD }}
- name: "Candidates for pip resolver backtrack triggers: ${{ matrix.python-version }}"
if: failure() || cancelled()
run: airflow-find-newer-dependencies --max-age 1 --python "${{ matrix.python-version }}"
Expand Down
78 changes: 76 additions & 2 deletions dev/breeze/src/airflow_breeze/breeze.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,15 @@
],
},
{
"name": "Preparing cache (for maintainers)",
"name": "Preparing cache and push (for maintainers and CI)",
"options": [
"--platform",
"--prepare-buildx-cache",
"--push-image",
"--empty-image",
"--github-token",
"--github-username",
"--login-to-github-registry",
],
},
],
Expand Down Expand Up @@ -199,10 +204,15 @@
],
},
{
"name": "Preparing cache (for maintainers)",
"name": "Preparing cache and push (for maintainers and CI)",
"options": [
"--platform",
"--prepare-buildx-cache",
"--push-image",
"--empty-image",
"--github-token",
"--github-username",
"--login-to-github-registry",
],
},
],
Expand Down Expand Up @@ -462,6 +472,25 @@ def main(ctx: Context, **kwargs):
envvar='GITHUB_REPOSITORY',
)

option_login_to_github_registry = click.option(
'--login-to-github-registry',
help='Logs in to GitHub registry.',
envvar='LOGIN_TO_GITHUB_REGISTRY',
)


option_github_token = click.option(
'--github-token',
help='The token used to authenticate to GitHub.',
envvar='GITHUB_TOKEN',
)

option_github_username = click.option(
'--github-username',
help='The user name used to authenticate to GitHub.',
envvar='GITHUB_USERNAME',
)

option_github_image_id = click.option(
'-s',
'--github-image-id',
Expand Down Expand Up @@ -570,6 +599,21 @@ def main(ctx: Context, **kwargs):
envvar='PREPARE_BUILDX_CACHE',
)

option_push_image = click.option(
'--push-image',
help='Push image after building it.',
is_flag=True,
envvar='PUSH_IMAGE',
)

option_empty_image = click.option(
'--empty-image',
help='Prepare empty image tagged with the same name as the Airflow image.',
is_flag=True,
envvar='EMPTY_IMAGE',
)


option_install_providers_from_sources = click.option(
'--install-providers-from-sources',
help="Install providers from sources when installing.",
Expand Down Expand Up @@ -745,9 +789,14 @@ def start_airflow(
@option_platform
@option_debian_version
@option_github_repository
@option_github_token
@option_github_username
@option_login_to_github_registry
@option_docker_cache
@option_image_tag
@option_prepare_buildx_cache
@option_push_image
@option_empty_image
@option_install_providers_from_sources
@option_additional_extras
@option_additional_dev_apt_deps
Expand Down Expand Up @@ -782,10 +831,15 @@ def build_ci_image(
runtime_apt_command: Optional[str],
runtime_apt_deps: Optional[str],
github_repository: Optional[str],
github_username: Optional[str],
github_token: Optional[str],
login_to_github_registry: bool,
docker_cache: Optional[str],
platform: Optional[str],
debian_version: Optional[str],
prepare_buildx_cache: bool,
push_image: bool,
empty_image: bool,
answer: Optional[str],
upgrade_to_newer_dependencies: str = "false",
):
Expand Down Expand Up @@ -815,10 +869,15 @@ def build_ci_image(
runtime_apt_command=runtime_apt_command,
runtime_apt_deps=runtime_apt_deps,
github_repository=github_repository,
github_token=github_token,
login_to_github_registry=login_to_github_registry,
github_username=github_username,
docker_cache=docker_cache,
platform=platform,
debian_version=debian_version,
prepare_buildx_cache=prepare_buildx_cache,
push_image=push_image,
empty_image=empty_image,
upgrade_to_newer_dependencies=upgrade_to_newer_dependencies,
)

Expand All @@ -831,9 +890,14 @@ def build_ci_image(
@option_platform
@option_debian_version
@option_github_repository
@option_github_token
@option_github_username
@option_login_to_github_registry
@option_docker_cache
@option_image_tag
@option_prepare_buildx_cache
@option_push_image
@option_empty_image
@click.option(
'--installation-method',
help="Install Airflow from: sources or PyPI.",
Expand Down Expand Up @@ -905,9 +969,14 @@ def build_prod_image(
runtime_apt_command: Optional[str],
runtime_apt_deps: Optional[str],
github_repository: Optional[str],
github_token: Optional[str],
github_username: Optional[str],
login_to_github_registry: bool,
platform: Optional[str],
debian_version: Optional[str],
prepare_buildx_cache: bool,
push_image: bool,
empty_image: bool,
install_providers_from_sources: bool,
extras: Optional[str],
installation_method: Optional[str],
Expand Down Expand Up @@ -948,10 +1017,15 @@ def build_prod_image(
runtime_apt_command=runtime_apt_command,
runtime_apt_deps=runtime_apt_deps,
github_repository=github_repository,
github_token=github_token,
github_username=github_username,
login_to_github_registry=login_to_github_registry,
platform=platform,
debian_version=debian_version,
upgrade_to_newer_dependencies=upgrade_to_newer_dependencies,
prepare_buildx_cache=prepare_buildx_cache,
push_image=push_image,
empty_image=empty_image,
install_providers_from_sources=install_providers_from_sources,
extras=extras,
installation_method=installation_method,
Expand Down
25 changes: 19 additions & 6 deletions dev/breeze/src/airflow_breeze/build_image/ci/build_ci_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
from airflow_breeze.build_image.ci.build_ci_params import BuildCiParams
from airflow_breeze.utils.cache import synchronize_parameters_with_cache, touch_cache_file
from airflow_breeze.utils.console import console
from airflow_breeze.utils.docker_command_utils import construct_build_docker_command
from airflow_breeze.utils.docker_command_utils import (
construct_docker_build_command,
construct_empty_docker_build_command,
tag_and_push_image,
)
from airflow_breeze.utils.md5_build_check import calculate_md5_checksum_for_files
from airflow_breeze.utils.path_utils import AIRFLOW_SOURCES_ROOT, BUILD_CACHE_DIR
from airflow_breeze.utils.registry import login_to_docker_registry
Expand Down Expand Up @@ -102,21 +106,30 @@ def build_image(verbose: bool, dry_run: bool, **kwargs) -> None:
text=True,
check=False,
)
cmd = construct_build_docker_command(
if ci_image_params.prepare_buildx_cache:
login_to_docker_registry(ci_image_params)
cmd = construct_docker_build_command(
image_params=ci_image_params,
verbose=verbose,
required_args=REQUIRED_CI_IMAGE_ARGS,
optional_args=OPTIONAL_CI_IMAGE_ARGS,
production_image=False,
)
if ci_image_params.prepare_buildx_cache:
login_to_docker_registry(ci_image_params)
console.print(f"\n[blue]Building CI Image for Python {ci_image_params.python}\n")
run_command(cmd, verbose=verbose, dry_run=dry_run, cwd=AIRFLOW_SOURCES_ROOT, text=True)
if ci_image_params.empty_image:
console.print(f"\n[blue]Building empty CI Image for Python {ci_image_params.python}\n")
cmd = construct_empty_docker_build_command(image_params=ci_image_params)
run_command(
cmd, input="FROM scratch\n", verbose=verbose, dry_run=dry_run, cwd=AIRFLOW_SOURCES_ROOT, text=True
)
else:
console.print(f"\n[blue]Building CI Image for Python {ci_image_params.python}\n")
run_command(cmd, verbose=verbose, dry_run=dry_run, cwd=AIRFLOW_SOURCES_ROOT, text=True)
if not dry_run:
ci_image_cache_dir = BUILD_CACHE_DIR / ci_image_params.airflow_branch
ci_image_cache_dir.mkdir(parents=True, exist_ok=True)
touch_cache_file(f"built_{ci_image_params.python}", root_dir=ci_image_cache_dir)
calculate_md5_checksum_for_files(ci_image_params.md5sum_cache_dir, update=True)
else:
console.print("[blue]Not updating build cache because we are in `dry_run` mode.[/]")
if ci_image_params.push_image:
tag_and_push_image(image_params=ci_image_params, dry_run=dry_run, verbose=verbose)
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,12 @@ class BuildCiParams:
airflow_constraints_reference: Optional[str] = "constraints-main"
airflow_constraints_location: Optional[str] = ""
airflow_pre_cached_pip_packages: str = "true"
login_to_github_registry: str = "false"
github_username: str = ""
dev_apt_command: str = ""
dev_apt_deps: str = ""
image_tag: str = ""
github_token: str = ""
additional_dev_apt_command: str = ""
additional_dev_apt_deps: str = ""
additional_dev_apt_env: str = ""
Expand All @@ -63,6 +66,8 @@ class BuildCiParams:
platform: str = f"linux/{os.uname().machine}"
debian_version: str = "bullseye"
prepare_buildx_cache: bool = False
push_image: bool = False
empty_image: bool = False
skip_rebuild_check: bool = False

@property
Expand All @@ -77,7 +82,7 @@ def airflow_image_name(self):
return image

@property
def airflow_ci_image_name_with_tag(self):
def airflow_image_name_with_tag(self):
"""Construct CI image link"""
image = f'{self.airflow_base_image_name}/{self.airflow_branch}/ci/python{self.python}'
return image if not self.image_tag else image + f":{self.image_tag}"
Expand Down
31 changes: 22 additions & 9 deletions dev/breeze/src/airflow_breeze/build_image/prod/build_prod_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
from airflow_breeze.build_image.prod.build_prod_params import BuildProdParams
from airflow_breeze.utils.cache import synchronize_parameters_with_cache
from airflow_breeze.utils.console import console
from airflow_breeze.utils.docker_command_utils import construct_build_docker_command
from airflow_breeze.utils.docker_command_utils import (
construct_docker_build_command,
construct_empty_docker_build_command,
tag_and_push_image,
)
from airflow_breeze.utils.path_utils import AIRFLOW_SOURCES_ROOT, DOCKER_CONTEXT_DIR
from airflow_breeze.utils.registry import login_to_docker_registry
from airflow_breeze.utils.run_utils import filter_out_none, fix_group_permissions, run_command
Expand Down Expand Up @@ -163,11 +167,20 @@ def build_production_image(verbose: bool, dry_run: bool, **kwargs):
check=False,
)
console.print(f"\n[blue]Building PROD Image for Python {prod_image_params.python}\n")
cmd = construct_build_docker_command(
image_params=prod_image_params,
verbose=verbose,
required_args=REQUIRED_PROD_IMAGE_ARGS,
optional_args=OPTIONAL_PROD_IMAGE_ARGS,
production_image=True,
)
run_command(cmd, verbose=verbose, dry_run=dry_run, cwd=AIRFLOW_SOURCES_ROOT, text=True)
if prod_image_params.empty_image:
console.print(f"\n[blue]Building empty PROD Image for Python {prod_image_params.python}\n")
cmd = construct_empty_docker_build_command(image_params=prod_image_params)
run_command(
cmd, input="FROM scratch\n", verbose=verbose, dry_run=dry_run, cwd=AIRFLOW_SOURCES_ROOT, text=True
)
else:
cmd = construct_docker_build_command(
image_params=prod_image_params,
verbose=verbose,
required_args=REQUIRED_PROD_IMAGE_ARGS,
optional_args=OPTIONAL_PROD_IMAGE_ARGS,
production_image=True,
)
run_command(cmd, verbose=verbose, dry_run=dry_run, cwd=AIRFLOW_SOURCES_ROOT, text=True)
if prod_image_params.push_image:
tag_and_push_image(image_params=prod_image_params, dry_run=dry_run, verbose=verbose)
Loading

0 comments on commit 7c64b92

Please sign in to comment.