diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/backfills.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/backfills.py index aa3a7fd0ef9b7..6b37b9e381694 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/backfills.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/backfills.py @@ -35,6 +35,7 @@ class BackfillPostBody(StrictBaseModel): dag_run_conf: dict = {} reprocess_behavior: ReprocessBehavior = ReprocessBehavior.NONE max_active_runs: int = 10 + run_on_latest_version: bool = True class BackfillResponse(BaseModel): diff --git a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml index ceaf90b60f805..5f7d5144e7ed8 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml +++ b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml @@ -8770,6 +8770,10 @@ components: type: integer title: Max Active Runs default: 10 + run_on_latest_version: + type: boolean + title: Run On Latest Version + default: true additionalProperties: false type: object required: diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/backfills.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/backfills.py index 30efea4d79ab8..b9c1416b2ce72 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/backfills.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/backfills.py @@ -243,6 +243,7 @@ def create_backfill( dag_run_conf=backfill_request.dag_run_conf, triggering_user_name=user.get_name(), reprocess_behavior=backfill_request.reprocess_behavior, + run_on_latest_version=backfill_request.run_on_latest_version, ) return BackfillResponse.model_validate(backfill_obj) diff --git a/airflow-core/src/airflow/cli/cli_config.py b/airflow-core/src/airflow/cli/cli_config.py index 5c8497ead6e4f..a5062545e86bc 100644 --- a/airflow-core/src/airflow/cli/cli_config.py +++ b/airflow-core/src/airflow/cli/cli_config.py @@ -344,10 +344,11 @@ def string_lower_type(val): ARG_BACKFILL_RUN_ON_LATEST_VERSION = Arg( ("--run-on-latest-version",), help=( - "(Experimental) If set, the backfill will run tasks using the latest bundle version instead of " - "the version that was active when the original Dag run was created." + "(Experimental) The backfill will run tasks using the latest bundle version instead of " + "the version that was active when the original Dag run was created. Defaults to True." ), action="store_true", + default=True, ) diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts b/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts index e45ee585988d8..c2bc9a822d373 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts @@ -418,6 +418,11 @@ export const $BackfillPostBody = { type: 'integer', title: 'Max Active Runs', default: 10 + }, + run_on_latest_version: { + type: 'boolean', + title: 'Run On Latest Version', + default: true } }, additionalProperties: false, diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts index 006f33286fdd3..1a1bf0f50e9ac 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts @@ -115,6 +115,7 @@ export type BackfillPostBody = { }; reprocess_behavior?: ReprocessBehavior; max_active_runs?: number; + run_on_latest_version?: boolean; }; /** diff --git a/airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx b/airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx index 6d15801a05fcd..5155e48275112 100644 --- a/airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx +++ b/airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx @@ -43,9 +43,8 @@ type RunBackfillFormProps = { readonly dag: DAGResponse | DAGWithLatestDagRunsResponse; readonly onClose: () => void; }; -const today = new Date().toISOString().slice(0, 16); - type BackfillFormProps = DagRunTriggerParams & Omit; +const today = new Date().toISOString().slice(0, 16); const RunBackfillForm = ({ dag, onClose }: RunBackfillFormProps) => { const { t: translate } = useTranslation(["components", "common"]); @@ -62,6 +61,7 @@ const RunBackfillForm = ({ dag, onClose }: RunBackfillFormProps) => { max_active_runs: 1, reprocess_behavior: "none", run_backwards: false, + run_on_latest_version: true, to_date: "", }, mode: "onBlur", @@ -78,6 +78,7 @@ const RunBackfillForm = ({ dag, onClose }: RunBackfillFormProps) => { max_active_runs: values.max_active_runs ?? 1, reprocess_behavior: values.reprocess_behavior, run_backwards: values.run_backwards ?? false, + run_on_latest_version: values.run_on_latest_version ?? true, to_date: values.to_date ?? "", }, }, @@ -92,16 +93,11 @@ const RunBackfillForm = ({ dag, onClose }: RunBackfillFormProps) => { setErrors((prev) => ({ ...prev, date: dateValidationError })); } }, [dateValidationError]); - useEffect(() => { if (conf) { - reset((prevValues) => ({ - ...prevValues, - conf, - })); + reset((prevValues) => ({ ...prevValues, conf })); } }, [conf, reset]); - const dataIntervalStart = watch("from_date"); const dataIntervalEnd = watch("to_date"); const noDataInterval = !Boolean(dataIntervalStart) || !Boolean(dataIntervalEnd); @@ -128,16 +124,8 @@ const RunBackfillForm = ({ dag, onClose }: RunBackfillFormProps) => { reset(fdata); onClose(); }; - - const resetDateError = () => { - setErrors((prev) => ({ ...prev, date: undefined })); - }; - - const affectedTasks = data ?? { - backfills: [], - total_entries: 0, - }; - + const resetDateError = () => setErrors((prev) => ({ ...prev, date: undefined })); + const affectedTasks = data ?? { backfills: [], total_entries: 0 }; const inlineMessage = getInlineMessage(isPendingDryRun, affectedTasks.total_entries, translate); return ( @@ -178,12 +166,7 @@ const RunBackfillForm = ({ dag, onClose }: RunBackfillFormProps) => { control={control} name="reprocess_behavior" render={({ field }) => ( - { - field.onChange(event); - }} - > + {translate("backfill.reprocessBehavior")} @@ -230,6 +213,16 @@ const RunBackfillForm = ({ dag, onClose }: RunBackfillFormProps) => { )} /> + ( + + {translate("dags:runAndTaskActions.options.runOnLatestVersion")} + + )} + /> + {dag.is_paused ? ( <> { ) : undefined} -