Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only run separate per-platform build when preparing build cache #24023

Merged
merged 1 commit into from
May 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1664,6 +1664,7 @@ ${{ hashFiles('.pre-commit-config.yaml') }}"
fail-fast: false
matrix:
python-version: ${{ fromJson(needs.build-info.outputs.pythonVersions) }}
platform: ["linux/amd64", "linux/arm64"]
env:
RUNS_ON: ${{ fromJson(needs.build-info.outputs.runsOn) }}
PYTHON_MAJOR_MINOR_VERSION: ${{ matrix.python-version }}
Expand All @@ -1685,11 +1686,12 @@ ${{ hashFiles('.pre-commit-config.yaml') }}"
run: breeze free-space
- name: "Start ARM instance"
run: ./scripts/ci/images/ci_start_arm_instance_and_connect_to_docker.sh
if: matrix.platform == 'linux/arm64'
- name: "Build & Push CI image ${{ matrix.python-version }}:latest"
run: >
breeze build-image
--prepare-buildx-cache
--platform linux/amd64,linux/arm64
--platform ${{ matrix.platform }}
env:
PYTHON_MAJOR_MINOR_VERSION: ${{ matrix.python-version }}
- name: >
Expand Down Expand Up @@ -1722,12 +1724,12 @@ ${{ hashFiles('.pre-commit-config.yaml') }}"
--install-packages-from-context
--prepare-buildx-cache
--disable-airflow-repo-cache
--platform linux/amd64,linux/arm64
--platform ${{ matrix.platform }}
env:
PYTHON_MAJOR_MINOR_VERSION: ${{ matrix.python-version }}
- name: "Stop ARM instance"
run: ./scripts/ci/images/ci_stop_arm_instance.sh
if: always()
if: always() && matrix.platform == 'linux/arm64'
- name: "Fix ownership"
run: breeze fix-ownership
if: always()
89 changes: 40 additions & 49 deletions dev/breeze/src/airflow_breeze/commands/ci_image_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
build_cache,
perform_environment_checks,
prepare_docker_build_command,
prepare_empty_docker_build_command,
prepare_docker_build_from_input,
)
from airflow_breeze.utils.image import run_pull_image, run_pull_in_parallel, tag_image_as_latest
from airflow_breeze.utils.mark_image_as_refreshed import mark_image_as_refreshed
Expand Down Expand Up @@ -142,13 +142,13 @@
{
"name": "Preparing cache and push (for maintainers and CI)",
"options": [
"--platform",
"--prepare-buildx-cache",
"--push-image",
"--empty-image",
"--github-token",
"--github-username",
"--platform",
"--login-to-github-registry",
"--push-image",
"--empty-image",
"--prepare-buildx-cache",
],
},
],
Expand Down Expand Up @@ -457,54 +457,45 @@ def build_ci_image(verbose: bool, dry_run: bool, ci_image_params: BuildCiParams)
return 0, f"Image build: {ci_image_params.python}"
if ci_image_params.prepare_buildx_cache or ci_image_params.push_image:
login_to_github_docker_registry(image_params=ci_image_params, dry_run=dry_run, verbose=verbose)
cmd = prepare_docker_build_command(
image_params=ci_image_params,
verbose=verbose,
)
if ci_image_params.empty_image:
env = os.environ.copy()
env['DOCKER_BUILDKIT'] = "1"
get_console().print(f"\n[info]Building empty CI Image for Python {ci_image_params.python}\n")
cmd = prepare_empty_docker_build_command(image_params=ci_image_params)
build_command_result = run_command(
cmd,
input="FROM scratch\n",
verbose=verbose,
dry_run=dry_run,
cwd=AIRFLOW_SOURCES_ROOT,
text=True,
env=env,
)
if ci_image_params.prepare_buildx_cache:
build_command_result = build_cache(image_params=ci_image_params, dry_run=dry_run, verbose=verbose)
else:
get_console().print(f"\n[info]Building CI Image for Python {ci_image_params.python}\n")
build_command_result = run_command(
cmd, verbose=verbose, dry_run=dry_run, cwd=AIRFLOW_SOURCES_ROOT, text=True, check=False
)
if build_command_result.returncode == 0:
if ci_image_params.prepare_buildx_cache:
build_command_result = build_cache(
image_params=ci_image_params, dry_run=dry_run, verbose=verbose
)

