From 7aa38ce89f0a632be1b97a3e04fa39281a2c3f5a Mon Sep 17 00:00:00 2001 From: Sean Conroy Date: Tue, 23 Jun 2026 11:27:02 +0100 Subject: [PATCH] fix(KFLUXSPRT-8173): use taskGitRevision SHA for pipeline metadata The operator already resolves the pipeline ref revision to a SHA via ResolveBranchToSHA and passes it as taskGitRevision. Use that directly instead of calling the GitHub API. Fail back to curl-with-retry if taskGitRevision is not a SHA. The curl will not fail the task since it is only metadata. Signed-off-by: Sean Conroy --- tasks/managed/collect-data/collect-data.yaml | 8 +- tasks/managed/collect-data/tests/mocks.sh | 9 +- ...lect-data-print-pipeline-ref-api-fail.yaml | 246 +++++++++++++++++ ...t-collect-data-print-pipeline-ref-sha.yaml | 248 ++++++++++++++++++ .../test-collect-data-print-pipeline-ref.yaml | 5 +- 5 files changed, 510 insertions(+), 6 deletions(-) create mode 100644 tasks/managed/collect-data/tests/test-collect-data-print-pipeline-ref-api-fail.yaml create mode 100644 tasks/managed/collect-data/tests/test-collect-data-print-pipeline-ref-sha.yaml diff --git a/tasks/managed/collect-data/collect-data.yaml b/tasks/managed/collect-data/collect-data.yaml index 1212a6d043..607f9cbedd 100644 --- a/tasks/managed/collect-data/collect-data.yaml +++ b/tasks/managed/collect-data/collect-data.yaml @@ -286,7 +286,13 @@ spec: org=$(echo "${orgrepo}" | cut -f1 -d/) repo=$(echo "${orgrepo}" | cut -f2 -d/ | cut -d. -f1) - sha=$(curl -s "https://api.github.com/repos/${org}/${repo}/commits/${revision}" | jq -r '.sha // ""') + # taskGitRevision is resolved to a SHA by the release-service operator, + # fall back to the revision from the pipeline ref if it is not a SHA + sha="$(params.taskGitRevision)" + if [[ ! "${sha}" =~ ^[0-9a-f]{40}$ ]]; then + sha=$(curl-with-retry -s "https://api.github.com/repos/${org}/${repo}/commits/${revision}" \ + | jq -r '.sha // ""' || true) + fi fi diff --git a/tasks/managed/collect-data/tests/mocks.sh b/tasks/managed/collect-data/tests/mocks.sh index 0313fc4ccc..a3251fc064 100644 --- a/tasks/managed/collect-data/tests/mocks.sh +++ b/tasks/managed/collect-data/tests/mocks.sh @@ -2,9 +2,12 @@ set -eux # mocks to be injected into task step scripts -curl() { - # Output the call to stderr - echo "Mock curl called with:" "$@" >&2 +curl-with-retry() { + echo "Mock curl-with-retry called with:" "$@" >&2 echo "$@" >> "$(params.dataDir)/mock_curl.txt" + if [[ "$*" =~ fail-catalog ]]; then + echo "API rate limit exceeded" >&2 + return 1 + fi echo '{ "sha": "12345"}' } diff --git a/tasks/managed/collect-data/tests/test-collect-data-print-pipeline-ref-api-fail.yaml b/tasks/managed/collect-data/tests/test-collect-data-print-pipeline-ref-api-fail.yaml new file mode 100644 index 0000000000..d895419928 --- /dev/null +++ b/tasks/managed/collect-data/tests/test-collect-data-print-pipeline-ref-api-fail.yaml @@ -0,0 +1,246 @@ +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: test-collect-data-print-pipeline-ref-api-fail +spec: + description: | + Run the collect-data task with a non-SHA taskGitRevision and a failing GitHub API call, + verify that the task does not fail and sha defaults to unknown + params: + - name: ociStorage + description: The OCI repository where the Trusted Artifacts are stored. + type: string + - name: ociArtifactExpiresAfter + description: Expiration date for the trusted artifacts created in the + OCI repository. An empty string means the artifacts do not expire. + type: string + default: "1d" + - name: orasOptions + description: oras options to pass to Trusted Artifacts calls + type: string + default: "--insecure" + - name: trustedArtifactsDebug + description: Flag to enable debug logging in trusted artifacts. Set to a non-empty string to enable. + type: string + default: "" + - name: dataDir + description: The location where data will be stored + type: string + tasks: + - name: setup + taskSpec: + volumes: + - name: workdir + emptyDir: {} + stepTemplate: + volumeMounts: + - mountPath: /var/workdir + name: workdir + env: + - name: IMAGE_EXPIRES_AFTER + value: $(params.ociArtifactExpiresAfter) + - name: "ORAS_OPTIONS" + value: "$(params.orasOptions)" + - name: "DEBUG" + value: "$(params.trustedArtifactsDebug)" + steps: + - name: create-crs + image: quay.io/konflux-ci/release-service-utils@sha256:440c27f13adab931460a9371df82d3757b77f7ccc1b7604d737e0c78760a95c9 + script: | + #!/usr/bin/env bash + set -eux + + mkdir -p "$(params.dataDir)/$(context.pipelineRun.uid)" + cd "$(params.dataDir)/$(context.pipelineRun.uid)" + cat > release << EOF + apiVersion: appstudio.redhat.com/v1alpha1 + kind: Release + metadata: + name: release-sample + namespace: default + spec: + snapshot: foo + releasePlan: foo + EOF + kubectl apply -f release + + cat > releaseplan << EOF + apiVersion: appstudio.redhat.com/v1alpha1 + kind: ReleasePlan + metadata: + name: releaseplan-sample + namespace: default + spec: + application: foo + target: foo + EOF + kubectl apply -f releaseplan + + cat > releaseplanadmission << EOF + apiVersion: appstudio.redhat.com/v1alpha1 + kind: ReleasePlanAdmission + metadata: + name: releaseplanadmission-sample + namespace: default + spec: + applications: + - foo + origin: foo + policy: foo + pipeline: + pipelineRef: + params: + - name: url + value: 'https://github.com/fail-catalog/some-service-catalog.git' + - name: revision + value: development + - name: pathInRepo + value: pipelines/rh-advisories/rh-advisories.yaml + resolver: git + serviceAccountName: release-service-account + timeouts: + pipeline: 5h0m0s + EOF + kubectl apply -f releaseplanadmission + + cat > releaseserviceconfig << EOF + apiVersion: appstudio.redhat.com/v1alpha1 + kind: ReleaseServiceConfig + metadata: + name: releaseserviceconfig-sample + namespace: default + spec: + EOF + kubectl apply -f releaseserviceconfig + + cat > snapshot << EOF + apiVersion: appstudio.redhat.com/v1alpha1 + kind: Snapshot + metadata: + name: snapshot-sample + namespace: default + spec: + application: foo + components: + - name: name + containerImage: newimage + EOF + kubectl apply -f snapshot + - name: run-task + taskRef: + name: collect-data + params: + - name: release + value: default/release-sample + - name: releasePlan + value: default/releaseplan-sample + - name: releasePlanAdmission + value: default/releaseplanadmission-sample + - name: releaseServiceConfig + value: default/releaseserviceconfig-sample + - name: snapshot + value: default/snapshot-sample + - name: subdirectory + value: $(context.pipelineRun.uid) + - name: orasOptions + value: $(params.orasOptions) + - name: ociStorage + value: $(params.ociStorage) + - name: dataDir + value: $(params.dataDir) + - name: trustedArtifactsDebug + value: $(params.trustedArtifactsDebug) + - name: taskGitUrl + value: "http://localhost" + - name: taskGitRevision + value: "development" + runAfter: + - setup + - name: check-result + params: + - name: releasePipelineMetadata + value: "$(tasks.run-task.results.releasePipelineMetadata)" + - name: sourceDataArtifact + value: "$(tasks.run-task.results.sourceDataArtifact)=$(params.dataDir)" + - name: subdirectory + value: $(tasks.run-task.results.subdirectory) + - name: dataDir + value: $(params.dataDir) + runAfter: + - run-task + taskSpec: + params: + - name: releasePipelineMetadata + type: string + - name: subdirectory + type: string + - name: sourceDataArtifact + type: string + - name: dataDir + type: string + volumes: + - name: workdir + emptyDir: {} + stepTemplate: + volumeMounts: + - mountPath: /var/workdir + name: workdir + env: + - name: IMAGE_EXPIRES_AFTER + value: $(params.ociArtifactExpiresAfter) + - name: "ORAS_OPTIONS" + value: "$(params.orasOptions)" + - name: "DEBUG" + value: "$(params.trustedArtifactsDebug)" + steps: + - name: use-trusted-artifact + ref: + name: use-trusted-artifact + params: + - name: workDir + value: $(params.dataDir) + - name: sourceDataArtifact + value: $(params.sourceDataArtifact) + - name: check-result + image: quay.io/konflux-ci/release-service-utils@sha256:440c27f13adab931460a9371df82d3757b77f7ccc1b7604d737e0c78760a95c9 + env: + - name: PIPELINE_METADATA + value: '$(params.releasePipelineMetadata)' + script: | + #!/usr/bin/env bash + set -eux + + if [ "$(wc -l < "$(params.dataDir)/mock_curl.txt")" != 1 ]; then + echo Error: curl-with-retry was expected to be called 1 time. Actual calls: + cat "$(params.dataDir)/mock_curl.txt" + exit 1 + fi + + org=$(jq -r '.org' <<< "$PIPELINE_METADATA") + repo=$(jq -r '.repo' <<< "$PIPELINE_METADATA") + revision=$(jq -r '.revision' <<< "$PIPELINE_METADATA") + pathinrepo=$(jq -r '.pathinrepo' <<< "$PIPELINE_METADATA") + sha=$(jq -r '.sha' <<< "$PIPELINE_METADATA") + + test "${org}" == 'fail-catalog' + test "${repo}" == 'some-service-catalog' + test "${revision}" == 'development' + test "${pathinrepo}" == 'pipelines/rh-advisories/rh-advisories.yaml' + test "${sha}" == 'unknown' + + finally: + - name: cleanup + taskSpec: + steps: + - name: delete-crs + image: quay.io/konflux-ci/release-service-utils@sha256:440c27f13adab931460a9371df82d3757b77f7ccc1b7604d737e0c78760a95c9 + script: | + #!/usr/bin/env sh + set -eux + + kubectl delete release release-sample + kubectl delete releaseplan releaseplan-sample + kubectl delete releaseplanadmission releaseplanadmission-sample + kubectl delete releaseserviceconfig releaseserviceconfig-sample + kubectl delete snapshot snapshot-sample diff --git a/tasks/managed/collect-data/tests/test-collect-data-print-pipeline-ref-sha.yaml b/tasks/managed/collect-data/tests/test-collect-data-print-pipeline-ref-sha.yaml new file mode 100644 index 0000000000..ec03beca62 --- /dev/null +++ b/tasks/managed/collect-data/tests/test-collect-data-print-pipeline-ref-sha.yaml @@ -0,0 +1,248 @@ +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: test-collect-data-print-pipeline-ref-sha +spec: + description: | + Run the collect-data task and verify that when taskGitRevision is already a SHA, + it is used directly without calling the GitHub API + params: + - name: ociStorage + description: The OCI repository where the Trusted Artifacts are stored. + type: string + - name: ociArtifactExpiresAfter + description: Expiration date for the trusted artifacts created in the + OCI repository. An empty string means the artifacts do not expire. + type: string + default: "1d" + - name: orasOptions + description: oras options to pass to Trusted Artifacts calls + type: string + default: "--insecure" + - name: trustedArtifactsDebug + description: Flag to enable debug logging in trusted artifacts. Set to a non-empty string to enable. + type: string + default: "" + - name: dataDir + description: The location where data will be stored + type: string + tasks: + - name: setup + taskSpec: + volumes: + - name: workdir + emptyDir: {} + stepTemplate: + volumeMounts: + - mountPath: /var/workdir + name: workdir + env: + - name: IMAGE_EXPIRES_AFTER + value: $(params.ociArtifactExpiresAfter) + - name: "ORAS_OPTIONS" + value: "$(params.orasOptions)" + - name: "DEBUG" + value: "$(params.trustedArtifactsDebug)" + steps: + - name: create-crs + image: quay.io/konflux-ci/release-service-utils@sha256:440c27f13adab931460a9371df82d3757b77f7ccc1b7604d737e0c78760a95c9 + script: | + #!/usr/bin/env bash + set -eux + + mkdir -p "$(params.dataDir)/$(context.pipelineRun.uid)" + cd "$(params.dataDir)/$(context.pipelineRun.uid)" + cat > release << EOF + apiVersion: appstudio.redhat.com/v1alpha1 + kind: Release + metadata: + name: release-sample + namespace: default + spec: + snapshot: foo + releasePlan: foo + EOF + kubectl apply -f release + + cat > releaseplan << EOF + apiVersion: appstudio.redhat.com/v1alpha1 + kind: ReleasePlan + metadata: + name: releaseplan-sample + namespace: default + spec: + application: foo + target: foo + EOF + kubectl apply -f releaseplan + + cat > releaseplanadmission << EOF + apiVersion: appstudio.redhat.com/v1alpha1 + kind: ReleasePlanAdmission + metadata: + name: releaseplanadmission-sample + namespace: default + spec: + applications: + - foo + origin: foo + policy: foo + pipeline: + pipelineRef: + params: + - name: url + value: 'https://github.com/some-catalog/some-service-catalog.git' + - name: revision + value: development + - name: pathInRepo + value: pipelines/rh-advisories/rh-advisories.yaml + resolver: git + serviceAccountName: release-service-account + timeouts: + pipeline: 5h0m0s + EOF + kubectl apply -f releaseplanadmission + + cat > releaseserviceconfig << EOF + apiVersion: appstudio.redhat.com/v1alpha1 + kind: ReleaseServiceConfig + metadata: + name: releaseserviceconfig-sample + namespace: default + spec: + EOF + kubectl apply -f releaseserviceconfig + + cat > snapshot << EOF + apiVersion: appstudio.redhat.com/v1alpha1 + kind: Snapshot + metadata: + name: snapshot-sample + namespace: default + spec: + application: foo + components: + - name: name + containerImage: newimage + EOF + kubectl apply -f snapshot + - name: run-task + taskRef: + name: collect-data + params: + - name: release + value: default/release-sample + - name: releasePlan + value: default/releaseplan-sample + - name: releasePlanAdmission + value: default/releaseplanadmission-sample + - name: releaseServiceConfig + value: default/releaseserviceconfig-sample + - name: snapshot + value: default/snapshot-sample + - name: subdirectory + value: $(context.pipelineRun.uid) + - name: orasOptions + value: $(params.orasOptions) + - name: ociStorage + value: $(params.ociStorage) + - name: dataDir + value: $(params.dataDir) + - name: trustedArtifactsDebug + value: $(params.trustedArtifactsDebug) + - name: taskGitUrl + value: "http://localhost" + - name: taskGitRevision + value: "abcdef1234567890abcdef1234567890abcdef12" + runAfter: + - setup + - name: check-result + params: + - name: releasePipelineMetadata + value: "$(tasks.run-task.results.releasePipelineMetadata)" + - name: sourceDataArtifact + value: "$(tasks.run-task.results.sourceDataArtifact)=$(params.dataDir)" + - name: subdirectory + value: $(tasks.run-task.results.subdirectory) + - name: dataDir + value: $(params.dataDir) + runAfter: + - run-task + taskSpec: + params: + - name: releasePipelineMetadata + type: string + - name: subdirectory + type: string + - name: sourceDataArtifact + type: string + - name: dataDir + type: string + volumes: + - name: workdir + emptyDir: {} + stepTemplate: + volumeMounts: + - mountPath: /var/workdir + name: workdir + env: + - name: IMAGE_EXPIRES_AFTER + value: $(params.ociArtifactExpiresAfter) + - name: "ORAS_OPTIONS" + value: "$(params.orasOptions)" + - name: "DEBUG" + value: "$(params.trustedArtifactsDebug)" + steps: + - name: use-trusted-artifact + ref: + name: use-trusted-artifact + params: + - name: workDir + value: $(params.dataDir) + - name: sourceDataArtifact + value: $(params.sourceDataArtifact) + - name: check-result + image: quay.io/konflux-ci/release-service-utils@sha256:440c27f13adab931460a9371df82d3757b77f7ccc1b7604d737e0c78760a95c9 + env: + - name: PIPELINE_METADATA + value: '$(params.releasePipelineMetadata)' + script: | + #!/usr/bin/env bash + set -eux + + mkdir -p "$(params.dataDir)/$(context.pipelineRun.uid)" + touch "$(params.dataDir)/mock_curl.txt" + if [ "$(wc -l < "$(params.dataDir)/mock_curl.txt")" != 0 ]; then + echo Error: curl-with-retry was expected to be called 0 times. Actual calls: + cat "$(params.dataDir)/mock_curl.txt" + exit 1 + fi + + org=$(jq -r '.org' <<< "$PIPELINE_METADATA") + repo=$(jq -r '.repo' <<< "$PIPELINE_METADATA") + revision=$(jq -r '.revision' <<< "$PIPELINE_METADATA") + pathinrepo=$(jq -r '.pathinrepo' <<< "$PIPELINE_METADATA") + sha=$(jq -r '.sha' <<< "$PIPELINE_METADATA") + + test "${org}" == 'some-catalog' + test "${repo}" == 'some-service-catalog' + test "${revision}" == 'development' + test "${pathinrepo}" == 'pipelines/rh-advisories/rh-advisories.yaml' + test "${sha}" == 'abcdef1234567890abcdef1234567890abcdef12' + + finally: + - name: cleanup + taskSpec: + steps: + - name: delete-crs + image: quay.io/konflux-ci/release-service-utils@sha256:440c27f13adab931460a9371df82d3757b77f7ccc1b7604d737e0c78760a95c9 + script: | + #!/usr/bin/env sh + set -eux + + kubectl delete release release-sample + kubectl delete releaseplan releaseplan-sample + kubectl delete releaseplanadmission releaseplanadmission-sample + kubectl delete releaseserviceconfig releaseserviceconfig-sample + kubectl delete snapshot snapshot-sample diff --git a/tasks/managed/collect-data/tests/test-collect-data-print-pipeline-ref.yaml b/tasks/managed/collect-data/tests/test-collect-data-print-pipeline-ref.yaml index 3c0f4e3482..b8017ce2c3 100644 --- a/tasks/managed/collect-data/tests/test-collect-data-print-pipeline-ref.yaml +++ b/tasks/managed/collect-data/tests/test-collect-data-print-pipeline-ref.yaml @@ -5,7 +5,8 @@ metadata: name: test-collect-data-print-pipeline-ref spec: description: | - Run the collect-data task and verify that the pipeline ref info is made available + Run the collect-data task with a non SHA taskGitRevision and verify that the pipeline ref + info is resolved via the GitHub API fallback params: - name: ociStorage description: The OCI repository where the Trusted Artifacts are stored. @@ -211,7 +212,7 @@ spec: set -eux if [ "$(wc -l < "$(params.dataDir)/mock_curl.txt")" != 1 ]; then - echo Error: curl was expected to be called 1 time. Actual calls: + echo Error: curl-with-retry was expected to be called 1 time. Actual calls: cat "$(params.dataDir)/mock_curl.txt" exit 1 fi