This is an automated email from the ASF dual-hosted git repository.
jason810496 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new e043a279628 Go SDK: pack a bundle that registers no Dags at pack time
(#74637)
e043a279628 is described below
commit e043a279628a9e13c4a986ad2eeab39604e62825
Author: Jason(Zhe-You) Liu <[email protected]>
AuthorDate: Tue Oct 13 18:50:09 2026 +0100
Go SDK: pack a bundle that registers no Dags at pack time (#74637)
Co-authored-by: Claude <[email protected]>
---
go-sdk/cmd/airflow-go-pack/pack.go | 4 +++-
go-sdk/cmd/airflow-go-pack/pack_test.go | 36 ++++++++++++++++++++++++++++++
task-sdk/docs/airflow-metadata.schema.json | 3 +--
task-sdk/docs/executable-bundle-spec.rst | 7 +++---
4 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/go-sdk/cmd/airflow-go-pack/pack.go
b/go-sdk/cmd/airflow-go-pack/pack.go
index c09cbe87e1e..068afa9bf1d 100644
--- a/go-sdk/cmd/airflow-go-pack/pack.go
+++ b/go-sdk/cmd/airflow-go-pack/pack.go
@@ -165,7 +165,9 @@ func runPack(stdout, stderr io.Writer, opts *packOptions)
error {
return err
}
if len(meta.Dags) == 0 && len(meta.DagSourceFiles) == 0 {
- return fmt.Errorf("bundle exposes no dags: nothing to pack")
+ fmt.Fprintln(stderr, "warning: no Dags or task handlers were
registered at pack time; "+
+ "this is expected only if the bundle generates its Dags
at run time, "+
+ "and those Dags show the entrypoint source in the Code
view")
}
for dagID, dag := range meta.Dags {
if len(dag.Tasks) == 0 {
diff --git a/go-sdk/cmd/airflow-go-pack/pack_test.go
b/go-sdk/cmd/airflow-go-pack/pack_test.go
index 992e1e6da87..e1aafd9801c 100644
--- a/go-sdk/cmd/airflow-go-pack/pack_test.go
+++ b/go-sdk/cmd/airflow-go-pack/pack_test.go
@@ -445,6 +445,42 @@ func TestRunPack_PacksABundleWithOnlyNativeDags(t
*testing.T) {
assert.Contains(t, stdout.String(), "task_handler_dags=0,
native_dags=1")
}
+// A bundle that generates its Dags at run time registers nothing at pack time.
+func TestRunPack_PacksABundleWithNoDags(t *testing.T) {
+ dir := t.TempDir()
+ exe := filepath.Join(dir, "generated")
+ require.NoError(t, os.WriteFile(exe, []byte("generated-binary-bytes"),
0o755))
+ source := filepath.Join(dir, "main.go")
+ require.NoError(t, os.WriteFile(source, []byte("package main\nfunc
main() {}\n"), 0o644))
+ meta := filepath.Join(dir, "airflow-metadata.json")
+ require.NoError(t, os.WriteFile(meta, []byte(
+ `{"airflow_bundle_metadata_version":"1.0",`+
+
`"sdk":{"language":"go","version":"0.1.0","supervisor_schema_version":"2026-06-16"},`+
+ `"dags":{}}`,
+ ), 0o644))
+ out := filepath.Join(dir, "bundle")
+
+ var stdout, stderr bytes.Buffer
+ err := runPack(&stdout, &stderr, &packOptions{
+ executable: exe,
+ source: source,
+ airflowMetadata: meta,
+ output: out,
+ })
+ require.NoError(t, err)
+
+ _, gotMeta, err := bundlefooter.Read(out)
+ require.NoError(t, err)
+ assert.Contains(t, string(gotMeta), `entrypoint_path: "main.go"`)
+ assert.Contains(t, string(gotMeta), `path: "main.go"`)
+ assert.Contains(
+ t,
+ stderr.String(),
+ "warning: no Dags or task handlers were registered at pack
time",
+ )
+ assert.Contains(t, stdout.String(), "task_handler_dags=0,
native_dags=0")
+}
+
// --airflow-metadata also accepts a YAML manifest, not only the JSON the
// binary prints.
func TestRunPack_AcceptsYAMLMetadataFile(t *testing.T) {
diff --git a/task-sdk/docs/airflow-metadata.schema.json
b/task-sdk/docs/airflow-metadata.schema.json
index c9c699ba029..c8ae05318fa 100644
--- a/task-sdk/docs/airflow-metadata.schema.json
+++ b/task-sdk/docs/airflow-metadata.schema.json
@@ -57,8 +57,7 @@
},
"dags": {
"type": "object",
- "description": "Mapping of dag_id to DAG entry. Every dag_id the bundle
exposes must appear here.",
- "minProperties": 1,
+ "description": "Mapping of dag_id to the tasks the bundle runs for a
Python Dag with stub TaskHandler. May be empty, for example when the bundle
only declares Dag definitions.",
"additionalProperties": {
"$ref": "#/$defs/dagEntry"
}
diff --git a/task-sdk/docs/executable-bundle-spec.rst
b/task-sdk/docs/executable-bundle-spec.rst
index b8041b6357a..968b35a4417 100644
--- a/task-sdk/docs/executable-bundle-spec.rst
+++ b/task-sdk/docs/executable-bundle-spec.rst
@@ -262,9 +262,10 @@ Top-level keys:
- ``sha256`` (string, required): the lower-case hexadecimal SHA-256 of the
file's bytes.
``dags`` (mapping, required)
- Mapping of ``dag_id`` to a *DAG entry*. Every ``dag_id`` the bundle
- exposes MUST appear here. The scanner uses these keys to match a DAG
- parsing or task-execution request to the bundle that owns it.
+ Mapping of ``dag_id`` to a *DAG entry*, for each Python Dag with stub
TaskHandler whose tasks the
+ bundle runs. The scanner uses these keys to match a task-execution request
to the bundle that
+ owns it. The mapping MAY be empty, for example when the bundle only
declares Dag definitions,
+ because the Dag processor finds those by running the binary.
DAG entry fields: