From c32c248bb3ab580860e3eefa5b55f7f0d06b818a Mon Sep 17 00:00:00 2001 From: VincentHsiao Date: Sun, 1 Mar 2026 14:00:38 +0800 Subject: [PATCH 1/3] feat(i18n): Complete zh-TW translations - Add 10 missing keys - Add pendingDagRun (singular and plural) translations - Add partitionedDagRun (singular and plural) translations - Add partitionedDagRunDetail.receivedAssetEvents translation - Add panel.showVersionIndicator label and options translations - Achieves 100% zh-TW translation coverage (786/786 keys) --- .../src/airflow/ui/public/i18n/locales/zh-TW/common.json | 7 +++++++ .../src/airflow/ui/public/i18n/locales/zh-TW/dag.json | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json index 5fa1c4f83cb3a..60f483c7939c9 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json @@ -161,6 +161,13 @@ "placeholder": "新增筆記...", "taskInstance": "任務實例筆記" }, + "partitionedDagRun_one": "分割的 Dag 執行", + "partitionedDagRun_other": "分割的 Dag 執行", + "partitionedDagRunDetail": { + "receivedAssetEvents": "收到的資源事件" + }, + "pendingDagRun_one": "待執行的 Dag 執行", + "pendingDagRun_other": "待執行的 Dag 執行", "reset": "重置", "runId": "執行 ID", "runTypes": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json index 74149b0d08e42..9c6dced4c52fe 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json @@ -121,6 +121,15 @@ "graphDirection": { "label": "圖表方向" }, + "showVersionIndicator": { + "label": "版本指示器", + "options": { + "hideAll": "隱藏全部", + "showAll": "顯示全部", + "showBundleVersion": "顯示套件包版本", + "showDagVersion": "顯示 Dag 版本" + } + }, "taskStreamFilter": { "activeFilter": "啟用過濾器", "clearFilter": "清除過濾器", From 33f50b2eaac53ab37fe8d8137e32f48587c9f375 Mon Sep 17 00:00:00 2001 From: VincentHsiao Date: Mon, 2 Mar 2026 15:55:26 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat(i18n):=20Change=20partition=20->=20?= =?UTF-8?q?=E5=88=86=E5=89=B2=20to=20partition=20->=20=E5=88=86=E5=8D=80?= =?UTF-8?q?=20to=20zh-TW=20translations=20and=20add=20partition=20->=20?= =?UTF-8?q?=E5=8D=80=E5=88=86=20to=20zh-TW.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../airflow-translations/locales/zh-TW.md | 1 + .../openapi/v2-rest-api-generated.yaml | 8 +++ .../core_api/routes/public/dag_run.py | 4 ++ .../airflow/ui/openapi-gen/queries/common.ts | 5 +- .../ui/openapi-gen/queries/ensureQueryData.ts | 6 +- .../ui/openapi-gen/queries/prefetch.ts | 6 +- .../airflow/ui/openapi-gen/queries/queries.ts | 6 +- .../ui/openapi-gen/queries/suspense.ts | 6 +- .../ui/openapi-gen/requests/services.gen.ts | 2 + .../ui/openapi-gen/requests/types.gen.ts | 1 + .../ui/public/i18n/locales/zh-TW/common.json | 4 +- .../ui/src/constants/filterConfigs.tsx | 6 ++ .../airflow/ui/src/constants/searchParams.ts | 1 + .../src/airflow/ui/src/pages/DagRuns.tsx | 3 + .../airflow/ui/src/pages/DagRunsFilters.tsx | 1 + .../airflow/ui/src/utils/useFiltersHandler.ts | 1 + dags/generate_dag_runs.py | 68 +++++++++++++++++++ dags/test_dag.py | 66 ++++++++++++++++++ 18 files changed, 183 insertions(+), 12 deletions(-) create mode 100644 dags/generate_dag_runs.py create mode 100644 dags/test_dag.py diff --git a/.github/skills/airflow-translations/locales/zh-TW.md b/.github/skills/airflow-translations/locales/zh-TW.md index 0430726a57e62..f22b1dc8fb9b2 100644 --- a/.github/skills/airflow-translations/locales/zh-TW.md +++ b/.github/skills/airflow-translations/locales/zh-TW.md @@ -150,5 +150,6 @@ Use the following established translations in the Airflow UI: - **Triggerer** → 觸發者 - **trigger** → 觸發器 +- **partition** → 分區 Ensure these terms are used consistently across the locale. 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 f50499bdb8590..9206bfc57367c 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 @@ -2297,6 +2297,14 @@ paths: items: type: integer title: Dag Version + - name: bundle_version + in: query + required: false + schema: + anyOf: + - type: string + - type: 'null' + title: Bundle Version - name: order_by in: query required: false diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py index d0cc597fd5123..359809458cf29 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py @@ -346,6 +346,9 @@ def get_dag_runs( run_type: QueryDagRunRunTypesFilter, state: QueryDagRunStateFilter, dag_version: QueryDagRunVersionFilter, + bundle_version: Annotated[ + FilterParam[str | None], Depends(filter_param_factory(DagRun.bundle_version, str | None)) + ], order_by: Annotated[ SortParam, Depends( @@ -407,6 +410,7 @@ def get_dag_runs( state, run_type, dag_version, + bundle_version, readable_dag_runs_filter, run_id_pattern, triggering_user_name_pattern, diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts index 4f32c3773cf30..c788101379461 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts @@ -143,7 +143,8 @@ export const UseDagRunServiceGetUpstreamAssetEventsKeyFn = ({ dagId, dagRunId }: export type DagRunServiceGetDagRunsDefaultResponse = Awaited>; export type DagRunServiceGetDagRunsQueryResult = UseQueryResult; export const useDagRunServiceGetDagRunsKey = "DagRunServiceGetDagRuns"; -export const UseDagRunServiceGetDagRunsKeyFn = ({ confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { +export const UseDagRunServiceGetDagRunsKeyFn = ({ bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { + bundleVersion?: string; confContains?: string; dagId: string; dagIdPattern?: string; @@ -180,7 +181,7 @@ export const UseDagRunServiceGetDagRunsKeyFn = ({ confContains, dagId, dagIdPatt updatedAtGte?: string; updatedAtLt?: string; updatedAtLte?: string; -}, queryKey?: Array) => [useDagRunServiceGetDagRunsKey, ...(queryKey ?? [{ confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }])]; +}, queryKey?: Array) => [useDagRunServiceGetDagRunsKey, ...(queryKey ?? [{ bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }])]; export type DagRunServiceWaitDagRunUntilFinishedDefaultResponse = Awaited>; export type DagRunServiceWaitDagRunUntilFinishedQueryResult = UseQueryResult; export const useDagRunServiceWaitDagRunUntilFinishedKey = "DagRunServiceWaitDagRunUntilFinished"; diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts index 2b61c294b2e00..8ccaf76a47a83 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts @@ -293,6 +293,7 @@ export const ensureUseDagRunServiceGetUpstreamAssetEventsData = (queryClient: Qu * @param data.runType * @param data.state * @param data.dagVersion +* @param data.bundleVersion * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id` * @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). or the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. * @param data.triggeringUserNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). or the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. @@ -301,7 +302,8 @@ export const ensureUseDagRunServiceGetUpstreamAssetEventsData = (queryClient: Qu * @returns DAGRunCollectionResponse Successful Response * @throws ApiError */ -export const ensureUseDagRunServiceGetDagRunsData = (queryClient: QueryClient, { confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { +export const ensureUseDagRunServiceGetDagRunsData = (queryClient: QueryClient, { bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { + bundleVersion?: string; confContains?: string; dagId: string; dagIdPattern?: string; @@ -338,7 +340,7 @@ export const ensureUseDagRunServiceGetDagRunsData = (queryClient: QueryClient, { updatedAtGte?: string; updatedAtLt?: string; updatedAtLte?: string; -}) => queryClient.ensureQueryData({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }), queryFn: () => DagRunService.getDagRuns({ confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) }); +}) => queryClient.ensureQueryData({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) }); /** * Experimental: Wait for a dag run to complete, and return task results if requested. * 🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state. diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts index 43f9ad49c88ff..57c4174683dfa 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts @@ -293,6 +293,7 @@ export const prefetchUseDagRunServiceGetUpstreamAssetEvents = (queryClient: Quer * @param data.runType * @param data.state * @param data.dagVersion +* @param data.bundleVersion * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id` * @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). or the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. * @param data.triggeringUserNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). or the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. @@ -301,7 +302,8 @@ export const prefetchUseDagRunServiceGetUpstreamAssetEvents = (queryClient: Quer * @returns DAGRunCollectionResponse Successful Response * @throws ApiError */ -export const prefetchUseDagRunServiceGetDagRuns = (queryClient: QueryClient, { confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { +export const prefetchUseDagRunServiceGetDagRuns = (queryClient: QueryClient, { bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { + bundleVersion?: string; confContains?: string; dagId: string; dagIdPattern?: string; @@ -338,7 +340,7 @@ export const prefetchUseDagRunServiceGetDagRuns = (queryClient: QueryClient, { c updatedAtGte?: string; updatedAtLt?: string; updatedAtLte?: string; -}) => queryClient.prefetchQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }), queryFn: () => DagRunService.getDagRuns({ confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) }); +}) => queryClient.prefetchQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) }); /** * Experimental: Wait for a dag run to complete, and return task results if requested. * 🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state. diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts index fd4924351c416..4ee2599aefea5 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts @@ -293,6 +293,7 @@ export const useDagRunServiceGetUpstreamAssetEvents = = unknown[]>({ confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { +export const useDagRunServiceGetDagRuns = = unknown[]>({ bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { + bundleVersion?: string; confContains?: string; dagId: string; dagIdPattern?: string; @@ -338,7 +340,7 @@ export const useDagRunServiceGetDagRuns = , "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }, queryKey), queryFn: () => DagRunService.getDagRuns({ confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) as TData, ...options }); +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }, queryKey), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) as TData, ...options }); /** * Experimental: Wait for a dag run to complete, and return task results if requested. * 🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state. diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts index 87d9580e0317c..2d01abdb58f4f 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts @@ -293,6 +293,7 @@ export const useDagRunServiceGetUpstreamAssetEventsSuspense = = unknown[]>({ confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { +export const useDagRunServiceGetDagRunsSuspense = = unknown[]>({ bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { + bundleVersion?: string; confContains?: string; dagId: string; dagIdPattern?: string; @@ -338,7 +340,7 @@ export const useDagRunServiceGetDagRunsSuspense = , "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }, queryKey), queryFn: () => DagRunService.getDagRuns({ confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) as TData, ...options }); +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }, queryKey), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, dagId, dagIdPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) as TData, ...options }); /** * Experimental: Wait for a dag run to complete, and return task results if requested. * 🚧 This is an experimental endpoint and may change or be removed without notice.Successful response are streamed as newline-delimited JSON (NDJSON). Each line is a JSON object representing the DAG run state. diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts b/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts index 62d70dca2c3e4..d5ee0a91e935d 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts @@ -1006,6 +1006,7 @@ export class DagRunService { * @param data.runType * @param data.state * @param data.dagVersion + * @param data.bundleVersion * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id` * @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). or the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. * @param data.triggeringUserNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). or the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. @@ -1052,6 +1053,7 @@ export class DagRunService { run_type: data.runType, state: data.state, dag_version: data.dagVersion, + bundle_version: data.bundleVersion, order_by: data.orderBy, run_id_pattern: data.runIdPattern, triggering_user_name_pattern: data.triggeringUserNamePattern, 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 53c9e259d640b..bdf9e429e4c87 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 @@ -2509,6 +2509,7 @@ export type ClearDagRunData = { export type ClearDagRunResponse = TaskInstanceCollectionResponse | DAGRunResponse; export type GetDagRunsData = { + bundleVersion?: string | null; confContains?: string; dagId: string; /** diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json index 60f483c7939c9..efaa36625d231 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json @@ -161,8 +161,8 @@ "placeholder": "新增筆記...", "taskInstance": "任務實例筆記" }, - "partitionedDagRun_one": "分割的 Dag 執行", - "partitionedDagRun_other": "分割的 Dag 執行", + "partitionedDagRun_one": "分區的 Dag 執行", + "partitionedDagRun_other": "分區的 Dag 執行", "partitionedDagRunDetail": { "receivedAssetEvents": "收到的資源事件" }, diff --git a/airflow-core/src/airflow/ui/src/constants/filterConfigs.tsx b/airflow-core/src/airflow/ui/src/constants/filterConfigs.tsx index 698d485f93c0f..691ed35c04272 100644 --- a/airflow-core/src/airflow/ui/src/constants/filterConfigs.tsx +++ b/airflow-core/src/airflow/ui/src/constants/filterConfigs.tsx @@ -77,6 +77,12 @@ export const useFilterConfigs = () => { label: translate("hitl:filters.body"), type: FilterTypes.TEXT, }, + [SearchParamsKeys.BUNDLE_VERSION]: { + hotkeyDisabled: true, + icon: , + label: translate("common:bundleVersion"), + type: FilterTypes.TEXT, + }, [SearchParamsKeys.CONF_CONTAINS]: { hotkeyDisabled: true, icon: , diff --git a/airflow-core/src/airflow/ui/src/constants/searchParams.ts b/airflow-core/src/airflow/ui/src/constants/searchParams.ts index 0215a55b2da51..d37001e768802 100644 --- a/airflow-core/src/airflow/ui/src/constants/searchParams.ts +++ b/airflow-core/src/airflow/ui/src/constants/searchParams.ts @@ -21,6 +21,7 @@ export enum SearchParamsKeys { ASSET_EVENT_DATE_RANGE = "asset_event_date_range", BEFORE = "before", BODY_SEARCH = "body_search", + BUNDLE_VERSION = "bundle_version", CONF_CONTAINS = "conf_contains", CREATED_AT_GTE = "created_at_gte", CREATED_AT_LTE = "created_at_lte", diff --git a/airflow-core/src/airflow/ui/src/pages/DagRuns.tsx b/airflow-core/src/airflow/ui/src/pages/DagRuns.tsx index 99186d6102ee1..6daf580279fa3 100644 --- a/airflow-core/src/airflow/ui/src/pages/DagRuns.tsx +++ b/airflow-core/src/airflow/ui/src/pages/DagRuns.tsx @@ -43,6 +43,7 @@ import { renderDuration, useAutoRefresh, isStatePending } from "src/utils"; type DagRunRow = { row: { original: DAGRunResponse } }; const { + BUNDLE_VERSION: BUNDLE_VERSION_PARAM, CONF_CONTAINS: CONF_CONTAINS_PARAM, DAG_ID_PATTERN: DAG_ID_PATTERN_PARAM, DAG_VERSION: DAG_VERSION_PARAM, @@ -209,6 +210,7 @@ export const DagRuns = () => { const filteredTriggeringUserNamePattern = searchParams.get(TRIGGERING_USER_NAME_PATTERN_PARAM); const filteredDagIdPattern = searchParams.get(DAG_ID_PATTERN_PARAM); const filteredDagVersion = searchParams.get(DAG_VERSION_PARAM); + const bundleVersion = searchParams.get(BUNDLE_VERSION_PARAM); const startDateGte = searchParams.get(START_DATE_GTE_PARAM); const startDateLte = searchParams.get(START_DATE_LTE_PARAM); const endDateGte = searchParams.get(END_DATE_GTE_PARAM); @@ -224,6 +226,7 @@ export const DagRuns = () => { const { data, error, isLoading } = useDagRunServiceGetDagRuns( { + bundleVersion: bundleVersion ?? undefined, confContains: confContains !== null && confContains !== "" ? confContains : undefined, dagId: dagId ?? "~", dagIdPattern: filteredDagIdPattern ?? undefined, diff --git a/airflow-core/src/airflow/ui/src/pages/DagRunsFilters.tsx b/airflow-core/src/airflow/ui/src/pages/DagRunsFilters.tsx index 201b77d0814cb..b0f90d66f9876 100644 --- a/airflow-core/src/airflow/ui/src/pages/DagRunsFilters.tsx +++ b/airflow-core/src/airflow/ui/src/pages/DagRunsFilters.tsx @@ -41,6 +41,7 @@ export const DagRunsFilters = ({ dagId }: DagRunsFiltersProps) => { SearchParamsKeys.TRIGGERING_USER_NAME_PATTERN, SearchParamsKeys.DAG_VERSION, SearchParamsKeys.PARTITION_KEY_PATTERN, + SearchParamsKeys.BUNDLE_VERSION, ]; if (dagId === undefined) { diff --git a/airflow-core/src/airflow/ui/src/utils/useFiltersHandler.ts b/airflow-core/src/airflow/ui/src/utils/useFiltersHandler.ts index 2e879ee0c8e4d..17ab2fc35061f 100644 --- a/airflow-core/src/airflow/ui/src/utils/useFiltersHandler.ts +++ b/airflow-core/src/airflow/ui/src/utils/useFiltersHandler.ts @@ -58,6 +58,7 @@ const handleDateRangeChange = ( export type FilterableSearchParamsKeys = | SearchParamsKeys.ASSET_EVENT_DATE_RANGE | SearchParamsKeys.BODY_SEARCH + | SearchParamsKeys.BUNDLE_VERSION | SearchParamsKeys.CONF_CONTAINS | SearchParamsKeys.CREATED_AT_RANGE | SearchParamsKeys.DAG_DISPLAY_NAME_PATTERN diff --git a/dags/generate_dag_runs.py b/dags/generate_dag_runs.py new file mode 100644 index 0000000000000..954304240d6d9 --- /dev/null +++ b/dags/generate_dag_runs.py @@ -0,0 +1,68 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +from airflow import settings +from airflow.models import DagRun +from airflow.models.dagrun import DagRunType +from airflow.utils import timezone + + +def create_test_dag_runs(): + """生成測試 DAG runs.""" + session = settings.Session() + + dag_runs = [ + # 創建不同狀態的 runs + DagRun( + dag_id="test_dag_simple", + run_id="test_simple_2024_01_01", + logical_date=timezone.parse("2024-01-01"), + start_date=timezone.parse("2024-01-01 10:00:00"), + end_date=timezone.parse("2024-01-01 10:05:00"), + state="success", + run_type=DagRunType.SCHEDULED, + ), + DagRun( + dag_id="test_dag_simple", + run_id="test_simple_2024_01_02", + logical_date=timezone.parse("2024-01-02"), + start_date=timezone.parse("2024-01-02 12:00:00"), + state="failed", + run_type=DagRunType.MANUAL, + ), + DagRun( + dag_id="test_dag_parametrized", + run_id="test_param_2024_01_01", + logical_date=timezone.parse("2024-01-01"), + start_date=timezone.parse("2024-01-01 06:15:00"), + end_date=timezone.parse("2024-01-01 06:45:00"), + state="success", + run_type=DagRunType.SCHEDULED, + ), + ] + + for run in dag_runs: + session.add(run) + + session.commit() + session.close() + print("✅ DAG runs 已創建") + + +if __name__ == "__main__": + create_test_dag_runs() diff --git a/dags/test_dag.py b/dags/test_dag.py new file mode 100644 index 0000000000000..c4c73e14b345d --- /dev/null +++ b/dags/test_dag.py @@ -0,0 +1,66 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +from datetime import datetime, timedelta + +from airflow import DAG +from airflow.operators.bash import BashOperator +from airflow.operators.empty import EmptyOperator + +default_args = { + "owner": "airflow", + "retries": 1, + "retry_delay": timedelta(minutes=5), + "start_date": datetime(2024, 1, 1), +} + +# 測試 DAG 1: 基本 DAG +with DAG( + "test_dag_simple", + default_args=default_args, + schedule="0 0 * * *", + tags=["test", "example"], + doc_md="### 簡單測試 DAG", +) as dag1: + task1 = EmptyOperator(task_id="task_1") + task2 = BashOperator(task_id="task_2", bash_command='echo "Running task 2"') + task1 >> task2 + +# 測試 DAG 2: 帶參數的 DAG +with DAG( + "test_dag_parametrized", + default_args=default_args, + schedule="0 6 * * *", + tags=["test", "parametrized"], + params={ + "partner_id": "default_partner", + "data_date": datetime.now().strftime("%Y-%m-%d"), + }, +) as dag2: + task_a = EmptyOperator(task_id="task_a") + task_b = EmptyOperator(task_id="task_b") + task_a >> task_b + +# 測試 DAG 3: 長時間運行的 DAG +with DAG( + "test_dag_long_running", + default_args=default_args, + schedule="0 12 * * *", + tags=["test", "long-running"], +) as dag3: + long_task = BashOperator(task_id="long_running_task", bash_command='sleep 3600 && echo "Done"') From 21e8f708a2dccffe5514580d9142634f2c2a8d72 Mon Sep 17 00:00:00 2001 From: VincentHsiao Date: Wed, 4 Mar 2026 16:25:23 +0800 Subject: [PATCH 3/3] Remove unrelated files from PR --- .../airflow-translations/locales/zh-TW.md | 1 - .../ui/public/i18n/locales/zh-TW/common.json | 7 -- .../ui/public/i18n/locales/zh-TW/dag.json | 9 --- dags/generate_dag_runs.py | 68 ------------------- dags/test_dag.py | 66 ------------------ 5 files changed, 151 deletions(-) delete mode 100644 dags/generate_dag_runs.py delete mode 100644 dags/test_dag.py diff --git a/.github/skills/airflow-translations/locales/zh-TW.md b/.github/skills/airflow-translations/locales/zh-TW.md index f22b1dc8fb9b2..0430726a57e62 100644 --- a/.github/skills/airflow-translations/locales/zh-TW.md +++ b/.github/skills/airflow-translations/locales/zh-TW.md @@ -150,6 +150,5 @@ Use the following established translations in the Airflow UI: - **Triggerer** → 觸發者 - **trigger** → 觸發器 -- **partition** → 分區 Ensure these terms are used consistently across the locale. diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json index efaa36625d231..5fa1c4f83cb3a 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json @@ -161,13 +161,6 @@ "placeholder": "新增筆記...", "taskInstance": "任務實例筆記" }, - "partitionedDagRun_one": "分區的 Dag 執行", - "partitionedDagRun_other": "分區的 Dag 執行", - "partitionedDagRunDetail": { - "receivedAssetEvents": "收到的資源事件" - }, - "pendingDagRun_one": "待執行的 Dag 執行", - "pendingDagRun_other": "待執行的 Dag 執行", "reset": "重置", "runId": "執行 ID", "runTypes": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json index 9c6dced4c52fe..74149b0d08e42 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json @@ -121,15 +121,6 @@ "graphDirection": { "label": "圖表方向" }, - "showVersionIndicator": { - "label": "版本指示器", - "options": { - "hideAll": "隱藏全部", - "showAll": "顯示全部", - "showBundleVersion": "顯示套件包版本", - "showDagVersion": "顯示 Dag 版本" - } - }, "taskStreamFilter": { "activeFilter": "啟用過濾器", "clearFilter": "清除過濾器", diff --git a/dags/generate_dag_runs.py b/dags/generate_dag_runs.py deleted file mode 100644 index 954304240d6d9..0000000000000 --- a/dags/generate_dag_runs.py +++ /dev/null @@ -1,68 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -from __future__ import annotations - -from airflow import settings -from airflow.models import DagRun -from airflow.models.dagrun import DagRunType -from airflow.utils import timezone - - -def create_test_dag_runs(): - """生成測試 DAG runs.""" - session = settings.Session() - - dag_runs = [ - # 創建不同狀態的 runs - DagRun( - dag_id="test_dag_simple", - run_id="test_simple_2024_01_01", - logical_date=timezone.parse("2024-01-01"), - start_date=timezone.parse("2024-01-01 10:00:00"), - end_date=timezone.parse("2024-01-01 10:05:00"), - state="success", - run_type=DagRunType.SCHEDULED, - ), - DagRun( - dag_id="test_dag_simple", - run_id="test_simple_2024_01_02", - logical_date=timezone.parse("2024-01-02"), - start_date=timezone.parse("2024-01-02 12:00:00"), - state="failed", - run_type=DagRunType.MANUAL, - ), - DagRun( - dag_id="test_dag_parametrized", - run_id="test_param_2024_01_01", - logical_date=timezone.parse("2024-01-01"), - start_date=timezone.parse("2024-01-01 06:15:00"), - end_date=timezone.parse("2024-01-01 06:45:00"), - state="success", - run_type=DagRunType.SCHEDULED, - ), - ] - - for run in dag_runs: - session.add(run) - - session.commit() - session.close() - print("✅ DAG runs 已創建") - - -if __name__ == "__main__": - create_test_dag_runs() diff --git a/dags/test_dag.py b/dags/test_dag.py deleted file mode 100644 index c4c73e14b345d..0000000000000 --- a/dags/test_dag.py +++ /dev/null @@ -1,66 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -from __future__ import annotations - -from datetime import datetime, timedelta - -from airflow import DAG -from airflow.operators.bash import BashOperator -from airflow.operators.empty import EmptyOperator - -default_args = { - "owner": "airflow", - "retries": 1, - "retry_delay": timedelta(minutes=5), - "start_date": datetime(2024, 1, 1), -} - -# 測試 DAG 1: 基本 DAG -with DAG( - "test_dag_simple", - default_args=default_args, - schedule="0 0 * * *", - tags=["test", "example"], - doc_md="### 簡單測試 DAG", -) as dag1: - task1 = EmptyOperator(task_id="task_1") - task2 = BashOperator(task_id="task_2", bash_command='echo "Running task 2"') - task1 >> task2 - -# 測試 DAG 2: 帶參數的 DAG -with DAG( - "test_dag_parametrized", - default_args=default_args, - schedule="0 6 * * *", - tags=["test", "parametrized"], - params={ - "partner_id": "default_partner", - "data_date": datetime.now().strftime("%Y-%m-%d"), - }, -) as dag2: - task_a = EmptyOperator(task_id="task_a") - task_b = EmptyOperator(task_id="task_b") - task_a >> task_b - -# 測試 DAG 3: 長時間運行的 DAG -with DAG( - "test_dag_long_running", - default_args=default_args, - schedule="0 12 * * *", - tags=["test", "long-running"], -) as dag3: - long_task = BashOperator(task_id="long_running_task", bash_command='sleep 3600 && echo "Done"')