Skip to content

Commit 341d5b7

Browse files
authored
Add feture of "not-ready" provider. (apache#36391)
This PR adds possibility of marking the provider as "not ready" in the provider.yaml (by setting optional field as "not-ready" to `true". Setting provider as "not-ready", removes it by default from all the release management commands - preparing documentation files preparing provider packages, publishing docs. You can include such providers via `--include-not-ready-providers` flag (or setting INCLUDE_NOT_READY_PROVIDERS environment variable to true). This flag is set to True in our CI, so that we can make sure the providers in-progress are also being tested and verified, but when release manager prepares packages, those providers are not prepared. That will help in early stage of a lifecycle of a provider when we already want to iterate and test it continuously, but - for example the API of such provider is not yet stable or when we are in progress of moving functionality for such provider from core. This PR also marks `fab` providers as "not-ready" as it is still early days and we want to exclude it for now from any kind of release process.
1 parent 8e70d56 commit 341d5b7

24 files changed

+275
-122
lines changed

.github/workflows/build-images.yml

+1
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ jobs:
259259
RUNS_ON: "${{ needs.build-info.outputs.runs-on }}"
260260
BACKEND: sqlite
261261
VERSION_SUFFIX_FOR_PYPI: "dev0"
262+
INCLUDE_NOT_READY_PROVIDERS: "true"
262263
steps:
263264
- name: Cleanup repo
264265
run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*"

.github/workflows/ci.yml

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ env:
4949
IMAGE_TAG: "${{ github.event.pull_request.head.sha || github.sha }}"
5050
USE_SUDO: "true"
5151
INCLUDE_SUCCESS_OUTPUTS: "true"
52+
INCLUDE_NOT_READY_PROVIDERS: "true"
5253
AIRFLOW_ENABLE_AIP_44: "true"
5354
MOUNT_SOURCES: "skip"
5455

airflow/provider.yaml.schema.json

+4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
"description": "If set to true, the provider is also removed and will be soon removed from the code",
3030
"type:": "boolean"
3131
},
32+
"not-ready": {
33+
"description": "If set to true, the provider is not included by default in release commands - for example when provider release or documentation is being prepared (not-ready providers are enabled in CI by default)",
34+
"type:": "boolean"
35+
},
3236
"dependencies": {
3337
"description": "Dependencies that should be added to the provider",
3438
"type": "array",

airflow/providers/fab/provider.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ description: |
2525
`Flask App Builder <https://flask-appbuilder.readthedocs.io/>`__
2626
2727
suspended: false
28+
29+
# The provider is not yet ready to be released, we will skip it by default when preparing new release waves
30+
# For providers until we think it should be released.
31+
not-ready: true
32+
2833
source-date-epoch: 1703288133
2934

3035
versions:

dev/README_RELEASE_PROVIDER_PACKAGES.md

+52
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
- [Bump min Airflow version for providers](#bump-min-airflow-version-for-providers)
2626
- [Decide when to release](#decide-when-to-release)
2727
- [Provider packages versioning](#provider-packages-versioning)
28+
- [Possible states of provider packages](#possible-states-of-provider-packages)
2829
- [Prepare Regular Provider packages (RC)](#prepare-regular-provider-packages-rc)
2930
- [Increasing version number](#increasing-version-number)
3031
- [Generate release notes](#generate-release-notes)
@@ -122,6 +123,57 @@ packages.
122123
Details about maintaining the SEMVER version are going to be discussed and implemented in
123124
[the related issue](https://github.com/apache/airflow/issues/11425)
124125

126+
# Possible states of provider packages
127+
128+
The provider packages can be in one of several states.
129+
130+
* The `ready` state the provider package is released as part of the regular release cycle (including the
131+
documentation, package building and publishing). This is the default state for all providers.
132+
* The `not-ready` state is when the provider has `not-ready` field set to `true` in the `provider.yaml` file.
133+
This is usually used when the provider has some in-progress changes (usually API changes) that we do not
134+
want to release yet as part of the regular release cycle. Providers in this state are excluded from being
135+
released as part of the regular release cycle (including documentation building). You can build and prepare
136+
such provider when you explicitly specify it as argument of a release command or by passing
137+
`--include-not-ready-providers` flag in corresponding command. The `not-ready` providers are treated as
138+
regular providers when it comes to running tests and preparing and releasing packages in `CI` - as we want
139+
to make sure they are properly releasable any time and we want them to contribute to dependencies and we
140+
want to test them.
141+
* The `suspended` state is when the provider has `suspended` field set to `true` in the `provider.yaml` file.
142+
This is used when we have a good reason to suspend such provider, following the devlist discussion and
143+
vote or "lazy consensus". The process of suspension is described in [Provider's docs](../PROVIDERS.rst).
144+
The `suspended` providers are excluded from being released as part of the regular release cycle (including
145+
documentation building) but also they do not contribute dependencies to the CI image and their tests are
146+
not run in CI process. You can build and prepare such provider when you explicitly specify it as argument
147+
of a release command or by passing `--include-suspended-providers` flag in corresponding command (but it
148+
might or might not work at any time as the provider release commands are not regularly run on CI for the
149+
suspended providers). The `suspended` providers are not released as part of the regular release cycle.
150+
* The `removed` state is when the provider is marked as `removed` - usually after some period of time being
151+
`suspended`. This is a temporary state after the provider has been voted (or agreed in "lazy consensus") to
152+
be removed and it is only used for exactly one release cycle - in order to produce the final version of
153+
the package - identical to the previous version with the exception of the removal notice. The process
154+
of removal is described in [Provider's docs](../PROVIDERS.rst). The `removed` providers are included in
155+
the regular release cycle (including documentation building) because the `--include-removed-providers`
156+
flag is passed to commands that release manager runs (see below). The difference between `suspended`
157+
and `removed` providers is that additional information is added to their documentation about the provider
158+
not being maintained any more by the community.
159+
160+
This graph shows the possible transitions between the states:
161+
162+
```mermaid
163+
graph TD;
164+
new[/new/]
165+
new -- Add to the code -->ready;
166+
ready
167+
ready-- Mark as not ready -->not-ready;
168+
not-ready-- Mark as ready -->ready;
169+
ready-- Suspend -->suspended;
170+
suspended-- Resume -->ready;
171+
ready-- Mark as removed -->removed;
172+
suspended-- Mark as removed -->removed;
173+
gone[\gone\]
174+
removed -- Remove from the code --> gone;
175+
```
176+
125177
# Prepare Regular Provider packages (RC)
126178

127179
## Increasing version number

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

+10-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ def _set_default_from_parent(ctx: click.core.Context, option: click.core.Option,
7474
required=False,
7575
type=NotVerifiedBetterChoice(
7676
get_available_packages(
77-
include_non_provider_doc_packages=True, include_all_providers=True, include_removed=True
77+
include_non_provider_doc_packages=True,
78+
include_all_providers=True,
79+
include_removed=True,
80+
include_not_ready=True,
7881
)
7982
),
8083
)
@@ -189,6 +192,12 @@ def _set_default_from_parent(ctx: click.core.Context, option: click.core.Option,
189192
is_flag=True,
190193
envvar="INCLUDE_REMOVED_PROVIDERS",
191194
)
195+
option_include_not_ready_providers = click.option(
196+
"--include-not-ready-providers",
197+
help="Whether to include providers that are not yet ready to be released.",
198+
is_flag=True,
199+
envvar="INCLUDE_NOT_READY_PROVIDERS",
200+
)
192201
option_include_success_outputs = click.option(
193202
"--include-success-outputs",
194203
help="Whether to include outputs of successful parallel runs (skipped by default).",

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
option_forward_credentials,
4545
option_github_repository,
4646
option_image_tag_for_running,
47+
option_include_not_ready_providers,
4748
option_include_removed_providers,
4849
option_installation_package_format,
4950
option_integration,
@@ -590,6 +591,7 @@ def start_airflow(
590591
@click.option("-d", "--docs-only", help="Only build documentation.", is_flag=True)
591592
@option_dry_run
592593
@option_github_repository
594+
@option_include_not_ready_providers
593595
@option_include_removed_providers
594596
@click.option(
595597
"--one-pass-only",
@@ -612,6 +614,7 @@ def build_docs(
612614
clean_build: bool,
613615
docs_only: bool,
614616
github_repository: str,
617+
include_not_ready_providers: bool,
615618
include_removed_providers: bool,
616619
one_pass_only: bool,
617620
package_filter: tuple[str, ...],
@@ -640,7 +643,9 @@ def build_docs(
640643
spellcheck_only=spellcheck_only,
641644
one_pass_only=one_pass_only,
642645
short_doc_packages=expand_all_provider_packages(
643-
doc_packages, include_removed=include_removed_providers
646+
short_doc_packages=doc_packages,
647+
include_removed=include_removed_providers,
648+
include_not_ready=include_not_ready_providers,
644649
),
645650
)
646651
cmd = "/opt/airflow/scripts/in_container/run_docs_build.sh " + " ".join(

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

+1
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@
294294
"--clean-build",
295295
"--one-pass-only",
296296
"--package-filter",
297+
"--include-not-ready-providers",
297298
"--include-removed-providers",
298299
"--github-repository",
299300
"--builder",

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

+30-5
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
option_github_repository,
4747
option_historical_python_version,
4848
option_image_tag_for_running,
49+
option_include_not_ready_providers,
4950
option_include_removed_providers,
5051
option_include_success_outputs,
5152
option_installation_package_format,
@@ -153,7 +154,7 @@
153154
"provider_packages",
154155
nargs=-1,
155156
required=False,
156-
type=NotVerifiedBetterChoice(get_available_packages(include_removed=False)),
157+
type=NotVerifiedBetterChoice(get_available_packages(include_removed=False, include_not_ready=False)),
157158
)
158159
option_airflow_site_directory = click.option(
159160
"-a",
@@ -347,6 +348,7 @@ def provider_action_summary(description: str, message_type: MessageType, package
347348
@argument_provider_packages
348349
@option_answer
349350
@option_dry_run
351+
@option_include_not_ready_providers
350352
@option_include_removed_providers
351353
@click.option(
352354
"--non-interactive",
@@ -369,6 +371,7 @@ def provider_action_summary(description: str, message_type: MessageType, package
369371
def prepare_provider_documentation(
370372
base_branch: str,
371373
github_repository: str,
374+
include_not_ready_providers: bool,
372375
include_removed_providers: bool,
373376
non_interactive: bool,
374377
only_min_version_update: bool,
@@ -391,7 +394,9 @@ def prepare_provider_documentation(
391394
fix_ownership_using_docker()
392395
cleanup_python_generated_files()
393396
if not provider_packages:
394-
provider_packages = get_available_packages(include_removed=include_removed_providers)
397+
provider_packages = get_available_packages(
398+
include_removed=include_removed_providers, include_not_ready=include_not_ready_providers
399+
)
395400

396401
if not skip_git_fetch:
397402
run_command(["git", "remote", "rm", "apache-https-for-providers"], check=False, stderr=DEVNULL)
@@ -521,12 +526,14 @@ def basic_provider_checks(provider_package_id: str) -> dict[str, Any]:
521526
)
522527
@option_dry_run
523528
@option_github_repository
529+
@option_include_not_ready_providers
524530
@option_include_removed_providers
525531
@argument_provider_packages
526532
@option_verbose
527533
def prepare_provider_packages(
528534
clean_dist: bool,
529535
github_repository: str,
536+
include_not_ready_providers: bool,
530537
include_removed_providers: bool,
531538
package_format: str,
532539
package_list_file: IO | None,
@@ -539,7 +546,10 @@ def prepare_provider_packages(
539546
fix_ownership_using_docker()
540547
cleanup_python_generated_files()
541548
packages_list = get_packages_list_to_act_on(
542-
package_list_file, provider_packages, include_removed_providers
549+
package_list_file=package_list_file,
550+
provider_packages=provider_packages,
551+
include_removed=include_removed_providers,
552+
include_not_ready=include_not_ready_providers,
543553
)
544554
if not skip_tag_check:
545555
run_command(["git", "remote", "rm", "apache-https-for-providers"], check=False, stderr=DEVNULL)
@@ -1146,6 +1156,7 @@ def run_publish_docs_in_parallel(
11461156
@option_airflow_site_directory
11471157
@option_debug_resources
11481158
@option_dry_run
1159+
@option_include_not_ready_providers
11491160
@option_include_removed_providers
11501161
@option_include_success_outputs
11511162
@click.option("-s", "--override-versioned", help="Overrides versioned directories.", is_flag=True)
@@ -1166,6 +1177,7 @@ def publish_docs(
11661177
debug_resources: bool,
11671178
doc_packages: tuple[str, ...],
11681179
include_success_outputs: bool,
1180+
include_not_ready_providers: bool,
11691181
include_removed_providers: bool,
11701182
override_versioned: bool,
11711183
package_filter: tuple[str, ...],
@@ -1181,7 +1193,11 @@ def publish_docs(
11811193
)
11821194

11831195
current_packages = find_matching_long_package_names(
1184-
short_packages=expand_all_provider_packages(doc_packages, include_removed=include_removed_providers),
1196+
short_packages=expand_all_provider_packages(
1197+
short_doc_packages=doc_packages,
1198+
include_removed=include_removed_providers,
1199+
include_not_ready=include_not_ready_providers,
1200+
),
11851201
filters=package_filter,
11861202
)
11871203
print(f"Publishing docs for {len(current_packages)} package(s)")
@@ -1210,12 +1226,14 @@ def publish_docs(
12101226
help="Command to add back references for documentation to make it backward compatible.",
12111227
)
12121228
@option_airflow_site_directory
1229+
@option_include_not_ready_providers
12131230
@option_include_removed_providers
12141231
@argument_doc_packages
12151232
@option_dry_run
12161233
@option_verbose
12171234
def add_back_references(
12181235
airflow_site_directory: str,
1236+
include_not_ready_providers: bool,
12191237
include_removed_providers: bool,
12201238
doc_packages: tuple[str, ...],
12211239
):
@@ -1233,7 +1251,14 @@ def add_back_references(
12331251
)
12341252
sys.exit(1)
12351253
start_generating_back_references(
1236-
site_path, list(expand_all_provider_packages(doc_packages, include_removed=include_removed_providers))
1254+
site_path,
1255+
list(
1256+
expand_all_provider_packages(
1257+
short_doc_packages=doc_packages,
1258+
include_removed=include_removed_providers,
1259+
include_not_ready=include_not_ready_providers,
1260+
)
1261+
),
12371262
)
12381263

12391264

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

+4
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
"options": [
133133
"--clean-dist",
134134
"--github-repository",
135+
"--include-not-ready-providers",
135136
"--include-removed-providers",
136137
"--package-format",
137138
"--package-list-file",
@@ -147,6 +148,7 @@
147148
"options": [
148149
"--base-branch",
149150
"--github-repository",
151+
"--include-not-ready-providers",
150152
"--include-removed-providers",
151153
"--non-interactive",
152154
"--only-min-version-update",
@@ -197,6 +199,7 @@
197199
"name": "Publish Docs",
198200
"options": [
199201
"--airflow-site-directory",
202+
"--include-not-ready-providers",
200203
"--include-removed-providers",
201204
"--override-versioned",
202205
"--package-filter",
@@ -218,6 +221,7 @@
218221
"name": "Add Back References to Docs",
219222
"options": [
220223
"--airflow-site-directory",
224+
"--include-not-ready-providers",
221225
"--include-removed-providers",
222226
],
223227
},

dev/breeze/src/airflow_breeze/prepare_providers/provider_packages.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@
2222
import sys
2323
from pathlib import Path
2424
from shutil import copytree, rmtree
25-
from typing import IO, Any
25+
from typing import Any, TextIO
2626

2727
from airflow_breeze.utils.console import get_console
2828
from airflow_breeze.utils.packages import (
2929
get_available_packages,
3030
get_latest_provider_tag,
31+
get_not_ready_provider_ids,
3132
get_provider_details,
3233
get_provider_jinja_context,
3334
get_removed_provider_ids,
@@ -228,7 +229,10 @@ def move_built_packages_and_cleanup(
228229

229230

230231
def get_packages_list_to_act_on(
231-
package_list_file: IO | None, provider_packages: tuple[str, ...], include_removed: bool = False
232+
package_list_file: TextIO | None,
233+
provider_packages: tuple[str, ...],
234+
include_not_ready: bool = False,
235+
include_removed: bool = False,
232236
) -> list[str]:
233237
if package_list_file and provider_packages:
234238
get_console().print(
@@ -237,11 +241,13 @@ def get_packages_list_to_act_on(
237241
sys.exit(1)
238242
if package_list_file:
239243
removed_provider_ids = get_removed_provider_ids()
244+
not_ready_provider_ids = get_not_ready_provider_ids()
240245
return [
241246
package.strip()
242247
for package in package_list_file.readlines()
243-
if package.strip() not in removed_provider_ids
248+
if (package.strip() not in removed_provider_ids or include_removed)
249+
and (package.strip() not in not_ready_provider_ids or include_not_ready)
244250
]
245251
elif provider_packages:
246252
return list(provider_packages)
247-
return get_available_packages(include_removed=include_removed)
253+
return get_available_packages(include_removed=include_removed, include_not_ready=include_not_ready)

0 commit comments

Comments
 (0)