Skip to content
Open
Show file tree
Hide file tree
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
35 changes: 35 additions & 0 deletions internal/dockerfile/Dockerfile.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,41 @@ RUN {{ if .UseBuildKit }}--mount=type=cache,target=/go/pkg/mod \
{{ end -}}
################################################################################

# To only build the tests run: docker build . --target test
# We can't do `FROM builder AS test` here, as then make prepare-static-check would not be cached during interactive use when developing
# and caching all the tools, especially golangci-lint, takes a few minutes.
FROM {{ .DockerHubMirror }}golang:{{ .Constants.DefaultGoVersion }}-alpine{{ .Constants.DefaultAlpineImage }} AS test

COPY Makefile /src/Makefile

# used below by USER
RUN addgroup -g 4200 appgroup \
&& adduser -h /home/appuser -s /sbin/nologin -G appgroup -D -u 4200 appuser

RUN apk add --no-cache --no-progress git make {{- range .ExtraTestPackages }} {{.}}{{ end }} \
{{- if .ReuseEnabled }}
&& pip3 install --break-system-packages reuse \
{{- end }}
&& make -C /src prepare-static-check


# We only copy here because we want the "prepare-static-check" to be cacheable.
# It is not a problem that we are overwriting the go cache from the earlier steps because we do not need to rebuild those tools.
COPY --from=builder /go /go
COPY --from=builder /src /src

RUN make -C /src static-check

# Some things like postgres do not like to run as root. For simplicity, just always run as an unprivileged user,
# but for it to be able to read the go cache, we need to allow it.
RUN chmod 777 -R /src/
USER 4200:4200
RUN cd /src \
&& git config --global --add safe.directory /src \
&& make build/cover.out

################################################################################

FROM {{ .DockerHubMirror }}alpine:{{ .Constants.DefaultAlpineImage }}

{{ if not $dcfg.RunAsRoot -}}
Expand Down
21 changes: 19 additions & 2 deletions internal/dockerfile/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/sapcc/go-bits/must"

"github.com/sapcc/go-makefile-maker/internal/core"
"github.com/sapcc/go-makefile-maker/internal/golang"
"github.com/sapcc/go-makefile-maker/internal/util"
)

Expand All @@ -22,7 +23,7 @@ var (
dockerignoreTemplate string
)

