go build ./...
go test ./...Run tests for specific packages:
go test ./internal/packages/... ./internal/kibana/... ./internal/resources/... ./internal/testrunner/...Run integration tests with test packages:
go run . stack up -v -d
go run . test -C ./test/packages/parallel/apacheImportant: Linting before giving the task for complete.
make build format lint licenser gomod update- Keep exported surface small — unexport functions that are only used within the same package.
- Do not leave trailing spaces on new lines.
- Do not leave trailing newlines at the end of files.
- Wrap errors with context using
fmt.Errorf("...: %w", err). - Return explicit errors rather than silently falling back to a default value.
- Place functions in the package that owns the types they primarily operate on.
- Functions that produce
kibana.*types and callkibana.*helpers belong ininternal/kibana. - Functions that navigate or filter
packages.*types belong ininternal/packages. - Resource lifecycle logic (create/update/delete) belongs in
internal/resources. - Disk I/O should happen at the call site, not inside builder/helper functions that are meant to be pure transformations over already-loaded data.
The import graph must be acyclic. The established layering is:
internal/packages
↑
internal/kibana (imports packages)
↑
internal/resources (imports kibana, packages)
↑
internal/testrunner (imports resources, kibana, packages)
- When possible use real package fixtures from
test/packages/ortestdatadirectories rather than inline YAML strings. Refer to them with relative paths like../../test/packages/....
elastic-package uses the objects-based Fleet API (PackagePolicy) — not the deprecated arrays-based API (PackageDataStream).
- Input key:
"{policyTemplate.Name}-{input.Type}"(e.g."apache-logfile"). - Stream key: built by
datasetKey(pkgName, ds)— usesds.Datasetwhen set, otherwise"{pkgName}.{ds.Name}". - Sibling stream disabling: Fleet auto-enables all streams for an enabled input unless they are explicitly listed with
enabled: false. Always send{enabled: false}for every sibling data stream sharing the same input type within the same policy template. - Policy template scoping: When a policy template declares a
data_streamslist, only include data streams from that list as siblings. Usepackages.FilterDatastreamsForPolicyTemplate(datastreams, policyTemplate)on the result ofpackages.ReadAllDataStreamManifests(packageRoot)to get the correct set. - Variable format: the objects-based API expects raw values, not
{"type": ..., "value": ...}wrappers.Vars.ToMapStr()extracts raw values viaval.Value.Value(). - otelcol input packages:
data_stream.datasetis the base dataset name (without a.otelsuffix). Elastic Agent appends.otelat ingest; Fleet does not add it in the policy payload. System tests in elastic-package mirror that append when resolving data stream names and expected document datasets—do not put.otelin the override unless you intentionally want a*.otel.oteldataset in Elasticsearch.