Skip to content
This repository was archived by the owner on Nov 21, 2023. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 31 additions & 56 deletions templates/go/multiarch/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,92 +4,67 @@ import (
"context"
"fmt"
"os"
"path/filepath"

"dagger.io/dagger"
"golang.org/x/sync/errgroup"
)

func main() {
repo := "https://github.com/kpenfound/greetings-api.git" // Default repo to build
if len(os.Args) > 1 { // Optionally pass in a git repo as a command line argument
repo = os.Args[1]
if len(os.Args) < 2 {
fmt.Println("Must pass in a Git repository to build")
os.Exit(1)
}
if err := build(repo); err != nil {
repo := os.Args[1]
if err := build(context.Background(), repo); err != nil {
fmt.Println(err)
}
filepath.Walk("build", func(name string, info os.FileInfo, err error) error {
if !info.IsDir() {
fmt.Println(name)
}
return nil
})
}

func build(repoUrl string) error {
ctx := context.Background()
g, ctx := errgroup.WithContext(ctx)
func build(ctx context.Context, repoURL string) error {
fmt.Printf("Building %s\n", repoURL)

// Our build matrix
// define build matrix
oses := []string{"linux", "darwin"}
arches := []string{"amd64", "arm64"}
goVersions := []string{"1.18", "1.19"}

// create a Dagger client
// initialize Dagger client
client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stdout))
if err != nil {
return err
}
defer client.Close()

// clone the specified git repo
repo := client.Git(repoUrl)
// clone repository with Dagger
repo := client.Git(repoURL)
src := repo.Branch("main").Tree()

outputDirectory := client.Directory()

for _, version := range goVersions {
// Get golang image and mount go source
// get `golang` image for specified Go version
imageTag := fmt.Sprintf("golang:%s", version)
golang := client.Container().From(imageTag)
golang = golang.WithMountedDirectory("/src", src).WithWorkdir("/src")
golang := client.Container().
From(imageTag).
WithMountedDirectory("/src", src).
WithWorkdir("/src")

// Run matrix builds in parallel
for _, goos := range oses {
for _, goarch := range arches {
goos, goarch, version := goos, goarch, version // closures
g.Go(func() error {
return buildOsArch(ctx, golang, goos, goarch, version)
})
}
}
}
if err := g.Wait(); err != nil {
return err
}
return nil
}
// create a directory for each os, arch and version
path := fmt.Sprintf("build/%s/%s/%s/", version, goos, goarch)

func buildOsArch(ctx context.Context, builder *dagger.Container, goos string, goarch string, version string) error {
fmt.Printf("Building %s %s with go %s\n", goos, goarch, version)
// set GOARCH and GOOS in the build environment
build := golang.WithEnvVariable("GOOS", goos).
WithEnvVariable("GOARCH", goarch).
Exec(dagger.ContainerExecOpts{
Args: []string{"go", "build", "-o", path},
})

// Create the output path for the build
path := fmt.Sprintf("build/%s/%s/%s/", version, goos, goarch)
outpath := filepath.Join(".", path)
err := os.MkdirAll(outpath, os.ModePerm)
if err != nil {
return err
// build application
outputDirectory = outputDirectory.WithDirectory(path, build.Directory(path))
}
}
}

// Set GOARCH and GOOS and build
build := builder.WithEnvVariable("GOOS", goos)
build = build.WithEnvVariable("GOARCH", goarch)
build = build.Exec(dagger.ContainerExecOpts{
Args: []string{"go", "build", "-o", path},
})

// Get build output from builder
output := build.Directory(path)

// Write the build output to the host
_, err = output.Export(ctx, path)
_, err = outputDirectory.Export(ctx, ".")
return err
}