func RenderConfig(cfg core.Configuration) {
func RenderConfig(cfg core.Configuration, sr golang.ScanResult) {
// if there is an entrypoint configured use that otherwise fallback to the first binary name
var entrypoint string
if len(cfg.Dockerfile.Entrypoint) > 0 {
Expand Down Expand Up @@ -70,19 +71,35 @@ func RenderConfig(cfg core.Configuration) {
dockerHubMirror = "keppel.eu-de-1.cloud.sap/ccloud-dockerhub-mirror/library/"
}

var extraTestPackages []string
reuseEnabled := cfg.Reuse.Enabled.UnwrapOr(true)
if reuseEnabled {
extraTestPackages = append(extraTestPackages, "py3-pip")
}
if sr.UsesPostgres {
extraTestPackages = append(extraTestPackages, "postgresql")
}

must.Succeed(util.WriteFileFromTemplate("Dockerfile", dockerfileTemplate, map[string]any{
"Config": cfg,
"Constants": map[string]any{
"DefaultGoVersion": core.DefaultGoVersion,
"DefaultAlpineImage": core.DefaultAlpineImage,
},
"DockerHubMirror": dockerHubMirror,
"ExtraTestPackages": extraTestPackages,
"Entrypoint": entrypoint,
"ReuseEnabled": reuseEnabled,
"RunCommands": strings.Join(commands, " \\\n && "),
"RunVersionCommands": strings.Join(runVersionCommands, " \\\n && "),
"UseBuildKit": cfg.Dockerfile.UseBuildKit,
}))

ignores := cfg.Dockerfile.ExtraIgnores
if sr.UsesPostgres {
ignores = append(ignores, "/.testdb/")
}
must.Succeed(util.WriteFileFromTemplate(".dockerignore", dockerignoreTemplate, map[string]any{
"ExtraIgnores": cfg.Dockerfile.ExtraIgnores,
"ExtraIgnores": ignores,
}))
}
3 changes: 0 additions & 3 deletions internal/dockerfile/dockerignore.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@
# TODO: uncomment when applications no longer use git to get version information
#.git/
/.github/
/.gitignore
/.golangci.yaml
/.goreleaser.yml
/.vscode/
/CONTRIBUTING.md
/Dockerfile
/LICENSE*
/Makefile.maker.yaml
/README.md
/build/
Expand Down
73 changes: 44 additions & 29 deletions internal/makefile/makefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func newMakefile(cfg core.Configuration, sr golang.ScanResult) *makefile {
// TODO: checking on GoVersion is only an aid until we can properly detect rust applications
isGolang := sr.GoVersion != ""
isSAPCC := cfg.Metadata.IsSAPProject()
reuseEnabled := cfg.Reuse.Enabled.UnwrapOr(true)

///////////////////////////////////////////////////////////////////////////
// General
Expand Down Expand Up @@ -153,22 +154,24 @@ endif
})
prepareStaticRecipe = append(prepareStaticRecipe, "install-addlicense")

prepare.addRule(rule{
description: "Install reuse required by license-headers/check-reuse",
phony: true,
target: "install-reuse",
recipe: []string{
`@if ! hash reuse 2>/dev/null; then` +
` if ! hash pip3 2>/dev/null; then` +
` printf "\e[1;31m>> Cannot install reuse because no pip3 was found. Either install it using your package manager or install pip3\e[0m\n";` +
` else` +
` printf "\e[1;36m>> Installing reuse...\e[0m\n";` +
` pip3 install --user reuse;` +
` fi;` +
` fi`,
},
})
prepareStaticRecipe = append(prepareStaticRecipe, "install-reuse")
if reuseEnabled {
prepare.addRule(rule{
description: "Install reuse required by license-headers/check-reuse",
phony: true,
target: "install-reuse",
recipe: []string{
`@if ! hash reuse 2>/dev/null; then` +
` if ! hash pip3 2>/dev/null; then` +
` printf "\e[1;31m>> Cannot install reuse because no pip3 was found. Either install it using your package manager or install pip3\e[0m\n";` +
` else` +
` printf "\e[1;36m>> Installing reuse...\e[0m\n";` +
` pip3 install --user reuse;` +
` fi;` +
` fi`,
},
})
prepareStaticRecipe = append(prepareStaticRecipe, "install-reuse")
}
}
// add target for installing dependencies for `make static-check`
prepare.addRule(rule{
Expand Down Expand Up @@ -506,11 +509,16 @@ endif
`))
copyright := cfg.License.Copyright.UnwrapOr("SAP SE or an SAP affiliate company")

licenseHeaderPrereqs := []string{"install-addlicense"}
if reuseEnabled {
licenseHeaderPrereqs = append(licenseHeaderPrereqs, "install-reuse")
}

dev.addRule(rule{
description: "Add (or overwrite) license headers on all non-vendored source code files.",
target: "license-headers",
phony: true,
prerequisites: []string{"install-addlicense", "install-reuse"},
prerequisites: licenseHeaderPrereqs,
recipe: []string{
`@printf "\e[1;36m>> addlicense (for license headers on source code files)\e[0m\n"`,
// We must use gawk to use gnu awk on Darwin
Expand Down Expand Up @@ -544,22 +552,29 @@ endif
fmt.Sprintf(`@addlicense --check %s %s`, ignoreOptionsStr, allSourceFilesExpr),
},
})
test.addRule(rule{
description: "Check reuse compliance",
target: "check-reuse",
phony: true,
prerequisites: []string{"install-reuse"},
recipe: []string{
`@printf "\e[1;36m>> reuse lint\e[0m\n"`,
// reuse is very verbose, so we only show the output if there are problems
`@if ! reuse lint -q; then reuse lint; fi`,
},
})
if reuseEnabled {
test.addRule(rule{
description: "Check reuse compliance",
target: "check-reuse",
phony: true,
prerequisites: []string{"install-reuse"},
recipe: []string{
`@printf "\e[1;36m>> reuse lint\e[0m\n"`,
// reuse is very verbose, so we only show the output if there are problems
`@if ! reuse lint -q; then reuse lint; fi`,
},
})
}
// add target for static code checks
staticCodeChecksPrerequisites := []string{"check-addlicense"}
if reuseEnabled {
staticCodeChecksPrerequisites = append(staticCodeChecksPrerequisites, "check-reuse")
}
test.addRule(rule{
description: "Run static code checks",
phony: true,
target: "check-license-headers",
prerequisites: []string{"check-addlicense", "check-reuse"},
prerequisites: staticCodeChecksPrerequisites,
})

if isGolang {
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func main() {
// Render Dockerfile
if cfg.Dockerfile.Enabled {
logg.Debug("rendering Dockerfile")
dockerfile.RenderConfig(cfg)
dockerfile.RenderConfig(cfg, sr)
}

// Render golangci-lint config file
Expand Down
Loading