diff --git a/.buildkite/scripts/common.sh b/.buildkite/scripts/common.sh index fee21e2df0b..ae13403a565 100755 --- a/.buildkite/scripts/common.sh +++ b/.buildkite/scripts/common.sh @@ -320,20 +320,12 @@ delete_kind_cluster() { } kibana_version_manifest() { - local kibana_version - kibana_version=$(cat manifest.yml | yq ".conditions.kibana.version") - if [ "${kibana_version}" != "null" ]; then - echo "${kibana_version}" - return - fi - - kibana_version=$(cat manifest.yml | yq ".conditions.\"kibana.version\"") - if [ "${kibana_version}" != "null" ]; then - echo "${kibana_version}" - return + local kibana_version="" + if ! kibana_version=$(mage -d "${WORKSPACE}" -w . kibanaConstraintPackage) ; then + return 1 fi - - echo "null" + echo "${kibana_version}" + return 0 } capabilities_manifest() { @@ -459,35 +451,25 @@ is_supported_stack() { return 0 fi - local kibana_version - kibana_version=$(kibana_version_manifest) - if [ "${kibana_version}" == "null" ]; then - return 0 - fi - if [[ ( ! "${kibana_version}" =~ \^7\. ) && "${STACK_VERSION}" =~ ^7\. ]]; then - return 1 - fi - if [[ ( ! "${kibana_version}" =~ \^8\. ) && "${STACK_VERSION}" =~ ^8\. ]]; then - return 1 - fi - - # TODO: Allowed temporarily to test packages with stack version 9.0 if they have as constraint ^8.0 defined too. - # This workaround should be removed once packages have been updated their constraints for 9.0 stack. - if [[ ( ! ( "${kibana_version}" =~ \^9\. || "${kibana_version}" =~ \^8\. ) ) && "${STACK_VERSION}" =~ ^9\. ]]; then + local supported + if ! supported=$(mage -d "${WORKSPACE}" -w . isSupportedStack "${STACK_VERSION}"); then return 1 fi - + echo "${supported}" return 0 } oldest_supported_version() { local kibana_version - kibana_version=$(kibana_version_manifest) + if ! kibana_version=$(kibana_version_manifest); then + return 1 + fi if [ "$kibana_version" != "null" ]; then python3 "${SCRIPTS_BUILDKITE_PATH}/find_oldest_supported_version.py" --manifest-path manifest.yml - return + return 0 fi echo "null" + return 0 } create_elastic_package_profile() { @@ -509,7 +491,9 @@ prepare_stack() { version_set="${STACK_VERSION}" else local version - version=$(oldest_supported_version) + if ! version=$(oldest_supported_version); then + return 1 + fi if [[ "${requiredLogsDB}" == "true" ]]; then # If LogsDB index mode is enabled, the required Elastic stack should be at least 8.17.0 # In 8.17.0 LogsDB index mode was made GA. @@ -724,7 +708,12 @@ is_pr_affected() { local from="${2}" local to="${3}" - if ! is_supported_stack ; then + local stack_supported="" + if ! stack_supported=$(is_supported_stack) ; then + echo "${FATAL_ERROR}" + return 1 + fi + if [[ "${stack_supported}" == "false" ]]; then echo "[${package}] PR is not affected: unsupported stack (${STACK_VERSION})" return 1 fi diff --git a/dev/citools/kibana.go b/dev/citools/kibana.go new file mode 100644 index 00000000000..aef47205cb0 --- /dev/null +++ b/dev/citools/kibana.go @@ -0,0 +1,50 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package citools + +import ( + "fmt" + "strings" + + "github.com/Masterminds/semver/v3" +) + +func KibanaConstraintPackage(path string) (*semver.Constraints, error) { + manifest, err := readPackageManifest(path) + if err != nil { + return nil, fmt.Errorf("failed to read package manifest: %w", err) + } + + kibanaVersion := manifest.Conditions.Kibana.Version + if kibanaVersion == "" { + return nil, nil + } + + constraint, err := semver.NewConstraint(kibanaVersion) + if err != nil { + return nil, fmt.Errorf("failed to parse kibana constraint: %w", err) + } + return constraint, nil +} + +func IsPackageSupportedInStackVersion(stackVersion string, path string) (bool, error) { + stackVersion = strings.TrimSuffix(stackVersion, "-SNAPSHOT") + + stackSemVersion, err := semver.NewVersion(stackVersion) + if err != nil { + return false, fmt.Errorf("failed to parse stack version: %w", err) + } + + packageConstraint, err := KibanaConstraintPackage(path) + if err != nil { + return false, err + } + + if packageConstraint == nil { + return true, nil + } + + return packageConstraint.Check(stackSemVersion), nil +} diff --git a/dev/citools/kibana_test.go b/dev/citools/kibana_test.go new file mode 100644 index 00000000000..8f550080bb3 --- /dev/null +++ b/dev/citools/kibana_test.go @@ -0,0 +1,141 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package citools + +import ( + "os" + "path/filepath" + "testing" + + "github.com/Masterminds/semver/v3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestKibanaConstraintPackage(t *testing.T) { + constraintTest, err := semver.NewConstraint("^8.0.0") + require.NoError(t, err) + + cases := []struct { + title string + contents string + expected *semver.Constraints + }{ + { + title: "kibana constrasint defined", + contents: `name: "version" +conditions: + kibana: + version: "^8.0.0" +`, + expected: constraintTest, + }, + { + title: "kibana constraint defined with dotted field", + contents: `name: "version" +conditions: + kibana.version: "^8.0.0" +`, + expected: constraintTest, + }, + { + title: "kibana constraint not defined", + contents: `name: "version" +`, + expected: nil, + }, + } + + for _, c := range cases { + t.Run(c.title, func(t *testing.T) { + directory := t.TempDir() + pkgManifestPath := filepath.Join(directory, "manifest.yml") + err := os.WriteFile(pkgManifestPath, []byte(c.contents), 0o644) + require.NoError(t, err) + constraint, err := KibanaConstraintPackage(pkgManifestPath) + require.NoError(t, err) + assert.Equal(t, c.expected, constraint) + }) + } +} + +func TestIsPackageSupportedInStackVersion(t *testing.T) { + cases := []struct { + title string + contents string + stackVersion string + supported bool + }{ + { + title: "Test simple kibana constraint", + stackVersion: "8.18.0", + contents: `name: "stack" +conditions: + kibana: + version: "^8.0.0" +`, + supported: true, + }, + { + title: "Test or condition", + stackVersion: "8.18.0", + contents: `name: "stack" +conditions: + kibana: + version: "^8.0.0 || ^9.0.0" +`, + supported: true, + }, + { + title: "Test snapshot", + stackVersion: "8.18.0-SNAPSHOT", + contents: `name: "stack" +conditions: + kibana: + version: "^8.0.0 || ^9.0.0" +`, + supported: true, + }, + { + title: "Test greater or equal", + stackVersion: "8.18.0-SNAPSHOT", + contents: `name: "stack" +conditions: + kibana: + version: ">=8.0.0" +`, + supported: true, + }, + { + title: "Test not supported", + stackVersion: "8.18.0-SNAPSHOT", + contents: `name: "stack" +conditions: + kibana: + version: "^9.0.0" +`, + supported: false, + }, + { + title: "Test missing kibana version", + stackVersion: "8.18.0-SNAPSHOT", + contents: `name: "stack" +`, + supported: true, + }, + } + + for _, c := range cases { + t.Run(c.title, func(t *testing.T) { + directory := t.TempDir() + pkgManifestPath := filepath.Join(directory, "manifest.yml") + err := os.WriteFile(pkgManifestPath, []byte(c.contents), 0o644) + require.NoError(t, err) + supported, err := IsPackageSupportedInStackVersion(c.stackVersion, pkgManifestPath) + require.NoError(t, err) + assert.Equal(t, c.supported, supported) + }) + } +} diff --git a/magefile.go b/magefile.go index c22b4a6c334..f8e57f44166 100644 --- a/magefile.go +++ b/magefile.go @@ -235,7 +235,41 @@ func IsSubscriptionCompatible() error { return nil } -// IsLogsDBSupportedInPackage checks wheter or not the package in the current directory supports LogsDB +// KibanaConstraintPackage returns the Kibana version constraint defined in the package manifest +func KibanaConstraintPackage() error { + constraint, err := citools.KibanaConstraintPackage("manifest.yml") + if err != nil { + return fmt.Errorf("faile") + } + if constraint == nil { + fmt.Println("null") + return nil + } + fmt.Println(constraint) + return nil +} + +// IsSupportedStack checks whether or not the package in the current directory is allowed to be installed in the given stack version +func IsSupportedStack(stackVersion string) error { + if stackVersion == "" { + fmt.Println("true") + return nil + } + + supported, err := citools.IsPackageSupportedInStackVersion(stackVersion, "manifest.yml") + if err != nil { + return err + } + + if supported { + fmt.Println("true") + return nil + } + fmt.Println("false") + return nil +} + +// IsLogsDBSupportedInPackage checks whether or not the package in the current directory supports LogsDB func IsLogsDBSupportedInPackage() error { supported, err := citools.IsLogsDBSupportedInPackage("manifest.yml") if err != nil { @@ -249,7 +283,7 @@ func IsLogsDBSupportedInPackage() error { return nil } -// IsVersionLessThanLogsDBGA checks wheter or not the given version supports LogsDB. Minimum version that supports LogsDB as GA 8.17.0. +// IsVersionLessThanLogsDBGA checks whether or not the given version supports LogsDB. Minimum version that supports LogsDB as GA 8.17.0. func IsVersionLessThanLogsDBGA(version string) error { stackVersion, err := semver.NewVersion(version) if err != nil {