Skip to content

Commit 2b1a194

Browse files
authored
Remove "eager upgrade" from PROD image completely (#33784)
There were still some left-overs of EAGER_UPGRADE in PROD image building. Howwever "eager upgrade" only makes sense for CI images. PROD images when being built should use eager upgrades as they are produced in the CI image step. This PR does the following: * removes eager upgrade parameters from PROD image * instead, prod image build has a new flag for installing the images: --use-constraints-for-context-packages which will automatically use constraints from "docker-context-files" if they are present there. * modifies the CI workflows to upload constraints as artifacts and download them for PROD image build when "eager upgrade" has been used and directs it to use "source" constraints * adds back support to "upgrade to newer dependencies" label that makes it easy to test "eager upgrade" As the result, when PROD image is build in CI: * when regular PR is run, it will use latest github "source" constraints * whwn "eager upgrade" PR is run, it will use the eager-upgrade constraints that were generated during CI build
1 parent a746def commit 2b1a194

21 files changed

+428
-322
lines changed

.github/actions/build-ci-images/action.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ runs:
4848
cat "files/constraints-${PYTHON_VERSION}/*.md" >> $GITHUB_STEP_SUMMARY || true
4949
done
5050
if: env.UPGRADE_TO_NEWER_DEPENDENCIES != 'false'
51+
- name: "Upload constraint artifacts"
52+
uses: actions/upload-artifact@v3
53+
with:
54+
name: constraints
55+
path: ./files/constraints-*/constraints-*.txt
56+
retention-days: 7
5157
- name: "Fix ownership"
5258
shell: bash
5359
run: breeze ci fix-ownership

.github/actions/build-prod-images/action.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,18 @@ runs:
5656
- name: "Move dist packages to docker-context files"
5757
shell: bash
5858
run: mv -v ./dist/*.whl ./docker-context-files
59+
- name: "Download constraints from the CI build"
60+
uses: actions/download-artifact@v3
61+
with:
62+
name: constraints
63+
path: ./docker-context-files
64+
if: env.UPGRADE_TO_NEWER_DEPENDENCIES != 'false'
5965
- name: "Build & Push PROD images ${{ env.IMAGE_TAG }}:${{ env.PYTHON_VERSIONS }}"
6066
shell: bash
6167
run: >
6268
breeze prod-image build --tag-as-latest --run-in-parallel --push
63-
--install-packages-from-context --upgrade-on-failure
69+
--install-packages-from-context --airflow-constraints-mode constraints-source-providers
70+
--use-constraints-for-context-packages
6471
env:
6572
COMMIT_SHA: ${{ github.sha }}
6673
- name: "Fix ownership"

Dockerfile

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -593,17 +593,42 @@ function install_airflow_and_providers_from_docker_context_files(){
593593
return
594594
fi
595595

596-
echo
597-
echo "${COLOR_BLUE}Force re-installing airflow and providers from local files with eager upgrade${COLOR_RESET}"
598-
echo
599-
# force reinstall all airflow + provider package local files with eager upgrade
600-
set -x
601-
pip install "${pip_flags[@]}" --root-user-action ignore --upgrade --upgrade-strategy eager \
602-
${ADDITIONAL_PIP_INSTALL_FLAGS} \
603-
${reinstalling_apache_airflow_package} ${reinstalling_apache_airflow_providers_packages} \
604-
${EAGER_UPGRADE_ADDITIONAL_REQUIREMENTS=}
605-
set +x
596+
if [[ ${USE_CONSTRAINTS_FOR_CONTEXT_PACKAGES=} == "true" ]]; then
597+
local python_version
598+
python_version=$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
599+
local local_constraints_file=/docker-context-files/constraints-"${python_version}"/${AIRFLOW_CONSTRAINTS_MODE}-"${python_version}".txt
606600

601+
if [[ -f "${local_constraints_file}" ]]; then
602+
echo
603+
echo "${COLOR_BLUE}Installing docker-context-files packages with constraints found in ${local_constraints_file}${COLOR_RESET}"
604+
echo
605+
# force reinstall all airflow + provider packages with constraints found in
606+
set -x
607+
pip install "${pip_flags[@]}" --root-user-action ignore --upgrade \
608+
${ADDITIONAL_PIP_INSTALL_FLAGS} --constraint "${local_constraints_file}" \
609+
${reinstalling_apache_airflow_package} ${reinstalling_apache_airflow_providers_packages}
610+
set +x
611+
else
612+
echo
613+
echo "${COLOR_BLUE}Installing docker-context-files packages with constraints from GitHub${COLOR_RESET}"
614+
echo
615+
set -x
616+
pip install "${pip_flags[@]}" --root-user-action ignore \
617+
${ADDITIONAL_PIP_INSTALL_FLAGS} \
618+
--constraint "${AIRFLOW_CONSTRAINTS_LOCATION}" \
619+
${reinstalling_apache_airflow_package} ${reinstalling_apache_airflow_providers_packages}
620+
set +x
621+
fi
622+
else
623+
echo
624+
echo "${COLOR_BLUE}Installing docker-context-files packages without constraints${COLOR_RESET}"
625+
echo
626+
set -x
627+
pip install "${pip_flags[@]}" --root-user-action ignore \
628+
${ADDITIONAL_PIP_INSTALL_FLAGS} \
629+
${reinstalling_apache_airflow_package} ${reinstalling_apache_airflow_providers_packages}
630+
set +x
631+
fi
607632
common::install_pip_version
608633
pip check
609634
}
@@ -1280,6 +1305,12 @@ COPY --from=scripts common.sh install_pip_version.sh \
12801305
# is installed from docker-context files rather than from PyPI)
12811306
ARG INSTALL_PACKAGES_FROM_CONTEXT="false"
12821307

1308+
# Normally constraints are not used when context packages are build - because we might have packages
1309+
# that are conflicting with Airflow constraints, however there are cases when we want to use constraints
1310+
# for example in CI builds when we already have source-package constraints - either from github branch or
1311+
# from eager-upgraded constraints by the CI builds
1312+
ARG USE_CONSTRAINTS_FOR_CONTEXT_PACKAGES="false"
1313+
12831314
# In case of Production build image segment we want to pre-install main version of airflow
12841315
# dependencies from GitHub so that we do not have to always reinstall it from the scratch.
12851316
# The Airflow (and providers in case INSTALL_PROVIDERS_FROM_SOURCES is "false")
@@ -1304,6 +1335,7 @@ ARG VERSION_SUFFIX_FOR_PYPI=""
13041335

13051336
ENV ADDITIONAL_PYTHON_DEPS=${ADDITIONAL_PYTHON_DEPS} \
13061337
INSTALL_PACKAGES_FROM_CONTEXT=${INSTALL_PACKAGES_FROM_CONTEXT} \
1338+
USE_CONSTRAINTS_FOR_CONTEXT_PACKAGES=${USE_CONSTRAINTS_FOR_CONTEXT_PACKAGES} \
13071339
VERSION_SUFFIX_FOR_PYPI=${VERSION_SUFFIX_FOR_PYPI}
13081340

13091341
WORKDIR ${AIRFLOW_HOME}

dev/breeze/src/airflow_breeze/commands/ci_image_commands.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
option_airflow_constraints_mode_ci,
4444
option_airflow_constraints_reference_build,
4545
option_answer,
46+
option_build_progress,
4647
option_build_timeout_minutes,
4748
option_builder,
4849
option_commit_sha,
@@ -226,6 +227,7 @@ def kill_process_group(build_process_group_id: int):
226227
@option_additional_dev_apt_command
227228
@option_additional_dev_apt_env
228229
@option_builder
230+
@option_build_progress
229231
@option_build_timeout_minutes
230232
@option_commit_sha
231233
@option_dev_apt_command

dev/breeze/src/airflow_breeze/commands/ci_image_commands_config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"--tag-as-latest",
3737
"--docker-cache",
3838
"--force-build",
39+
"--build-progress",
3940
],
4041
},
4142
{

dev/breeze/src/airflow_breeze/commands/production_image_commands.py

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
option_airflow_constraints_location,
4040
option_airflow_constraints_mode_prod,
4141
option_airflow_constraints_reference_build,
42+
option_build_progress,
4243
option_builder,
4344
option_commit_sha,
4445
option_debug_resources,
@@ -67,8 +68,6 @@
6768
option_runtime_apt_deps,
6869
option_skip_cleanup,
6970
option_tag_as_latest,
70-
option_upgrade_on_failure,
71-
option_upgrade_to_newer_dependencies,
7271
option_verbose,
7372
option_verify,
7473
option_version_suffix_for_pypi,
@@ -156,8 +155,6 @@ def prod_image():
156155
@option_debug_resources
157156
@option_include_success_outputs
158157
@option_python_versions
159-
@option_upgrade_to_newer_dependencies
160-
@option_upgrade_on_failure
161158
@option_platform_multiple
162159
@option_github_token
163160
@option_docker_cache
@@ -178,6 +175,12 @@ def prod_image():
178175
"Implies --disable-airflow-repo-cache.",
179176
is_flag=True,
180177
)
178+
@click.option(
179+
"--use-constraints-for-context-packages",
180+
help="Uses constraints for context packages installation - "
181+
"either from constraints store in docker-context-files or from github.",
182+
is_flag=True,
183+
)
181184
@click.option(
182185
"--cleanup-context",
183186
help="Clean up docker context files before running build (cannot be used together"
@@ -213,6 +216,7 @@ def prod_image():
213216
@option_additional_runtime_apt_env
214217
@option_additional_runtime_apt_command
215218
@option_builder
219+
@option_build_progress
216220
@option_dev_apt_command
217221
@option_dev_apt_deps
218222
@option_python_image
@@ -434,7 +438,12 @@ def check_docker_context_files(install_packages_from_context: bool):
434438
:param install_packages_from_context: whether we want to install from docker-context-files
435439
"""
436440
context_file = DOCKER_CONTEXT_DIR.rglob("*")
437-
any_context_files = any(context.is_file() and context.name != ".README.md" for context in context_file)
441+
any_context_files = any(
442+
context.is_file()
443+
and context.name not in (".README.md", ".DS_Store")
444+
and not context.parent.name.startswith("constraints")
445+
for context in context_file
446+
)
438447
if not any_context_files and install_packages_from_context:
439448
get_console().print("[warning]\nERROR! You want to install packages from docker-context-files")
440449
get_console().print("[warning]\n but there are no packages to install in this folder.")
@@ -501,24 +510,6 @@ def run_build_production_image(
501510
text=True,
502511
output=output,
503512
)
504-
if (
505-
build_command_result.returncode != 0
506-
and prod_image_params.upgrade_on_failure
507-
and not prod_image_params.upgrade_to_newer_dependencies
508-
):
509-
prod_image_params.upgrade_to_newer_dependencies = True
510-
get_console().print("[warning]Attempting to build with upgrade_to_newer_dependencies on failure")
511-
build_command_result = run_command(
512-
prepare_docker_build_command(
513-
image_params=prod_image_params,
514-
),
515-
cwd=AIRFLOW_SOURCES_ROOT,
516-
check=False,
517-
text=True,
518-
env=env,
519-
output=output,
520-
)
521-
if build_command_result.returncode == 0:
522-
if prod_image_params.tag_as_latest:
523-
build_command_result = tag_image_as_latest(image_params=prod_image_params, output=output)
513+
if build_command_result.returncode == 0 and prod_image_params.tag_as_latest:
514+
build_command_result = tag_image_as_latest(image_params=prod_image_params, output=output)
524515
return build_command_result.returncode, f"Image build: {prod_image_params.python}"

dev/breeze/src/airflow_breeze/commands/production_image_commands_config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,10 @@
3131
"options": [
3232
"--python",
3333
"--install-airflow-version",
34-
"--upgrade-to-newer-dependencies",
35-
"--upgrade-on-failure",
3634
"--image-tag",
3735
"--tag-as-latest",
3836
"--docker-cache",
37+
"--build-progress",
3938
],
4039
},
4140
{
@@ -79,6 +78,7 @@
7978
"name": "Customization options (for specific customization needs)",
8079
"options": [
8180
"--install-packages-from-context",
81+
"--use-constraints-for-context-packages",
8282
"--cleanup-context",
8383
"--disable-mysql-client-installation",
8484
"--disable-mssql-client-installation",

dev/breeze/src/airflow_breeze/global_constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ def all_helm_test_packages() -> list[str]:
147147
ALLOWED_INSTALLATION_PACKAGE_FORMATS = ["wheel", "sdist"]
148148
ALLOWED_INSTALLATION_METHODS = [".", "apache-airflow"]
149149
ALLOWED_BUILD_CACHE = ["registry", "local", "disabled"]
150+
ALLOWED_BUILD_PROGRESS = ["auto", "plain", "tty"]
150151
MULTI_PLATFORM = "linux/amd64,linux/arm64"
151152
SINGLE_PLATFORMS = ["linux/amd64", "linux/arm64"]
152153
ALLOWED_PLATFORMS = [*SINGLE_PLATFORMS, MULTI_PLATFORM]

dev/breeze/src/airflow_breeze/params/build_ci_params.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class BuildCiParams(CommonBuildParams):
3636
airflow_extras: str = "devel_ci"
3737
airflow_pre_cached_pip_packages: bool = True
3838
force_build: bool = False
39+
upgrade_to_newer_dependencies: bool = False
40+
upgrade_on_failure: bool = False
3941
eager_upgrade_additional_requirements: str = ""
4042
skip_provider_dependencies_check: bool = False
4143

@@ -66,7 +68,7 @@ def extra_docker_build_flags(self) -> list[str]:
6668
f"EAGER_UPGRADE_ADDITIONAL_REQUIREMENTS={eager_upgrade_arg}",
6769
]
6870
)
69-
return extra_ci_flags
71+
return super().extra_docker_build_flags + extra_ci_flags
7072

7173
@property
7274
def md5sum_cache_dir(self) -> Path:
@@ -111,6 +113,7 @@ def optional_image_args(self) -> list[str]:
111113
"additional_python_deps",
112114
"version_suffix_for_pypi",
113115
"commit_sha",
116+
"build_progress",
114117
]
115118

116119
def __post_init__(self):

dev/breeze/src/airflow_breeze/params/build_prod_params.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class BuildProdParams(CommonBuildParams):
5252
install_airflow_reference: str = ""
5353
install_airflow_version: str = ""
5454
install_packages_from_context: bool = False
55+
use_constraints_for_context_packages: bool = False
5556
installation_method: str = "."
5657
runtime_apt_command: str = ""
5758
runtime_apt_deps: str = ""
@@ -159,7 +160,6 @@ def extra_docker_build_flags(self) -> list[str]:
159160
f"AIRFLOW_CONSTRAINTS_REFERENCE={self.airflow_constraints_reference}",
160161
]
161162
)
162-
163163
maintainers = json.dumps([{"name": "Apache Airflow PMC", "email": "[email protected]"}])
164164
logo_url = "https://github.com/apache/airflow/raw/main/docs/apache-airflow/img/logos/wordmark_1.png"
165165
readme_url = "https://raw.githubusercontent.com/apache/airflow/main/docs/docker-stack/README.md"
@@ -175,7 +175,7 @@ def extra_docker_build_flags(self) -> list[str]:
175175
f"io.artifacthub.package.logo-url={logo_url}",
176176
]
177177
)
178-
return extra_build_flags
178+
return super().extra_docker_build_flags + extra_build_flags
179179

180180
@property
181181
def airflow_pre_cached_pip_packages(self) -> str:
@@ -221,7 +221,6 @@ def required_image_args(self) -> list[str]:
221221
"install_postgres_client",
222222
"install_providers_from_sources",
223223
"python_base_image",
224-
"upgrade_to_newer_dependencies",
225224
]
226225

227226
@property
@@ -242,4 +241,6 @@ def optional_image_args(self) -> list[str]:
242241
"runtime_apt_deps",
243242
"version_suffix_for_pypi",
244243
"commit_sha",
244+
"build_progress",
245+
"use_constraints_for_context_packages",
245246
]

dev/breeze/src/airflow_breeze/params/common_build_params.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@
2222
from datetime import datetime
2323

2424
from airflow_breeze.branch_defaults import AIRFLOW_BRANCH, DEFAULT_AIRFLOW_CONSTRAINTS_BRANCH
25-
from airflow_breeze.global_constants import APACHE_AIRFLOW_GITHUB_REPOSITORY, DOCKER_DEFAULT_PLATFORM
25+
from airflow_breeze.global_constants import (
26+
ALLOWED_BUILD_PROGRESS,
27+
APACHE_AIRFLOW_GITHUB_REPOSITORY,
28+
DOCKER_DEFAULT_PLATFORM,
29+
)
2630
from airflow_breeze.utils.console import get_console
2731
from airflow_breeze.utils.platforms import get_real_platform
2832

@@ -46,6 +50,7 @@ class CommonBuildParams:
4650
airflow_constraints_location: str = ""
4751
build_id: int = 0
4852
builder: str = "autodetect"
53+
build_progress: str = ALLOWED_BUILD_PROGRESS[0]
4954
constraints_github_repository: str = APACHE_AIRFLOW_GITHUB_REPOSITORY
5055
commit_sha: str = ""
5156
dev_apt_command: str = ""
@@ -62,8 +67,6 @@ class CommonBuildParams:
6267
push: bool = False
6368
python: str = "3.8"
6469
tag_as_latest: bool = False
65-
upgrade_to_newer_dependencies: bool = False
66-
upgrade_on_failure: bool = False
6770
dry_run: bool = False
6871
version_suffix_for_pypi: str = ""
6972
verbose: bool = False
@@ -96,7 +99,10 @@ def airflow_image_name(self):
9699

97100
@property
98101
def extra_docker_build_flags(self) -> list[str]:
99-
raise NotImplementedError()
102+
extra_flass = []
103+
if self.build_progress:
104+
extra_flass.append(f"--progress={self.build_progress}")
105+
return extra_flass
100106

101107
@property
102108
def docker_cache_directive(self) -> list[str]:

dev/breeze/src/airflow_breeze/utils/common_options.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
ALL_HISTORICAL_PYTHON_VERSIONS,
2626
ALLOWED_BACKENDS,
2727
ALLOWED_BUILD_CACHE,
28+
ALLOWED_BUILD_PROGRESS,
2829
ALLOWED_CELERY_BROKERS,
2930
ALLOWED_CONSTRAINTS_MODES_CI,
3031
ALLOWED_CONSTRAINTS_MODES_PROD,
@@ -511,6 +512,14 @@ def _set_default_from_parent(ctx: click.core.Context, option: click.core.Option,
511512
show_default=True,
512513
default="autodetect",
513514
)
515+
option_build_progress = click.option(
516+
"--build-progress",
517+
help="Build progress.",
518+
type=BetterChoice(ALLOWED_BUILD_PROGRESS),
519+
envvar="BUILD_PROGRESS",
520+
show_default=True,
521+
default=ALLOWED_BUILD_PROGRESS[0],
522+
)
514523
option_include_success_outputs = click.option(
515524
"--include-success-outputs",
516525
help="Whether to include outputs of successful parallel runs (skipped by default).",

0 commit comments

Comments
 (0)