diff --git a/.gitignore b/.gitignore index 73713a2db78c8..32a41051640e3 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,4 @@ shellcheck-reports # These files need to be ignored in order for `make tag` return a clean version string. repository-to-cpe.json container-name-repos-map.json +pkg/version/internal/zversion.go diff --git a/operator/Dockerfile b/operator/Dockerfile index 0ebaa95528713..03be79b6676d8 100644 --- a/operator/Dockerfile +++ b/operator/Dockerfile @@ -44,10 +44,14 @@ COPY generated/ generated/ # Copy scripts/go-build.sh and dependencies. COPY scripts/ scripts/ -COPY operator/build/status.sh status.sh -# This creates a git repo in workdir so that `git grep` command in build.sh can succeed and actually find //XDef-s. -RUN git init && git add . +# Copy version data files needed by go-tool.sh. +COPY *VERSION ./ + +# go-tool.sh needs BUILD_TAG to generate version info when there's no .git +# directory. The Makefile sets this via --build-arg from `make tag`. +ARG BUILD_TAG +ENV BUILD_TAG=${BUILD_TAG} # We've been historically building operator without CGO both upstream and downstream. ENV CGO_ENABLED=0 diff --git a/operator/Makefile b/operator/Makefile index 64b16c917bf5a..c31f8232198d2 100644 --- a/operator/Makefile +++ b/operator/Makefile @@ -336,23 +336,9 @@ chart: kubebuilder manifests ## Generate a helm chart with all necessary resourc build: manifests generate fmt vet ## Build operator local binary. ../scripts/go-build-file.sh ./cmd/main.go bin/manager -.PHONY: smuggled-status-sh -smuggled-status-sh: - $(SILENT)( \ - `# status.sh file is used by scripts/go-build.sh which we try to run in the docker container.` \ - `# status.sh needs git repo, make and Makefile and who knows what else but its actual output is simple.` \ - `# Here we grab the output and create a new build/status.sh from it. That file will be copied into the` \ - `# container and used there without having to bring all dependencies.` \ - set -euxo pipefail ;\ - smuggled_status_sh="$(PROJECT_DIR)/build/status.sh" ;\ - mkdir -p "$(PROJECT_DIR)/build" ;\ - cd "$(PROJECT_DIR)/.." ;\ - echo "#!/bin/sh" > "$${smuggled_status_sh}" ;\ - ./status.sh | awk '{print "echo \"" $$0 "\""}' >> "$${smuggled_status_sh}" ;\ - chmod +x "$${smuggled_status_sh}" ;\ - `# Verify that the resulting status.sh is actually runnable` \ - "$${smuggled_status_sh}" ;\ - ) + +# Version tag passed to Docker builds for go-tool.sh version generation. +OPERATOR_BUILD_TAG ?= $(shell cd .. && make --quiet --no-print-directory tag) # Force re-building the file to make sure the current environment is correctly reflected. .PHONY: build/Dockerfile.gen @@ -361,10 +347,11 @@ build/Dockerfile.gen: Dockerfile sed -e 's,$${ROX_IMAGE_FLAVOR},$(ROX_IMAGE_FLAVOR),g; s,$${BUILD_IMAGE_VERSION},$(shell sed 's/\s*\#.*//' ../BUILD_IMAGE_VERSION),' < $< > $@ .PHONY: docker-build -docker-build: build/Dockerfile.gen smuggled-status-sh ## Build docker image with the operator. +docker-build: build/Dockerfile.gen ## Build docker image with the operator. BUILDKIT_PROGRESS=plain ../scripts/docker-build.sh \ -t ${IMG} \ $(if $(GOARCH),--build-arg TARGET_ARCH=$(GOARCH)) \ + --build-arg BUILD_TAG=$(OPERATOR_BUILD_TAG) \ -f $< \ .. @@ -567,11 +554,11 @@ docker-push-index: ## Push docker image with the index. # To properly provided solutions that supports more than one platform you should use this option. PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le .PHONY: docker-buildx -docker-buildx: smuggled-status-sh test build/Dockerfile.gen ## Build and push docker image for the manager for cross-platform support +docker-buildx: test build/Dockerfile.gen ## Build and push docker image for the manager for cross-platform support # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' build/Dockerfile.gen > build/Dockerfile.cross - docker buildx create --name project-v3-builder docker buildx use project-v3-builder - - docker buildx build --platform=$(PLATFORMS) --push --tag ${IMG} -f build/Dockerfile.cross .. + - docker buildx build --platform=$(PLATFORMS) --push --tag ${IMG} --build-arg BUILD_TAG=$(OPERATOR_BUILD_TAG) -f build/Dockerfile.cross .. - docker buildx rm project-v3-builder rm build/Dockerfile.cross diff --git a/pkg/version/internal/version_data.go b/pkg/version/internal/version_data.go index 47b7af84355c7..343b8a6d10a58 100644 --- a/pkg/version/internal/version_data.go +++ b/pkg/version/internal/version_data.go @@ -1,14 +1,16 @@ package internal +// Version variables are populated at init time by the generated zversion.go +// file (created by go-tool.sh). Without go-tool.sh, all values remain empty. var ( // MainVersion is the Rox version. - MainVersion string //XDef:STABLE_MAIN_VERSION + MainVersion string // CollectorVersion is the collector version to be used by default. - CollectorVersion string //XDef:STABLE_COLLECTOR_VERSION + CollectorVersion string // FactVersion is the fact version to be used by default. - FactVersion string //XDef:STABLE_FACT_VERSION + FactVersion string // ScannerVersion is the scanner version to be used with this Rox version. - ScannerVersion string //XDef:STABLE_SCANNER_VERSION + ScannerVersion string // GitShortSha is the (short) Git SHA that was built. - GitShortSha string //XDef:STABLE_GIT_SHORT_SHA + GitShortSha string ) diff --git a/scripts/go-tool.sh b/scripts/go-tool.sh index 4d96666e4a775..7dbbad9280917 100755 --- a/scripts/go-tool.sh +++ b/scripts/go-tool.sh @@ -12,46 +12,55 @@ die() { } RACE="${RACE:-false}" - -x_defs=() -x_def_errors=() - -while read -r line || [[ -n "$line" ]]; do - if [[ "$line" =~ ^[[:space:]]*$ ]]; then - continue - elif [[ "$line" =~ ^([^[:space:]]+)[[:space:]]+(.*)[[:space:]]*$ ]]; then - var="${BASH_REMATCH[1]}" - def="${BASH_REMATCH[2]}" - eval "status_${var}=$(printf '%q' "$def")" +REPO_ROOT="${SCRIPT_DIR}/.." + +# Read version data from committed files. +COLLECTOR_VERSION="$(cat "${REPO_ROOT}/COLLECTOR_VERSION")" || die "Missing COLLECTOR_VERSION" +SCANNER_VERSION="$(cat "${REPO_ROOT}/SCANNER_VERSION")" || die "Missing SCANNER_VERSION" +FACT_VERSION="$(cat "${REPO_ROOT}/FACT_VERSION")" || die "Missing FACT_VERSION" + +# Generate version data file. Tests use only the base tag (stable across +# commits) to keep ActionIDs stable for test result caching. Builds get +# the full git-describe version with commit count and SHA. +generate_version_file() { + local target="${REPO_ROOT}/pkg/version/internal/zversion.go" + local main_version git_short_sha + + if [[ "$TOOL" == "test" ]]; then + # Base tag only (e.g. "4.11.x") — stable across commits. + main_version="$(cd "${REPO_ROOT}"; git describe --tags --abbrev=0 --exclude '*-nightly-*' 2>/dev/null)" || die "git describe failed" + git_short_sha="" + elif [[ -n "${BUILD_TAG:-}" ]]; then + # Konflux/release builds set BUILD_TAG to the full version string. + # Use it directly (the Docker build context has no .git directory). + main_version="${BUILD_TAG}" + git_short_sha="$(echo "$BUILD_TAG" | sed -n 's/.*g\([0-9a-f]\{1,\}\)$/\1/p')" else - die "Malformed status.sh output line ${line}" + # Full version from git describe (e.g. "4.11.x-193-g7257553280"). + main_version="$(cd "${REPO_ROOT}"; git describe --tags --abbrev=10 --long --exclude '*-nightly-*' 2>/dev/null)" || die "git describe failed" + git_short_sha="$(cd "${REPO_ROOT}"; git rev-parse --short HEAD 2>/dev/null || echo "")" fi -done < <(cd "${SCRIPT_DIR}/.."; ./status.sh) - -while read -r line || [[ -n "$line" ]]; do - if [[ "$line" =~ ^[[:space:]]*$ ]]; then - continue - elif [[ "$line" =~ ^([^:]+):([[:digit:]]+):[[:space:]]*(var[[:space:]]+)?([^[:space:]]+)[[:space:]].*//XDef:([^[:space:]]+)[[:space:]]*$ ]]; then - go_file="${BASH_REMATCH[1]}" - go_line="${BASH_REMATCH[2]}" - go_var="${BASH_REMATCH[4]}" - status_var="${BASH_REMATCH[5]}" - - varname="status_${status_var}" - [[ -n "${!varname}" ]] || x_def_errors+=( - "Variable ${go_var} defined in ${go_file}:${go_line} references status var ${status_var} that is not part of the status.sh output" - ) - go_package="$(cd "${SCRIPT_DIR}/.."; go list -e "./$(dirname "$go_file")")" - - x_defs+=(-X "\"${go_package}.${go_var}=${!varname}\"") + + local new_content + new_content="// Code generated by go-tool.sh; DO NOT EDIT. + +package internal + +func init() { + MainVersion = \"${main_version}\" + CollectorVersion = \"${COLLECTOR_VERSION}\" + FactVersion = \"${FACT_VERSION}\" + ScannerVersion = \"${SCANNER_VERSION}\" + GitShortSha = \"${git_short_sha}\" +}" + if [[ -f "$target" ]] && [[ "$(cat "$target")" == "$new_content" ]]; then + return fi -done < <(git -C "${SCRIPT_DIR}/.." grep -n '//XDef:' -- '*.go') -if [[ "${#x_def_errors[@]}" -gt 0 ]]; then - printf >&2 "%s\n" "${x_def_errors[@]}" - exit 1 -fi + echo "$new_content" > "$target" +} +generate_version_file -ldflags=("${x_defs[@]}") +ldflags=() if [[ "$DEBUG_BUILD" != "yes" ]]; then ldflags+=(-s -w) fi