if not ci_image_params.prepare_buildx_cache:
if not dry_run:
if ci_image_params.empty_image:
env = os.environ.copy()
env['DOCKER_BUILDKIT'] = "1"
get_console().print(f"\n[info]Building empty CI Image for Python {ci_image_params.python}\n")
build_command_result = run_command(
prepare_docker_build_from_input(image_params=ci_image_params),
input="FROM scratch\n",
verbose=verbose,
dry_run=dry_run,
cwd=AIRFLOW_SOURCES_ROOT,
text=True,
env=env,
)
else:
get_console().print(f"\n[info]Building CI Image for Python {ci_image_params.python}\n")
build_command_result = run_command(
prepare_docker_build_command(
image_params=ci_image_params,
verbose=verbose,
),
verbose=verbose,
dry_run=dry_run,
cwd=AIRFLOW_SOURCES_ROOT,
text=True,
check=False,
)
if build_command_result.returncode == 0:
if ci_image_params.tag_as_latest:
build_command_result = tag_image_as_latest(ci_image_params, dry_run, verbose)
if (
ci_image_params.airflow_image_name == ci_image_params.airflow_image_name_with_tag
or ci_image_params.tag_as_latest
and build_command_result.returncode == 0
):
mark_image_as_refreshed(ci_image_params)
else:
get_console().print("[error]Error when building image![/]")
return (
build_command_result.returncode,
f"Image build: {ci_image_params.python}",
)
else:
get_console().print("[info]Not updating build cache because we are in `dry_run` mode.[/]")
if ci_image_params.preparing_latest_image():
if dry_run:
get_console().print(
"[info]Not updating build hash because we are in `dry_run` mode.[/]"
)
else:
mark_image_as_refreshed(ci_image_params)
return build_command_result.returncode, f"Image build: {ci_image_params.python}"


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
build_cache,
perform_environment_checks,
prepare_docker_build_command,
prepare_empty_docker_build_command,
prepare_docker_build_from_input,
)
from airflow_breeze.utils.image import run_pull_image, run_pull_in_parallel, tag_image_as_latest
from airflow_breeze.utils.path_utils import AIRFLOW_SOURCES_ROOT, DOCKER_CONTEXT_DIR
Expand Down Expand Up @@ -148,11 +148,11 @@
"options": [
"--github-token",
"--github-username",
"--platform",
"--login-to-github-registry",
"--push-image",
"--prepare-buildx-cache",
"--platform",
"--empty-image",
"--prepare-buildx-cache",
],
},
],
Expand Down Expand Up @@ -497,36 +497,36 @@ def build_production_image(
if prod_image_params.prepare_buildx_cache or prod_image_params.push_image:
login_to_github_docker_registry(image_params=prod_image_params, dry_run=dry_run, verbose=verbose)
get_console().print(f"\n[info]Building PROD Image for Python {prod_image_params.python}\n")
if prod_image_params.empty_image:
env = os.environ.copy()
env['DOCKER_BUILDKIT'] = "1"
get_console().print(f"\n[info]Building empty PROD Image for Python {prod_image_params.python}\n")
cmd = prepare_empty_docker_build_command(image_params=prod_image_params)
build_command_result = run_command(
cmd,
input="FROM scratch\n",
verbose=verbose,
dry_run=dry_run,
cwd=AIRFLOW_SOURCES_ROOT,
check=False,
text=True,
env=env,
)
if prod_image_params.prepare_buildx_cache:
build_command_result = build_cache(image_params=prod_image_params, dry_run=dry_run, verbose=verbose)
else:
cmd = prepare_docker_build_command(
image_params=prod_image_params,
verbose=verbose,
)
build_command_result = run_command(
cmd, verbose=verbose, dry_run=dry_run, cwd=AIRFLOW_SOURCES_ROOT, check=False, text=True
)
if build_command_result.returncode == 0:
if prod_image_params.prepare_buildx_cache:
build_command_result = build_cache(
image_params=prod_image_params, dry_run=dry_run, verbose=verbose
)
else:
if prod_image_params.empty_image:
env = os.environ.copy()
env['DOCKER_BUILDKIT'] = "1"
get_console().print(f"\n[info]Building empty PROD Image for Python {prod_image_params.python}\n")
build_command_result = run_command(
prepare_docker_build_from_input(image_params=prod_image_params),
input="FROM scratch\n",
verbose=verbose,
dry_run=dry_run,
cwd=AIRFLOW_SOURCES_ROOT,
check=False,
text=True,
env=env,
)
else:
build_command_result = run_command(
prepare_docker_build_command(
image_params=prod_image_params,
verbose=verbose,
),
verbose=verbose,
dry_run=dry_run,
cwd=AIRFLOW_SOURCES_ROOT,
check=False,
text=True,
)
if build_command_result.returncode == 0:
if prod_image_params.tag_as_latest:
build_command_result = tag_image_as_latest(prod_image_params, dry_run, verbose)

return build_command_result.returncode, f"Image build: {prod_image_params.python}"
9 changes: 3 additions & 6 deletions dev/breeze/src/airflow_breeze/params/build_ci_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@

from airflow_breeze.branch_defaults import DEFAULT_AIRFLOW_CONSTRAINTS_BRANCH
from airflow_breeze.global_constants import get_airflow_version
from airflow_breeze.params._common_build_params import _CommonBuildParams
from airflow_breeze.utils.console import get_console
from airflow_breeze.params.common_build_params import CommonBuildParams
from airflow_breeze.utils.path_utils import BUILD_CACHE_DIR


@dataclass
class BuildCiParams(_CommonBuildParams):
class BuildCiParams(CommonBuildParams):
"""
CI build parameters. Those parameters are used to determine command issued to build CI image.
"""
Expand Down Expand Up @@ -96,6 +95,4 @@ def optional_image_args(self) -> List[str]:
]

