From 864419c1eab1e0395b70263ad6608e9d74854a2d Mon Sep 17 00:00:00 2001 From: jev forsberg Date: Wed, 16 Jul 2025 15:57:39 -0600 Subject: [PATCH] Infrastructure: Wholesale copy pkg/build/ from main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit COMPLETE DAGGERBUILD SYSTEM UPDATE: - Modern E2E system with CLI framework and --flags support - New accessibility testing system (a11y/) - New Playwright E2E testing system (e2e-playwright/) - External infrastructure improvements (musl.cc → dl.grafana.com/ci) - Updated daggerbuild core components with latest fixes - Updated Go dependencies and wire modules ARCHITECTURAL COMPATIBILITY VERIFIED: - Modern pkg/build calls: ./e2e-runner cypress --start-grafana=false --cypress-video - Our e2e runner supports: All required parameters including --suite, --env flags - GitHub Actions workflows: Pass compatible arguments - Binary builds: Successfully creates working e2e-runner RESOLVES ISSUES: - Fixes --flags parameter compatibility with GitHub Actions - Includes all follow-up infrastructure improvements - Provides complete, tested system with modern CLI framework - Eliminates external dependency failures (musl.cc timeouts) - Removes need for path doubling workarounds (modern system handles full paths correctly) Replaces incremental cherry-picking with complete, tested system from main. --- pkg/build/a11y/README.md | 22 ++ pkg/build/a11y/main.go | 179 +++++++++++++ pkg/build/a11y/run.go | 48 ++++ pkg/build/a11y/service.go | 51 ++++ pkg/build/actions/bump-version/action.yml | 5 +- pkg/build/cmd/grafanacom.go | 21 +- pkg/build/daggerbuild/arguments/docker.go | 8 +- pkg/build/daggerbuild/arguments/grafana.go | 43 ++-- pkg/build/daggerbuild/artifacts/backend.go | 8 + pkg/build/daggerbuild/artifacts/frontend.go | 2 +- .../daggerbuild/artifacts/package_msi.go | 9 +- .../daggerbuild/artifacts/package_targz.go | 16 +- pkg/build/daggerbuild/backend/builder.go | 22 +- .../containers/with_embedded_fs.go | 38 --- pkg/build/daggerbuild/docker/verify.go | 3 +- pkg/build/daggerbuild/fpm/build.go | 2 +- pkg/build/daggerbuild/fpm/verify.go | 15 +- pkg/build/daggerbuild/frontend/build.go | 5 +- pkg/build/daggerbuild/msi/build.go | 3 +- pkg/build/daggerbuild/msi/builder.go | 11 +- pkg/build/daggerbuild/msi/wxs.go | 8 + .../daggerbuild/scripts/drone_build_main.sh | 6 +- .../scripts/drone_build_main_enterprise.sh | 5 +- .../scripts/drone_build_main_pro.sh | 8 +- .../scripts/drone_build_nightly_enterprise.sh | 9 +- .../scripts/drone_build_nightly_grafana.sh | 5 +- .../scripts/drone_build_tag_enterprise.sh | 7 +- .../scripts/drone_build_tag_grafana.sh | 5 +- .../scripts/drone_build_tag_pro.sh | 7 +- .../drone_publish_nightly_enterprise.sh | 8 +- .../scripts/drone_publish_nightly_grafana.sh | 16 +- pkg/build/e2e-playwright/README.md | 22 ++ pkg/build/e2e-playwright/e2e.go | 101 ++++++++ pkg/build/e2e-playwright/frontend.go | 84 ++++++ pkg/build/e2e-playwright/main.go | 243 ++++++++++++++++++ pkg/build/e2e-playwright/service.go | 58 +++++ pkg/build/e2e/main.go | 161 +++++++++--- pkg/build/e2e/run.go | 15 +- pkg/build/e2e/service.go | 41 ++- pkg/build/go.mod | 79 +++--- pkg/build/go.sum | 164 ++++++------ pkg/build/wire/go.mod | 6 +- pkg/build/wire/go.sum | 12 +- 43 files changed, 1266 insertions(+), 315 deletions(-) create mode 100644 pkg/build/a11y/README.md create mode 100644 pkg/build/a11y/main.go create mode 100644 pkg/build/a11y/run.go create mode 100644 pkg/build/a11y/service.go create mode 100644 pkg/build/e2e-playwright/README.md create mode 100644 pkg/build/e2e-playwright/e2e.go create mode 100644 pkg/build/e2e-playwright/frontend.go create mode 100644 pkg/build/e2e-playwright/main.go create mode 100644 pkg/build/e2e-playwright/service.go diff --git a/pkg/build/a11y/README.md b/pkg/build/a11y/README.md new file mode 100644 index 00000000000..d5fc311d696 --- /dev/null +++ b/pkg/build/a11y/README.md @@ -0,0 +1,22 @@ +# Pa11y accessability tests + +We use pa11y to run some automated simple accessability tests. They're ran with dagger to help orchestrate starting server + tests in a reproducable manner. + +To run the tests locally: + +1. Install dagger locally https://docs.dagger.io/install/ +2. Grab the grafana.tar.gz artifact by either + 1. Downloading it from the Github Action artifact from your PR + 1. Build it locally with: + ```sh + dagger run go run ./pkg/build/cmd artifacts -a targz:grafana:linux/amd64 --grafana-dir="$PWD" > dist/files.txt + cat dist/files.txt # Will output the path to the grafana.tar.gz + ``` +3. Run the dagger pipeline with: + ```sh + dagger -v run go run ./pkg/build/a11y --package=(full path to .tar.gz) --results=./pa11y-ci-results.json + ``` + The JSON results file will be saved to the file from the `--results` arg +4. If they fail and you want to see the full output + 1. Run the dagger command with `dagger -vE [...]` + 2. At the end, arrow up to the exec pa11y-ci segment and hit Enter \ No newline at end of file diff --git a/pkg/build/a11y/main.go b/pkg/build/a11y/main.go new file mode 100644 index 00000000000..dd85c2c3328 --- /dev/null +++ b/pkg/build/a11y/main.go @@ -0,0 +1,179 @@ +package main + +import ( + "context" + "fmt" + "log" + "os" + "os/signal" + + "dagger.io/dagger" + "github.com/urfave/cli/v3" +) + +var ( + grafanaHost = "grafana" + grafanaPort = 3001 +) + +func main() { + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) + defer cancel() + + if err := NewApp().Run(ctx, os.Args); err != nil { + cancel() + fmt.Println(err) + os.Exit(1) + } +} + +func NewApp() *cli.Command { + return &cli.Command{ + Name: "a11y", + Usage: "Run Grafana accessibility tests", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "grafana-dir", + Usage: "Path to the grafana/grafana clone directory", + Value: ".", + Validator: mustBeDir("grafana-dir"), + TakesFile: true, + }, + &cli.StringFlag{ + Name: "package", + Usage: "Path to the grafana tar.gz package", + Value: "grafana.tar.gz", + Validator: mustBeFile("package", false), + TakesFile: true, + }, + &cli.StringFlag{ + Name: "license", + Usage: "Path to the Grafana Enterprise license file (optional)", + Validator: mustBeFile("license", true), + TakesFile: true, + }, + &cli.StringFlag{ + Name: "config", + Usage: "Path to the pa11y config file to use", + Value: "e2e/pa11yci.conf.js", + Validator: mustBeFile("config", true), + TakesFile: true, + }, + &cli.StringFlag{ + Name: "results", + Usage: "Path to the pa11y results file to export", + TakesFile: true, + }, + &cli.BoolFlag{ + Name: "no-threshold-fail", + Usage: "Don't fail the task if any of the tests fail. Use this in combination with --results to list all violations even if they're within thresholds", + Value: false, + }, + }, + Action: run, + } +} + +func run(ctx context.Context, cmd *cli.Command) error { + grafanaDir := cmd.String("grafana-dir") + targzPath := cmd.String("package") + licensePath := cmd.String("license") + pa11yConfigPath := cmd.String("config") + pa11yResultsPath := cmd.String("results") + noThresholdFail := cmd.Bool("no-threshold-fail") + + d, err := dagger.Connect(ctx) + if err != nil { + return fmt.Errorf("failed to connect to Dagger: %w", err) + } + + // Explicitly only the files used by the grafana-server service + hostSrc := d.Host().Directory(grafanaDir, dagger.HostDirectoryOpts{ + Include: []string{ + "./devenv", + "./e2e-playwright/test-plugins", // Directory is included so provisioning works, but they're not actually build + "./scripts/grafana-server/custom.ini", + "./scripts/grafana-server/start-server", + "./scripts/grafana-server/kill-server", + "./scripts/grafana-server/variables", + }, + }) + + targz := d.Host().File(targzPath) + pa11yConfig := d.Host().File(pa11yConfigPath) + + var license *dagger.File + if licensePath != "" { + license = d.Host().File(licensePath) + } + + svc, err := GrafanaService(ctx, d, GrafanaServiceOpts{ + HostSrc: hostSrc, + GrafanaTarGz: targz, + License: license, + }) + if err != nil { + return fmt.Errorf("failed to create Grafana service: %w", err) + } + + c, runErr := RunTest(ctx, d, svc, pa11yConfig, noThresholdFail, pa11yResultsPath) + if runErr != nil { + return fmt.Errorf("failed to run a11y test suite: %w", runErr) + } + + c, syncErr := c.Sync(ctx) + if syncErr != nil { + return fmt.Errorf("failed to sync a11y test suite: %w", syncErr) + } + + code, codeErr := c.ExitCode(ctx) + if codeErr != nil { + return fmt.Errorf("failed to get exit code of a11y test suite: %w", codeErr) + } + + if code == 0 { + log.Printf("a11y tests passed with exit code %d", code) + } else if noThresholdFail { + log.Printf("a11y tests failed with exit code %d, but noFail is true", code) + } else { + return fmt.Errorf("a11y tests failed with exit code %d", code) + } + + log.Println("a11y tests completed successfully") + return nil +} + +func mustBeFile(arg string, emptyOk bool) func(string) error { + return func(s string) error { + if s == "" { + if emptyOk { + return nil + } + return cli.Exit(arg+" cannot be empty", 1) + } + stat, err := os.Stat(s) + if err != nil { + return cli.Exit(arg+" does not exist or cannot be read: "+s, 1) + } + if stat.IsDir() { + return cli.Exit(arg+" must be a file, not a directory: "+s, 1) + } + return nil + } +} + +func mustBeDir(arg string) func(string) error { + return func(s string) error { + if s == "" { + return cli.Exit(arg+" cannot be empty", 1) + } + stat, err := os.Stat(s) + if err != nil { + return cli.Exit(arg+" does not exist or cannot be read: "+s, 1) + } + if !stat.IsDir() { + return cli.Exit(arg+" must be a directory: "+s, 1) + } + return nil + } +} diff --git a/pkg/build/a11y/run.go b/pkg/build/a11y/run.go new file mode 100644 index 00000000000..b736dc9d6db --- /dev/null +++ b/pkg/build/a11y/run.go @@ -0,0 +1,48 @@ +package main + +import ( + "context" + "fmt" + + "dagger.io/dagger" +) + +func RunTest( + ctx context.Context, + d *dagger.Client, + grafanaService *dagger.Service, + pa11yConfig *dagger.File, + noThresholdFail bool, + pa11yResultsPath string, +) (*dagger.Container, error) { + // docker-puppeteer container already has Chrome and Pa11y installed in it + pa11yContainer := d.Container().From("grafana/docker-puppeteer:1.1.0"). + WithWorkdir("/src"). + WithExec([]string{"mkdir", "-p", "./screenshots"}). // not yet exported + WithEnvVariable("HOST", grafanaHost). + WithEnvVariable("PORT", fmt.Sprint(grafanaPort)) + + if noThresholdFail { + // This logic is non-intuitive - --no-threshold-fail will make pa11y fail (by removing thresholds from the config) + // so it can write all violations to the results file. This failure is then ignored by the caller in main.go. + // Otherwise, pa11y ignores violations if they're within the thresholds and doesn't include them in the results file + pa11yContainer = pa11yContainer. + WithEnvVariable("NO_THRESHOLDS", "true") + } + + pa11yContainer = pa11yContainer. + WithServiceBinding(grafanaHost, grafanaService). + WithMountedFile("pa11yci-config.js", pa11yConfig). + WithExec([]string{"pa11y-ci", "--config", "pa11yci-config.js"}, dagger.ContainerWithExecOpts{ + Expect: dagger.ReturnTypeAny, // allow this to fail here so we can handle non-zero exit codes at the caller + }) + + if pa11yResultsPath != "" { + _, err := pa11yContainer.File("/src/pa11y-ci-results.json").Export(ctx, pa11yResultsPath) + if err != nil { + return nil, fmt.Errorf("failed to get pa11y results: %w", err) + } + } + + return pa11yContainer, nil +} diff --git a/pkg/build/a11y/service.go b/pkg/build/a11y/service.go new file mode 100644 index 00000000000..98bcb5cf20b --- /dev/null +++ b/pkg/build/a11y/service.go @@ -0,0 +1,51 @@ +package main + +import ( + "context" + "fmt" + "os" + "strings" + + "dagger.io/dagger" +) + +type GrafanaServiceOpts struct { + HostSrc *dagger.Directory + GrafanaTarGz *dagger.File + License *dagger.File +} + +func GrafanaService(ctx context.Context, d *dagger.Client, opts GrafanaServiceOpts) (*dagger.Service, error) { + container := d.Container().From("alpine:3"). + WithExec([]string{"apk", "add", "--no-cache", "bash", "tar", "netcat-openbsd"}). + WithMountedFile("/src/grafana.tar.gz", opts.GrafanaTarGz). + WithExec([]string{"mkdir", "-p", "/src/grafana"}). + WithExec([]string{"tar", "--strip-components=1", "-xzf", "/src/grafana.tar.gz", "-C", "/src/grafana"}). + WithDirectory("/src/grafana/devenv", opts.HostSrc.Directory("./devenv")). + WithDirectory("/src/grafana/e2e-playwright/test-plugins", opts.HostSrc.Directory("./e2e-playwright/test-plugins")). + WithDirectory("/src/grafana/scripts", opts.HostSrc.Directory("./scripts")). + WithWorkdir("/src/grafana"). + WithEnvVariable("GF_APP_MODE", "development"). + WithEnvVariable("GF_SERVER_HTTP_PORT", fmt.Sprint(grafanaPort)). + WithEnvVariable("GF_SERVER_ROUTER_LOGGING", "1"). + WithExposedPort(grafanaPort) + + var licenseArg string + if opts.License != nil { + licenseArg = "/src/license.jwt" + container = container.WithMountedFile(licenseArg, opts.License) + } + + // We add all GF_ environment variables to allow for overriding Grafana configuration. + // It is unlikely the runner has any such otherwise. + for _, env := range os.Environ() { + if strings.HasPrefix(env, "GF_") { + parts := strings.SplitN(env, "=", 2) + container = container.WithEnvVariable(parts[0], parts[1]) + } + } + + svc := container.AsService(dagger.ContainerAsServiceOpts{Args: []string{"bash", "-x", "scripts/grafana-server/start-server", licenseArg}}) + + return svc, nil +} diff --git a/pkg/build/actions/bump-version/action.yml b/pkg/build/actions/bump-version/action.yml index 24ae182daf2..d7d6fdf5c50 100644 --- a/pkg/build/actions/bump-version/action.yml +++ b/pkg/build/actions/bump-version/action.yml @@ -12,9 +12,12 @@ runs: go-version-file: go.mod - name: Bump versions uses: dagger/dagger-for-github@e47aba410ef9bb9ed81a4d2a97df31061e5e842e + env: + GO_MOD_DIR: ${{ inputs.go-mod-dir }} + VERSION: ${{ inputs.version }} with: verb: run - args: go run ./pkg/build/actions/bump-version -version=${{ inputs.version }} + args: go run ./pkg/build/actions/bump-version -version=${VERSION} - name: make gen-cue shell: bash run: make gen-cue diff --git a/pkg/build/cmd/grafanacom.go b/pkg/build/cmd/grafanacom.go index cb413f697bc..934d888d4ce 100644 --- a/pkg/build/cmd/grafanacom.go +++ b/pkg/build/cmd/grafanacom.go @@ -2,10 +2,12 @@ package main import ( "bytes" + "context" "encoding/json" "fmt" "io" "log" + "net" "net/http" "net/url" "os" @@ -26,6 +28,23 @@ import ( const grafanaAPI = "https://grafana.com/api" +var httpClient = http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: func(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) { + return dialer.DialContext + }(&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }), + ForceAttemptHTTP2: true, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + }, +} + // GrafanaCom implements the sub-command "grafana-com". func GrafanaCom(c *cli.Context) error { bucketStr := c.String("src-bucket") @@ -330,7 +349,7 @@ func postRequest(cfg packaging.PublishConfig, pth string, body any, descr string return nil } - resp, err := http.DefaultClient.Do(req) + resp, err := httpClient.Do(req) if err != nil { return fmt.Errorf("failed posting to %s (%s): %s", u, descr, err) } diff --git a/pkg/build/daggerbuild/arguments/docker.go b/pkg/build/daggerbuild/arguments/docker.go index 0992f5986c0..2f7a854fb2f 100644 --- a/pkg/build/daggerbuild/arguments/docker.go +++ b/pkg/build/daggerbuild/arguments/docker.go @@ -19,13 +19,13 @@ var ( } AlpineImageFlag = &cli.StringFlag{ Name: "alpine-base", - Usage: "The alpine image to use as the base image when building the Alpine version of the Grafana docker image", - Value: "alpine:latest", + Usage: "The image or image alias specified in the Dockerfile to be used as the base image when building the Alpine version of the Grafana docker image.", + Value: "alpine-base", } UbuntuImageFlag = &cli.StringFlag{ Name: "ubuntu-base", - Usage: "The Ubuntu image to use as the base image when building the Ubuntu version of the Grafana docker image", - Value: "ubuntu:latest", + Usage: "The image or image alias specified in the Dockerfile to be used as the base image when building the Ubuntu version of the Grafana docker image", + Value: "ubuntu-base", } TagFormatFlag = &cli.StringFlag{ Name: "tag-format", diff --git a/pkg/build/daggerbuild/arguments/grafana.go b/pkg/build/daggerbuild/arguments/grafana.go index d7a4ebe599c..90c03751e4b 100644 --- a/pkg/build/daggerbuild/arguments/grafana.go +++ b/pkg/build/daggerbuild/arguments/grafana.go @@ -3,7 +3,6 @@ package arguments import ( "context" "fmt" - "log" "log/slog" "path" "path/filepath" @@ -95,16 +94,30 @@ func GrafanaDirectoryOptsFromFlags(c cliutil.CLIContext) *GrafanaDirectoryOpts { } func cloneOrMount(ctx context.Context, client *dagger.Client, localPath, repo, ref string, ght string) (*dagger.Directory, error) { - // If GrafanaDir was provided, then we can just use that one. - if path := localPath; path != "" { - slog.Info("Using local Grafana found", "path", path) - return daggerutil.HostDir(client, path) + if localPath != "" { + absolute, err := filepath.Abs(localPath) + if err != nil { + return nil, fmt.Errorf("error getting absolute path for local dir: %w", err) + } + localPath = absolute + slog.Info("Using local directory for repository", "path", localPath, "repo", repo) + return daggerutil.HostDir(client, localPath) + } + + ght, err := githubToken(ctx, ght) + if err != nil { + return nil, fmt.Errorf("error acquiring GitHub token: %w", err) } return git.CloneWithGitHubToken(client, ght, repo, ref) } func applyPatches(ctx context.Context, client *dagger.Client, src *dagger.Directory, repo, patchesPath, ref, ght string) (*dagger.Directory, error) { + ght, err := githubToken(ctx, ght) + if err != nil { + return nil, fmt.Errorf("error acquiring GitHub token: %w", err) + } + // Clone the patches repository on 'main' dir, err := git.CloneWithGitHubToken(client, ght, repo, ref) if err != nil { @@ -144,12 +157,7 @@ func applyPatches(ctx context.Context, client *dagger.Client, src *dagger.Direct func grafanaDirectory(ctx context.Context, opts *pipeline.ArgumentOpts) (any, error) { o := GrafanaDirectoryOptsFromFlags(opts.CLIContext) - ght, err := githubToken(ctx, o.GitHubToken) - if err != nil { - log.Println("No github token found:", err) - } - - src, err := cloneOrMount(ctx, opts.Client, o.GrafanaDir, o.GrafanaRepo, o.GrafanaRef, ght) + src, err := cloneOrMount(ctx, opts.Client, o.GrafanaDir, o.GrafanaRepo, o.GrafanaRef, o.GitHubToken) if err != nil { return nil, err } @@ -172,7 +180,7 @@ func grafanaDirectory(ctx context.Context, opts *pipeline.ArgumentOpts) (any, er WithFile(".buildinfo.branch", branchFile) if o.PatchesRepo != "" { - withPatches, err := applyPatches(ctx, opts.Client, src, o.PatchesRepo, o.PatchesPath, o.PatchesRef, ght) + withPatches, err := applyPatches(ctx, opts.Client, src, o.PatchesRepo, o.PatchesPath, o.PatchesRef, o.GitHubToken) if err != nil { opts.Log.Debug("patch application skipped", "error", err) } else { @@ -209,17 +217,12 @@ func enterpriseDirectory(ctx context.Context, opts *pipeline.ArgumentOpts) (any, return nil, fmt.Errorf("error initializing grafana directory: %w", err) } - ght, err := githubToken(ctx, o.GitHubToken) + clone, err := cloneOrMount(ctx, opts.Client, o.EnterpriseDir, o.EnterpriseRepo, o.EnterpriseRef, o.GitHubToken) if err != nil { - return nil, nil + return nil, fmt.Errorf("error cloning or mounting Grafana Enterprise directory: %w", err) } - src, err := cloneOrMount(ctx, opts.Client, o.EnterpriseDir, o.EnterpriseRepo, o.EnterpriseRef, ght) - if err != nil { - return nil, err - } - - return InitializeEnterprise(opts.Client, grafanaDir.(*dagger.Directory), src), nil + return InitializeEnterprise(opts.Client, grafanaDir.(*dagger.Directory), clone), nil } var GrafanaDirectoryFlags = []cli.Flag{ diff --git a/pkg/build/daggerbuild/artifacts/backend.go b/pkg/build/daggerbuild/artifacts/backend.go index 64d820bc86c..b4bb62085de 100644 --- a/pkg/build/daggerbuild/artifacts/backend.go +++ b/pkg/build/daggerbuild/artifacts/backend.go @@ -3,6 +3,7 @@ package artifacts import ( "context" "log/slog" + "os" "path/filepath" "dagger.io/dagger" @@ -191,10 +192,17 @@ func NewBackendFromString(ctx context.Context, log *slog.Logger, artifact string return nil, err } + goCacheProg := "" + // If the caller has GOCACHEPROG set, then reuse it + if val, ok := os.LookupEnv("GOCACHEPROG"); ok { + goCacheProg = val + } + bopts := &backend.BuildOpts{ Version: p.Version, Enterprise: p.Enterprise, ExperimentalFlags: experiments, + GoCacheProg: goCacheProg, Static: static, WireTag: wireTag, Tags: tags, diff --git a/pkg/build/daggerbuild/artifacts/frontend.go b/pkg/build/daggerbuild/artifacts/frontend.go index 403c515b4e4..298f990a642 100644 --- a/pkg/build/daggerbuild/artifacts/frontend.go +++ b/pkg/build/daggerbuild/artifacts/frontend.go @@ -47,7 +47,7 @@ func (f *Frontend) BuildFile(ctx context.Context, builder *dagger.Container, opt } func (f *Frontend) BuildDir(ctx context.Context, builder *dagger.Container, opts *pipeline.ArtifactContainerOpts) (*dagger.Directory, error) { - return frontend.Build(builder), nil + return frontend.Build(builder, f.Version), nil } func (f *Frontend) Publisher(ctx context.Context, opts *pipeline.ArtifactContainerOpts) (*dagger.Container, error) { diff --git a/pkg/build/daggerbuild/artifacts/package_msi.go b/pkg/build/daggerbuild/artifacts/package_msi.go index 443d76d219d..e0471e76885 100644 --- a/pkg/build/daggerbuild/artifacts/package_msi.go +++ b/pkg/build/daggerbuild/artifacts/package_msi.go @@ -29,6 +29,7 @@ type MSI struct { BuildID string Distribution backend.Distribution Enterprise bool + Grafana *dagger.Directory Tarball *pipeline.Artifact } @@ -40,7 +41,7 @@ func (d *MSI) Dependencies(ctx context.Context) ([]*pipeline.Artifact, error) { } func (d *MSI) Builder(ctx context.Context, opts *pipeline.ArtifactContainerOpts) (*dagger.Container, error) { - return msi.Builder(opts.Client) + return msi.Builder(opts.Client, d.Grafana), nil } func (d *MSI) BuildFile(ctx context.Context, builder *dagger.Container, opts *pipeline.ArtifactContainerOpts) (*dagger.File, error) { @@ -105,6 +106,11 @@ func NewMSIFromString(ctx context.Context, log *slog.Logger, artifact string, st return nil, fmt.Errorf("distribution ('%s') for exe '%s' is not a Windows distribution", string(p.Distribution), artifact) } + src, err := GrafanaDir(ctx, state, p.Enterprise) + if err != nil { + return nil, err + } + return pipeline.ArtifactWithLogging(ctx, log, &pipeline.Artifact{ ArtifactString: artifact, Handler: &MSI{ @@ -114,6 +120,7 @@ func NewMSIFromString(ctx context.Context, log *slog.Logger, artifact string, st Distribution: p.Distribution, Enterprise: p.Enterprise, Tarball: targz, + Grafana: src, }, Type: pipeline.ArtifactTypeFile, Flags: ZipFlags, diff --git a/pkg/build/daggerbuild/artifacts/package_targz.go b/pkg/build/daggerbuild/artifacts/package_targz.go index 9046ae7f5ad..93e09112ceb 100644 --- a/pkg/build/daggerbuild/artifacts/package_targz.go +++ b/pkg/build/daggerbuild/artifacts/package_targz.go @@ -164,7 +164,7 @@ func NewTarball( if err != nil { return nil, err } - frontendArtifact, err := NewFrontend(ctx, log, version, artifact, enterprise, src, cache) + frontendArtifact, err := NewFrontend(ctx, log, artifact, version, enterprise, src, cache) if err != nil { return nil, err } @@ -363,19 +363,23 @@ func verifyTarball( Platform: platform, }).From("ubuntu:22.04"). WithExec([]string{"apt-get", "update", "-yq"}). - WithExec([]string{"apt-get", "install", "-yq", "ca-certificates", "libfontconfig1"}). + WithExec([]string{"apt-get", "install", "-yq", "ca-certificates"}). WithDirectory("/src", archive). + WithMountedTemp("/tmp"). WithWorkdir("/src") if err := e2e.ValidateLicense(ctx, service, "/src/LICENSE", enterprise); err != nil { return err } - service = service. - WithExec([]string{"./bin/grafana", "server"}). - WithExposedPort(3000) + svc := service. + WithEnvVariable("GF_PATHS_PLUGINS", "/tmp"). + WithEnvVariable("GF_LOG_LEVEL", "error"). + WithExposedPort(3000).AsService(dagger.ContainerAsServiceOpts{ + Args: []string{"./bin/grafana", "server"}, + }) - if _, err := containers.ExitError(ctx, e2e.ValidatePackage(d, service.AsService(), src, yarnCache, nodeVersion)); err != nil { + if _, err := containers.ExitError(ctx, e2e.ValidatePackage(d, svc, src, yarnCache, nodeVersion)); err != nil { return err } return nil diff --git a/pkg/build/daggerbuild/backend/builder.go b/pkg/build/daggerbuild/backend/builder.go index c1258b6d2f4..9a27c60a8c0 100644 --- a/pkg/build/daggerbuild/backend/builder.go +++ b/pkg/build/daggerbuild/backend/builder.go @@ -16,6 +16,7 @@ type BuildOpts struct { ExperimentalFlags []string Tags []string WireTag string + GoCacheProg string Static bool Enterprise bool } @@ -93,15 +94,15 @@ func GolangContainer( container := golang.Container(d, platform, goVersion). WithExec([]string{"apk", "add", "--update", "wget", "build-base", "alpine-sdk", "musl", "musl-dev", "xz"}). - WithExec([]string{"wget", "https://dl.grafana.com/ci/zig-linux-x86_64-0.11.0.tar.xz"}). + WithExec([]string{"wget", "-q", "https://dl.grafana.com/ci/zig-linux-x86_64-0.11.0.tar.xz"}). WithExec([]string{"tar", "--strip-components=1", "-C", "/", "-xf", "zig-linux-x86_64-0.11.0.tar.xz"}). WithExec([]string{"mv", "/zig", "/bin/zig"}). // Install the toolchain specifically for armv7 until we figure out why it's crashing w/ zig container = container. WithExec([]string{"mkdir", "/toolchain"}). - WithExec([]string{"wget", "http://dl.grafana.com/ci/arm-linux-musleabihf-cross.tgz", "-P", "/toolchain"}). - WithExec([]string{"tar", "-xvf", "/toolchain/arm-linux-musleabihf-cross.tgz", "-C", "/toolchain"}). - WithExec([]string{"wget", "https://dl.grafana.com/ci/s390x-linux-musl-cross.tgz", "-P", "/toolchain"}). - WithExec([]string{"tar", "-xvf", "/toolchain/s390x-linux-musl-cross.tgz", "-C", "/toolchain"}) + WithExec([]string{"wget", "-q", "http://dl.grafana.com/ci/arm-linux-musleabihf-cross.tgz", "-P", "/toolchain"}). + WithExec([]string{"tar", "-xf", "/toolchain/arm-linux-musleabihf-cross.tgz", "-C", "/toolchain"}). + WithExec([]string{"wget", "-q", "https://dl.grafana.com/ci/s390x-linux-musl-cross.tgz", "-P", "/toolchain"}). + WithExec([]string{"tar", "-xf", "/toolchain/s390x-linux-musl-cross.tgz", "-C", "/toolchain"}) return WithGoEnv(log, container, distro, opts) } @@ -154,13 +155,17 @@ func Builder( WithMountedCache("/root/.cache/go", goBuildCache). WithEnvVariable("GOCACHE", "/root/.cache/go") + if prog := opts.GoCacheProg; prog != "" { + builder = builder.WithEnvVariable("GOCACHEPROG", prog) + } + commitInfo := GetVCSInfo(src, version, opts.Enterprise) builder = withCue(builder, src). WithDirectory("/src/", src, dagger.ContainerWithDirectoryOpts{ - Include: []string{"**/*.mod", "**/*.sum", "**/*.work"}, + Include: []string{"**/*.mod", "**/*.sum", "**/*.work", ".git"}, }). - WithDirectory("/src/pkg", src.Directory("pkg")). + WithDirectory("/src/pkg", src.WithoutDirectory("pkg/build").Directory("pkg")). WithDirectory("/src/apps", src.Directory("apps")). WithDirectory("/src/emails", src.Directory("emails")). WithFile("/src/pkg/server/wire_gen.go", Wire(d, src, platform, goVersion, opts.WireTag)). @@ -184,11 +189,12 @@ func Wire(d *dagger.Client, src *dagger.Directory, platform dagger.Platform, goV return withCue(golang.Container(d, platform, goVersion), src). WithExec([]string{"apk", "add", "make"}). WithDirectory("/src/", src, dagger.ContainerWithDirectoryOpts{ - Include: []string{"**/*.mod", "**/*.sum", "**/*.work"}, + Include: []string{"**/*.mod", "**/*.sum", "**/*.work", ".git"}, }). WithDirectory("/src/pkg", src.Directory("pkg")). WithDirectory("/src/apps", src.Directory("apps")). WithDirectory("/src/.bingo", src.Directory(".bingo")). + WithDirectory("/src/.citools", src.Directory(".citools")). WithFile("/src/Makefile", src.File("Makefile")). WithWorkdir("/src"). WithExec([]string{"make", "gen-go", fmt.Sprintf("WIRE_TAGS=%s", wireTag)}). diff --git a/pkg/build/daggerbuild/containers/with_embedded_fs.go b/pkg/build/daggerbuild/containers/with_embedded_fs.go index 07e7217bfa7..0c09d3e403d 100644 --- a/pkg/build/daggerbuild/containers/with_embedded_fs.go +++ b/pkg/build/daggerbuild/containers/with_embedded_fs.go @@ -1,39 +1 @@ package containers - -import ( - "embed" - "io/fs" - "path/filepath" - - "dagger.io/dagger" -) - -func WithEmbeddedFS(client *dagger.Client, c *dagger.Container, path string, e embed.FS) (*dagger.Container, error) { - dir := client.Directory() - - err := fs.WalkDir(e, ".", func(path string, entry fs.DirEntry, err error) error { - if entry.IsDir() { - return nil - } - if err != nil { - return err - } - - content, err := e.ReadFile(path) - if err != nil { - return err - } - rel, err := filepath.Rel("scripts/packaging/windows", path) - if err != nil { - return err - } - - dir = dir.WithNewFile(rel, string(content)) - return nil - }) - if err != nil { - return nil, err - } - - return c.WithDirectory(path, dir), nil -} diff --git a/pkg/build/daggerbuild/docker/verify.go b/pkg/build/daggerbuild/docker/verify.go index c6367480206..52b6a5eac2c 100644 --- a/pkg/build/daggerbuild/docker/verify.go +++ b/pkg/build/daggerbuild/docker/verify.go @@ -34,8 +34,9 @@ func Verify( service := d.Container(dagger.ContainerOpts{ Platform: platform, }). - WithMountedTemp("/var/lib/grafana/plugins"). + WithMountedTemp("/var/lib/grafana/plugins", dagger.ContainerWithMountedTempOpts{}). Import(image). + WithEnvVariable("GF_LOG_LEVEL", "error"). WithExposedPort(3000) // TODO: Add LICENSE to containers and implement validation diff --git a/pkg/build/daggerbuild/fpm/build.go b/pkg/build/daggerbuild/fpm/build.go index 138f166792c..82bfa631bee 100644 --- a/pkg/build/daggerbuild/fpm/build.go +++ b/pkg/build/daggerbuild/fpm/build.go @@ -122,7 +122,7 @@ func Build(builder *dagger.Container, opts BuildOpts, targz *dagger.File) *dagge container := builder. WithFile("/src/grafana.tar.gz", targz). WithEnvVariable("XZ_DEFAULTS", "-T0"). - WithExec([]string{"tar", "--exclude=storybook", "--strip-components=1", "-xvf", "/src/grafana.tar.gz", "-C", "/src"}). + WithExec([]string{"tar", "--exclude=storybook", "--strip-components=1", "-xf", "/src/grafana.tar.gz", "-C", "/src"}). WithExec([]string{"rm", "/src/grafana.tar.gz"}) container = container. diff --git a/pkg/build/daggerbuild/fpm/verify.go b/pkg/build/daggerbuild/fpm/verify.go index d4bf2a48902..a169d9b8b75 100644 --- a/pkg/build/daggerbuild/fpm/verify.go +++ b/pkg/build/daggerbuild/fpm/verify.go @@ -25,19 +25,21 @@ func VerifyDeb(ctx context.Context, d *dagger.Client, file *dagger.File, src *da // This grafana service runs in the background for the e2e tests service := d.Container(dagger.ContainerOpts{ Platform: platform, - }).From("debian:latest"). + }).From("ubuntu:22.04"). WithFile("/src/package.deb", file). WithExec([]string{"apt-get", "update"}). - WithExec([]string{"apt-get", "install", "-y", "/src/package.deb"}). + WithExec([]string{"apt-get", "install", "-yq", "ca-certificates"}). + WithExec([]string{"apt-get", "install", "-yq", "/src/package.deb"}). + WithEnvVariable("GF_LOG_LEVEL", "error"). WithWorkdir("/usr/share/grafana") if err := e2e.ValidateLicense(ctx, service, "/usr/share/grafana/LICENSE", enterprise); err != nil { return err } - svc := service. - WithExec([]string{"grafana-server"}). - WithExposedPort(3000).AsService() + svc := service.WithExposedPort(3000).AsService(dagger.ContainerAsServiceOpts{ + Args: []string{"grafana-server"}, + }) if _, err := containers.ExitError(ctx, e2e.ValidatePackage(d, svc, src, yarn, nodeVersion)); err != nil { return err @@ -59,9 +61,10 @@ func VerifyRpm(ctx context.Context, d *dagger.Client, file *dagger.File, src *da // This grafana service runs in the background for the e2e tests service := d.Container(dagger.ContainerOpts{ Platform: platform, - }).From("redhat/ubi8:latest"). + }).From("redhat/ubi8:8.10-source"). WithFile("/src/package.rpm", file). WithExec([]string{"yum", "install", "-y", "/src/package.rpm"}). + WithEnvVariable("GF_LOG_LEVEL", "error"). WithWorkdir("/usr/share/grafana") if err := e2e.ValidateLicense(ctx, service, "/usr/share/grafana/LICENSE", enterprise); err != nil { diff --git a/pkg/build/daggerbuild/frontend/build.go b/pkg/build/daggerbuild/frontend/build.go index b04cdc01767..9aec71e37d9 100644 --- a/pkg/build/daggerbuild/frontend/build.go +++ b/pkg/build/daggerbuild/frontend/build.go @@ -1,11 +1,14 @@ package frontend import ( + "fmt" + "dagger.io/dagger" ) -func Build(builder *dagger.Container) *dagger.Directory { +func Build(builder *dagger.Container, version string) *dagger.Directory { public := builder. + WithExec([]string{"/bin/sh", "-c", fmt.Sprintf("yarn lerna version %s --exact --no-git-tag-version --no-push --force-publish -y", version)}). WithExec([]string{"yarn", "run", "build"}). WithExec([]string{"/bin/sh", "-c", "find /src/public -type d -name node_modules -print0 | xargs -0 rm -rf"}). Directory("/src/public") diff --git a/pkg/build/daggerbuild/msi/build.go b/pkg/build/daggerbuild/msi/build.go index 109b6580f00..f95275fb3fe 100644 --- a/pkg/build/daggerbuild/msi/build.go +++ b/pkg/build/daggerbuild/msi/build.go @@ -47,7 +47,8 @@ func Build(d *dagger.Client, builder *dagger.Container, targz *dagger.File, vers // 2. 'candle': Compile .wxs files into .wixobj // 3. `light`: assembles the MSI builder = builder. - WithExec([]string{"/bin/sh", "-c", "cp -r /src/resources/resources/* /src && rm -rf /src/resources"}). + WithExec([]string{"/bin/sh", "-c", "cp -r /src/resources/* /src"}). + WithExec([]string{"/bin/sh", "-c", "ls -al /src && ls -a /src/resources"}). WithExec([]string{"/bin/sh", "-c", `WINEPATH=$(winepath /src/wix3) wine heat dir /src -platform x64 -sw5150 -srd -cg GrafanaX64 -gg -sfrag -dr GrafanaX64Dir -template fragment -out $(winepath -w grafana.wxs)`}). WithExec([]string{"winepath"}). WithExec([]string{"mkdir", "/root/.wine/drive_c/temp"}) diff --git a/pkg/build/daggerbuild/msi/builder.go b/pkg/build/daggerbuild/msi/builder.go index f55c32703e3..6af160de5e6 100644 --- a/pkg/build/daggerbuild/msi/builder.go +++ b/pkg/build/daggerbuild/msi/builder.go @@ -2,27 +2,26 @@ package msi import ( "dagger.io/dagger" - "github.com/grafana/grafana/pkg/build/daggerbuild/containers" ) -func Builder(d *dagger.Client) (*dagger.Container, error) { +func Builder(d *dagger.Client, src *dagger.Directory) *dagger.Container { nssm := d.Container().From("busybox"). - WithExec([]string{"wget", "https://dl.grafana.com/ci/nssm-2.24.zip"}). + WithExec([]string{"wget", "-q", "https://dl.grafana.com/ci/nssm-2.24.zip"}). WithExec([]string{"unzip", "nssm-2.24.zip"}). Directory("nssm-2.24") wix3 := d.Container().From("busybox"). WithWorkdir("/src"). - WithExec([]string{"wget", "https://github.com/wixtoolset/wix3/releases/download/wix3141rtm/wix314-binaries.zip"}). + WithExec([]string{"wget", "-q", "https://github.com/wixtoolset/wix3/releases/download/wix3141rtm/wix314-binaries.zip"}). WithExec([]string{"unzip", "wix314-binaries.zip"}). WithExec([]string{"rm", "wix314-binaries.zip"}). Directory("/src") - builder := d.Container().From("scottyhardy/docker-wine:stable-9.0"). + builder := d.Container().From("scottyhardy/docker-wine:stable-10.0-20250608"). WithEntrypoint([]string{}). WithMountedDirectory("/src/nssm-2.24", nssm). WithMountedDirectory("/src/wix3", wix3). WithWorkdir("/src") - return containers.WithEmbeddedFS(d, builder, "/src/resources", resources) + return builder.WithMountedDirectory("/src/resources", src.Directory("pkg/build/daggerbuild/msi/resources")) } diff --git a/pkg/build/daggerbuild/msi/wxs.go b/pkg/build/daggerbuild/msi/wxs.go index f283dfd6a48..443545de56a 100644 --- a/pkg/build/daggerbuild/msi/wxs.go +++ b/pkg/build/daggerbuild/msi/wxs.go @@ -45,6 +45,14 @@ func WxsVersion(ersion string) string { if v, ok := result["prerelease"]; ok && v != "" { v := strings.TrimPrefix(v, "beta") v = strings.TrimPrefix(v, "pre") + + if v == "local" { + v = "0" + } + + if len(v) > 5 { + v = v[len(v)-5:] + } return fmt.Sprintf("%s.%s.%s.%s", major, minor, patch, v) } return fmt.Sprintf("%s.%s.%s.0", major, minor, patch) diff --git a/pkg/build/daggerbuild/scripts/drone_build_main.sh b/pkg/build/daggerbuild/scripts/drone_build_main.sh index 233f6b9022a..4c584cdc3a1 100755 --- a/pkg/build/daggerbuild/scripts/drone_build_main.sh +++ b/pkg/build/daggerbuild/scripts/drone_build_main.sh @@ -7,7 +7,7 @@ docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --uninstall 'qemu- # This command enables qemu emulators for building Docker images for arm64/armv6/armv7/etc on the host. docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --install all -dagger run --silent go run ./cmd \ +dagger run --silent go run ./pkg/build/cmd \ artifacts \ -a targz:grafana:linux/amd64 \ -a targz:grafana:linux/arm64 \ @@ -24,11 +24,9 @@ dagger run --silent go run ./cmd \ -a docker:grafana:linux/arm/v7 \ --yarn-cache=${YARN_CACHE_FOLDER} \ --checksum \ - --verify \ --build-id=${DRONE_BUILD_NUMBER} \ --grafana-dir=${GRAFANA_DIR} \ --github-token=${GITHUB_TOKEN} \ - --go-version=${GO_VERSION} \ --ubuntu-base=${UBUNTU_BASE} \ --alpine-base=${ALPINE_BASE} \ --destination=${local_dst} > assets.txt @@ -37,4 +35,4 @@ echo "Final list of artifacts:" cat assets.txt # Move the tar.gz packages to their expected locations -cat assets.txt | IS_MAIN=true go run ./scripts/move_packages.go ./dist/main +cat assets.txt | IS_MAIN=true go run ./pkg/build/daggerbuild/scripts/move_packages.go ./dist/main diff --git a/pkg/build/daggerbuild/scripts/drone_build_main_enterprise.sh b/pkg/build/daggerbuild/scripts/drone_build_main_enterprise.sh index b8e88f0c1bf..4e04d60343c 100755 --- a/pkg/build/daggerbuild/scripts/drone_build_main_enterprise.sh +++ b/pkg/build/daggerbuild/scripts/drone_build_main_enterprise.sh @@ -5,7 +5,7 @@ set -e docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --uninstall 'qemu-*' # This command enables qemu emulators for building Docker images for arm64/armv6/armv7/etc on the host. docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --install all -dagger run --silent go run ./cmd \ +dagger run --silent go run ./pkg/build/cmd \ artifacts \ -a targz:enterprise:linux/amd64 \ -a targz:enterprise:linux/arm64 \ @@ -25,7 +25,6 @@ dagger run --silent go run ./cmd \ --grafana-repo="https://github.com/grafana/grafana.git" \ --enterprise-ref=${DRONE_COMMIT} \ --github-token=${GITHUB_TOKEN} \ - --go-version=${GO_VERSION} \ --ubuntu-base=${UBUNTU_BASE} \ --alpine-base=${ALPINE_BASE} \ --patches-repo=${PATCHES_REPO} \ @@ -35,4 +34,4 @@ dagger run --silent go run ./cmd \ cat assets.txt # Move the tar.gz packages to their expected locations -cat assets.txt | DESTINATION=gs://grafana-downloads IS_MAIN=true go run ./scripts/move_packages.go ./dist/main +cat assets.txt | DESTINATION=gs://grafana-downloads IS_MAIN=true go run ./pkg/build/daggerbuild/scripts/move_packages.go ./dist/main diff --git a/pkg/build/daggerbuild/scripts/drone_build_main_pro.sh b/pkg/build/daggerbuild/scripts/drone_build_main_pro.sh index 26f25b234d3..932c6420d08 100755 --- a/pkg/build/daggerbuild/scripts/drone_build_main_pro.sh +++ b/pkg/build/daggerbuild/scripts/drone_build_main_pro.sh @@ -6,7 +6,7 @@ docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --uninstall 'qemu- # This command enables qemu emulators for building Docker images for arm64/armv6/armv7/etc on the host. docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --install all # Build all of the grafana.tar.gz packages. -dagger run --silent go run ./cmd \ +dagger run --silent go run ./pkg/build/cmd \ artifacts \ -a targz:pro:linux/amd64 \ -a targz:pro:linux/arm64 \ @@ -15,13 +15,11 @@ dagger run --silent go run ./cmd \ -a frontend:enterprise \ --yarn-cache=${YARN_CACHE_FOLDER} \ --checksum \ - --verify \ --build-id=${DRONE_BUILD_NUMBER} \ --grafana-ref=${SOURCE_COMMIT} \ --grafana-repo="https://github.com/grafana/grafana.git" \ --enterprise-ref=${DRONE_COMMIT} \ --github-token=${GITHUB_TOKEN} \ - --go-version=${GO_VERSION} \ --ubuntu-base=${UBUNTU_BASE} \ --alpine-base=${ALPINE_BASE} \ --patches-repo=${PATCHES_REPO} \ @@ -30,5 +28,5 @@ dagger run --silent go run ./cmd \ echo "Final list of artifacts:" # Move the tar.gz packages to their expected locations -cat assets.txt | grep -v "public" | DESTINATION=gs://grafana-downloads-enterprise2 IS_MAIN=true go run ./scripts/move_packages.go ./dist/main -cat assets.txt | grep "public" | DESTINATION=gs://grafana-static-assets IS_MAIN=true go run ./scripts/move_packages.go ./dist/cdn +cat assets.txt | grep -v "public" | DESTINATION=gs://grafana-downloads-enterprise2 IS_MAIN=true go run ./pkg/build/daggerbuild/scripts/move_packages.go ./dist/main +cat assets.txt | grep "public" | DESTINATION=gs://grafana-static-assets IS_MAIN=true go run ./pkg/build/daggerbuild/scripts/move_packages.go ./dist/cdn diff --git a/pkg/build/daggerbuild/scripts/drone_build_nightly_enterprise.sh b/pkg/build/daggerbuild/scripts/drone_build_nightly_enterprise.sh index 1ef23dffb2d..2f616bd5055 100755 --- a/pkg/build/daggerbuild/scripts/drone_build_nightly_enterprise.sh +++ b/pkg/build/daggerbuild/scripts/drone_build_nightly_enterprise.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh set -e local_dst="${DRONE_WORKSPACE}/dist" @@ -12,8 +12,8 @@ docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --install all # -a deb:enterprise:linux/arm/v7:nightly \ # -a docker:enterprise:linux/arm/v7 \ # -a docker:enterprise:linux/arm/v7:ubuntu \ - -dagger run --silent go run ./cmd \ + +dagger run --silent go run ./pkg/build/cmd \ artifacts \ -a targz:enterprise:linux/amd64 \ -a targz:enterprise:linux/arm64 \ @@ -38,7 +38,7 @@ dagger run --silent go run ./cmd \ -a docker:enterprise:linux/arm64:ubuntu \ -a docker:enterprise:linux/arm/v7:ubuntu \ --checksum \ - --verify \ + --verify=false \ --build-id=${DRONE_BUILD_NUMBER} \ --grafana-ref=main \ --enterprise-ref=main \ @@ -46,7 +46,6 @@ dagger run --silent go run ./cmd \ --github-token=${GITHUB_TOKEN} \ --destination=${local_dst} \ --yarn-cache=${YARN_CACHE_FOLDER} \ - --go-version=${GO_VERSION} \ --ubuntu-base="${UBUNTU_BASE}" \ --alpine-base="${ALPINE_BASE}" > assets.txt diff --git a/pkg/build/daggerbuild/scripts/drone_build_nightly_grafana.sh b/pkg/build/daggerbuild/scripts/drone_build_nightly_grafana.sh index 96cfcf12c15..495eda0e282 100755 --- a/pkg/build/daggerbuild/scripts/drone_build_nightly_grafana.sh +++ b/pkg/build/daggerbuild/scripts/drone_build_nightly_grafana.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh set -e local_dst="${DRONE_WORKSPACE}/dist" @@ -6,7 +6,7 @@ docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --uninstall 'qemu- # This command enables qemu emulators for building Docker images for arm64/armv6/armv7/etc on the host. docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --install all -dagger run --silent go run ./cmd \ +dagger run --silent go run ./pkg/build/cmd \ artifacts \ -a targz:grafana:linux/amd64 \ -a targz:grafana:linux/arm64 \ @@ -37,7 +37,6 @@ dagger run --silent go run ./cmd \ --github-token=${GITHUB_TOKEN} \ --destination=${local_dst} \ --yarn-cache=${YARN_CACHE_FOLDER} \ - --go-version=${GO_VERSION} \ --ubuntu-base="${UBUNTU_BASE}" \ --alpine-base="${ALPINE_BASE}" > assets.txt diff --git a/pkg/build/daggerbuild/scripts/drone_build_tag_enterprise.sh b/pkg/build/daggerbuild/scripts/drone_build_tag_enterprise.sh index 98c24a6472e..43240ed7bec 100755 --- a/pkg/build/daggerbuild/scripts/drone_build_tag_enterprise.sh +++ b/pkg/build/daggerbuild/scripts/drone_build_tag_enterprise.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh local_dst="dist/${DRONE_BUILD_EVENT}" set -e @@ -7,7 +7,7 @@ docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --uninstall 'qemu- docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --install all # Build all of the grafana.tar.gz packages. -dagger run go run ./cmd \ +dagger run --silent go run ./pkg/build/cmd \ artifacts \ -a targz:enterprise:linux/amd64 \ -a targz:enterprise:linux/arm64 \ @@ -42,11 +42,10 @@ dagger run go run ./cmd \ --grafana-ref=${DRONE_TAG} \ --grafana-repo=https://github.com/grafana/grafana-security-mirror.git \ --github-token=${GITHUB_TOKEN} \ - --go-version=${GO_VERSION} \ --ubuntu-base="${UBUNTU_BASE}" \ --alpine-base="${ALPINE_BASE}" \ --version=${DRONE_TAG} \ --destination=${local_dst} > assets.txt # Move the tar.gz packages to their expected locations -cat assets.txt | go run ./scripts/move_packages.go ./dist/prerelease +cat assets.txt | go run ./pkg/build/daggerbuild/scripts/move_packages.go ./dist/prerelease diff --git a/pkg/build/daggerbuild/scripts/drone_build_tag_grafana.sh b/pkg/build/daggerbuild/scripts/drone_build_tag_grafana.sh index 3d91cbc18ba..e21a705b380 100755 --- a/pkg/build/daggerbuild/scripts/drone_build_tag_grafana.sh +++ b/pkg/build/daggerbuild/scripts/drone_build_tag_grafana.sh @@ -7,7 +7,7 @@ docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --uninstall 'qemu- # This command enables qemu emulators for building Docker images for arm64/armv6/armv7/etc on the host. docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --install all -dagger run --silent go run ./cmd \ +dagger run --silent go run ./pkg/build/cmd \ artifacts \ -a npm:grafana \ -a storybook \ @@ -39,10 +39,9 @@ dagger run --silent go run ./cmd \ --build-id=${DRONE_BUILD_NUMBER} \ --grafana-dir=${GRAFANA_DIR} \ --github-token=${GITHUB_TOKEN} \ - --go-version=${GO_VERSION} \ --ubuntu-base="${UBUNTU_BASE}" \ --alpine-base="${ALPINE_BASE}" \ --version=${DRONE_TAG} \ --destination=${local_dst} > assets.txt -cat assets.txt | go run ./scripts/move_packages.go ./dist/prerelease +cat assets.txt | go run ./pkg/build/daggerbuild/scripts/move_packages.go ./dist/prerelease diff --git a/pkg/build/daggerbuild/scripts/drone_build_tag_pro.sh b/pkg/build/daggerbuild/scripts/drone_build_tag_pro.sh index aa0a3625696..8023e2a0f0c 100755 --- a/pkg/build/daggerbuild/scripts/drone_build_tag_pro.sh +++ b/pkg/build/daggerbuild/scripts/drone_build_tag_pro.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh local_dst="dist/${DRONE_BUILD_EVENT}" set -e @@ -7,7 +7,7 @@ docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --uninstall 'qemu- docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --install all # Build all of the grafana.tar.gz packages. -dagger run --silent go run ./cmd \ +dagger run --silent go run ./pkg/build/cmd \ artifacts \ -a frontend:enterprise \ -a targz:pro:linux/amd64 \ @@ -33,10 +33,9 @@ dagger run --silent go run ./cmd \ --grafana-repo=https://github.com/grafana/grafana-security-mirror.git \ --github-token=${GITHUB_TOKEN} \ --version=${DRONE_TAG} \ - --go-version=${GO_VERSION} \ --ubuntu-base="${UBUNTU_BASE}" \ --alpine-base="${ALPINE_BASE}" \ --destination=${local_dst} > assets.txt # Move the tar.gz packages to their expected locations -cat assets.txt | go run ./scripts/move_packages.go ./dist/prerelease +cat assets.txt | go run ./pkg/build/daggerbuild/scripts/move_packages.go ./dist/prerelease diff --git a/pkg/build/daggerbuild/scripts/drone_publish_nightly_enterprise.sh b/pkg/build/daggerbuild/scripts/drone_publish_nightly_enterprise.sh index 6ae88f85a84..3c7ab2f2e78 100755 --- a/pkg/build/daggerbuild/scripts/drone_publish_nightly_enterprise.sh +++ b/pkg/build/daggerbuild/scripts/drone_publish_nightly_enterprise.sh @@ -1,9 +1,9 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh set -e local_dir="${DRONE_WORKSPACE}/dist" # Publish the docker images present in the bucket -dagger run --silent go run ./cmd docker publish \ +dagger run --silent go run ./pkg/build/cmd docker publish \ $(find $local_dir | grep docker.tar.gz | grep -v sha256 | awk '{print "--package=file://"$0}') \ --username=${DOCKER_USERNAME} \ --password=${DOCKER_PASSWORD} \ @@ -11,13 +11,13 @@ dagger run --silent go run ./cmd docker publish \ --repo="grafana-enterprise-dev" # Publish packages to the downloads bucket -dagger run --silent go run ./cmd package publish \ +dagger run --silent go run ./pkg/build/cmd package publish \ $(find $local_dir | grep -e .rpm -e .tar.gz -e .exe -e .zip -e .deb | awk '{print "--package=file://"$0}') \ --gcp-service-account-key-base64=${GCP_KEY_BASE64} \ --destination="${DOWNLOADS_DESTINATION}/enterprise/release" # Publish packages to grafana.com -dagger run --silent go run ./cmd gcom publish \ +dagger run --silent go run ./pkg/build/cmd gcom publish \ $(find $local_dir | grep -e .rpm -e .tar.gz -e .exe -e .zip -e .deb | grep -v sha256 | grep -v docker | awk '{print "--package=file://"$0}') \ --api-key=${GCOM_API_KEY} \ --api-url="https://grafana.com/api/grafana-enterprise" \ diff --git a/pkg/build/daggerbuild/scripts/drone_publish_nightly_grafana.sh b/pkg/build/daggerbuild/scripts/drone_publish_nightly_grafana.sh index 3d468a06c25..85ef11a1920 100755 --- a/pkg/build/daggerbuild/scripts/drone_publish_nightly_grafana.sh +++ b/pkg/build/daggerbuild/scripts/drone_publish_nightly_grafana.sh @@ -1,43 +1,43 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh set -e # ver=$(cat ${GRAFANA_DIR}/package.json | jq -r .version | sed -E "s/$/-/" | sed -E "s/-.*/-${DRONE_BUILD_NUMBER}/") local_dir="${DRONE_WORKSPACE}/dist" # Publish the docker images present in the bucket -dagger run --silent go run ./cmd docker publish \ +dagger run --silent go run ./pkg/build/cmd docker publish \ $(find $local_dir | grep docker.tar.gz | grep -v sha256 | awk '{print "--package=file://"$0}') \ --username=${DOCKER_USERNAME} \ --password=${DOCKER_PASSWORD} \ --repo="grafana-dev" # Publish packages to the downloads bucket -dagger run --silent go run ./cmd package publish \ +dagger run --silent go run ./pkg/build/cmd package publish \ $(find $local_dir | grep -e .rpm -e .tar.gz -e .exe -e .zip -e .deb | awk '{print "--package=file://"$0}') \ --gcp-service-account-key-base64=${GCP_KEY_BASE64} \ --destination="${DOWNLOADS_DESTINATION}/oss/release" # Publish only the linux/amd64 edition storybook into the storybook bucket -# dagger run --silent go run ./cmd storybook \ +# dagger run --silent go run ./pkg/build/cmd storybook \ # $(find $local_dir | grep tar.gz | grep linux | grep amd64 | grep -v sha256 | grep -v docker | awk '{print "--package=file://"$0}') \ # --gcp-service-account-key-base64=${GCP_KEY_BASE64} \ # --destination="${STORYBOOK_DESTINATION}/${ver}" # # Publish only the linux/amd64 edition static assets into the static assets bucket -# dagger run --silent go run ./cmd cdn \ +# dagger run --silent go run ./pkg/build/cmd cdn \ # $(find $local_dir | grep tar.gz | grep linux | grep amd64 | grep -v sha256 | grep -v docker | awk '{print "--package=file://"$0}') \ # --gcp-service-account-key-base64=${GCP_KEY_BASE64} \ # --destination="${CDN_DESTINATION}/${ver}/public" # Publish only the linux/amd64 edition npm packages to npm -dagger run --silent go run ./cmd npm publish \ +dagger run --silent go run ./pkg/build/cmd npm publish \ $(find $local_dir | grep tar.gz | grep linux | grep amd64 | grep -v sha256 | grep -v docker | awk '{print "--package=file://"$0}') \ --token=${NPM_TOKEN} \ --tag="nightly" # Publish packages to grafana.com -dagger run --silent go run ./cmd gcom publish \ +dagger run --silent go run ./pkg/build/cmd gcom publish \ $(find $local_dir | grep -e .rpm -e .tar.gz -e .exe -e .zip -e .deb | grep -v sha256 | grep -v docker | awk '{print "--package=file://"$0}') \ --api-key=${GCOM_API_KEY} \ --api-url="https://grafana.com/api/grafana" \ --download-url="https://dl.grafana.com/oss/release" \ - --nightly \ No newline at end of file + --nightly diff --git a/pkg/build/e2e-playwright/README.md b/pkg/build/e2e-playwright/README.md new file mode 100644 index 00000000000..d5fc311d696 --- /dev/null +++ b/pkg/build/e2e-playwright/README.md @@ -0,0 +1,22 @@ +# Pa11y accessability tests + +We use pa11y to run some automated simple accessability tests. They're ran with dagger to help orchestrate starting server + tests in a reproducable manner. + +To run the tests locally: + +1. Install dagger locally https://docs.dagger.io/install/ +2. Grab the grafana.tar.gz artifact by either + 1. Downloading it from the Github Action artifact from your PR + 1. Build it locally with: + ```sh + dagger run go run ./pkg/build/cmd artifacts -a targz:grafana:linux/amd64 --grafana-dir="$PWD" > dist/files.txt + cat dist/files.txt # Will output the path to the grafana.tar.gz + ``` +3. Run the dagger pipeline with: + ```sh + dagger -v run go run ./pkg/build/a11y --package=(full path to .tar.gz) --results=./pa11y-ci-results.json + ``` + The JSON results file will be saved to the file from the `--results` arg +4. If they fail and you want to see the full output + 1. Run the dagger command with `dagger -vE [...]` + 2. At the end, arrow up to the exec pa11y-ci segment and hit Enter \ No newline at end of file diff --git a/pkg/build/e2e-playwright/e2e.go b/pkg/build/e2e-playwright/e2e.go new file mode 100644 index 00000000000..35579e8dd2f --- /dev/null +++ b/pkg/build/e2e-playwright/e2e.go @@ -0,0 +1,101 @@ +package main + +import ( + "context" + "fmt" + "strings" + + "dagger.io/dagger" +) + +var ( + // Locations in the container to write results to + testResultsDir = "/playwright-test-results" + htmlResultsDir = "/playwright-html-report" + blobResultsDir = "/playwright-blob-report" +) + +type RunTestOpts struct { + GrafanaService *dagger.Service + FrontendContainer *dagger.Container + HostSrc *dagger.Directory + Shard string + HTMLReportExportDir string + BlobReportExportDir string + TestResultsExportDir string +} + +func RunTest( + ctx context.Context, + d *dagger.Client, + opts RunTestOpts, +) (*dagger.Container, error) { + playwrightCommand := buildPlaywrightCommand(opts) + + e2eContainer := opts.FrontendContainer. + WithWorkdir("/src"). + WithDirectory("/src", opts.HostSrc). + WithMountedCache(".nx", d.CacheVolume("nx-cache")). + WithEnvVariable("HOST", grafanaHost). + WithEnvVariable("PORT", fmt.Sprint(grafanaPort)). + WithServiceBinding(grafanaHost, opts.GrafanaService). + WithEnvVariable("bustcache", "1"). + WithEnvVariable("PLAYWRIGHT_HTML_OPEN", "never"). + WithEnvVariable("PLAYWRIGHT_HTML_OUTPUT_DIR", htmlResultsDir). + WithEnvVariable("PLAYWRIGHT_BLOB_OUTPUT_DIR", blobResultsDir). + WithExec(playwrightCommand, dagger.ContainerWithExecOpts{ + Expect: dagger.ReturnTypeAny, + }) + + if opts.TestResultsExportDir != "" { + _, err := e2eContainer.Directory(testResultsDir).Export(ctx, opts.TestResultsExportDir) + if err != nil { + return nil, err + } + } + + if opts.HTMLReportExportDir != "" { + _, err := e2eContainer.Directory(htmlResultsDir).Export(ctx, opts.HTMLReportExportDir) + if err != nil { + return nil, err + } + } + + if opts.BlobReportExportDir != "" { + _, err := e2eContainer.Directory(blobResultsDir).Export(ctx, opts.BlobReportExportDir) + if err != nil { + return nil, err + } + } + + return e2eContainer, nil +} + +func buildPlaywrightCommand(opts RunTestOpts) []string { + playwrightReporters := []string{ + "dot", // minimal output in shards + } + + if opts.HTMLReportExportDir != "" { + playwrightReporters = append(playwrightReporters, "html") + } + + if opts.BlobReportExportDir != "" { + playwrightReporters = append(playwrightReporters, "blob") + } + + playwrightCommand := []string{ + "yarn", + "e2e:playwright", + "--reporter", + strings.Join(playwrightReporters, ","), + "--output", + testResultsDir, + } + + if opts.Shard != "" { + playwrightCommand = append(playwrightCommand, "--shard", opts.Shard) + } + + return playwrightCommand +} diff --git a/pkg/build/e2e-playwright/frontend.go b/pkg/build/e2e-playwright/frontend.go new file mode 100644 index 00000000000..625ea155ae4 --- /dev/null +++ b/pkg/build/e2e-playwright/frontend.go @@ -0,0 +1,84 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + "dagger.io/dagger" +) + +type Deps struct { + NodeVersion string + PlaywrightVersion string +} + +// Create a container with frontend dependencies installed, ready to build plugins +// or run e2e tests. +// Theoretically we would setup Playwright in e2e.go, but to optimise layer caching +// we want it to happen before yarn install. +func WithFrontendContainer(ctx context.Context, d *dagger.Client, yarnHostSrc *dagger.Directory) (*dagger.Container, error) { + deps, err := GetVersions(ctx, yarnHostSrc) + if err != nil { + return nil, err + } + + nodeBase := WithNode(d, deps.NodeVersion) + playwrightBase := WithPlaywright(d, nodeBase, deps.PlaywrightVersion) + + return WithYarnInstall(d, playwrightBase, yarnHostSrc), nil +} + +func GetVersions(ctx context.Context, src *dagger.Directory) (Deps, error) { + nvmrc, err := src.File(".nvmrc").Contents(ctx) + if err != nil { + return Deps{}, err + } + pkgJSON, err := src.File("package.json").Contents(ctx) + if err != nil { + return Deps{}, err + } + + // parse package.json + var pkgJson struct { + DevDependencies map[string]string `json:"devDependencies"` + } + if err := json.Unmarshal([]byte(pkgJSON), &pkgJson); err != nil { + return Deps{}, err + } + + return Deps{ + NodeVersion: strings.TrimSpace(strings.TrimPrefix(nvmrc, "v")), + PlaywrightVersion: strings.TrimSpace(pkgJson.DevDependencies["@playwright/test"]), + }, nil +} + +func WithNode(d *dagger.Client, version string) *dagger.Container { + nodeImage := fmt.Sprintf("node:%s-slim", strings.TrimPrefix(version, "v")) + return d.Container().From(nodeImage) +} + +func WithPlaywright(d *dagger.Client, base *dagger.Container, version string) *dagger.Container { + brCache := d.CacheVolume("playwright-browsers") + return base. + WithEnvVariable("PLAYWRIGHT_BROWSERS_PATH", "/playwright-cache"). + WithMountedCache("/playwright-cache", brCache). + WithExec([]string{"npx", "-y", "playwright@" + version, "install", "--with-deps"}) +} + +func WithYarnInstall(d *dagger.Client, base *dagger.Container, yarnHostSrc *dagger.Directory) *dagger.Container { + yarnCache := d.CacheVolume("yarn-cache") + + return base. + WithWorkdir("/src"). + WithMountedCache("/.yarn", yarnCache). + WithEnvVariable("YARN_CACHE_FOLDER", "/.yarn"). + WithEnvVariable("CYPRESS_INSTALL_BINARY", "0"). // Don't download Cypress binaries + + // It's important to copy all files here because the whole src directory is then copied into the test runner container + WithDirectory("/src", yarnHostSrc). + WithExec([]string{"corepack", "enable"}). + WithExec([]string{"corepack", "install"}). + WithExec([]string{"yarn", "install", "--immutable"}) +} diff --git a/pkg/build/e2e-playwright/main.go b/pkg/build/e2e-playwright/main.go new file mode 100644 index 00000000000..09384c8614b --- /dev/null +++ b/pkg/build/e2e-playwright/main.go @@ -0,0 +1,243 @@ +package main + +import ( + "context" + "fmt" + "log" + "os" + "os/signal" + + "dagger.io/dagger" + "github.com/urfave/cli/v3" +) + +var ( + grafanaHost = "grafana" + grafanaPort = 3001 +) + +func main() { + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) + defer cancel() + + if err := NewApp().Run(ctx, os.Args); err != nil { + cancel() + fmt.Println(err) + os.Exit(1) + } +} + +func NewApp() *cli.Command { + return &cli.Command{ + Name: "a11y", + Usage: "Run Grafana playwright e2e tests", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "grafana-dir", + Usage: "Path to the grafana/grafana clone directory", + Value: ".", + Validator: mustBeDir("grafana-dir", false, false), + TakesFile: true, + }, + &cli.StringFlag{ + Name: "package", + Usage: "Path to the grafana tar.gz package", + Value: "grafana.tar.gz", + Validator: mustBeFile("package", false), + TakesFile: true, + }, + &cli.StringFlag{ + Name: "license", + Usage: "Path to the Grafana Enterprise license file (optional)", + Validator: mustBeFile("license", true), + TakesFile: true, + }, + &cli.StringFlag{ + Name: "shard", + Usage: "Test shard to run. See Playwright docs", + }, + &cli.StringFlag{ + Name: "results-dir", + Usage: "Path to the directory to export the playwright test results to (optional)", + Validator: mustBeDir("results-dir", true, true), + }, + &cli.StringFlag{ + Name: "html-dir", + Usage: "Enables the HTML reporter, exported to this directory (optional)", + Validator: mustBeDir("html-dir", true, true), + }, + &cli.StringFlag{ + Name: "blob-dir", + Usage: "Enables the blob reporter, exported to this directory. Useful with --shard (optional)", + Validator: mustBeDir("blob-dir", true, true), + }, + }, + Action: run, + } +} + +func run(ctx context.Context, cmd *cli.Command) error { + grafanaDir := cmd.String("grafana-dir") + targzPath := cmd.String("package") + licensePath := cmd.String("license") + pwShard := cmd.String("shard") + resultsDir := cmd.String("results-dir") + htmlDir := cmd.String("html-dir") + blobDir := cmd.String("blob-dir") + // pa11yConfigPath := cmd.String("config") + // pa11yResultsPath := cmd.String("results") + // noThresholdFail := cmd.Bool("no-threshold-fail") + + d, err := dagger.Connect(ctx) + if err != nil { + return fmt.Errorf("failed to connect to Dagger: %w", err) + } + + // Explicitly only the files used by the grafana-server service + grafanaHostSrc := d.Host().Directory(grafanaDir, dagger.HostDirectoryOpts{ + Include: []string{ + "./devenv", + + // Must build test plugins to run e2e tests + "./e2e-playwright/test-plugins", + "./packages/grafana-plugin-configs", + + "./scripts/grafana-server/custom.ini", + "./scripts/grafana-server/start-server", + "./scripts/grafana-server/kill-server", + "./scripts/grafana-server/variables", + }, + }) + + // Minimal files needed to run yarn install + yarnHostSrc := d.Host().Directory(grafanaDir, dagger.HostDirectoryOpts{ + Include: []string{ + "package.json", + "yarn.lock", + ".yarnrc.yml", + ".yarn", + "packages/*/package.json", + "packages/grafana-plugin-configs", + "public/app/plugins/*/*/package.json", + "e2e-playwright/test-plugins/*/package.json", + ".nvmrc", + }, + }) + + // Files needed to run e2e tests. yarnHostSrc will be copied into the test runner container as well. + e2eHostSrc := d.Host().Directory(".", dagger.HostDirectoryOpts{ + Include: []string{ + "public/app/types/*.d.ts", + "public/app/core/icons/cached.json", + + // packages we use in playwright tests + "packages", // TODO: do we need all of this? + "public/app/plugins", // TODO: do we need all of this? + + // e2e files + "e2e-playwright", + "e2e-playwright/test-plugins", + "playwright.config.ts", + }, + Exclude: []string{ + "**/dist", + }, + }) + + frontendContainer, err := WithFrontendContainer(ctx, d, yarnHostSrc) + if err != nil { + return fmt.Errorf("failed to create frontend container: %w", err) + } + + targz := d.Host().File(targzPath) + + var license *dagger.File + if licensePath != "" { + license = d.Host().File(licensePath) + } + + svc, err := GrafanaService(ctx, d, GrafanaServiceOpts{ + HostSrc: grafanaHostSrc, + FrontendContainer: frontendContainer, + GrafanaTarGz: targz, + License: license, + }) + if err != nil { + return fmt.Errorf("failed to create Grafana service: %w", err) + } + + runOpts := RunTestOpts{ + GrafanaService: svc, + FrontendContainer: frontendContainer, + HostSrc: e2eHostSrc, + Shard: pwShard, + TestResultsExportDir: resultsDir, + HTMLReportExportDir: htmlDir, + BlobReportExportDir: blobDir, + } + + c, runErr := RunTest(ctx, d, runOpts) + if runErr != nil { + return fmt.Errorf("failed to run e2e test suite: %w", runErr) + } + + c, syncErr := c.Sync(ctx) + if syncErr != nil { + return fmt.Errorf("failed to sync e2e test suite: %w", syncErr) + } + + code, codeErr := c.ExitCode(ctx) + if codeErr != nil { + return fmt.Errorf("failed to get exit code of e2e test suite: %w", codeErr) + } + + if code == 0 { + log.Printf("e2e tests passed with exit code %d", code) + } else { + return fmt.Errorf("e2e tests failed with exit code %d", code) + } + + log.Println("e2e tests completed successfully") + return nil +} + +func mustBeFile(arg string, emptyOk bool) func(string) error { + return func(s string) error { + if s == "" { + if emptyOk { + return nil + } + return cli.Exit(arg+" cannot be empty", 1) + } + stat, err := os.Stat(s) + if err != nil { + return cli.Exit(arg+" does not exist or cannot be read: "+s, 1) + } + if stat.IsDir() { + return cli.Exit(arg+" must be a file, not a directory: "+s, 1) + } + return nil + } +} + +func mustBeDir(arg string, emptyOk bool, notExistOk bool) func(string) error { + return func(s string) error { + if s == "" { + if emptyOk { + return nil + } + return cli.Exit(arg+" cannot be empty", 1) + } + stat, err := os.Stat(s) + if err != nil { + if notExistOk { + return nil + } + return cli.Exit(arg+" does not exist or cannot be read: "+s, 1) + } + if !stat.IsDir() { + return cli.Exit(arg+" must be a directory: "+s, 1) + } + return nil + } +} diff --git a/pkg/build/e2e-playwright/service.go b/pkg/build/e2e-playwright/service.go new file mode 100644 index 00000000000..d162451ef70 --- /dev/null +++ b/pkg/build/e2e-playwright/service.go @@ -0,0 +1,58 @@ +package main + +import ( + "context" + "fmt" + "os" + "strings" + + "dagger.io/dagger" +) + +type GrafanaServiceOpts struct { + HostSrc *dagger.Directory + FrontendContainer *dagger.Container + GrafanaTarGz *dagger.File + License *dagger.File +} + +func GrafanaService(ctx context.Context, d *dagger.Client, opts GrafanaServiceOpts) (*dagger.Service, error) { + testPlugins := opts.FrontendContainer. + WithDirectory("e2e-playwright/test-plugins", opts.HostSrc.Directory("./e2e-playwright/test-plugins")). + WithDirectory("packages/grafana-plugin-configs", opts.HostSrc.Directory("./packages/grafana-plugin-configs")). + WithExec([]string{"yarn", "e2e:plugin:build"}) + + container := d.Container().From("alpine:3"). + WithExec([]string{"apk", "add", "--no-cache", "bash", "tar", "netcat-openbsd", "util-linux"}). + WithMountedFile("/src/grafana.tar.gz", opts.GrafanaTarGz). + WithExec([]string{"mkdir", "-p", "/src/grafana"}). + WithExec([]string{"tar", "--strip-components=1", "-xzf", "/src/grafana.tar.gz", "-C", "/src/grafana"}). + WithDirectory("/src/grafana/devenv", opts.HostSrc.Directory("./devenv")). + WithDirectory("/src/grafana/e2e-playwright/test-plugins", testPlugins.Directory("./e2e-playwright/test-plugins")). + WithDirectory("/src/grafana/scripts", opts.HostSrc.Directory("./scripts")). + WithWorkdir("/src/grafana"). + // Only set config variables here that are specific to the dagger/GHA runner. + // Prefer to configure scripts/grafana-server/custom.ini instead so they're also used + // when running locally. + WithEnvVariable("GF_SERVER_HTTP_PORT", fmt.Sprint(grafanaPort)). + WithExposedPort(grafanaPort) + + var licenseArg string + if opts.License != nil { + licenseArg = "/src/license.jwt" + container = container.WithMountedFile(licenseArg, opts.License) + } + + // We add all GF_ environment variables to allow for overriding Grafana configuration. + // It is unlikely the runner has any such otherwise. + for _, env := range os.Environ() { + if strings.HasPrefix(env, "GF_") { + parts := strings.SplitN(env, "=", 2) + container = container.WithEnvVariable(parts[0], parts[1]) + } + } + + svc := container.AsService(dagger.ContainerAsServiceOpts{Args: []string{"bash", "scripts/grafana-server/start-server", licenseArg}}) + + return svc, nil +} diff --git a/pkg/build/e2e/main.go b/pkg/build/e2e/main.go index 8ce20b66864..9bc35151de8 100644 --- a/pkg/build/e2e/main.go +++ b/pkg/build/e2e/main.go @@ -2,74 +2,173 @@ package main import ( "context" - "flag" "fmt" "log" "os" - "path/filepath" + "os/signal" + "path" "dagger.io/dagger" + "github.com/urfave/cli/v3" ) func main() { - var ( - ctx = context.Background() - grafanaPath = flag.String("grafana-dir", ".", "Path to cloned grafana repo") - targzPath = flag.String("package", "grafana.tar.gz", "Path to grafana tar.gz package") - suite = flag.String("suite", "", "e2e suite name (used in arg to run-suite script)") - ) - flag.Parse() + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) + defer cancel() + + if err := NewApp().Run(ctx, os.Args); err != nil { + cancel() + fmt.Println(err) + os.Exit(1) + } +} + +func NewApp() *cli.Command { + return &cli.Command{ + Name: "e2e", + Usage: "Run the E2E tests for Grafana", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "suite", + Usage: "E2E test suite path (e.g. e2e/various-suite)", + Validator: mustBeDir("suite"), + TakesFile: true, + Required: true, + }, + + &cli.StringFlag{ + Name: "grafana-dir", + Usage: "Path to the grafana/grafana clone directory", + Value: ".", + Validator: mustBeDir("grafana-dir"), + TakesFile: true, + }, + &cli.StringFlag{ + Name: "package", + Usage: "Path to the grafana tar.gz package", + Value: "grafana.tar.gz", + Validator: mustBeFile("package", false), + TakesFile: true, + }, + &cli.StringFlag{ + Name: "license", + Usage: "Path to the Grafana Enterprise license file (optional)", + Validator: mustBeFile("license", true), + TakesFile: true, + }, + &cli.StringFlag{ + Name: "flags", + Usage: "Flags to pass through to the e2e runner", + }, + &cli.BoolFlag{ + Name: "image-renderer", + Usage: "Install the image renderer plugin", + Value: false, + }, + }, + Action: run, + } +} + +func run(ctx context.Context, cmd *cli.Command) error { + grafanaDir := cmd.String("grafana-dir") + suite := cmd.String("suite") + targzPath := cmd.String("package") + licensePath := cmd.String("license") + imageRenderer := cmd.Bool("image-renderer") + runnerFlags := cmd.String("flags") d, err := dagger.Connect(ctx) if err != nil { - panic(err) + return fmt.Errorf("failed to connect to Dagger: %w", err) } yarnCache := d.CacheVolume("yarn") - log.Println("grafana dir:", *grafanaPath) - log.Println("targz:", *targzPath) + log.Println("grafana dir:", grafanaDir) + log.Println("targz:", targzPath) + log.Println("license path:", licensePath) grafana := d.Host().Directory(".", dagger.HostDirectoryOpts{ - Exclude: []string{".git", "node_modules", "*.tar.gz"}, + Exclude: []string{"node_modules", "*.tar.gz"}, }) + targz := d.Host().File(targzPath) - targz := d.Host().File("grafana.tar.gz") - - svc, err := GrafanaService(ctx, d, GrafanaServiceOpts{ - GrafanaDir: grafana, - GrafanaTarGz: targz, - YarnCache: yarnCache, - }) - if err != nil { - panic(err) + var license *dagger.File + if licensePath != "" { + license = d.Host().File(licensePath) } - // Extract just the suite name from the path (e.g., "e2e/dashboards-suite" -> "dashboards-suite") - suiteName := filepath.Base(*suite) - videosDir := fmt.Sprintf("/src/e2e/%s/videos", suiteName) + svc, err := GrafanaService(ctx, d, GrafanaServiceOpts{ + GrafanaDir: grafana, + GrafanaTarGz: targz, + YarnCache: yarnCache, + License: license, + InstallImageRenderer: imageRenderer, + }) + if err != nil { + return fmt.Errorf("failed to create Grafana service: %w", err) + } + + videosDir := path.Join("/src", suite, "videos") // *spec.ts.mp4 - c := RunSuite(d, svc, grafana, yarnCache, suiteName) + c := RunSuite(d, svc, grafana, yarnCache, suite, runnerFlags) c, err = c.Sync(ctx) if err != nil { - log.Fatalf("error running dagger: %s", err) + return fmt.Errorf("failed to run e2e test suite: %w", err) } code, err := c.ExitCode(ctx) if err != nil { - log.Fatalf("error getting exit code: %s", err) + return fmt.Errorf("failed to get exit code of e2e test suite: %w", err) } log.Println("exit code:", code) // No sync error; export the videos dir if _, err := c.Directory(videosDir).Export(ctx, "videos"); err != nil { - log.Fatalf("error getting videos: %s", err) + return fmt.Errorf("failed to export videos directory: %w", err) } if code != 0 { - log.Printf("tests failed: exit code %d", code) + return fmt.Errorf("e2e tests failed with exit code %d", code) } - os.Exit(code) + log.Println("e2e tests completed successfully") + return nil +} + +func mustBeFile(arg string, emptyOk bool) func(string) error { + return func(s string) error { + if s == "" { + if emptyOk { + return nil + } + return cli.Exit(arg+" cannot be empty", 1) + } + stat, err := os.Stat(s) + if err != nil { + return cli.Exit(arg+" does not exist or cannot be read: "+s, 1) + } + if stat.IsDir() { + return cli.Exit(arg+" must be a file, not a directory: "+s, 1) + } + return nil + } +} + +func mustBeDir(arg string) func(string) error { + return func(s string) error { + if s == "" { + return cli.Exit(arg+" cannot be empty", 1) + } + stat, err := os.Stat(s) + if err != nil { + return cli.Exit(arg+" does not exist or cannot be read: "+s, 1) + } + if !stat.IsDir() { + return cli.Exit(arg+" must be a directory: "+s, 1) + } + return nil + } } diff --git a/pkg/build/e2e/run.go b/pkg/build/e2e/run.go index d1577576e97..e5d36d34b7b 100644 --- a/pkg/build/e2e/run.go +++ b/pkg/build/e2e/run.go @@ -6,17 +6,14 @@ import ( "dagger.io/dagger" ) -func RunSuite(d *dagger.Client, svc *dagger.Service, src *dagger.Directory, cache *dagger.CacheVolume, suite string) *dagger.Container { +func RunSuite(d *dagger.Client, svc *dagger.Service, src *dagger.Directory, cache *dagger.CacheVolume, suite, runnerFlags string) *dagger.Container { + command := fmt.Sprintf( + "./e2e-runner cypress --start-grafana=false --cypress-video"+ + " --grafana-base-url http://grafana:3001 --suite %s %s", suite, runnerFlags) + return WithYarnCache(WithGrafanaFrontend(d.Container().From("cypress/included:13.1.0"), src), cache). WithWorkdir("/src"). - WithEnvVariable("HOST", "grafana"). - WithEnvVariable("PORT", "3001"). WithServiceBinding("grafana", svc). WithExec([]string{"yarn", "install", "--immutable"}). - WithExec([]string{ - "/bin/bash", "-c", - fmt.Sprintf("./e2e/run-suite %s true", suite), - }, dagger.ContainerWithExecOpts{ - Expect: dagger.ReturnTypeAny, - }) + WithExec([]string{"/bin/bash", "-c", command}, dagger.ContainerWithExecOpts{Expect: dagger.ReturnTypeAny}) } diff --git a/pkg/build/e2e/service.go b/pkg/build/e2e/service.go index 04ddbf10f7b..5c6eb0c4e78 100644 --- a/pkg/build/e2e/service.go +++ b/pkg/build/e2e/service.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "log" + "os" "strings" "dagger.io/dagger" @@ -22,9 +23,11 @@ func NodeImage(version string) string { } type GrafanaServiceOpts struct { - GrafanaDir *dagger.Directory - GrafanaTarGz *dagger.File - YarnCache *dagger.CacheVolume + GrafanaDir *dagger.Directory + GrafanaTarGz *dagger.File + YarnCache *dagger.CacheVolume + License *dagger.File + InstallImageRenderer bool } func Frontend(src *dagger.Directory) *dagger.Directory { @@ -71,21 +74,45 @@ func GrafanaService(ctx context.Context, d *dagger.Client, opts GrafanaServiceOp WithExec([]string{"yarn", "install", "--immutable"}). WithExec([]string{"yarn", "e2e:plugin:build"}) - svc := d.Container().From("alpine"). - WithExec([]string{"apk", "add", "bash"}). + // _/ubuntu:latest sticks to latest LTS. + // We need ubuntu to support the image renderer plugin, which assumes glibc. + container := d.Container().From("ubuntu:latest"). WithMountedFile("/src/grafana.tar.gz", opts.GrafanaTarGz). WithExec([]string{"mkdir", "-p", "/src/grafana"}). WithExec([]string{"tar", "--strip-components=1", "-xzf", "/src/grafana.tar.gz", "-C", "/src/grafana"}). WithDirectory("/src/grafana/devenv", src.Directory("/src/devenv")). WithDirectory("/src/grafana/e2e", src.Directory("/src/e2e")). + WithDirectory("/src/grafana/e2e-playwright/test-plugins", src.Directory("/src/e2e-playwright/test-plugins")). WithDirectory("/src/grafana/scripts", src.Directory("/src/scripts")). WithDirectory("/src/grafana/tools", src.Directory("/src/tools")). WithWorkdir("/src/grafana"). WithEnvVariable("GF_APP_MODE", "development"). WithEnvVariable("GF_SERVER_HTTP_PORT", "3001"). WithEnvVariable("GF_SERVER_ROUTER_LOGGING", "1"). - WithExposedPort(3001). - AsService(dagger.ContainerAsServiceOpts{Args: []string{"bash", "-x", "scripts/grafana-server/start-server"}}) + WithExposedPort(3001) + + var licenseArg string + if opts.License != nil { + container = container.WithMountedFile("/src/license.jwt", opts.License) + licenseArg = "/src/license.jwt" + } + + if opts.InstallImageRenderer { + container = container.WithEnvVariable("INSTALL_IMAGE_RENDERER", "true"). + WithExec([]string{"apt-get", "update"}). + WithExec([]string{"apt-get", "install", "-y", "ca-certificates"}) + } + + // We add all GF_ environment variables to allow for overriding Grafana configuration. + // It is unlikely the runner has any such otherwise. + for _, env := range os.Environ() { + if strings.HasPrefix(env, "GF_") { + parts := strings.SplitN(env, "=", 2) + container = container.WithEnvVariable(parts[0], parts[1]) + } + } + + svc := container.AsService(dagger.ContainerAsServiceOpts{Args: []string{"bash", "-x", "scripts/grafana-server/start-server", licenseArg}}) return svc, nil } diff --git a/pkg/build/go.mod b/pkg/build/go.mod index f7782b13cec..514f105fb0b 100644 --- a/pkg/build/go.mod +++ b/pkg/build/go.mod @@ -8,9 +8,9 @@ go 1.24.4 replace github.com/docker/docker => github.com/moby/moby v27.5.1+incompatible require ( - cloud.google.com/go/storage v1.50.0 // @grafana/grafana-backend-group + cloud.google.com/go/storage v1.52.0 // @grafana/grafana-backend-group github.com/Masterminds/semver/v3 v3.3.1 // @grafana/grafana-developer-enablement-squad - github.com/aws/aws-sdk-go v1.55.6 // @grafana/aws-datasources + github.com/aws/aws-sdk-go v1.55.7 // @grafana/aws-datasources github.com/docker/docker v28.1.1+incompatible // @grafana/grafana-developer-enablement-squad github.com/drone/drone-cli v1.8.0 // @grafana/grafana-developer-enablement-squad github.com/gogo/protobuf v1.3.2 // indirect; @grafana/alerting-backend @@ -22,27 +22,27 @@ require ( github.com/urfave/cli v1.22.16 // @grafana/grafana-backend-group github.com/urfave/cli/v2 v2.27.6 // @grafana/grafana-backend-group go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect; @grafana/plugins-platform-backend - go.opentelemetry.io/otel v1.35.0 // @grafana/grafana-backend-group - go.opentelemetry.io/otel/sdk v1.35.0 // indirect; @grafana/grafana-backend-group - go.opentelemetry.io/otel/trace v1.35.0 // @grafana/grafana-backend-group - golang.org/x/crypto v0.38.0 // indirect; @grafana/grafana-backend-group - golang.org/x/net v0.40.0 // indirect; @grafana/oss-big-tent @grafana/partner-datasources - golang.org/x/oauth2 v0.29.0 // @grafana/identity-access-team - golang.org/x/sync v0.14.0 // @grafana/alerting-backend - golang.org/x/text v0.25.0 // indirect; @grafana/grafana-backend-group + go.opentelemetry.io/otel v1.36.0 // @grafana/grafana-backend-group + go.opentelemetry.io/otel/sdk v1.36.0 // indirect; @grafana/grafana-backend-group + go.opentelemetry.io/otel/trace v1.36.0 // @grafana/grafana-backend-group + golang.org/x/crypto v0.39.0 // indirect; @grafana/grafana-backend-group + golang.org/x/net v0.41.0 // indirect; @grafana/oss-big-tent @grafana/partner-datasources + golang.org/x/oauth2 v0.30.0 // @grafana/identity-access-team + golang.org/x/sync v0.15.0 // @grafana/alerting-backend + golang.org/x/text v0.26.0 // indirect; @grafana/grafana-backend-group golang.org/x/time v0.11.0 // indirect; @grafana/grafana-backend-group - google.golang.org/api v0.223.0 // @grafana/grafana-backend-group - google.golang.org/grpc v1.72.1 // indirect; @grafana/plugins-platform-backend + google.golang.org/api v0.233.0 // @grafana/grafana-backend-group + google.golang.org/grpc v1.73.0 // indirect; @grafana/plugins-platform-backend google.golang.org/protobuf v1.36.6 // indirect; @grafana/plugins-platform-backend gopkg.in/yaml.v3 v3.0.1 // @grafana/alerting-backend ) require ( - cloud.google.com/go v0.118.2 // indirect - cloud.google.com/go/auth v0.15.0 // indirect - cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect + cloud.google.com/go v0.120.0 // indirect + cloud.google.com/go/auth v0.16.1 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.6.0 // indirect - cloud.google.com/go/iam v1.3.1 // indirect + cloud.google.com/go/iam v1.5.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/buildkite/yaml v2.1.0+incompatible // indirect @@ -60,18 +60,18 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/s2a-go v0.1.9 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect - go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel/metric v1.36.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect golang.org/x/sys v0.33.0 // indirect - google.golang.org/genproto v0.0.0-20250122153221-138b5a5a4fd4 // indirect; @grafana/grafana-backend-group + google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect; @grafana/grafana-backend-group google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect @@ -82,21 +82,22 @@ require ( github.com/Masterminds/semver v1.5.0 github.com/google/go-github/v70 v70.0.0 github.com/quasilyte/go-ruleguard/dsl v0.3.22 + github.com/urfave/cli/v3 v3.3.3 ) require ( cel.dev/expr v0.23.1 // indirect - cloud.google.com/go/monitoring v1.23.0 // indirect + cloud.google.com/go/monitoring v1.24.0 // indirect github.com/99designs/gqlgen v0.17.73 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.49.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect github.com/Khan/genqlient v0.8.1 // indirect github.com/adrg/xdg v0.5.3 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cenkalti/backoff/v5 v5.0.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 // indirect + github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect github.com/containerd/log v0.1.0 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect @@ -114,17 +115,18 @@ require ( github.com/vektah/gqlparser/v2 v2.5.27 // indirect github.com/zeebo/errs v1.4.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/detectors/gcp v1.34.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.11.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.11.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.35.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 // indirect - go.opentelemetry.io/otel/log v0.11.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.11.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect + go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 // indirect + go.opentelemetry.io/otel/log v0.12.2 // indirect + go.opentelemetry.io/otel/sdk/log v0.12.2 // indirect + go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect go.opentelemetry.io/proto/otlp v1.6.0 // indirect gotest.tools/v3 v3.5.1 // indirect ) @@ -137,6 +139,3 @@ replace github.com/crewjam/saml => github.com/grafana/saml v0.4.15-0.20240523142 replace github.com/prometheus/alertmanager => github.com/grafana/prometheus-alertmanager v0.25.1-0.20240625192351-66ec17e3aa45 exclude github.com/mattn/go-sqlite3 v2.0.3+incompatible - -// Use our fork xorm. go.work currently overrides this and points to the local ./pkg/util/xorm directory. -replace xorm.io/xorm => github.com/grafana/grafana/pkg/util/xorm v0.0.1 diff --git a/pkg/build/go.sum b/pkg/build/go.sum index 69f82631a4b..8c8edfafedd 100644 --- a/pkg/build/go.sum +++ b/pkg/build/go.sum @@ -1,24 +1,24 @@ cel.dev/expr v0.23.1 h1:K4KOtPCJQjVggkARsjG9RWXP6O4R73aHeJMa/dmCQQg= cel.dev/expr v0.23.1/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.118.2 h1:bKXO7RXMFDkniAAvvuMrAPtQ/VHrs9e7J5UT3yrGdTY= -cloud.google.com/go v0.118.2/go.mod h1:CFO4UPEPi8oV21xoezZCrd3d81K4fFkDTEJu4R8K+9M= -cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps= -cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8= -cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M= -cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= +cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA= +cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= +cloud.google.com/go/auth v0.16.1 h1:XrXauHMd30LhQYVRHLGvJiYeczweKQXZxsTbV9TiguU= +cloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= -cloud.google.com/go/iam v1.3.1 h1:KFf8SaT71yYq+sQtRISn90Gyhyf4X8RGgeAVC8XGf3E= -cloud.google.com/go/iam v1.3.1/go.mod h1:3wMtuyT4NcbnYNPLMBzYRFiEfjKfJlLVLrisE7bwm34= +cloud.google.com/go/iam v1.5.0 h1:QlLcVMhbLGOjRcGe6VTGGTyQib8dRLK2B/kYNV0+2xs= +cloud.google.com/go/iam v1.5.0/go.mod h1:U+DOtKQltF/LxPEtcDLoobcsZMilSRwR7mgNL7knOpo= cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc= cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA= -cloud.google.com/go/longrunning v0.6.4 h1:3tyw9rO3E2XVXzSApn1gyEEnH2K9SynNQjMlBi3uHLg= -cloud.google.com/go/longrunning v0.6.4/go.mod h1:ttZpLCe6e7EXvn9OxpBRx7kZEB0efv8yBO6YnVMfhJs= -cloud.google.com/go/monitoring v1.23.0 h1:M3nXww2gn9oZ/qWN2bZ35CjolnVHM3qnSbu6srCPgjk= -cloud.google.com/go/monitoring v1.23.0/go.mod h1:034NnlQPDzrQ64G2Gavhl0LUHZs9H3rRmhtnp7jiJgg= -cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs= -cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY= +cloud.google.com/go/longrunning v0.6.6 h1:XJNDo5MUfMM05xK3ewpbSdmt7R2Zw+aQEMbdQR65Rbw= +cloud.google.com/go/longrunning v0.6.6/go.mod h1:hyeGJUrPHcx0u2Uu1UFSoYZLn4lkMrccJig0t4FI7yw= +cloud.google.com/go/monitoring v1.24.0 h1:csSKiCJ+WVRgNkRzzz3BPoGjFhjPY23ZTcaenToJxMM= +cloud.google.com/go/monitoring v1.24.0/go.mod h1:Bd1PRK5bmQBQNnuGwHBfUamAV1ys9049oEPHnn4pcsc= +cloud.google.com/go/storage v1.52.0 h1:ROpzMW/IwipKtatA69ikxibdzQSiXJrY9f6IgBa9AlA= +cloud.google.com/go/storage v1.52.0/go.mod h1:4wrBAbAYUvYkbrf19ahGm4I5kDQhESSqN3CGEkMGvOY= cloud.google.com/go/trace v1.11.3 h1:c+I4YFjxRQjvAhRmSsmjpASUKq88chOX854ied0K/pE= cloud.google.com/go/trace v1.11.3/go.mod h1:pt7zCYiDSQjC9Y2oqCsh9jF4GStB/hmjrYLsxRR27q8= dagger.io/dagger v0.18.8 h1:k3+DvD93Fy5SKijuPqFGvnQIBdJQJdfZtrGp4rqU1Xg= @@ -32,14 +32,14 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0 h1:f2Qw/Ehhimh5uO1fayV0QIW7DShEQqhtUfhYc+cBPlw= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0/go.mod h1:2bIszWvQRlJVmJLiuLhukLImRjKPcYdzzsx6darK02A= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0 h1:o90wcURuxekmXrtxmYWTyNla0+ZEHhud6DI1ZTxd1vI= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0/go.mod h1:6fTWu4m3jocfUZLYF5KsZC1TUfRvEjs7lM4crme/irw= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.49.0 h1:jJKWl98inONJAr/IZrdFQUWcwUO95DLY1XMD1ZIut+g= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.49.0/go.mod h1:l2fIqmwB+FKSfvn3bAD/0i+AXAxhIZjTK2svT/mgUXs= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.49.0 h1:GYUJLfvd++4DMuMhCFLgLXvFwofIxh/qOwoGuS/LTew= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.49.0/go.mod h1:wRbFgBQUVm1YXrvWKofAEmq9HNJTDphbAaJSSX01KUI= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0 h1:OqVGm6Ei3x5+yZmSJG1Mh2NwHvpVmZ08CB5qJhT9Nuk= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0/go.mod h1:SZiPHWGOOk3bl8tkevxkoiwPgsIl6CwrWcbwjfHZpdM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs= github.com/Khan/genqlient v0.8.1/go.mod h1:R2G6DzjBvCbhjsEajfRjbWdVglSH/73kSivC9TLWVjU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= @@ -55,15 +55,15 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk= -github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= github.com/buildkite/yaml v2.1.0+incompatible h1:xirI+ql5GzfikVNDmt+yeiXpf/v1Gt03qXTtT5WXdr8= github.com/buildkite/yaml v2.1.0+incompatible/go.mod h1:UoU8vbcwu1+vjZq01+KrpSeLBgQQIjL/H7Y6KwikUrI= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= +github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -72,8 +72,8 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 h1:Om6kYQYDUk5wWbT0t0q6pvyM49i9XZAv9dDrkDA7gjk= -github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k= +github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= @@ -166,8 +166,8 @@ github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= -github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= @@ -251,6 +251,8 @@ github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ= github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g= github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= +github.com/urfave/cli/v3 v3.3.3 h1:byCBaVdIXuLPIDm5CYZRVG6NvT7tv1ECqdU4YzlEa3I= +github.com/urfave/cli/v3 v3.3.3/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo= github.com/vektah/gqlparser/v2 v2.5.27 h1:RHPD3JOplpk5mP5JGX8RKZkt2/Vwj/PZv0HxTdwFp0s= github.com/vektah/gqlparser/v2 v2.5.27/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= @@ -261,42 +263,44 @@ github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/detectors/gcp v1.34.0 h1:JRxssobiPg23otYU5SbWtQC//snGVIM3Tx6QRzlQBao= -go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo= +go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF2rS0bdD3aJYEnmzA= +go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= -go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= -go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.11.0 h1:HMUytBT3uGhPKYY/u/G5MR9itrlSO2SMOsSD3Tk3k7A= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.11.0/go.mod h1:hdDXsiNLmdW/9BF2jQpnHHlhFajpWCEYfM6e5m2OAZg= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.11.0 h1:C/Wi2F8wEmbxJ9Kuzw/nhP+Z9XaHYMkyDmXy6yR2cjw= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.11.0/go.mod h1:0Lr9vmGKzadCTgsiBydxr6GEZ8SsZ7Ks53LzjWG5Ar4= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 h1:QcFwRrZLc82r8wODjvyCbP7Ifp3UANaBSmhDSFjnqSc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0/go.mod h1:CXIWhUomyWBG/oY2/r/kLp6K/cmx9e/7DLpBuuGdLCA= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.35.0 h1:0NIXxOCFx+SKbhCVxwl3ETG8ClLPAa0KuKV6p3yhxP8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.35.0/go.mod h1:ChZSJbbfbl/DcRZNc9Gqh6DYGlfjw4PvO1pEOZH1ZsE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= -go.opentelemetry.io/otel/log v0.11.0 h1:c24Hrlk5WJ8JWcwbQxdBqxZdOK7PcP/LFtOtwpDTe3Y= -go.opentelemetry.io/otel/log v0.11.0/go.mod h1:U/sxQ83FPmT29trrifhQg+Zj2lo1/IPN1PF6RTFqdwc= -go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= -go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= -go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= -go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= -go.opentelemetry.io/otel/sdk/log v0.11.0 h1:7bAOpjpGglWhdEzP8z0VXc4jObOiDEwr3IYbhBnjk2c= -go.opentelemetry.io/otel/sdk/log v0.11.0/go.mod h1:dndLTxZbwBstZoqsJB3kGsRPkpAgaJrWfQg3lhlHFFY= -go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= -go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= -go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= -go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= +go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2/go.mod h1:DvPtKE63knkDVP88qpatBj81JxN+w1bqfVbsbCbj1WY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 h1:tPLwQlXbJ8NSOfZc4OkgU5h2A38M4c9kfHSVc4PFQGs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2/go.mod h1:QTnxBwT/1rBIgAG1goq6xMydfYOBKU6KTiYF4fp5zL8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.36.0 h1:zwdo1gS2eH26Rg+CoqVQpEK1h8gvt5qyU5Kk5Bixvow= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.36.0/go.mod h1:rUKCPscaRWWcqGT6HnEmYrK+YNe5+Sw64xgQTOJ5b30= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 h1:gAU726w9J8fwr4qRDqu1GYMNNs4gXrU+Pv20/N1UpB4= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0/go.mod h1:RboSDkp7N292rgu+T0MgVt2qgFGu6qa1RpZDOtpL76w= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 h1:JgtbA0xkWHnTmYk7YusopJFX6uleBmAuZ8n05NEh8nQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0/go.mod h1:179AK5aar5R3eS9FucPy6rggvU0g52cvKId8pv4+v0c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 h1:nRVXXvf78e00EwY6Wp0YII8ww2JVWshZ20HfTlE11AM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= +go.opentelemetry.io/otel/log v0.12.2 h1:yob9JVHn2ZY24byZeaXpTVoPS6l+UrrxmxmPKohXTwc= +go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCfuEbVZi/98E= +go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= +go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= +go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= +go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/sdk/log v0.12.2 h1:yNoETvTByVKi7wHvYS6HMcZrN5hFLD7I++1xIZ/k6W0= +go.opentelemetry.io/otel/sdk/log v0.12.2/go.mod h1:DcpdmUXHJgSqN/dh+XMWa7Vf89u9ap0/AAk/XGLnEzY= +go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc h1:uqxdywfHqqCl6LmZzI3pUnXT1RGFYyUgxj0AkWPFxi0= +go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc/go.mod h1:TY/N/FT7dmFrP/r5ym3g0yysP1DefqGpAZr4f82P0dE= +go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= +go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= +go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= +go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= go.opentelemetry.io/proto/otlp v1.6.0 h1:jQjP+AQyTf+Fe7OKj/MfkDrmK4MNVtw2NpXsf9fefDI= go.opentelemetry.io/proto/otlp v1.6.0/go.mod h1:cicgGehlFuNdgZkcALOCh3VE6K/u2tAjzlRhDwmVpZc= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= @@ -307,8 +311,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -323,18 +327,18 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= -golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -349,8 +353,8 @@ golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= @@ -366,15 +370,15 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.223.0 h1:JUTaWEriXmEy5AhvdMgksGGPEFsYfUKaPEYXd4c3Wvc= -google.golang.org/api v0.223.0/go.mod h1:C+RS7Z+dDwds2b+zoAk5hN/eSfsiCn0UDrYof/M4d2M= +google.golang.org/api v0.233.0 h1:iGZfjXAJiUFSSaekVB7LzXl6tRfEKhUN7FkZN++07tI= +google.golang.org/api v0.233.0/go.mod h1:TCIVLLlcwunlMpZIhIp7Ltk77W+vUSdUKAAIlbxY44c= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20250122153221-138b5a5a4fd4 h1:Pw6WnI9W/LIdRxqK7T6XGugGbHIRl5Q7q3BssH6xk4s= -google.golang.org/genproto v0.0.0-20250122153221-138b5a5a4fd4/go.mod h1:qbZzneIOXSq+KFAFut9krLfRLZiFLzZL5u2t8SV83EE= +google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE= +google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE= google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 h1:Kog3KlB4xevJlAcbbbzPfRG0+X9fdoGM+UBRKVz6Wr0= google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237/go.mod h1:ezi0AVyMKDWy5xAncvjLWH7UcLBB5n7y2fQ8MzjJcto= google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 h1:cJfm9zPbe1e873mHJzmQ1nwVEeRDU/T1wXDK2kUSU34= @@ -384,8 +388,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA= -google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/pkg/build/wire/go.mod b/pkg/build/wire/go.mod index f2286a2c311..1c3a3bf1206 100644 --- a/pkg/build/wire/go.mod +++ b/pkg/build/wire/go.mod @@ -6,10 +6,10 @@ require ( github.com/google/go-cmp v0.7.0 github.com/google/subcommands v1.2.0 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 - golang.org/x/tools v0.33.0 + golang.org/x/tools v0.34.0 ) require ( - golang.org/x/mod v0.24.0 // indirect - golang.org/x/sync v0.14.0 // indirect + golang.org/x/mod v0.25.0 // indirect + golang.org/x/sync v0.15.0 // indirect ) diff --git a/pkg/build/wire/go.sum b/pkg/build/wire/go.sum index 264cb153333..0b2f45ba30a 100644 --- a/pkg/build/wire/go.sum +++ b/pkg/build/wire/go.sum @@ -4,9 +4,9 @@ github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= -golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= +golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= +golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=