func()

in dev-tools/mage/downloads/releases.go [47:164]


func (r *ArtifactURLResolver) Resolve() (string, string, error) {
	resolvedVersion, err := GetElasticArtifactVersion(r.Version)
	if err != nil {
		return "", "", fmt.Errorf("failed to get version %s: %w", r.Version, err)
	}
	r.Version = resolvedVersion

	fullName := strings.ReplaceAll(r.FullName, r.Version, resolvedVersion)
	r.FullName = fullName

	artifactName := r.FullName
	artifact := r.Name
	version := r.Version

	exp := getExponentialBackoff(time.Minute)

	retryCount := 1

	body := []byte{}

	tmpVersion := version
	hasCommit := SnapshotHasCommit(version)
	if hasCommit {
		logger.Log(context.Background(), TraceLevel, "Removing SNAPSHOT from version including commit",
			slog.String("resolver", r.Kind()),
			slog.String("version", version),
		)

		// remove the SNAPSHOT from the VERSION as the artifacts API supports commits in the version, but without the snapshot suffix
		tmpVersion = GetCommitVersion(version)
	}

	apiStatus := func() error {
		url := fmt.Sprintf("https://artifacts-api.elastic.co/v1/search/%s/%s?x-elastic-no-kpi=true", tmpVersion, artifact)
		req := httpRequest{
			URL: url,
		}
		bodyStr, err := get(req)
		if err != nil {
			logger.Warn("Resolver failed",
				slog.String("kind", r.Kind()),
				slog.String("artifact", artifact),
				slog.String("artifactName", artifactName),
				slog.String("version", tmpVersion),
				slog.String("error", err.Error()),
				slog.Int("retry", retryCount),
				slog.String("statusEndpoint", url),
				slog.Duration("elapsedTime", exp.GetElapsedTime()),
				slog.String("resp", bodyStr),
			)
			retryCount++

			return err
		}

		body = []byte(bodyStr)
		return nil
	}

	err = backoff.Retry(apiStatus, exp)
	if err != nil {
		logger.Error("Failed to get artifact",
			slog.String("resolver", r.Kind()),
			slog.String("artifact", artifact),
			slog.String("artifactName", artifactName),
			slog.String("version", tmpVersion),
		)
		return "", "", err
	}

	jsonParsed, err := gabs.ParseJSON(body)
	if err != nil {
		logger.Error("Could not parse the response body for the artifact",
			slog.String("resolver", r.Kind()),
			slog.String("artifact", artifact),
			slog.String("artifactName", artifactName),
			slog.String("version", tmpVersion),
		)
		return "", "", err
	}

	logger.Log(context.Background(), TraceLevel, "Resolver succeeded",
		slog.String("resolver", r.Kind()),
		slog.Int("retries", retryCount),
		slog.String("artifact", artifact),
		slog.String("artifactName", artifactName),
		slog.Duration("elapsedTime", exp.GetElapsedTime()),
		slog.String("version", tmpVersion),
	)

	if hasCommit {
		// remove commit from the artifact as it comes like this: elastic-agent-8.0.0-abcdef-SNAPSHOT-darwin-x86_64.tar.gz
		artifactName = RemoveCommitFromSnapshot(artifactName)
	}

	packagesObject := jsonParsed.Path("packages")
	// we need to get keys with dots using Search instead of Path
	downloadObject := packagesObject.Search(artifactName)
	if downloadObject == nil {
		logger.Error("ArtifactURLResolver object not found in Artifact API",
			slog.String("artifact", artifact),
			slog.String("name", artifactName),
			slog.String("version", version),
		)
		return "", "", fmt.Errorf("object not found in Artifact API")
	}

	downloadURL, ok := downloadObject.Path("url").Data().(string)
	if !ok {
		return "", "", fmt.Errorf("key 'url' does not exist for artifact %s", artifact)
	}
	downloadshaURL, ok := downloadObject.Path("sha_url").Data().(string)
	if !ok {
		return "", "", fmt.Errorf("key 'sha_url' does not exist for artifact %s", artifact)
	}

	return downloadURL, downloadshaURL, nil
}