def __post_init__(self):
if self.prepare_buildx_cache:
get_console().print("[info]Forcing --push-image since we are preparing buildx cache[/]")
self.push_image = True
pass
4 changes: 2 additions & 2 deletions dev/breeze/src/airflow_breeze/params/build_prod_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
get_airflow_extras,
get_airflow_version,
)
from airflow_breeze.params._common_build_params import _CommonBuildParams
from airflow_breeze.params.common_build_params import CommonBuildParams
from airflow_breeze.utils.console import get_console


@dataclass
class BuildProdParams(_CommonBuildParams):
class BuildProdParams(CommonBuildParams):
"""
PROD build parameters. Those parameters are used to determine command issued to build PROD image.
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@


@dataclass
class _CommonBuildParams:
class CommonBuildParams:
"""
Common build parameters. Those parameters are common parameters for CI And PROD build.
"""
Expand Down Expand Up @@ -147,6 +147,9 @@ def get_cache(self, single_platform: str) -> str:
def is_multi_platform(self) -> bool:
return "," in self.platform

def preparing_latest_image(self) -> bool:
return self.tag_as_latest or self.airflow_image_name == self.airflow_image_name_with_tag

@property
def platforms(self) -> List[str]:
return self.platform.split(",")
Expand All @@ -160,6 +163,4 @@ def optional_image_args(self) -> List[str]:
raise NotImplementedError()

def __post_init__(self):
if self.prepare_buildx_cache:
get_console().print("[info]Forcing --push-image since we are preparing buildx cache[/]")
self.push_image = True
pass
3 changes: 1 addition & 2 deletions dev/breeze/src/airflow_breeze/utils/common_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,7 @@
)
option_prepare_buildx_cache = click.option(
'--prepare-buildx-cache',
help='Prepares build cache additionally to building images (this is done as two separate steps after'
'the images are build). Implies --push-image flag',
help='Prepares build cache (this is done as separate per-platform steps instead of building the image).',
is_flag=True,
envvar='PREPARE_BUILDX_CACHE',
)
Expand Down
Loading