Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 17.7k
Add airflow-ts-pack bundle build tool for TypeScript SDK#69295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
88a1af9767e12444768b34492b4cFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -19,6 +19,7 @@ | ||
| from __future__ import annotations | ||
| import base64 | ||
| import os | ||
| import pathlib | ||
| from typing import TYPE_CHECKING, Any | ||
| @@ -45,6 +46,38 @@ | ||
| BUNDLE_FILENAME = "bundle.mjs" | ||
| METADATA_FILENAME = "airflow-metadata.yaml" | ||
| EMBEDDED_METADATA_MARKER = b"//# airflowMetadata=" | ||
| EMBEDDED_METADATA_MAX_BYTES = 1024 * 1024 | ||
| def _read_embedded_metadata(bundle_path: pathlib.Path) -> dict[str, Any] | None: | ||
| """ | ||
| Read the manifest ``airflow-ts-pack`` embeds in the bundle itself. | ||
| The packer prepends the ``airflow-metadata.yaml`` content as a leading | ||
| ``//# airflowMetadata=<base64>`` line comment, keeping bundle and metadata | ||
| a single artifact. Returns ``None`` when the bundle has no such marker. | ||
| """ | ||
| try: | ||
| with bundle_path.open("rb") as bundle_file: | ||
| line = bundle_file.readline(EMBEDDED_METADATA_MAX_BYTES + 1) | ||
| except OSError as exc: | ||
| raise ValueError(f"cannot read {bundle_path.name}: {exc}") from exc | ||
| if not line.startswith(EMBEDDED_METADATA_MARKER): | ||
| return None | ||
guan404ming marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| if len(line) > EMBEDDED_METADATA_MAX_BYTES: | ||
| raise ValueError( | ||
| f"embedded airflow metadata exceeds {EMBEDDED_METADATA_MAX_BYTES} bytes; " | ||
| f"rebuild {bundle_path.name} with airflow-ts-pack" | ||
| ) | ||
| payload = line[len(EMBEDDED_METADATA_MARKER) :].strip() | ||
| try: | ||
| decoded = base64.b64decode(payload, validate=True) | ||
| except ValueError as exc: | ||
| raise ValueError(f"cannot parse embedded airflow metadata: {exc}") from exc | ||
guan404ming marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| return parse_metadata_mapping(decoded, source="embedded airflow metadata") | ||
| def _read_bundle_metadata(metadata_path: pathlib.Path) -> dict[str, Any]: | ||
| @@ -63,8 +96,9 @@ def _find_bundle(bundles_root: Sequence[pathlib.Path]) -> ResolvedBundle: | ||
| """ | ||
| Locate the ``.mjs`` entry point in *bundles_root*. | ||
| Scans each configured directory for ``bundle.mjs`` and reads the sibling | ||
| ``airflow-metadata.yaml`` for the bundle's supervisor schema version. | ||
| Scans each configured directory for ``bundle.mjs`` and reads the bundle's | ||
| supervisor schema version from the metadata embedded in the bundle, | ||
| falling back to a sibling ``airflow-metadata.yaml`` sidecar. | ||
| This is an ordered fallback search, not Dag/task-aware multi-bundle | ||
| routing. The first bundle found wins. A future version can use the | ||
| @@ -77,7 +111,9 @@ def _find_bundle(bundles_root: Sequence[pathlib.Path]) -> ResolvedBundle: | ||
| if not candidate.is_file(): | ||
| continue | ||
| try: | ||
| metadata = _read_bundle_metadata(root / METADATA_FILENAME) | ||
| metadata = _read_embedded_metadata(candidate) | ||
| if metadata is None: | ||
| metadata = _read_bundle_metadata(root / METADATA_FILENAME) | ||
| log.debug("Selected TypeScript bundle", path=candidate, root=root) | ||
| return ResolvedBundle( | ||
| path=candidate, | ||
| @@ -123,8 +159,10 @@ class NodeCoordinator(SubprocessCoordinator): | ||
| ``"node"``, which relies on ``$PATH``). | ||
| :param bundles_root: Ordered list of directories scanned for a usable | ||
| TypeScript bundle. Each bundle directory must contain ``bundle.mjs`` | ||
| and ``airflow-metadata.yaml``. This is a fallback search path; it does | ||
| not yet route different Dag/task pairs to different bundles. | ||
| with embedded metadata (as produced by ``airflow-ts-pack``), or | ||
| ``bundle.mjs`` plus an ``airflow-metadata.yaml`` sidecar. This is a | ||
| fallback search path; it does not yet route different Dag/task pairs | ||
| to different bundles. | ||
| :param task_startup_timeout: Maximum time the coordinator waits for a task | ||
| process to start, in seconds. The default is 10 seconds. | ||
| """ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -5,7 +5,7 @@ | ||
| "type": "module", | ||
| "license": "Apache-2.0", | ||
| "scripts": { | ||
| "build": "esbuild src/main.ts --bundle --platform=node --format=esm --target=node22 --outfile=dist/bundle.mjs", | ||
| "build": "airflow-ts-pack src/main.ts --outdir dist", | ||
jason810496 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| "typecheck": "tsc --noEmit" | ||
| }, | ||
| "dependencies": { | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -7,6 +7,9 @@ | ||
| "type": "module", | ||
| "main": "./dist/index.js", | ||
| "types": "./dist/index.d.ts", | ||
| "bin": { | ||
| "airflow-ts-pack": "./dist/cli/main.js" | ||
| }, | ||
| "homepage": "https://airflow.apache.org", | ||
| "repository": { | ||
| "type": "git", | ||
| @@ -59,8 +62,17 @@ | ||
| "dependencies": { | ||
| "@msgpack/msgpack": "^3.1.2" | ||
| }, | ||
| "peerDependencies": { | ||
| "esbuild": "^0.28.1" | ||
guan404ming marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| }, | ||
| "peerDependenciesMeta": { | ||
| "esbuild": { | ||
| "optional": true | ||
| } | ||
| }, | ||
| "devDependencies": { | ||
| "@eslint/js": "^10.0.1", | ||
| "esbuild": "^0.28.1", | ||
| "@types/node": "^22.19.17", | ||
| "eslint": "^10.4.0", | ||
| "json-schema-to-typescript": "^15.0.4", | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.