support for 'compilation' of new dashboards-as-code format via elastic-package build#3531
support for 'compilation' of new dashboards-as-code format via elastic-package build#3531tommyers-elastic wants to merge 11 commits intomainfrom
elastic-package build#3531Conversation
Adds support for authoring dashboards in the new dashboards-as-code JSON format under _dev/dashboards_as_code/. During elastic-package build, each source file is POSTed to Kibana's /api/dashboards endpoint, the returned dashboard id is exported back through the standard dashboards export pipeline, and the imported saved object is deleted from Kibana. The compile step runs before CopyWithoutDev so the existing build pipeline (encodeDashboards, validation) handles the resulting saved objects unchanged. BuildPackage now takes a context.Context and an optional KibanaClient on BuildOptions; the client is constructed lazily in cmd/build.go only when _dev/dashboards_as_code/ is present, so packages that do not use the feature still build offline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The /api/dashboards import endpoint that backs dashboards-as-code is only available in Kibana 9.4.0 and later. The previous version check reused the dashboards export gate (which exists for an unrelated 8.8-8.10 export bug); replace it with a dedicated minimum-version check and drop the no-longer-needed CheckKibanaVersion export from the export package. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Be consistent with the existing dashboards-export version check, which just lets semver parsing fail on an empty version string. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switch the imported-dashboard cleanup from DELETE /api/saved_objects/dashboard/<id> to DELETE /api/dashboards/<id>, the companion of the import endpoint we already use. Accept 204 No Content in addition to 200 since the dashboards-as-code DELETE returns 204 on success. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
POST /api/dashboards generates a fresh UUID on every import, which made the compiled kibana/dashboard/<id>.json filename non-deterministic and caused old artifacts to accumulate in the source tree on each rebuild. Switch to PUT /api/dashboards/<id> and derive the id from the source filename (sans .json extension), so _dev/dashboards_as_code/foo.json always compiles to kibana/dashboard/<package>-foo.json after standardizeObjectID prefixes the package name. The compiled output is now stable across builds and reviewable in PRs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Group with other build-time inputs (build.yml, docs/) under _dev/build/ rather than introducing a top-level _dev/ category. Dashboards-as-code files now live at _dev/build/dashboards_as_code/<name>.json. Note: enabling this in real packages requires elastic/package-spec to allow _dev/build/dashboards_as_code/ — the spec change must land and the package-spec dependency be bumped before the feature is usable end to end (today the linter rejects the unknown folder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds test/packages/dashboards_as_code/sample/ with a single source under _dev/build/dashboards_as_code/overview.json. The compiled saved object is intentionally absent so the test can prove the build wrote it. Adds scripts/test-check-packages-dashboards-as-code.sh (modeled on the composable-packages script): brings up the stack, runs `elastic-package check` on each fixture, then for every <name>.json source asserts that kibana/dashboard/<package>-<name>.json was written by the build. Pre-flight guards against fixtures that already contain compiled SO files. Cleanup trap removes generated artefacts and brings the stack down. Wires the new target into the umbrella test-check-packages Makefile rule. The fixture and test require a package-spec release that allows _dev/build/dashboards_as_code/ and a corresponding bump of the github.com/elastic/package-spec/v3 dependency before this branch can pass CI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| if err != nil { | ||
| return fmt.Errorf("getting Kibana version information: %w", err) | ||
| } | ||
| if err := checkDashboardsAsCodeKibanaVersion(versionInfo); err != nil { |
There was a problem hiding this comment.
is this not checked by the package validation? when the version of a package is set with its kibana version?
There was a problem hiding this comment.
the intention here is just to check if the stack being used to build the package supports the API. it won't check vs the manifest version because existing check/build doesn't require a stack at all.
| // form of the API guarantees the resulting saved object uses the id we choose, | ||
| // rather than a freshly generated one). Returns the id reported by Kibana, | ||
| // which should match the supplied id. | ||
| func (c *Client) ImportDashboardAsCode(ctx context.Context, id string, body []byte) (string, error) { |
There was a problem hiding this comment.
I am not following the function, sorry. So ImportDashboardAsCode means:
- attach a body and update whatever dashboard is at kibana? with the given id, if not exists, creates it? from the elastic-package pov, isnt this exporting it to kibana? where is the object saved?
OR - is this sending the body to kibana and responding it with a good-to-go dashboard instead? in that case... can we rename the function, i feel Import semantics feels is a one way road, but is actually 2 ways? although i dont see where it saves it :D
There was a problem hiding this comment.
this creates or updates the dashboard in kibana.
the new dashboard API handles the underlying saved object management. you can create, update, and delete dashboards via the new API without touching saved objects.
There was a problem hiding this comment.
the semantics of import/export in elastic-package follow this naming convention. 'export' is exporting objects from kibana.
The package-spec already exposes _dev/shared as a generic shared-files folder (with additionalContents: true on integration packages, and the content-package spec explicitly mentioning dashboards-as-YML files there). Putting our sources in _dev/shared lets the feature ship without an upstream package-spec change. Convention: any *.json file directly under _dev/shared/ is treated as a dashboards-as-code source; the filename (sans .json) becomes the id. Other files in _dev/shared remain untouched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the auto-detection (any *.json under _dev/shared/) with an opt-in --compile-dashboards-as-code flag on elastic-package build. This avoids interpreting unrelated *.json files in _dev/shared/ as dashboards-as-code sources, and makes the intent (and the resulting dependency on a running Kibana) explicit at the command line. The builder treats the kibanaClient pointer as the gate: callers that want compilation pass a non-nil client; otherwise compileDashboardsAsCode returns immediately. `elastic-package check` doesn't forward flags to its composed `build` sub-command, so the test script now runs `lint` and `build --compile-dashboards-as-code` separately to exercise the full path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rror as WARN not DEBUG
💔 Build Failed
Failed CI StepsHistory
|
The contextcheck linter flags passing context.Background() inside a function that already has a ctx parameter. Use context.WithoutCancel instead — it preserves any values/tracing on the parent ctx while detaching from its cancellation, so cleanup still runs if the build's context has been cancelled by the time the defer fires. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lets package authors write dashboards in the new dashboards-as-code JSON format under
_dev/shared/*.json.During build, each dashboard is installed to Kibana via the new API, exported back through the standard dashboards pipeline, and written to
kibana/dashboard/<package>-<id>.json. The imported dashboard is cleaned up in Kibana.<id>is derived from the source filename, so output is stable across rebuilds. Requires Kibana ≥ 9.4.0; build fails with the usualErrUnavailableStackwhen the source dir is present and no stack is reachable. Packages without_dev/shared/*.jsonstill build offline.End-to-end test:
test/packages/dashboards_as_code/sample/plusscripts/test-check-packages-dashboards-as-code.sh, which brings up a stack and asserts the compiled SO is produced (the SO is deliberately not committed).