diff --git a/cmd/goreleaser/internal/configure.go b/cmd/goreleaser/internal/configure.go index f756d249a..d5548632e 100644 --- a/cmd/goreleaser/internal/configure.go +++ b/cmd/goreleaser/internal/configure.go @@ -28,290 +28,474 @@ import ( ) const ( - ArmArch = "arm" - CoreDistro = "otelcol" - ContribDistro = "otelcol-contrib" - K8sDistro = "otelcol-k8s" - OTLPDistro = "otelcol-otlp" - DockerHub = "otel" - GHCR = "ghcr.io/open-telemetry/opentelemetry-collector-releases" - BinaryNamePrefix = "otelcol" - ImageNamePrefix = "opentelemetry-collector" + armArch = "arm" + coreDistro = "otelcol" + contribDistro = "otelcol-contrib" + k8sDistro = "otelcol-k8s" + otlpDistro = "otelcol-otlp" + dockerHub = "otel" + ghcr = "ghcr.io/open-telemetry/opentelemetry-collector-releases" + binaryNamePrefix = "otelcol" + imageNamePrefix = "opentelemetry-collector" ) var ( - ImagePrefixes = []string{DockerHub, GHCR} - Architectures = []string{"386", "amd64", "arm", "arm64", "ppc64le", "s390x"} - DefaultConfigDists = map[string]bool{CoreDistro: true, ContribDistro: true} - MSIWindowsDists = map[string]bool{CoreDistro: true, ContribDistro: true, OTLPDistro: true} - K8sDockerSkipArchs = map[string]bool{"arm": true, "386": true} - K8sGoos = []string{"linux"} - K8sArchs = []string{"amd64", "arm64", "ppc64le", "s390x"} - Partial = config.Partial{By: "target"} + baseArchs = []string{"386", "amd64", "arm", "arm64", "ppc64le", "s390x"} + winArchs = []string{"386", "amd64", "arm64", "ppc64le"} + darwinArchs = []string{"amd64", "arm64"} + k8sArchs = []string{"amd64", "arm64", "ppc64le", "s390x"} + + imageRepos = []string{dockerHub, ghcr} + + // otelcol (core) distro + otelColDist = newDistributionBuilder(coreDistro).WithConfigFunc(func(d *distribution) { + d.buildConfigs = []buildConfig{ + &fullBuildConfig{targetOS: "linux", targetArch: baseArchs, armVersion: []string{"7"}, ppc64Version: []string{"power8"}}, + &fullBuildConfig{targetOS: "darwin", targetArch: darwinArchs}, + &fullBuildConfig{targetOS: "windows", targetArch: winArchs, ppc64Version: []string{"power8"}}, + } + d.containerImages = newContainerImages(d.name, "linux", baseArchs, containerImageOptions{armVersion: "7"}) + d.containerImageManifests = newContainerImageManifests(d.name, "linux", baseArchs) + }).WithPackagingDefaults().WithDefaultConfigIncluded().Build() + + // otlp distro + otlpDist = newDistributionBuilder(otlpDistro).WithConfigFunc(func(d *distribution) { + d.buildConfigs = []buildConfig{ + &fullBuildConfig{targetOS: "linux", targetArch: baseArchs, armVersion: []string{"7"}, ppc64Version: []string{"power8"}}, + &fullBuildConfig{targetOS: "darwin", targetArch: darwinArchs}, + &fullBuildConfig{targetOS: "windows", targetArch: winArchs, ppc64Version: []string{"power8"}}, + } + d.containerImages = newContainerImages(d.name, "linux", baseArchs, containerImageOptions{armVersion: "7"}) + d.containerImageManifests = newContainerImageManifests(d.name, "linux", baseArchs) + }).WithPackagingDefaults().Build() + + // contrib distro + contribDist = newDistributionBuilder(contribDistro).WithConfigFunc(func(d *distribution) { + d.buildConfigs = []buildConfig{ + &preBuiltBuildConfig{ + targetOS: "linux", + targetArch: baseArchs, + preBuilt: config.PreBuiltOptions{ + Path: "artifacts/otelcol-contrib-linux_{{ .Target }}/otelcol-contrib", + }, + }, + &preBuiltBuildConfig{ + targetOS: "darwin", + targetArch: darwinArchs, + preBuilt: config.PreBuiltOptions{ + Path: "artifacts/otelcol-contrib-darwin_{{ .Target }}/otelcol-contrib", + }, + }, + &preBuiltBuildConfig{ + targetOS: "windows", + targetArch: winArchs, + preBuilt: config.PreBuiltOptions{ + Path: "artifacts/otelcol-contrib-windows_{{ .Target }}/otelcol-contrib.exe", + }, + }, + } + d.containerImages = newContainerImages(d.name, "linux", baseArchs, containerImageOptions{armVersion: "7"}) + d.containerImageManifests = newContainerImageManifests(d.name, "linux", baseArchs) + }).WithPackagingDefaults().WithDefaultConfigIncluded().Build() + + // contrib build-only project + contribBuildOnlyDist = newDistributionBuilder(contribDistro).WithConfigFunc(func(d *distribution) { + d.buildConfigs = []buildConfig{ + &fullBuildConfig{targetOS: "linux", targetArch: baseArchs, armVersion: []string{"7"}}, + &fullBuildConfig{targetOS: "darwin", targetArch: darwinArchs}, + &fullBuildConfig{targetOS: "windows", targetArch: winArchs}, + } + }).WithBinArchive().Build() + + // k8s distro + k8sDist = newDistributionBuilder(k8sDistro).WithConfigFunc(func(d *distribution) { + d.buildConfigs = []buildConfig{ + &fullBuildConfig{targetOS: "linux", targetArch: k8sArchs, ppc64Version: []string{"power8"}}, + } + d.containerImages = newContainerImages(d.name, "linux", k8sArchs, containerImageOptions{}) + d.containerImageManifests = newContainerImageManifests(d.name, "linux", k8sArchs) + }).WithDefaultArchives().WithDefaultChecksum().WithDefaultSigns().WithDefaultDockerSigns().WithDefaultSBOMs().Build() ) -func GenerateContribBuildOnly(dist string, buildOrRest bool) config.Project { - return config.Project{ - ProjectName: "opentelemetry-collector-releases", - Builds: Builds(dist, buildOrRest), - Version: 2, - Monorepo: config.Monorepo{ - TagPrefix: "v", +type buildConfig interface { + Build(dist string) config.Build + OS() string +} + +type distributionBuilder struct { + dist *distribution + configFuncs []func(*distribution) +} + +func newDistributionBuilder(name string) *distributionBuilder { + return &distributionBuilder{dist: &distribution{name: name}} +} + +func (b *distributionBuilder) WithDefaultArchives() *distributionBuilder { + b.configFuncs = append(b.configFuncs, func(d *distribution) { + builds := make([]string, 0, len(d.buildConfigs)) + for _, build := range d.buildConfigs { + builds = append(builds, fmt.Sprintf("%s-%s", d.name, build.OS())) + } + d.archives = b.newArchives(d.name, builds) + }) + return b +} + +func (b *distributionBuilder) WithBinArchive() *distributionBuilder { + b.configFuncs = append(b.configFuncs, func(d *distribution) { + d.archives = append(d.archives, config.Archive{ + Formats: []string{"binary"}, + }) + }) + return b +} + +func (b *distributionBuilder) newArchives(dist string, builds []string) []config.Archive { + return []config.Archive{ + { + ID: dist, + NameTemplate: "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}", + Builds: builds, }, - Partial: Partial, - Archives: []config.Archive{ - { - Formats: []string{ - "binary", + } +} + +func (b *distributionBuilder) WithDefaultNfpms() *distributionBuilder { + b.configFuncs = append(b.configFuncs, func(d *distribution) { + d.nfpms = b.newNfpms(d.name) + }) + return b +} + +func (b *distributionBuilder) newNfpms(dist string) []config.NFPM { + nfpmContents := []config.NFPMContent{ + { + Source: fmt.Sprintf("%s.service", dist), + Destination: path.Join("/lib", "systemd", "system", fmt.Sprintf("%s.service", dist)), + }, + { + Source: fmt.Sprintf("%s.conf", dist), + Destination: path.Join("/etc", dist, fmt.Sprintf("%s.conf", dist)), + Type: "config|noreplace", + }, + } + return []config.NFPM{ + { + ID: dist, + Builds: []string{dist + "-linux"}, + Formats: []string{"deb", "rpm"}, + License: "Apache 2.0", + Description: fmt.Sprintf("OpenTelemetry Collector - %s", dist), + Maintainer: "The OpenTelemetry Collector maintainers ", + Overrides: map[string]config.NFPMOverridables{ + "rpm": { + Dependencies: []string{"/bin/sh"}, + }, + }, + NFPMOverridables: config.NFPMOverridables{ + PackageName: dist, + Scripts: config.NFPMScripts{ + PreInstall: "preinstall.sh", + PostInstall: "postinstall.sh", + PreRemove: "preremove.sh", }, + Contents: nfpmContents, }, }, } } -func Generate(dist string, buildOrRest bool) config.Project { - return config.Project{ - ProjectName: "opentelemetry-collector-releases", - Checksum: config.Checksum{ - NameTemplate: fmt.Sprintf("{{ .ProjectName }}_%v_checksums.txt", dist), - }, - Env: []string{"COSIGN_YES=true"}, - Builds: Builds(dist, buildOrRest), - Archives: Archives(dist), - MSI: WinPackages(dist), - NFPMs: Packages(dist), - Dockers: DockerImages(dist), - DockerManifests: DockerManifests(dist), - Signs: Sign(), - DockerSigns: DockerSigns(), - SBOMs: SBOM(), - Version: 2, - Monorepo: config.Monorepo{ - TagPrefix: "v", +func (b *distributionBuilder) WithDefaultMSIConfig() *distributionBuilder { + b.configFuncs = append(b.configFuncs, func(d *distribution) { + d.msiConfig = b.newMSIConfig(d.name) + }) + return b +} + +func (b *distributionBuilder) newMSIConfig(dist string) []config.MSI { + files := []string{"opentelemetry.ico"} + return []config.MSI{ + { + ID: dist, + Name: fmt.Sprintf("%s_{{ .Version }}_{{ .Os }}_{{ .MsiArch }}", dist), + WXS: "windows-installer.wxs", + Files: files, }, - Partial: Partial, } } -func Builds(dist string, buildOrRest bool) []config.Build { - return []config.Build{ - Build(dist, buildOrRest), - } +func (b *distributionBuilder) WithDefaultSigns() *distributionBuilder { + b.configFuncs = append(b.configFuncs, func(d *distribution) { + d.signs = b.signs() + }) + return b } -// Build configures a goreleaser build. -// https://goreleaser.com/customization/build/ -func Build(dist string, buildOrRest bool) config.Build { - goos := []string{"darwin", "linux", "windows"} - archs := Architectures - - if dist == ContribDistro && !buildOrRest { - // only return build config for contrib build file - return config.Build{ - ID: dist, - Builder: "prebuilt", - PreBuilt: config.PreBuiltOptions{ - Path: "artifacts/otelcol-contrib_{{ .Target }}" + - "/otelcol-contrib{{- if eq .Os \"windows\" }}.exe{{ end }}", +func (b *distributionBuilder) signs() []config.Sign { + return []config.Sign{ + { + Artifacts: "all", + Signature: "${artifact}.sig", + Certificate: "${artifact}.pem", + Cmd: "cosign", + Args: []string{ + "sign-blob", + "--output-signature", + "${artifact}.sig", + "--output-certificate", + "${artifact}.pem", + "${artifact}", }, - Goos: goos, - Goarch: archs, - Goarm: ArmVersions(dist), - Goppc64: Ppc64Versions(dist), - Dir: "_build", - Binary: dist, - Ignore: IgnoreBuildCombinations(dist), - } + }, } +} - if dist == K8sDistro { - goos = K8sGoos - archs = K8sArchs - } +func (b *distributionBuilder) WithDefaultDockerSigns() *distributionBuilder { + b.configFuncs = append(b.configFuncs, func(d *distribution) { + d.dockerSigns = b.dockerSigns() + }) + return b +} - return config.Build{ - ID: dist, - Dir: "_build", - Binary: dist, - BuildDetails: config.BuildDetails{ - Env: []string{"CGO_ENABLED=0"}, - Flags: []string{"-trimpath"}, - Ldflags: []string{"-s", "-w"}, +func (b *distributionBuilder) dockerSigns() []config.Sign { + return []config.Sign{ + { + Artifacts: "all", + Args: []string{ + "sign", + "${artifact}", + }, }, - Goos: goos, - Goarch: archs, - Goarm: ArmVersions(dist), - Goppc64: Ppc64Versions(dist), - Ignore: IgnoreBuildCombinations(dist), } } -func IgnoreBuildCombinations(dist string) []config.IgnoredBuild { - if dist == K8sDistro { - return nil - } - return []config.IgnoredBuild{ - {Goos: "darwin", Goarch: "386"}, - {Goos: "darwin", Goarch: "arm"}, - {Goos: "darwin", Goarch: "s390x"}, - {Goos: "windows", Goarch: "arm"}, - {Goos: "windows", Goarch: "arm64"}, - {Goos: "windows", Goarch: "s390x"}, - } +func (b *distributionBuilder) WithDefaultSBOMs() *distributionBuilder { + b.configFuncs = append(b.configFuncs, func(d *distribution) { + d.sboms = b.sboms() + }) + return b } -func ArmVersions(dist string) []string { - if dist == K8sDistro { - return nil +func (b *distributionBuilder) sboms() []config.SBOM { + return []config.SBOM{ + { + ID: "archive", + Artifacts: "archive", + }, + { + ID: "package", + Artifacts: "package", + }, } - return []string{"7"} } -func Ppc64Versions(dist string) []string { - return []string{"power8"} +func (b *distributionBuilder) WithDefaultChecksum() *distributionBuilder { + b.configFuncs = append(b.configFuncs, func(d *distribution) { + b.dist.checksum = config.Checksum{ + NameTemplate: fmt.Sprintf("{{ .ProjectName }}_%v_checksums.txt", d.name), + } + }) + return b } -func Archives(dist string) []config.Archive { - return []config.Archive{ - Archive(dist), - } +func (b *distributionBuilder) WithPackagingDefaults() *distributionBuilder { + return b.WithDefaultArchives(). + WithDefaultChecksum(). + WithDefaultNfpms(). + WithDefaultMSIConfig(). + WithDefaultSigns(). + WithDefaultDockerSigns(). + WithDefaultSBOMs() } -// Archive configures a goreleaser archive (tarball). -// https://goreleaser.com/customization/archive/ -func Archive(dist string) config.Archive { - return config.Archive{ - ID: dist, - NameTemplate: "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}", - Builds: []string{dist}, - } +func (b *distributionBuilder) WithConfigFunc(configFunc func(*distribution)) *distributionBuilder { + b.configFuncs = append(b.configFuncs, configFunc) + return b } -func WinPackages(dist string) []config.MSI { - if _, ok := MSIWindowsDists[dist]; !ok { - return nil - } - return []config.MSI{ - WinPackage(dist), +func (b *distributionBuilder) WithDefaultConfigIncluded() *distributionBuilder { + b.configFuncs = append(b.configFuncs, func(d *distribution) { + for i, container := range d.containerImages { + container.Files = append(container.Files, "config.yaml") + d.containerImages[i] = container + } + + for i, nfpm := range d.nfpms { + nfpm.Contents = append(nfpm.Contents, config.NFPMContent{ + Source: "config.yaml", + Destination: path.Join("/etc", d.name, "config.yaml"), + Type: "config|noreplace", + }) + d.nfpms[i] = nfpm + } + + for i := range d.msiConfig { + d.msiConfig[i].Files = append(d.msiConfig[i].Files, "config.yaml") + } + }) + return b +} + +func (b *distributionBuilder) Build() *distribution { + for _, configFunc := range b.configFuncs { + configFunc(b.dist) } + return b.dist } -// Package configures goreleaser to build a Windows MSI package. -// https://goreleaser.com/customization/msi/ -func WinPackage(dist string) config.MSI { - files := []string{"opentelemetry.ico"} - if _, ok := DefaultConfigDists[dist]; ok { - files = append(files, "config.yaml") +type distribution struct { + // Name of the distribution (i.e. otelcol, otelcol-contrib, k8s) + name string + + buildConfigs []buildConfig + archives []config.Archive + msiConfig []config.MSI + nfpms []config.NFPM + containerImages []config.Docker + containerImageManifests []config.DockerManifest + signs []config.Sign + dockerSigns []config.Sign + sboms []config.SBOM + checksum config.Checksum +} + +func (d *distribution) BuildProject() config.Project { + builds := make([]config.Build, 0, len(d.buildConfigs)) + for _, buildConfig := range d.buildConfigs { + builds = append(builds, buildConfig.Build(d.name)) } - return config.MSI{ - ID: dist, - Name: fmt.Sprintf("%s_{{ .Version }}_{{ .Os }}_{{ .MsiArch }}", dist), - WXS: "windows-installer.wxs", - Files: files, + + return config.Project{ + ProjectName: "opentelemetry-collector-releases", + Checksum: d.checksum, + Env: []string{ + "COSIGN_YES=true", + "LD_FLAGS=-s -w", + "CGO_ENABLED=0", + "BUILD_FLAGS=-trimpath", + }, + Builds: builds, + Archives: d.archives, + MSI: d.msiConfig, + NFPMs: d.nfpms, + Dockers: d.containerImages, + DockerManifests: d.containerImageManifests, + Signs: d.signs, + DockerSigns: d.dockerSigns, + SBOMs: d.sboms, + Version: 2, + Monorepo: config.Monorepo{ + TagPrefix: "v", + }, + Partial: config.Partial{By: "target"}, } } -func Packages(dist string) []config.NFPM { - if dist == K8sDistro { - return nil - } - return []config.NFPM{ - Package(dist), +func newContainerImageManifests(dist, os string, archs []string) []config.DockerManifest { + tags := []string{`{{ .Version }}`, "latest"} + var r []config.DockerManifest + for _, imageRepo := range imageRepos { + for _, tag := range tags { + r = append(r, osDockerManifest(imageRepo, tag, dist, os, archs)) + } } + return r } -// Package configures goreleaser to build a system package. -// https://goreleaser.com/customization/nfpm/ -func Package(dist string) config.NFPM { - nfpmContents := []config.NFPMContent{ - { - Source: fmt.Sprintf("%s.service", dist), - Destination: path.Join("/lib", "systemd", "system", fmt.Sprintf("%s.service", dist)), - }, - { - Source: fmt.Sprintf("%s.conf", dist), - Destination: path.Join("/etc", dist, fmt.Sprintf("%s.conf", dist)), - Type: "config|noreplace", - }, +type containerImageOptions struct { + armVersion string + winVersion string +} + +func (o *containerImageOptions) version() string { + if o.armVersion != "" { + return o.armVersion } - if _, ok := DefaultConfigDists[dist]; ok { - nfpmContents = append(nfpmContents, config.NFPMContent{ - Source: "config.yaml", - Destination: path.Join("/etc", dist, "config.yaml"), - Type: "config|noreplace", - }) + return o.winVersion +} + +func newContainerImages(dist string, targetOS string, targetArchs []string, opts containerImageOptions) []config.Docker { + images := []config.Docker{} + for _, targetArch := range targetArchs { + images = append(images, dockerImageWithOS(dist, targetOS, targetArch, opts)) } - return config.NFPM{ - ID: dist, - Builds: []string{dist}, - Formats: []string{"deb", "rpm"}, - License: "Apache 2.0", - Description: fmt.Sprintf("OpenTelemetry Collector - %s", dist), - Maintainer: "The OpenTelemetry Collector maintainers ", - Overrides: map[string]config.NFPMOverridables{ - "rpm": { - Dependencies: []string{"/bin/sh"}, - }, - }, - NFPMOverridables: config.NFPMOverridables{ - PackageName: dist, - Scripts: config.NFPMScripts{ - PreInstall: "preinstall.sh", - PostInstall: "postinstall.sh", - PreRemove: "preremove.sh", - }, - Contents: nfpmContents, + return images +} + +type fullBuildConfig struct { + targetOS string + targetArch []string + armVersion []string + ppc64Version []string +} + +func (c *fullBuildConfig) Build(dist string) config.Build { + buildConfig := config.Build{ + ID: dist + "-" + c.targetOS, + Dir: "_build", + Binary: dist, + BuildDetails: config.BuildDetails{ + Flags: []string{"{{ .Env.BUILD_FLAGS }}"}, + Ldflags: []string{"{{ .Env.LD_FLAGS }}"}, }, + Goos: []string{c.targetOS}, + Goarch: c.targetArch, + Goarm: c.armVersion, + Goppc64: c.ppc64Version, } + return buildConfig } -func DockerImages(dist string) []config.Docker { - var r []config.Docker - for _, arch := range Architectures { - if dist == K8sDistro && K8sDockerSkipArchs[arch] { - continue - } - switch arch { - case ArmArch: - for _, vers := range ArmVersions(dist) { - r = append(r, DockerImage(dist, arch, vers)) - } - default: - r = append(r, DockerImage(dist, arch, "")) - } +func (c *fullBuildConfig) OS() string { + return c.targetOS +} + +type preBuiltBuildConfig struct { + targetOS string + targetArch []string + preBuilt config.PreBuiltOptions +} + +func (c *preBuiltBuildConfig) Build(dist string) config.Build { + return config.Build{ + ID: dist + "-" + c.targetOS, + Builder: "prebuilt", + PreBuilt: c.preBuilt, + Dir: "_build", + Binary: dist, + Goos: []string{c.targetOS}, + Goarch: c.targetArch, + Goarm: armVersions(dist), + Goppc64: []string{"power8"}, } - return r } -// DockerImage configures goreleaser to build a container image. -// https://goreleaser.com/customization/docker/ -func DockerImage(dist, arch, armVersion string) config.Docker { - dockerArchName := archName(arch, armVersion) - imageTemplates := make([]string, 0) - for _, prefix := range ImagePrefixes { - dockerArchTag := strings.ReplaceAll(dockerArchName, "/", "") +func (c *preBuiltBuildConfig) OS() string { + return c.targetOS +} + +func dockerImageWithOS(dist, os, arch string, opts containerImageOptions) config.Docker { + osArch := osArch{os: os, arch: arch, version: opts.version()} + var imageTemplates []string + for _, prefix := range imageRepos { imageTemplates = append( imageTemplates, - fmt.Sprintf("%s/%s:{{ .Version }}-%s", prefix, imageName(dist), dockerArchTag), - fmt.Sprintf("%s/%s:latest-%s", prefix, imageName(dist), dockerArchTag), + fmt.Sprintf("%s/%s:{{ .Version }}-%s", prefix, imageName(dist), osArch.imageTag()), + fmt.Sprintf("%s/%s:latest-%s", prefix, imageName(dist), osArch.imageTag()), ) } label := func(name, template string) string { return fmt.Sprintf("--label=org.opencontainers.image.%s={{%s}}", name, template) } - files := make([]string, 0) - if _, ok := DefaultConfigDists[dist]; ok { - files = append(files, "config.yaml") - } - return config.Docker{ + imageConfig := config.Docker{ ImageTemplates: imageTemplates, Dockerfile: "Dockerfile", - - Use: "buildx", + Use: "buildx", BuildFlagTemplates: []string{ "--pull", - fmt.Sprintf("--platform=linux/%s", dockerArchName), + fmt.Sprintf("--platform=%s", osArch.buildPlatform()), label("created", ".Date"), label("name", ".ProjectName"), label("revision", ".FullCommit"), @@ -319,36 +503,66 @@ func DockerImage(dist, arch, armVersion string) config.Docker { label("source", ".GitURL"), "--label=org.opencontainers.image.licenses=Apache-2.0", }, - Files: files, - Goos: "linux", + Goos: os, Goarch: arch, - Goarm: armVersion, } + if arch == armArch { + imageConfig.Goarm = opts.armVersion + } + return imageConfig +} + +type osArch struct { + os, arch, version string } -func DockerManifests(dist string) []config.DockerManifest { - r := make([]config.DockerManifest, 0) - for _, prefix := range ImagePrefixes { - r = append(r, DockerManifest(prefix, `{{ .Version }}`, dist)) - r = append(r, DockerManifest(prefix, "latest", dist)) +func (o *osArch) buildPlatform() string { + switch o.os { + case "linux": + switch o.arch { + case armArch: + return fmt.Sprintf("linux/arm/v%s", o.version) + } } - return r + return fmt.Sprintf("linux/%s", o.arch) } -// DockerManifest configures goreleaser to build a multi-arch container image manifest. -// https://goreleaser.com/customization/docker_manifest/ -func DockerManifest(prefix, version, dist string) config.DockerManifest { - var imageTemplates []string - for _, arch := range Architectures { - if dist == K8sDistro { - if _, ok := K8sDockerSkipArchs[arch]; ok { - continue - } +func (o *osArch) imageTag() string { + switch o.os { + case "linux": + switch o.arch { + case armArch: + return fmt.Sprintf("armv%s", o.version) + } + } + return o.arch +} + +func BuildDist(dist string, onlyBuild bool) config.Project { + switch dist { + case coreDistro: + return otelColDist.BuildProject() + case otlpDistro: + return otlpDist.BuildProject() + case k8sDistro: + return k8sDist.BuildProject() + case contribDistro: + if onlyBuild { + return contribBuildOnlyDist.BuildProject() } + return contribDist.BuildProject() + default: + panic("Unknown distribution") + } +} + +func osDockerManifest(prefix, version, dist, os string, archs []string) config.DockerManifest { + var imageTemplates []string + for _, arch := range archs { switch arch { - case ArmArch: - for _, armVers := range ArmVersions(dist) { - dockerArchTag := strings.ReplaceAll(archName(arch, armVers), "/", "") + case armArch: + for _, armVers := range armVersions(dist) { + dockerArchTag := (&osArch{os: os, arch: arch, version: armVers}).imageTag() imageTemplates = append( imageTemplates, fmt.Sprintf("%s/%s:%s-%s", prefix, imageName(dist), version, dockerArchTag), @@ -368,61 +582,24 @@ func DockerManifest(prefix, version, dist string) config.DockerManifest { } } +func armVersions(dist string) []string { + if dist == k8sDistro { + return nil + } + return []string{"7"} +} + // imageName translates a distribution name to a container image name. func imageName(dist string) string { - return strings.Replace(dist, BinaryNamePrefix, ImageNamePrefix, 1) + return strings.Replace(dist, binaryNamePrefix, imageNamePrefix, 1) } // archName translates architecture to docker platform names. func archName(arch, armVersion string) string { switch arch { - case ArmArch: + case armArch: return fmt.Sprintf("%s/v%s", arch, armVersion) default: return arch } } - -func Sign() []config.Sign { - return []config.Sign{ - { - Artifacts: "all", - Signature: "${artifact}.sig", - Certificate: "${artifact}.pem", - Cmd: "cosign", - Args: []string{ - "sign-blob", - "--output-signature", - "${artifact}.sig", - "--output-certificate", - "${artifact}.pem", - "${artifact}", - }, - }, - } -} - -func DockerSigns() []config.Sign { - return []config.Sign{ - { - Artifacts: "all", - Args: []string{ - "sign", - "${artifact}", - }, - }, - } -} - -func SBOM() []config.SBOM { - return []config.SBOM{ - { - ID: "archive", - Artifacts: "archive", - }, - { - ID: "package", - Artifacts: "package", - }, - } -} diff --git a/cmd/goreleaser/main.go b/cmd/goreleaser/main.go index f28adebaf..edb60797d 100644 --- a/cmd/goreleaser/main.go +++ b/cmd/goreleaser/main.go @@ -19,14 +19,15 @@ import ( "log" "os" - "github.com/goreleaser/goreleaser-pro/v2/pkg/config" "gopkg.in/yaml.v3" "github.com/open-telemetry/opentelemetry-collector-releases/cmd/goreleaser/internal" ) -var distFlag = flag.String("d", "", "Collector distributions to build") -var contribBuildOrRestFlag = flag.Bool("generate-build-step", false, "Collector Contrib distribution only - switch between build and package config file - set to true to generate build step, false to generate package step") +var ( + distFlag = flag.String("d", "", "Collector distributions to build") + contribBuildOrRestFlag = flag.Bool("generate-build-step", false, "Collector Contrib distribution only - switch between build and package config file - set to true to generate build step, false to generate package step") +) func main() { flag.Parse() @@ -34,14 +35,7 @@ func main() { if len(*distFlag) == 0 { log.Fatal("no distribution to build") } - var project config.Project - - if *distFlag == internal.ContribDistro && *contribBuildOrRestFlag { - // Special care needs to be taken for otelcol-contrib since it has a split setup - project = internal.GenerateContribBuildOnly(*distFlag, *contribBuildOrRestFlag) - } else { - project = internal.Generate(*distFlag, *contribBuildOrRestFlag) - } + project := internal.BuildDist(*distFlag, *contribBuildOrRestFlag) e := yaml.NewEncoder(os.Stdout) e.SetIndent(2) diff --git a/distributions/otelcol-contrib/.goreleaser-build.yaml b/distributions/otelcol-contrib/.goreleaser-build.yaml index d92100837..ac44e2802 100644 --- a/distributions/otelcol-contrib/.goreleaser-build.yaml +++ b/distributions/otelcol-contrib/.goreleaser-build.yaml @@ -1,11 +1,14 @@ version: 2 project_name: opentelemetry-collector-releases +env: + - COSIGN_YES=true + - LD_FLAGS=-s -w + - CGO_ENABLED=0 + - BUILD_FLAGS=-trimpath builds: - - id: otelcol-contrib + - id: otelcol-contrib-linux goos: - - darwin - linux - - windows goarch: - "386" - amd64 @@ -15,30 +18,38 @@ builds: - s390x goarm: - "7" - goppc64: - - power8 - ignore: - - goos: darwin - goarch: "386" - - goos: darwin - goarch: arm - - goos: darwin - goarch: s390x - - goos: windows - goarch: arm - - goos: windows - goarch: arm64 - - goos: windows - goarch: s390x dir: _build binary: otelcol-contrib ldflags: - - -s - - -w + - '{{ .Env.LD_FLAGS }}' + flags: + - '{{ .Env.BUILD_FLAGS }}' + - id: otelcol-contrib-darwin + goos: + - darwin + goarch: + - amd64 + - arm64 + dir: _build + binary: otelcol-contrib + ldflags: + - '{{ .Env.LD_FLAGS }}' + flags: + - '{{ .Env.BUILD_FLAGS }}' + - id: otelcol-contrib-windows + goos: + - windows + goarch: + - "386" + - amd64 + - arm64 + - ppc64le + dir: _build + binary: otelcol-contrib + ldflags: + - '{{ .Env.LD_FLAGS }}' flags: - - -trimpath - env: - - CGO_ENABLED=0 + - '{{ .Env.BUILD_FLAGS }}' archives: - formats: - binary diff --git a/distributions/otelcol-contrib/.goreleaser.yaml b/distributions/otelcol-contrib/.goreleaser.yaml index ea5763f73..533632346 100644 --- a/distributions/otelcol-contrib/.goreleaser.yaml +++ b/distributions/otelcol-contrib/.goreleaser.yaml @@ -2,6 +2,9 @@ version: 2 project_name: opentelemetry-collector-releases env: - COSIGN_YES=true + - LD_FLAGS=-s -w + - CGO_ENABLED=0 + - BUILD_FLAGS=-trimpath msi: - id: otelcol-contrib name: otelcol-contrib_{{ .Version }}_{{ .Os }}_{{ .MsiArch }} @@ -10,11 +13,9 @@ msi: - opentelemetry.ico - config.yaml builds: - - id: otelcol-contrib + - id: otelcol-contrib-linux goos: - - darwin - linux - - windows goarch: - "386" - amd64 @@ -26,28 +27,49 @@ builds: - "7" goppc64: - power8 - ignore: - - goos: darwin - goarch: "386" - - goos: darwin - goarch: arm - - goos: darwin - goarch: s390x - - goos: windows - goarch: arm - - goos: windows - goarch: arm64 - - goos: windows - goarch: s390x dir: _build binary: otelcol-contrib builder: prebuilt prebuilt: - path: artifacts/otelcol-contrib_{{ .Target }}/otelcol-contrib{{- if eq .Os "windows" }}.exe{{ end }} + path: artifacts/otelcol-contrib-linux_{{ .Target }}/otelcol-contrib + - id: otelcol-contrib-darwin + goos: + - darwin + goarch: + - amd64 + - arm64 + goarm: + - "7" + goppc64: + - power8 + dir: _build + binary: otelcol-contrib + builder: prebuilt + prebuilt: + path: artifacts/otelcol-contrib-darwin_{{ .Target }}/otelcol-contrib + - id: otelcol-contrib-windows + goos: + - windows + goarch: + - "386" + - amd64 + - arm64 + - ppc64le + goarm: + - "7" + goppc64: + - power8 + dir: _build + binary: otelcol-contrib + builder: prebuilt + prebuilt: + path: artifacts/otelcol-contrib-windows_{{ .Target }}/otelcol-contrib.exe archives: - id: otelcol-contrib builds: - - otelcol-contrib + - otelcol-contrib-linux + - otelcol-contrib-darwin + - otelcol-contrib-windows name_template: '{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}' nfpms: - package_name: otelcol-contrib @@ -70,7 +92,7 @@ nfpms: - /bin/sh id: otelcol-contrib builds: - - otelcol-contrib + - otelcol-contrib-linux formats: - deb - rpm diff --git a/distributions/otelcol-k8s/.goreleaser.yaml b/distributions/otelcol-k8s/.goreleaser.yaml index 548aa2254..643d024fe 100644 --- a/distributions/otelcol-k8s/.goreleaser.yaml +++ b/distributions/otelcol-k8s/.goreleaser.yaml @@ -2,8 +2,11 @@ version: 2 project_name: opentelemetry-collector-releases env: - COSIGN_YES=true + - LD_FLAGS=-s -w + - CGO_ENABLED=0 + - BUILD_FLAGS=-trimpath builds: - - id: otelcol-k8s + - id: otelcol-k8s-linux goos: - linux goarch: @@ -16,16 +19,13 @@ builds: dir: _build binary: otelcol-k8s ldflags: - - -s - - -w + - '{{ .Env.LD_FLAGS }}' flags: - - -trimpath - env: - - CGO_ENABLED=0 + - '{{ .Env.BUILD_FLAGS }}' archives: - id: otelcol-k8s builds: - - otelcol-k8s + - otelcol-k8s-linux name_template: '{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}' checksum: name_template: '{{ .ProjectName }}_otelcol-k8s_checksums.txt' diff --git a/distributions/otelcol-otlp/.goreleaser.yaml b/distributions/otelcol-otlp/.goreleaser.yaml index d61231dff..b6d2cd2c9 100644 --- a/distributions/otelcol-otlp/.goreleaser.yaml +++ b/distributions/otelcol-otlp/.goreleaser.yaml @@ -2,6 +2,9 @@ version: 2 project_name: opentelemetry-collector-releases env: - COSIGN_YES=true + - LD_FLAGS=-s -w + - CGO_ENABLED=0 + - BUILD_FLAGS=-trimpath msi: - id: otelcol-otlp name: otelcol-otlp_{{ .Version }}_{{ .Os }}_{{ .MsiArch }} @@ -9,11 +12,9 @@ msi: extra_files: - opentelemetry.ico builds: - - id: otelcol-otlp + - id: otelcol-otlp-linux goos: - - darwin - linux - - windows goarch: - "386" - amd64 @@ -25,32 +26,46 @@ builds: - "7" goppc64: - power8 - ignore: - - goos: darwin - goarch: "386" - - goos: darwin - goarch: arm - - goos: darwin - goarch: s390x - - goos: windows - goarch: arm - - goos: windows - goarch: arm64 - - goos: windows - goarch: s390x dir: _build binary: otelcol-otlp ldflags: - - -s - - -w + - '{{ .Env.LD_FLAGS }}' + flags: + - '{{ .Env.BUILD_FLAGS }}' + - id: otelcol-otlp-darwin + goos: + - darwin + goarch: + - amd64 + - arm64 + dir: _build + binary: otelcol-otlp + ldflags: + - '{{ .Env.LD_FLAGS }}' + flags: + - '{{ .Env.BUILD_FLAGS }}' + - id: otelcol-otlp-windows + goos: + - windows + goarch: + - "386" + - amd64 + - arm64 + - ppc64le + goppc64: + - power8 + dir: _build + binary: otelcol-otlp + ldflags: + - '{{ .Env.LD_FLAGS }}' flags: - - -trimpath - env: - - CGO_ENABLED=0 + - '{{ .Env.BUILD_FLAGS }}' archives: - id: otelcol-otlp builds: - - otelcol-otlp + - otelcol-otlp-linux + - otelcol-otlp-darwin + - otelcol-otlp-windows name_template: '{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}' nfpms: - package_name: otelcol-otlp @@ -70,7 +85,7 @@ nfpms: - /bin/sh id: otelcol-otlp builds: - - otelcol-otlp + - otelcol-otlp-linux formats: - deb - rpm diff --git a/distributions/otelcol/.goreleaser.yaml b/distributions/otelcol/.goreleaser.yaml index ecd17fc99..f41ca1d12 100644 --- a/distributions/otelcol/.goreleaser.yaml +++ b/distributions/otelcol/.goreleaser.yaml @@ -2,6 +2,9 @@ version: 2 project_name: opentelemetry-collector-releases env: - COSIGN_YES=true + - LD_FLAGS=-s -w + - CGO_ENABLED=0 + - BUILD_FLAGS=-trimpath msi: - id: otelcol name: otelcol_{{ .Version }}_{{ .Os }}_{{ .MsiArch }} @@ -10,11 +13,9 @@ msi: - opentelemetry.ico - config.yaml builds: - - id: otelcol + - id: otelcol-linux goos: - - darwin - linux - - windows goarch: - "386" - amd64 @@ -26,32 +27,46 @@ builds: - "7" goppc64: - power8 - ignore: - - goos: darwin - goarch: "386" - - goos: darwin - goarch: arm - - goos: darwin - goarch: s390x - - goos: windows - goarch: arm - - goos: windows - goarch: arm64 - - goos: windows - goarch: s390x dir: _build binary: otelcol ldflags: - - -s - - -w + - '{{ .Env.LD_FLAGS }}' + flags: + - '{{ .Env.BUILD_FLAGS }}' + - id: otelcol-darwin + goos: + - darwin + goarch: + - amd64 + - arm64 + dir: _build + binary: otelcol + ldflags: + - '{{ .Env.LD_FLAGS }}' + flags: + - '{{ .Env.BUILD_FLAGS }}' + - id: otelcol-windows + goos: + - windows + goarch: + - "386" + - amd64 + - arm64 + - ppc64le + goppc64: + - power8 + dir: _build + binary: otelcol + ldflags: + - '{{ .Env.LD_FLAGS }}' flags: - - -trimpath - env: - - CGO_ENABLED=0 + - '{{ .Env.BUILD_FLAGS }}' archives: - id: otelcol builds: - - otelcol + - otelcol-linux + - otelcol-darwin + - otelcol-windows name_template: '{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}' nfpms: - package_name: otelcol @@ -74,7 +89,7 @@ nfpms: - /bin/sh id: otelcol builds: - - otelcol + - otelcol-linux formats: - deb - rpm