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:kjuulh/shuttle.git", dagger.GitOpts{ KeepGitDir: true, }). Branch("shuttletask"). 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") golangDir := golang.Directory("/usr/local/go") 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"). Directory("/usr/local/bin"). File("docker") image := client. Container(dagger.ContainerOpts{ Platform: platform, }). From("debian"). WithWorkdir("/app"). WithDirectory("/usr/local/go", golangDir). WithFile("/usr/local/bin/shuttle", shuttle). WithExec([]string{"shuttle", "version"}) if _, err := image.ExitCode(ctx); err != nil { log.Printf("%v", err) return err } image = image.WithFile("/usr/local/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 }