Skip to content

Commit dadcb13

Browse files
Merge branch 'main' into fix-cleartaskinstances-422-invalid-body
2 parents 232f0e1 + 6a0c3a6 commit dadcb13

80 files changed

Lines changed: 3567 additions & 608 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/actions/migration_tests/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ runs:
3939
--use-airflow-version "${MIN_AIRFLOW_VERSION}" \
4040
${AIRFLOW_EXTRAS} \
4141
--answer y &&
42-
breeze shell "export AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS=${DB_MANGERS}
42+
breeze shell "export AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS=${DB_MANAGERS}
4343
${AIRFLOW_3_CMD}" --no-db-cleanup
4444
env:
4545
COMPOSE_PROJECT_NAME: "docker-compose"
@@ -73,7 +73,7 @@ runs:
7373
--use-airflow-version "${MIN_AIRFLOW_VERSION}" \
7474
${AIRFLOW_EXTRAS} \
7575
--answer y &&
76-
breeze shell "export AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS=${DB_MANGERS}
76+
breeze shell "export AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS=${DB_MANAGERS}
7777
${AIRFLOW_3_CMD}" --no-db-cleanup
7878
env:
7979
COMPOSE_PROJECT_NAME: "docker-compose"

.github/workflows/release-constraints.yml

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020
#
2121
# The stage is derived from the version, so the two cannot be mismatched by hand:
2222
#
23-
# * a candidate (`3.1.3rc1`) resolves with pre-releases allowed - the providers of the wave
24-
# being voted on exist on PyPI only as rc versions - and lands on a branch of its own, so a
25-
# candidate never moves the branch every other build reads;
26-
# * a final (`3.1.3`) resolves without them, against the providers now published as finals, and
23+
# * a candidate (`3.3.1rc1`) pins the providers at the versions PyPI holds - the wave being
24+
# voted on exists there only as rc versions - and lands on a branch of its own, so a candidate
25+
# never moves the branch every other build reads. Re-running it for the same candidate
26+
# replaces that branch and its tag, so the two always describe the run that produced them;
27+
# * a final (`3.3.1`) pins the providers at their released versions, ignoring any candidate, and
2728
# commits onto `constraints-X-Y` itself, which is what makes the released constraints the
2829
# baseline everything downstream reads.
2930
#
@@ -35,11 +36,11 @@ on: # yamllint disable-line rule:truthy
3536
workflow_dispatch:
3637
inputs:
3738
version:
38-
description: "Version the constraints belong to, e.g. 3.1.3rc1 or 3.1.3"
39+
description: "Version the constraints belong to, e.g. 3.3.1rc1 or 3.3.1"
3940
required: true
4041
type: string
4142
ref:
42-
description: "Ref the constraints are resolved from, e.g. v3-1-stable or the release tag"
43+
description: "Ref the constraints are resolved from, e.g. v3-3-stable or the release tag"
4344
required: true
4445
type: string
4546
permissions:
@@ -203,6 +204,7 @@ jobs:
203204
VERSION: ${{ inputs.version }}
204205
CONSTRAINTS_BRANCH: ${{ needs.build-info.outputs.constraints-branch }}
205206
TARGET_BRANCH: ${{ needs.build-info.outputs.target-branch }}
207+
ALLOW_PRE_RELEASES: ${{ needs.build-info.outputs.allow-pre-releases }}
206208
steps:
207209
- name: "Cleanup repo"
208210
shell: bash
@@ -226,6 +228,26 @@ jobs:
226228
with:
227229
pattern: constraints-*
228230
path: ./files
231+
# A candidate's branch and tag belong to that candidate alone, so re-running for the same
232+
# rc replaces them rather than adding to them: the branch would otherwise already hold the
233+
# previous run's constraints (making the push a non-fast-forward) and the tag already exist.
234+
# A final never gets this - it commits onto the shared constraints-X-Y branch, whose history
235+
# every other build reads.
236+
- name: "Delete the previous ${{ needs.build-info.outputs.target-branch }} branch and tag"
237+
if: needs.build-info.outputs.allow-pre-releases == 'true'
238+
working-directory: "constraints"
239+
shell: bash
240+
run: |
241+
if git ls-remote --exit-code origin "refs/heads/${TARGET_BRANCH}" > /dev/null; then
242+
echo "Deleting the existing '${TARGET_BRANCH}' branch."
243+
git push origin --delete "refs/heads/${TARGET_BRANCH}"
244+
fi
245+
if git ls-remote --exit-code origin "refs/tags/constraints-${VERSION}" > /dev/null; then
246+
echo "Deleting the existing 'constraints-${VERSION}' tag."
247+
git push origin --delete "refs/tags/constraints-${VERSION}"
248+
fi
249+
git tag --delete "constraints-${VERSION}" > /dev/null 2>&1 || true
250+
git branch --delete --force "${TARGET_BRANCH}" > /dev/null 2>&1 || true
229251
- name: "Switch to ${{ needs.build-info.outputs.target-branch }}"
230252
working-directory: "constraints"
231253
shell: bash

