diff --git a/go.mod b/go.mod index 6700516..0d1861d 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/Ullaakut/nmap v2.0.0+incompatible github.com/VividCortex/ewma v1.1.1 // indirect github.com/fatih/color v1.7.0 // indirect + github.com/magefile/mage v1.11.0 // indirect github.com/mattn/go-colorable v0.1.2 // indirect github.com/spf13/pflag v1.0.3 github.com/spf13/viper v1.4.0 diff --git a/go.sum b/go.sum index b4ad037..db5292a 100644 --- a/go.sum +++ b/go.sum @@ -65,6 +65,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magefile/mage v1.11.0 h1:C/55Ywp9BpgVVclD3lRnSYCwXTYxmSppIgLeDYlNuls= +github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= diff --git a/tools/xplatform-docker-build/magefile.go b/tools/xplatform-docker-build/magefile.go new file mode 100644 index 0000000..11b84b0 --- /dev/null +++ b/tools/xplatform-docker-build/magefile.go @@ -0,0 +1,109 @@ +//+build mage + +package main + +import ( + "os" + + "github.com/magefile/mage/sh" + "github.com/Ullaakut/disgo" + "github.com/Ullaakut/disgo/style" +) + +var supportedPlatforms = map[string]string{ + "linux/amd64": "ullaakut/cameradar:amd64", + "linux/386": "ullaakut/cameradar:386", + "linux/arm64": "ullaakut/cameradar:arm64", + "linux/arm/v7": "ullaakut/cameradar:armv7", + //"linux/riscv64": "ullaakut/cameradar:riscv64", // UNSUPPORTED. + //"linux/ppc64le": "ullaakut/cameradar:ppc64le", // UNSUPPORTED. + //"linux/s390x": "ullaakut/cameradar:s390x", // UNSUPPORTED. + //"linux/arm/v6": "ullaakut/cameradar:armv6", // UNSUPPORTED. +} + +var Default = Build + +// Follows https://www.docker.com/blog/multi-platform-docker-builds/. +func Build() error { + term := disgo.NewTerminal(disgo.WithColors(true)) + + term.StartStep("Building images for all platforms") + term.Infof("Builds planned for %v\n", supportedPlatforms) + for platform, name := range supportedPlatforms { + term.Infoln("Building image for", platform, "at", name) + + // docker buildx build --platform linux/arm/v7 -t ullaakut/cameradar:armv7 . + if err := sh.Run("docker", "buildx", "build", "--platform", platform, "-t", name, "../../"); err != nil { + return term.FailStepf("unable to build image: %v", err) + } + } + + term.Infoln(style.Success("Cross-platform docker build successful.")) + + return nil +} + +func Publish() error { + term := disgo.NewTerminal(disgo.WithColors(true)) + + term.StartStep("Pushing images to DockerHub") + term.Infoln("Pushing ullaakut/cameradar:latest") + if err := sh.Run("docker", "push", "ullaakut/cameradar:latest"); err != nil { + return term.FailStepf("unable to push latest docker images to docker hub: %v", err) + } + + if version, exists := os.LookupEnv("CAMERADAR_VERSION"); exists { + term.Infoln("Pushing ullaakut/cameradar:"+version) + if err := sh.Run("docker", "push", "ullaakut/cameradar:"+version); err != nil { + return term.FailStepf("unable to push versionned docker images to docker hub: %v", err) + } + } + + term.StartStep("Pushing images to GitHub Packages") + term.Infoln("Pushing docker.pkg.github.com/ullaakut/cameradar/cameradar:latest") + if err := sh.Run("docker", "tag", "ullaakut/cameradar:latest", "docker.pkg.github.com/ullaakut/cameradar/cameradar:latest"); err != nil { + return term.FailStepf("unable to push latest docker images to docker hub: %v", err) + } + if err := sh.Run("docker", "push", "docker.pkg.github.com/ullaakut/cameradar/cameradar:latest"); err != nil { + return term.FailStepf("unable to push latest docker images to docker hub: %v", err) + } + + if version, exists := os.LookupEnv("CAMERADAR_VERSION"); exists { + term.Infoln("Pushing docker.pkg.github.com/ullaakut/cameradar/cameradar:"+version) + if err := sh.Run("docker", "tag", "ullaakut/cameradar:"+version, "docker.pkg.github.com/ullaakut/cameradar/cameradar:"+version); err != nil { + return term.FailStepf("unable to push latest docker images to docker hub: %v", err) + } + if err := sh.Run("docker", "push", "ullaakut/cameradar:"+version); err != nil { + return term.FailStepf("unable to push versionned docker images to docker hub: %v", err) + } + } + + term.StartStep("Creating manifest(s) for cross platform builds") + + var manifestImages []string + for _, image := range supportedPlatforms { + manifestImages = append(manifestImages, image) + } + + args := []string{"manifest", "create", "--amend", "ullaakut/cameradar:latest"} + args = append(args, manifestImages...) + + // docker manifest create ullaakut/cameradar:latest ullaakut/cameradar:amd64 ullaakut/cameradar:armv7 [...] + if err := sh.Run("docker", args...); err != nil { + return term.FailStepf("unable to create manifest: %v", err) + } + + if version, exists := os.LookupEnv("CAMERADAR_VERSION"); exists { + args = []string{"manifest", "create", "--amend", "ullaakut/cameradar:"+version} + args = append(args, manifestImages...) + + if err := sh.Run("docker", args...); err != nil { + return term.FailStepf("unable to create manifest: %v", err) + } + } + term.EndStep() + + term.Infoln(style.Success("Images published successfully.")) + + return nil +}