108 lines
3.7 KiB
Go
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
|
||
|
|
||
|
}
|