From c578982594342e74eb3065933b91922c5457bae3 Mon Sep 17 00:00:00 2001 From: Tomasz Janiszewski Date: Wed, 1 Apr 2026 10:54:56 +0200 Subject: [PATCH 1/5] Add Konflux pipeline for Go version validation Create a minimal, hermetic Konflux pipeline to verify Go version compatibility by running 'go mod tidy'. The pipeline: - Triggers automatically on PRs that modify go.mod (via labeler) - Runs go mod tidy in the same Go environment as production builds - Fails if go.mod or go.sum are modified by tidy (indicating version issues) - Provides fast feedback (~2-5 min) compared to full builds (~1+ hour) - Uses hermetic builds with Cachi2 dependency prefetching Files: - .github/labeler.yml: Add go-mod-check label for go.mod changes - .tekton/go-mod-validation-pipeline.yaml: Pipeline definition with inline verify-go-mod-tidy task - .tekton/go-mod-validation-build.yaml: PipelineRun with triggers User request: Create a Konflux pipeline to check if the installed Go version supports the version specified in go.mod, using go mod tidy as the validation mechanism. Note: Requires service account 'build-pipeline-go-mod-validation' to be created by Konflux admins with access to quay.io/rhacs-eng/go-mod-validation. This change was partially generated with AI assistance. Co-Authored-By: Claude Sonnet 4.5 --- .github/labeler.yml | 5 + .tekton/go-mod-validation-build.yaml | 70 +++++++ .tekton/go-mod-validation-pipeline.yaml | 257 ++++++++++++++++++++++++ 3 files changed, 332 insertions(+) create mode 100644 .tekton/go-mod-validation-build.yaml create mode 100644 .tekton/go-mod-validation-pipeline.yaml diff --git a/.github/labeler.yml b/.github/labeler.yml index e00c2410a6e22..e572af38fd6cf 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -93,3 +93,8 @@ coderabbit-review: - roxctl/**/* - scripts/ci/**/ - sensor/**/* + +go-mod-check: +- changed-files: + - any-glob-to-any-file: + - go.mod diff --git a/.tekton/go-mod-validation-build.yaml b/.tekton/go-mod-validation-build.yaml new file mode 100644 index 0000000000000..cff34dce4b92b --- /dev/null +++ b/.tekton/go-mod-validation-build.yaml @@ -0,0 +1,70 @@ +apiVersion: tekton.dev/v1 +kind: PipelineRun + +metadata: + annotations: + build.appstudio.openshift.io/repo: https://github.com/stackrox/stackrox?rev={{revision}} + build.appstudio.redhat.com/commit_sha: '{{revision}}' + build.appstudio.redhat.com/pull_request_number: '{{pull_request_number}}' + build.appstudio.redhat.com/target_branch: '{{target_branch}}' + pipelinesascode.tekton.dev/max-keep-runs: "500" + pipelinesascode.tekton.dev/on-comment: "/konflux-retest go-mod-validation" + pipelinesascode.tekton.dev/on-cel-expression: | + event == "pull_request" && + (has(body.pull_request) && has(body.pull_request.labels) && + body.pull_request.labels.exists(l, l.name == "go-mod-check")) && + body.action != "ready_for_review" + pipelinesascode.tekton.dev/on-label: "[]" + labels: + appstudio.openshift.io/application: acs + appstudio.openshift.io/component: go-mod-validation + pipelines.appstudio.openshift.io/type: build + name: go-mod-validation-on-push + namespace: rh-acs-tenant + +spec: + + params: + - name: git-url + value: '{{source_url}}' + - name: revision + value: '{{revision}}' + - name: output-image-repo + value: quay.io/rhacs-eng/go-mod-validation + - name: clone-depth + value: '1' + - name: clone-fetch-tags + value: 'false' + - name: oci-artifact-expires-after + value: '1d' + - name: prefetch-input + value: | + [ + { "type": "gomod", "path": "." } + ] + + pipelineRef: + name: go-mod-validation-pipeline + + taskRunSpecs: + - pipelineTaskName: prefetch-dependencies + stepSpecs: + - name: prefetch-dependencies + computeResources: + limits: + cpu: 2 + requests: + cpu: 2 + + taskRunTemplate: + serviceAccountName: build-pipeline-go-mod-validation + + timeouts: + tasks: 10m + finally: 2m + pipeline: 12m + + workspaces: + - name: git-auth + secret: + secretName: '{{ git_auth_secret }}' diff --git a/.tekton/go-mod-validation-pipeline.yaml b/.tekton/go-mod-validation-pipeline.yaml new file mode 100644 index 0000000000000..678aef5219fc1 --- /dev/null +++ b/.tekton/go-mod-validation-pipeline.yaml @@ -0,0 +1,257 @@ +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: go-mod-validation-pipeline +spec: + + finally: + - name: slack-notification + params: + - name: message + value: ':x: `{{event_type}}` pipeline for (`go.mod validation`, revision <$(params.git-url)/commit/$(params.revision)|$(params.revision)>) has failed.' + - name: key-name + value: 'acs-konflux-notifications' + when: + - input: $(tasks.status) + operator: in + values: ["Failed"] + taskRef: + params: + - name: name + value: slack-webhook-notification + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-slack-webhook-notification:0.1@sha256:3eff579c511d6c5e846175920e8f184a87337e142bbc4c30107e76bda4a325cb + - name: kind + value: task + resolver: bundles + + - name: post-metric-end + params: + - name: AGGREGATE_TASKS_STATUS + value: $(tasks.status) + taskRef: &post-bigquery-metrics-ref + params: + - name: name + value: post-bigquery-metrics + - name: bundle + value: quay.io/rhacs-eng/konflux-tasks:latest@sha256:6d3297c7b231c086c8221087e4b315e422da4207823444a00faf411002523af0 + - name: kind + value: task + resolver: bundles + + params: + - description: Source Repository URL + name: git-url + type: string + - default: "" + description: Revision of the Source Repository + name: revision + type: string + - description: Output Image Repository (for OCI artifacts) + name: output-image-repo + type: string + - default: "1" + description: Depth of the git clone in number of commits. Use "1" for shallow clone. Use "0" for deep clone, i.e. to fetch all commits. + name: clone-depth + type: string + - default: "false" + description: Fetch tags with git clone + name: clone-fetch-tags + type: string + - default: "1d" + description: This sets the expiration time for intermediate OCI artifacts produced and used during builds after which they can be garbage collected. + name: oci-artifact-expires-after + type: string + - default: "false" + description: Enable cache proxy configuration + name: enable-cache-proxy + type: string + - default: "" + description: Build dependencies to be prefetched by Cachi2 + name: prefetch-input + type: string + + results: + - description: "" + name: CHAINS-GIT_URL + value: $(tasks.clone-repository.results.url) + - description: "" + name: CHAINS-GIT_COMMIT + value: $(tasks.clone-repository.results.commit) + - description: "" + name: GO_VERSION + value: $(tasks.verify-go-mod-tidy.results.GO_VERSION) + + workspaces: + - name: git-auth + + tasks: + + - name: post-metric-start + taskRef: *post-bigquery-metrics-ref + + - name: init + params: + - name: enable-cache-proxy + value: $(params.enable-cache-proxy) + taskRef: + params: + - name: name + value: init + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-init:0.4@sha256:288f3106118edc1d0f0c79a89c960abf5841a4dd8bc3f38feb10527253105b19 + - name: kind + value: task + resolver: bundles + + - name: clone-repository + params: + - name: url + value: $(params.git-url) + - name: revision + value: $(params.revision) + - name: depth + value: $(params.clone-depth) + - name: fetchTags + value: $(params.clone-fetch-tags) + - name: ociStorage + value: $(params.output-image-repo):konflux-$(params.revision).git + - name: ociArtifactExpiresAfter + value: $(params.oci-artifact-expires-after) + taskRef: + params: + - name: name + value: git-clone-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:2c388d28651457db60bb90287e7d8c3680303197196e4476878d98d81e8b6dc9 + - name: kind + value: task + resolver: bundles + workspaces: + - name: basic-auth + workspace: git-auth + + - name: prefetch-dependencies + params: + - name: input + value: $(params.prefetch-input) + - name: SOURCE_ARTIFACT + value: $(tasks.clone-repository.results.SOURCE_ARTIFACT) + - name: ociStorage + value: $(params.output-image-repo):konflux-$(params.revision).prefetch + - name: ociArtifactExpiresAfter + value: $(params.oci-artifact-expires-after) + taskRef: + params: + - name: name + value: prefetch-dependencies-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.3@sha256:a579d00fe370b6d9a1cb1751c883ecd0ec9f663604344e2fd61e1f6d5bf4e990 + - name: kind + value: task + resolver: bundles + workspaces: + - name: git-basic-auth + workspace: git-auth + + - name: verify-go-mod-tidy + params: + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + taskSpec: + params: + - name: SOURCE_ARTIFACT + type: string + - name: CACHI2_ARTIFACT + type: string + results: + - name: GO_VERSION + description: Go version used for validation + steps: + - name: verify + image: brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_9_golang_1.25@sha256:bd531796aacb86e4f97443797262680fbf36ca048717c00b6f4248465e1a7c0c + script: | + #!/bin/bash + set -euo pipefail + + # Extract source and Cachi2 artifacts from OCI storage + echo "=== Extracting source artifact ===" + SOURCE_OCI_PATH="${SOURCE_ARTIFACT#oci::}" + mkdir -p /workspace/source + oras pull -o /workspace/source "$SOURCE_OCI_PATH" + + echo "=== Extracting Cachi2 artifact ===" + CACHI2_OCI_PATH="${CACHI2_ARTIFACT#oci::}" + mkdir -p /workspace/cachi2 + oras pull -o /workspace/cachi2 "$CACHI2_OCI_PATH" + + cd /workspace/source + + # Inject Cachi2 environment for hermetic build + if [ -f /workspace/cachi2/cachi2.env ]; then + echo "=== Sourcing Cachi2 environment ===" + set +u + source /workspace/cachi2/cachi2.env + set -u + else + echo "WARNING: cachi2.env not found, proceeding without hermetic environment" + fi + + # Report Go version + echo "=== Go Version Check ===" + go version + go version > $(results.GO_VERSION.path) + + # Copy current state + echo "=== Saving current go.mod and go.sum ===" + cp go.mod go.mod.before + cp go.sum go.sum.before + + # Run go mod tidy + echo "=== Running go mod tidy ===" + go mod tidy + + # Check for changes + echo "=== Checking for changes ===" + CHANGES_DETECTED=0 + + if ! diff -u go.mod.before go.mod; then + echo "ERROR: go.mod changed after 'go mod tidy'" + CHANGES_DETECTED=1 + fi + + if ! diff -u go.sum.before go.sum; then + echo "ERROR: go.sum changed after 'go mod tidy'" + CHANGES_DETECTED=1 + fi + + if [ $CHANGES_DETECTED -eq 1 ]; then + echo "" + echo "================================" + echo "ERROR: go mod tidy produced changes!" + echo "================================" + echo "" + echo "This indicates one of the following:" + echo " 1. The go.mod or go.sum files were not up to date" + echo " 2. The installed Go version may not fully support go.mod requirements" + echo " 3. Dependencies need to be updated" + echo "" + echo "To fix this:" + echo " - Run 'go mod tidy' locally and commit the changes" + echo " - Ensure the Konflux build image uses a compatible Go version" + echo "" + exit 1 + fi + + echo "" + echo "================================" + echo "SUCCESS: go mod tidy produced no changes" + echo "================================" + echo "" + env: + - name: SOURCE_ARTIFACT + value: $(params.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(params.CACHI2_ARTIFACT) From b6c6990bd04aed7a9989ca8eb24446da496f92dd Mon Sep 17 00:00:00 2001 From: Tomasz Janiszewski Date: Wed, 1 Apr 2026 12:33:48 +0200 Subject: [PATCH 2/5] Simplify Go mod validation by removing diff checking The diff checking is unnecessary because go mod tidy will naturally fail with a clear error if the Go version is incompatible: 'go: go.mod requires go >= X.Y.Z (running go A.B.C)' Changes: - Keep Cachi2 prefetch task (required for hermetic dependency download) - Keep artifact extraction and environment sourcing - Remove file copying (cp go.mod go.mod.before) - Remove diff checking logic - Remove verbose error messages - Simplify to just run go mod tidy and report success This pipeline validates only: Can the installed Go version run go mod tidy? Other CI jobs check whether go.mod/go.sum are properly tidied. Co-Authored-By: Claude Sonnet 4.5 --- .tekton/go-mod-validation-pipeline.yaml | 48 ++----------------------- 1 file changed, 3 insertions(+), 45 deletions(-) diff --git a/.tekton/go-mod-validation-pipeline.yaml b/.tekton/go-mod-validation-pipeline.yaml index 678aef5219fc1..5d76bded0e533 100644 --- a/.tekton/go-mod-validation-pipeline.yaml +++ b/.tekton/go-mod-validation-pipeline.yaml @@ -201,55 +201,13 @@ spec: # Report Go version echo "=== Go Version Check ===" - go version - go version > $(results.GO_VERSION.path) + go version | tee $(results.GO_VERSION.path) - # Copy current state - echo "=== Saving current go.mod and go.sum ===" - cp go.mod go.mod.before - cp go.sum go.sum.before - - # Run go mod tidy + # Run go mod tidy - will fail if Go version is incompatible echo "=== Running go mod tidy ===" go mod tidy - # Check for changes - echo "=== Checking for changes ===" - CHANGES_DETECTED=0 - - if ! diff -u go.mod.before go.mod; then - echo "ERROR: go.mod changed after 'go mod tidy'" - CHANGES_DETECTED=1 - fi - - if ! diff -u go.sum.before go.sum; then - echo "ERROR: go.sum changed after 'go mod tidy'" - CHANGES_DETECTED=1 - fi - - if [ $CHANGES_DETECTED -eq 1 ]; then - echo "" - echo "================================" - echo "ERROR: go mod tidy produced changes!" - echo "================================" - echo "" - echo "This indicates one of the following:" - echo " 1. The go.mod or go.sum files were not up to date" - echo " 2. The installed Go version may not fully support go.mod requirements" - echo " 3. Dependencies need to be updated" - echo "" - echo "To fix this:" - echo " - Run 'go mod tidy' locally and commit the changes" - echo " - Ensure the Konflux build image uses a compatible Go version" - echo "" - exit 1 - fi - - echo "" - echo "================================" - echo "SUCCESS: go mod tidy produced no changes" - echo "================================" - echo "" + echo "=== SUCCESS: Go version is compatible with go.mod requirements ===" env: - name: SOURCE_ARTIFACT value: $(params.SOURCE_ARTIFACT) From 7bd31bd010401efeb96b5504883906f93c32ce33 Mon Sep 17 00:00:00 2001 From: Tomasz Janiszewski Date: Wed, 1 Apr 2026 12:59:54 +0200 Subject: [PATCH 3/5] Temporarily use build-pipeline-roxctl service account The build-pipeline-go-mod-validation service account hasn't been created yet. Temporarily use build-pipeline-roxctl to test the pipeline logic. TODO: Request the dedicated service account from Konflux admins: Name: build-pipeline-go-mod-validation Namespace: rh-acs-tenant Copy permissions from: build-pipeline-roxctl Co-Authored-By: Claude Sonnet 4.5 --- .tekton/go-mod-validation-build.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.tekton/go-mod-validation-build.yaml b/.tekton/go-mod-validation-build.yaml index cff34dce4b92b..9ad3dc29d7b57 100644 --- a/.tekton/go-mod-validation-build.yaml +++ b/.tekton/go-mod-validation-build.yaml @@ -57,7 +57,8 @@ spec: cpu: 2 taskRunTemplate: - serviceAccountName: build-pipeline-go-mod-validation + # TODO: Change to build-pipeline-go-mod-validation once created + serviceAccountName: build-pipeline-roxctl timeouts: tasks: 10m From a48e734537bd4334aa61f0cba8ace29dc69f69ac Mon Sep 17 00:00:00 2001 From: Tomasz Janiszewski Date: Wed, 1 Apr 2026 13:44:04 +0200 Subject: [PATCH 4/5] Use roxctl repository for OCI artifacts temporarily The build-pipeline-roxctl service account only has write access to quay.io/rhacs-eng/release-roxctl, not go-mod-validation. Temporarily use release-roxctl for storing OCI artifacts (git clone and Cachi2 prefetch results). TODO: Once dedicated service account is created, change back to quay.io/rhacs-eng/go-mod-validation Co-Authored-By: Claude Sonnet 4.5 --- .tekton/go-mod-validation-build.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.tekton/go-mod-validation-build.yaml b/.tekton/go-mod-validation-build.yaml index 9ad3dc29d7b57..dd3b9bd5f2c66 100644 --- a/.tekton/go-mod-validation-build.yaml +++ b/.tekton/go-mod-validation-build.yaml @@ -30,7 +30,8 @@ spec: - name: revision value: '{{revision}}' - name: output-image-repo - value: quay.io/rhacs-eng/go-mod-validation + # TODO: Change to quay.io/rhacs-eng/go-mod-validation once dedicated service account is created + value: quay.io/rhacs-eng/release-roxctl - name: clone-depth value: '1' - name: clone-fetch-tags From e6ab972058c738c075b540b70c033a9374c67475 Mon Sep 17 00:00:00 2001 From: Tomasz Janiszewski Date: Wed, 1 Apr 2026 16:19:27 +0200 Subject: [PATCH 5/5] Install oras CLI in verification task The openshift-golang-builder image doesn't include oras, which is needed to extract OCI artifacts. Install it at runtime from GitHub releases. This adds ~5 seconds to the pipeline but avoids needing a custom image. Alternative considered: Create a custom Dockerfile with oras pre-installed, but that adds maintenance overhead for a simple validation pipeline. Co-Authored-By: Claude Sonnet 4.5 --- .tekton/go-mod-validation-pipeline.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.tekton/go-mod-validation-pipeline.yaml b/.tekton/go-mod-validation-pipeline.yaml index 5d76bded0e533..86501970e5d78 100644 --- a/.tekton/go-mod-validation-pipeline.yaml +++ b/.tekton/go-mod-validation-pipeline.yaml @@ -176,6 +176,13 @@ spec: #!/bin/bash set -euo pipefail + # Install oras CLI + echo "=== Installing oras ===" + curl -LO https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_linux_amd64.tar.gz + tar -xzf oras_1.1.0_linux_amd64.tar.gz + chmod +x oras + mv oras /usr/local/bin/ + # Extract source and Cachi2 artifacts from OCI storage echo "=== Extracting source artifact ===" SOURCE_OCI_PATH="${SOURCE_ARTIFACT#oci::}"