package main import ( "context" "fmt" "log" "os" "time" "dagger.io/dagger" platformFormat "github.com/containerd/containerd/platforms" "golang.org/x/sync/errgroup" ) var platforms = []dagger.Platform{ "linux/amd64", "linux/arm64", } func architectureOf(platform dagger.Platform) string { return platformFormat.MustParse(string(platform)).Architecture } func Build(ctx context.Context) error { client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stdout)) if err != nil { return err } defer client.Close() containers := make([]*dagger.Container, 0, len(platforms)) egrp, _ := errgroup.WithContext(ctx) ctx = context.Background() shuttleGit := client. Git("git@github.com:lunarway/shuttle.git", dagger.GitOpts{ KeepGitDir: true, }). Tag("v0.17.2"). Tree(dagger.GitRefTreeOpts{ SSHAuthSocket: client.Host().UnixSocket(os.Getenv("SSH_AUTH_SOCK")), }) for _, platform := range platforms { platform := platform egrp.Go(func() error { golang := client.Container().From("golang:1.20.3") shuttleImg := golang. WithDirectory("/app", shuttleGit). WithWorkdir("/app"). WithEnvVariable("CGO_ENABLED", "0"). WithEnvVariable("GOOS", "linux"). WithEnvVariable("GOARCH", architectureOf(platform)). WithExec([]string{"go", "build"}) if _, err := shuttleImg.ExitCode(ctx); err != nil { log.Printf("%v", err) return err } shuttle := shuttleImg.Directory("/app"). File("shuttle") docker := client. Container(dagger.ContainerOpts{ Platform: platform, }). From("docker:cli"). File("/usr/local/bin/docker") image := client. Container(dagger.ContainerOpts{ Platform: platform, }). From("golang:1.20.3"). WithExec([]string{ "apt", "update", }). WithExec([]string{ "apt", "install", "-y", "curl", "build-essential", }). WithEnvVariable("RUSTUP_HOME", "/usr/local/rustup"). WithEnvVariable("CARGO_HOME", "/usr/local/cargo"). WithExec([]string{ "bash", "-c", "curl https://sh.rustup.rs -sSf | bash -s -- -y", }) path, err := image.EnvVariable(ctx, "PATH") if err != nil { return err } image = image. WithEnvVariable( "PATH", fmt.Sprintf("/usr/local/cargo/bin:%s", path), ). WithExec([]string{"rustup", "toolchain", "install", "nightly"}). WithExec([]string{"rustup", "default", "nightly"}). WithWorkdir("/app"). WithFile("/usr/local/bin/shuttle", shuttle). WithExec([]string{"shuttle", "version"}) if _, err := image.ExitCode(ctx); err != nil { log.Printf("%v", err) return err } if _, err := image.WithExec([]string{"cargo", "--version"}).ExitCode(ctx); err != nil { log.Printf("%v", err) return err } image = image.WithFile("/usr/bin/docker", docker) if _, err := image.ExitCode(ctx); err != nil { log.Printf("%v", err) return err } containers = append(containers, image) return nil }) time.Sleep(5 * time.Second) } if err := egrp.Wait(); err != nil { log.Printf("%v", err) return err } tag := time.Now().UnixMilli() imageTag, err := client.Container(). Publish( ctx, fmt.Sprintf("docker.io/kasperhermansen/shuttle-drone:%d", tag), dagger.ContainerPublishOpts{ PlatformVariants: containers, }) if err != nil { log.Printf("%v", err) return err } log.Printf("imageTag: %s\n", imageTag) return nil }