CI: move grafana-build into pkg/build (#105640)

* move grafana-build into pkg/build
This commit is contained in:
Kevin Minehart
2025-05-20 10:48:00 -05:00
committed by GitHub
parent 759933d3e2
commit 13f4cf162e
222 changed files with 17387 additions and 442 deletions
+31
View File
@@ -0,0 +1,31 @@
package frontend
import (
"dagger.io/dagger"
)
func Build(builder *dagger.Container) *dagger.Directory {
public := builder.
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")
return public
}
func BuildPlugins(builder *dagger.Container) *dagger.Directory {
public := builder.
WithExec([]string{"yarn", "install", "--immutable"}).
WithExec([]string{"/bin/sh", "-c", `if [ -d /src/plugins-bundled ]; then yarn run plugins:build-bundled; else mkdir /src/plugins-bundled; fi`}).
WithExec([]string{"/bin/sh", "-c", "find /src/plugins-bundled -type d -name node_modules -print0 | xargs -0 rm -rf"}).
Directory("/src/plugins-bundled")
return public
}
// WithYarnCache mounts the given YarnCacheDir in the provided container
func WithYarnCache(container *dagger.Container, vol *dagger.CacheVolume) *dagger.Container {
yarnCacheDir := "/yarn/cache"
c := container.WithEnvVariable("YARN_CACHE_FOLDER", yarnCacheDir)
return c.WithMountedCache(yarnCacheDir, vol)
}
+55
View File
@@ -0,0 +1,55 @@
package frontend
import (
"dagger.io/dagger"
)
// Builder mounts all of the necessary files to run yarn build commands and includes a yarn install exec
func Builder(d *dagger.Client, platform dagger.Platform, src *dagger.Directory, nodeVersion string, cache *dagger.CacheVolume) *dagger.Container {
container := WithYarnCache(
NodeContainer(d, NodeImage(nodeVersion), platform),
cache,
).
WithDirectory("/src",
src.
WithoutFile("go.mod").
WithoutFile("go.sum").
WithoutFile("go.work").
WithoutFile("go.work.sum").
WithoutDirectory("devenv").
WithoutDirectory(".github").
WithoutDirectory("docs").
WithoutDirectory("pkg").
WithoutDirectory("apps").
WithoutDirectory(".nx"),
dagger.ContainerWithDirectoryOpts{
Exclude: []string{
"*drone*",
"*.go",
"*.md",
},
},
).
WithWorkdir("/src")
// TODO: Should figure out exactly what we can include without all the extras so we can take advantage of caching better.
// This had to be commented because storybook builds on branches older than 10.1.x were failing.
// container = containers.WithDirectories(container, map[string]*dagger.Directory{
// ".yarn": src.Directory(".yarn"),
// "packages": src.Directory("packages"),
// "plugins-bundled": src.Directory("plugins-bundled"),
// "public": src.Directory("public"),
// "scripts": src.Directory("scripts"),
// })
// container = containers.WithFiles(container, map[string]*dagger.File{
// "package.json": src.File("package.json"),
// "lerna.json": src.File("lerna.json"),
// "yarn.lock": src.File("yarn.lock"),
// ".yarnrc.yml": src.File(".yarnrc.yml"),
// })
// This yarn install is ran just to rebuild the yarn pnp files; all of the dependencies should be in the cache by now
return container.WithExec([]string{"yarn", "install", "--immutable"})
}
+32
View File
@@ -0,0 +1,32 @@
package frontend
import (
"fmt"
"strings"
"dagger.io/dagger"
)
// NodeVersionContainer returns a container whose `stdout` will return the node version from the '.nvmrc' file in the directory 'src'.
func NodeVersion(d *dagger.Client, src *dagger.Directory) *dagger.Container {
return d.Container().From("alpine:3.17").
WithMountedDirectory("/src", src).
WithWorkdir("/src").
WithExec([]string{"cat", ".nvmrc"})
}
func NodeImage(version string) string {
return fmt.Sprintf("node:%s-slim", strings.TrimPrefix(strings.TrimSpace(version), "v"))
}
// NodeContainer returns a docker container with everything set up that is needed to build or run frontend tests.
func NodeContainer(d *dagger.Client, base string, platform dagger.Platform) *dagger.Container {
container := d.Container(dagger.ContainerOpts{
Platform: platform,
}).From(base).
WithExec([]string{"apt-get", "update", "-yq"}).
WithExec([]string{"apt-get", "install", "-yq", "make", "git", "g++", "python3"}).
WithEnvVariable("NODE_OPTIONS", "--max_old_space_size=8000")
return container
}
+61
View File
@@ -0,0 +1,61 @@
package frontend
import (
"context"
"fmt"
"log/slog"
"dagger.io/dagger"
"github.com/grafana/grafana/pkg/build/daggerbuild/containers"
)
// NPMPackages versions and packs the npm packages into tarballs into `npm-packages` directory.
// It then returns the npm-packages directory as a dagger.Directory.
func NPMPackages(builder *dagger.Container, d *dagger.Client, log *slog.Logger, src *dagger.Directory, ersion string) (*dagger.Directory, error) {
// Check if the version of Grafana uses lerna or nx to manage package versioning.
var (
out = fmt.Sprintf("/src/npm-packages/%%s-%v.tgz", "v"+ersion)
lernaBuild = fmt.Sprintf("yarn run packages:build && yarn lerna version %s --exact --no-git-tag-version --no-push --force-publish -y", ersion)
lernaPack = fmt.Sprintf("yarn lerna exec --no-private -- yarn pack --out %s", out)
nxBuild = fmt.Sprintf("yarn run packages:build && yarn nx release version %s --no-git-commit --no-git-tag --no-stage-changes --group grafanaPackages", ersion)
nxPack = fmt.Sprintf("yarn nx exec --projects=$(cat nx.json | jq -r '.relase.groups.grafanaPackages.projects | join(\",\")') -- yarn pack --out %s", out)
)
return builder.WithExec([]string{"mkdir", "npm-packages"}).
WithEnvVariable("SHELL", "/bin/bash").
WithExec([]string{"yarn", "install", "--immutable"}).
WithExec([]string{"/bin/bash", "-c", fmt.Sprintf("if [ -f lerna.json ]; then %s; else %s; fi", lernaBuild, nxBuild)}).
WithExec([]string{"/bin/bash", "-c", fmt.Sprintf("if [ -f lerna.json ]; then %s; else %s; fi", lernaPack, nxPack)}).
Directory("./npm-packages"), nil
}
// PublishNPM publishes a npm package to the given destination.
func PublishNPM(ctx context.Context, d *dagger.Client, pkg *dagger.File, token, registry string, tags []string) (string, error) {
src := containers.ExtractedArchive(d, pkg)
version, err := containers.GetJSONValue(ctx, d, src, "package.json", "version")
if err != nil {
return "", err
}
name, err := containers.GetJSONValue(ctx, d, src, "package.json", "name")
if err != nil {
return "", err
}
tokenSecret := d.SetSecret("npm-token", token)
c := d.Container().From(NodeImage("lts")).
WithFile("/pkg.tgz", pkg).
WithSecretVariable("NPM_TOKEN", tokenSecret).
WithExec([]string{"/bin/sh", "-c", fmt.Sprintf("npm set //%s/:_authToken $NPM_TOKEN", registry)}).
WithExec([]string{"npm", "publish", "/pkg.tgz", fmt.Sprintf("--registry https://%s", registry), "--tag", tags[0]})
for _, tag := range tags[1:] {
c = c.WithExec([]string{"npm", "dist-tag", "add", fmt.Sprintf("%s@%s", name, version), tag})
}
return c.Stdout(ctx)
}
@@ -0,0 +1,10 @@
package frontend
import "dagger.io/dagger"
// Storybook returns a dagger.Directory which contains the built storybook server.
func Storybook(builder *dagger.Container, src *dagger.Directory, version string) *dagger.Directory {
return builder.
WithExec([]string{"yarn", "run", "storybook:build"}).
Directory("./packages/grafana-ui/dist/storybook")
}
+10
View File
@@ -0,0 +1,10 @@
package frontend
import "dagger.io/dagger"
func YarnInstall(c *dagger.Client, src *dagger.Directory, version string, cache *dagger.CacheVolume, platform dagger.Platform) *dagger.Container {
return WithYarnCache(NodeContainer(c, NodeImage(version), platform), cache).
WithMountedDirectory("/src", src).
WithWorkdir("/src").
WithExec([]string{"yarn", "install", "--immutable", "--inline-builds"})
}