AGENTS.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Don't spell out **Directed Acyclic Graph** except for historical context.
5252
- **Lint with ruff only:** `prek run ruff --from-ref <target_branch>`
5353
- **Format with ruff only:** `prek run ruff-format --from-ref <target_branch>`
5454
- **Run regular (fast) static checks:** `prek run --from-ref <target_branch> --stage pre-commit`
55-
- **Run manual (slower) checks:** `prek run --from-ref <target_branch> --stage manual`
55+
- **Run manual (slower) checks:** `prek run --from-ref <target_branch> --stage manual --skip compile-ui-assets-dev --skip view-skill-eval` (the skipped hooks start long-running local servers rather than checks that complete)
5656
- **Build docs:** `breeze build-docs`
5757
- **Determine which tests to run based on changed files:** `breeze ci selective-check --commit-ref <commit_with_squashed_changes>`
5858
<!-- END generated-commands, please keep comment here to allow auto update -->
@@ -294,7 +294,10 @@ code review checklist in [`.github/instructions/code-review.instructions.md`](.g
294294
described in this file.
295295
4. Run regular (fast) static checks (`prek run --from-ref <target_branch> --stage pre-commit`)
296296
and fix any failures. This includes mypy checks for non-provider projects (airflow-core, task-sdk, airflow-ctl, dev, scripts, devel-common).
297-
5. Run manual (slower) checks (`prek run --from-ref <target_branch> --stage manual`) and fix any failures.
297+
5. Run manual (slower) checks
298+
(`prek run --from-ref <target_branch> --stage manual --skip compile-ui-assets-dev --skip view-skill-eval`)
299+
and fix any failures. The skipped hooks start long-running local servers rather than checks
300+
that complete.
298301
6. Run relevant individual tests and confirm they pass.
299302
7. Find which tests to run for the changes with selective-checks and run those tests in parallel to confirm they pass and check for CI-specific issues.
300303
8. Check for security issues — no secrets, no injection vulnerabilities, no unsafe patterns.

airflow-core/src/airflow/cli/commands/asset_command.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def _detail_asset(args, *, session: Session) -> BaseModel:
107107
return AssetResponse.model_validate(asset)
108108

109109

110-
@deprecated_for_airflowctl("airflowctl assets get / airflowctl assets get-by-alias")
110+
@deprecated_for_airflowctl("airflowctl assets get / airflowctl assets get-alias")
111111
@cli_utils.action_cli
112112
@provide_session
113113
def asset_details(args, *, session: Session = NEW_SESSION) -> None:

airflow-core/src/airflow/cli/commands/connection_command.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from sqlalchemy import select
3030
from sqlalchemy.orm import exc
3131

32+
from airflow._shared.secrets_masker import redact
3233
from airflow.cli.simple_table import AirflowConsole
3334
from airflow.cli.utils import (
3435
SENSITIVE_PLACEHOLDER,
@@ -365,22 +366,19 @@ def connections_add(args):
365366
with create_session() as session:
366367
if not session.scalar(select(Connection).where(Connection.conn_id == new_conn.conn_id).limit(1)):
367368
session.add(new_conn)
368-
msg = "Successfully added `conn_id`={conn_id} : {uri}"
369-
msg = msg.format(
370-
conn_id=new_conn.conn_id,
371-
uri=args.conn_uri
372-
or urlunsplit(
373-
(
374-
new_conn.conn_type,
375-
f"{new_conn.login or ''}:{'******' if new_conn.password else ''}"
376-
f"@{new_conn.host or ''}:{new_conn.port or ''}",
377-
new_conn.schema or "",
378-
"",
379-
"",
380-
)
381-
),
369+
print(f"Successfully added `conn_id`={new_conn.conn_id}")
370+
AirflowConsole().print_as(
371+
data=[new_conn],
372+
output="table",
373+
mapper=lambda conn: {
374+
"conn_id": conn.conn_id,
375+
"conn_type": conn.conn_type,
376+
"host": conn.host,
377+
"login": conn.login,
378+
"port": conn.port,
379+
"extra": redact(conn.extra_dejson),
380+
},
382381
)
383-
print(msg)
384382
else:
385383
msg = f"A connection with `conn_id`={new_conn.conn_id} already exists."
386384
raise SystemExit(msg)

airflow-core/src/airflow/configuration.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@
5858
warnings.filterwarnings(action="default", category=DeprecationWarning, module="airflow")
5959
warnings.filterwarnings(action="default", category=PendingDeprecationWarning, module="airflow")
6060

61-
_SQLITE3_VERSION_PATTERN = re.compile(r"(?P<version>^\d+(?:\.\d+)*)\D?.*$")
62-
6361
ConfigType = str | int | float | bool
6462
ConfigOptionsDictType = dict[str, ConfigType]
6563
ConfigSectionSourcesType = dict[str, str | tuple[str, str]]
@@ -99,13 +97,6 @@ def add_default_update(self, section: str, option: str, new_default: str) -> Non
9997
self.default_updates[(section, option)] = new_default
10098

10199

102-
def _parse_sqlite_version(s: str) -> tuple[int, ...]:
103-
match = _SQLITE3_VERSION_PATTERN.match(s)
104-
if match is None:
105-
return ()
106-
return tuple(int(p) for p in match.group("version").split("."))
107-
108-
109100
@overload
110101
def expand_env_var(env_var: None) -> None: ...
111102

@@ -426,7 +417,7 @@ def _validate_sqlite3_version(self):
426417
import sqlite3
427418

428419
min_sqlite_version = (3, 15, 0)
429-
if _parse_sqlite_version(sqlite3.sqlite_version) >= min_sqlite_version:
420+
if sqlite3.sqlite_version_info >= min_sqlite_version:
430421
return
431422

432423
from airflow.utils.docs import get_docs_url

airflow-core/src/airflow/dag_processing/manager.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,11 @@ def deactivate_stale_dags(
506506
# When the Dag's last_parsed_time is more than the stale_dag_threshold older than the
507507
# Dag file's last_finish_time, the Dag is considered stale as has apparently been removed from the file,
508508
# This is especially relevant for Dag files that generate Dags in a dynamic manner.
509-
file_info = DagFileInfo(rel_path=Path(dag.relative_fileloc), bundle_name=dag.bundle_name)
509+
rel_path = Path(dag.relative_fileloc)
510+
file_info = DagFileInfo(rel_path=rel_path, bundle_name=dag.bundle_name)
511+
if file_info not in last_parsed:
512+
# Zip-packaged dags are keyed by the archive path, not the inner file, so try the parent as well
513+
file_info = DagFileInfo(rel_path=rel_path.parent, bundle_name=dag.bundle_name)
510514
if last_finish_time := last_parsed.get(file_info, None):
511515
if dag.last_parsed_time + timedelta(seconds=self.stale_dag_threshold) < last_finish_time:
512516
self.log.info(

airflow-core/src/airflow/jobs/scheduler_job_runner.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1842,6 +1842,7 @@ def _run_scheduler_loop(self) -> None:
18421842
timers.call_regular_interval(
18431843
conf.getfloat("scheduler", "parsing_cleanup_interval"),
18441844
self._remove_unreferenced_triggers,
1845+
non_fatal=True,
18451846
)
18461847

18471848
if any(x.is_local for x in self.executors):
@@ -1859,6 +1860,7 @@ def _run_scheduler_loop(self) -> None:
18591860
timers.call_regular_interval(
18601861
delay=conf.getfloat("connection_test", "reaper_interval", fallback=30.0),
18611862
action=self._reap_stale_connection_tests,
1863+
non_fatal=True,
18621864
)
18631865

18641866
idle_count = 0

airflow-core/src/airflow/ui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"i18next-browser-languagedetector": "^8.2.1",
5252
"i18next-http-backend": "^4.0.1",
5353
"katex": "^0.17.0",
54-
"mermaid": "^11.16.0",
54+
"mermaid": "^11.16.1",
5555
"monaco-editor": "^0.56.0",
5656
"next-themes": "^0.4.6",
5757
"react": "^19.2.8",

0 commit comments

Comments
 (0)