releaser/shuttletask/build.go
2023-04-07 03:13:09 +02:00

108 lines
3.7 KiB
Go

package main
import (
"context"
"fmt"
"log"
"os"
"time"
"dagger.io/dagger"
"github.com/joho/godotenv"
)
func Build(ctx context.Context) error {
client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stdout))
if err != nil {
return err
}
// Load environment variables from .env file
_ = godotenv.Load()
rustImage := "docker.io/rustlang/rust:nightly"
workdir := client.Host().Directory(".",
dagger.HostDirectoryOpts{
Exclude: []string{"target/", ".git/", ".shuttle/", "shuttletask/"},
})
minioURL := "https://github.com/mozilla/sccache/releases/download/v0.3.3/sccache-v0.3.3-x86_64-unknown-linux-musl.tar.gz"
sccacheDownloadCache := client.CacheVolume("sccache_download")
cargoCache := client.CacheVolume("cargo_cache")
rustBase := client.Container().From(rustImage).
WithExec([]string{"apt-get", "update"}).
WithExec([]string{"apt-get", "install", "--yes", "libpq-dev", "wget"}).
WithExec([]string{"mkdir", "-p", "/src/downloads"}).
WithWorkdir("/src/downloads").
WithMountedCache("/src/downloads", sccacheDownloadCache).
WithExec([]string{"wget", minioURL}).
WithExec([]string{"tar", "xzf", "sccache-v0.3.3-x86_64-unknown-linux-musl.tar.gz"}).
WithExec([]string{"mv", "sccache-v0.3.3-x86_64-unknown-linux-musl/sccache", "/usr/local/bin/sccache"}).
WithExec([]string{"chmod", "+x", "/usr/local/bin/sccache"}).
WithEnvVariable("RUSTC_WRAPPER", "/usr/local/bin/sccache").
WithEnvVariable("AWS_ACCESS_KEY_ID", os.Getenv("AWS_ACCESS_KEY_ID")).
WithEnvVariable("AWS_SECRET_ACCESS_KEY", os.Getenv("AWS_SECRET_ACCESS_KEY")).
WithEnvVariable("SCCACHE_BUCKET", "sccache").
WithEnvVariable("SCCACHE_REGION", "auto").
WithEnvVariable("SCCACHE_ENDPOINT", "https://api-minio.front.kjuulh.io").
WithMountedCache("~/.cargo", cargoCache).
WithExec([]string{"cargo", "install", "cargo-chef"}).
WithWorkdir("/app")
if exitCode, err := rustBase.ExitCode(ctx); err != nil || exitCode != 0 {
return fmt.Errorf("could not build base")
}
targetCache := client.CacheVolume("target_cache")
rustPrepare := rustBase.WithMountedDirectory(".", workdir).
WithMountedCache("target", targetCache).
WithExec([]string{"cargo", "chef", "prepare", "--recipe-path", "recipe.json"})
if exitCode, err := rustPrepare.ExitCode(ctx); err != nil || exitCode != 0 {
return fmt.Errorf("could not build prepare")
}
targetRustCache := client.CacheVolume("target_rust_cache")
rustCacher := rustBase.
WithExec([]string{"apt", "update"}).
WithExec([]string{"apt", "install", "pkg-config", "openssl", "libssl-dev", "-y"}).
WithFile("/recipe.json", rustPrepare.File("./recipe.json")).
WithMountedCache("target", targetRustCache).
WithExec([]string{"cargo", "chef", "cook", "--release", "--recipe-path", "/recipe.json"}).
WithMountedDirectory(".", workdir)
if exitCode, err := rustCacher.ExitCode(ctx); err != nil || exitCode != 0 {
return fmt.Errorf("could not build cacher")
}
rustBuilder := rustCacher.WithExec([]string{"cargo", "build", "--release"})
if exitCode, err := rustBuilder.ExitCode(ctx); err != nil || exitCode != 0 {
return fmt.Errorf("could not build builder")
}
tag := time.Now().UTC().Unix()
prodImage := "debian:bullseye"
prod := client.Container().From(prodImage).
WithExec([]string{"apt", "update"}).
WithExec([]string{"apt", "install", "-y", "zlib1g", "git"}).
WithWorkdir("/app").
WithFile("/app/releaser", rustBuilder.File("/app/target/release/releaser")).
WithExec([]string{"/app/releaser", "--help"}).
WithEntrypoint([]string{"/app/releaser"})
imageTag := fmt.Sprintf("docker.io/kasperhermansen/releaser:%v", tag)
version, err := prod.Publish(ctx, imageTag)
if err != nil {
return err
}
log.Printf("published image: %s\n", version)
return nil
}