Repository: konflux-ci/release-service-catalog
Pull request #806: feat(RELEASE-1403): rework embargo-check task for issues
Author: login: johnbieren
Created: 2025-02-05T20:01:39Z | Merged: 2025-03-07T03:07:42Z

This commit reworks the managed embargo-check task for how it handles issues in issues.redhat.com. First, it adds authentication for searching for these issues. If the issue is found and is not of type Vulnerability, it will pass.

If the issue is of type Vulnerability, the task will now ensure that the component from the issue matches a component in the releaseNotes.content.images section and that the CVE from the issue is present in said component section.

## Describe your changes

## Relevant Jira

## Checklist before requesting a review
- [ ] I have marked as draft or added `do not merge` label if there's a dependency PR
  - If you want reviews on your draft PR, you can add reviewers or add the `release-service-maintainers` handle if you are unsure who to tag
- [ ] My commit message includes `Signed-off-by: My name <email>`
- [ ] I have bumped the task/pipeline version string and updated changelog in the relevant README
- [ ] I read CONTRIBUTING.MD and [commit formatting](CONTRIBUTING.md#commit-message-formatting-and-standards)




Diff:
diff --git a/tasks/managed/embargo-check/README.md b/tasks/managed/embargo-check/README.md
index ead6c7ef55..59e57de45a 100644
--- a/tasks/managed/embargo-check/README.md
+++ b/tasks/managed/embargo-check/README.md
@@ -1,7 +1,9 @@
 # embargo-check
 
 Tekton task to check if any issues or CVEs in the releaseNotes key of the data.json are embargoed. It checks the issues
-by server using curl and checks the CVEs via an InternalRequest. If any issue or CVE is embargoed, the task will fail.
+by server using curl and checks the CVEs via an InternalRequest. If any issue does not exist or any CVE is embargoed,
+the task will fail. The task will also fail if a Jira issue listed is for a component that does not exist in the
+releaseNotes.content.images section or if said component does not list the CVE from the issue.
 
 ## Parameters
 
@@ -13,6 +15,14 @@ by server using curl and checks the CVEs via an InternalRequest. If any issue or
 | taskGitUrl               | The url to the git repo where the release-service-catalog tasks to be used are stored     | No       | -             |
 | taskGitRevision          | The revision in the taskGitUrl repo to be used                                            | No       | -             |
 
+## Changes in 1.0.0
+* Authentication is added to checking issues in issues.redhat.com
+* If the issue exists and is not of type `Vulnerability`, the task will pass on that issue
+* If the issue is of type `Vulnerability`
+  * If the `Downstream Component Name` from the issue is not listed in the `releaseNotes.content.images`
+    section, the task will fail
+  * If the `CVE ID` from the issue is not present in its component's fixed cves section, the task will fail
+
 ## Changes in 0.5.0
 * Added taskGiturl and taskGitRevision parameters to be passed to the internalRequest
 * The pipeline is called via git resolver now instead of cluster resolver
diff --git a/tasks/managed/embargo-check/embargo-check.yaml b/tasks/managed/embargo-check/embargo-check.yaml
index 511250bd5b..fc7a8ccb1e 100644
--- a/tasks/managed/embargo-check/embargo-check.yaml
+++ b/tasks/managed/embargo-check/embargo-check.yaml
@@ -4,7 +4,7 @@ kind: Task
 metadata:
   name: embargo-check
   labels:
-    app.kubernetes.io/version: "0.5.0"
+    app.kubernetes.io/version: "1.0.0"
   annotations:
     tekton.dev/pipelines.minVersion: "0.12.1"
     tekton.dev/tags: release
@@ -12,7 +12,10 @@ spec:
   description: >
     Tekton task to check if any issues or CVEs in the releaseNotes key of the data.json
     are embargoed. It checks the issues by server using curl and checks the CVEs via an
-    InternalRequest. If any issue or CVE is embargoed, the task will fail.
+    InternalRequest. If any issue does not exist or any CVE is embargoed, the task will
+    fail. The task will also fail if a Jira issue listed is for a component that does
+    not exist in the releaseNotes.content.images section or if said component does not
+    list the CVE from the issue.
   params:
     - name: dataPath
       description: Path to the JSON string of the merged data to use in the data workspace
@@ -36,9 +39,14 @@ spec:
   steps:
     - name: check-issues
       image: quay.io/konflux-ci/release-service-utils:0f82be4be43294b6a96846d87ef7f7c0b9e34267
+      env:
+        - name: ACCESS_TOKEN
+          valueFrom:
+            secretKeyRef:
+              name: konflux-advisory-jira-secret
+              key: token
       script: |
         #!/usr/bin/env bash
-        set -x
 
         SUPPORTED_ISSUE_TRACKERS='{
             "Jira": {
@@ -62,19 +70,61 @@ spec:
             exit 1
         fi
 
+        # It is expected for the custom field ids to remain stable, but to get them, you can do:
+        # curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field
+        CVE_FIELD="customfield_12324749"
+        COMPONENT_FIELD="customfield_12324752"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
+            # We set +x before the curl call and then capture the exit code. That can lead to breaking out of the
+            # current loop iteration or continuing on, so let's set -x at the beginning of each iteration
+            set -x
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
             API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            AUTH_ARGS=()
+            set +x # We don't want to leak the ACCESS_TOKEN
+            if [ "$server" = "issues.redhat.com" ] ; then
+                AUTH_ARGS=(-H "Authorization: Bearer $ACCESS_TOKEN")
+            fi
+            OUTPUT=$(curl --retry 3 --fail "${AUTH_ARGS[@]}" "${API_URL}")
             if [ $? -ne 0 ] ; then
-                echo "${issue} is not publicly visible. Assuming it is embargoed and stopping pipelineRun execution."
+                echo "Error: ${issue} is not visible. Assuming it is embargoed and stopping pipelineRun execution."
+                RC=1
+                continue
+            fi
+            set -x
+
+            # Perform additional checks only for Vulnerability issues for issues.redhat.com
+            if [ "$server" != "issues.redhat.com" ] ; then
+                continue
+            fi
+            ISSUE_TYPE=$(jq -r '.fields.issuetype.name' <<< "$OUTPUT")
+            if [ "$ISSUE_TYPE" != "Vulnerability" ] ; then
+                continue
+            fi
+            CVE_ID=$(jq -r --arg field "$CVE_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            COMPONENT_NAME=$(jq -r --arg field "$COMPONENT_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            if ! COMPONENT_IN_RELEASE_NOTES="$(jq -ec --arg name "$COMPONENT_NAME" \
+              '.releaseNotes.content.images[] | select(.component==$name)' "$DATA_FILE")"; then
+                echo -n "Error: Issue $issue lists 'Downstream Component Name' $COMPONENT_NAME but that component does"
+                echo " not appear in releaseNotes.content.images. Failing"
+                RC=1
+                continue
+            fi
+
+            if [ "$(jq --arg CVE "$CVE_ID" '.cves.fixed | has($CVE)' <<< "$COMPONENT_IN_RELEASE_NOTES")" != "true" ]
+            then
+                echo -n "Error: Issue $issue lists 'Downstream Component Name' $COMPONENT_NAME and 'CVE ID' $CVE_ID"
+                echo " but that CVE is not present in the releaseNotes.content.images section for that component."
                 RC=1
+                continue
             fi
+            
         done
 
         exit $RC
diff --git a/tasks/managed/embargo-check/tests/mocks.sh b/tasks/managed/embargo-check/tests/mocks.sh
index a46e1c47d0..b11d4c394a 100644
--- a/tasks/managed/embargo-check/tests/mocks.sh
+++ b/tasks/managed/embargo-check/tests/mocks.sh
@@ -6,15 +6,24 @@ function curl() {
   echo Mock curl called with: $* >&2
   echo $* >> $(workspaces.data.path)/mock_curl.txt
 
-  if [[ "$*" == "--fail --output /dev/null https://jira.atlassian.com/rest/api/2/issue/ISSUE-123" ]]
+  if [[ "$*" == "--retry 3 --fail https://jira.atlassian.com/rest/api/2/issue/ISSUE-123" ]]
   then
     :
-  elif [[ "$*" == "--fail --output /dev/null https://bugzilla.redhat.com/rest/bug/12345" ]]
+  elif [[ "$*" == "--retry 3 --fail https://bugzilla.redhat.com/rest/bug/12345" ]]
   then
     :
-  elif [[ "$*" == "--fail --output /dev/null https://jira.atlassian.com/rest/api/2/issue/EMBARGOED-987" ]]
+  elif [[ "$*" == "--retry 3 --fail https://jira.atlassian.com/rest/api/2/issue/EMBARGOED-987" ]]
   then
     exit 1
+  elif [[ "$*" == *"Authorization: Bearer"*"https://issues.redhat.com/rest/api/2/issue/MISSINGRH-123" ]]
+  then
+    exit 1
+  elif [[ "$*" == *"Authorization: Bearer"*"https://issues.redhat.com/rest/api/2/issue/FEATURE-123" ]] # Not a Vulnerability
+  then
+    echo '{"fields":{"issuetype":{"name":"Feature"}}}'
+  elif [[ "$*" == *"Authorization: Bearer"*"https://issues.redhat.com/rest/api/2/issue/CVE-123" ]] # Vulnerability
+  then
+    echo '{"fields":{"issuetype":{"name":"Vulnerability"},"customfield_12324749":"CVE-123","customfield_12324752":"my-component"}}'
   else
     echo Error: Unexpected call
     exit 1
diff --git a/tasks/managed/embargo-check/tests/pre-apply-task-hook.sh b/tasks/managed/embargo-check/tests/pre-apply-task-hook.sh
index f24da0ca46..9bccf56d9e 100755
--- a/tasks/managed/embargo-check/tests/pre-apply-task-hook.sh
+++ b/tasks/managed/embargo-check/tests/pre-apply-task-hook.sh
@@ -5,3 +5,7 @@ TASK_PATH="$1"
 SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
 yq -i '.spec.steps[0].script = load_str("'$SCRIPT_DIR'/mocks.sh") + .spec.steps[0].script' "$TASK_PATH"
 yq -i '.spec.steps[1].script = load_str("'$SCRIPT_DIR'/mocks.sh") + .spec.steps[1].script' "$TASK_PATH"
+
+# Create a dummy access token secret (and delete it first if it exists)
+kubectl delete secret konflux-advisory-jira-secret --ignore-not-found
+kubectl create secret generic konflux-advisory-jira-secret --from-literal=token=abcdefg
diff --git a/tasks/managed/embargo-check/tests/test-embargo-check-non-vuln-rh-issue.yaml b/tasks/managed/embargo-check/tests/test-embargo-check-non-vuln-rh-issue.yaml
new file mode 100644
index 0000000000..b750e79a77
--- /dev/null
+++ b/tasks/managed/embargo-check/tests/test-embargo-check-non-vuln-rh-issue.yaml
@@ -0,0 +1,81 @@
+---
+apiVersion: tekton.dev/v1
+kind: Pipeline
+metadata:
+  name: test-embargo-check-non-vuln-rh-issue
+spec:
+  description: Test for embargo-check with a issues.redhat.com issue that is not of type Vulnerability
+  workspaces:
+    - name: tests-workspace
+  tasks:
+    - name: setup
+      workspaces:
+        - name: data
+          workspace: tests-workspace
+      taskSpec:
+        workspaces:
+          - name: data
+        steps:
+          - name: setup-values
+            image: quay.io/konflux-ci/release-service-utils:0f82be4be43294b6a96846d87ef7f7c0b9e34267
+            script: |
+              #!/usr/bin/env sh
+              set -eux
+
+              cat > "$(workspaces.data.path)"/data.json << EOF
+              {
+                "releaseNotes": {
+                  "issues": {
+                    "fixed": [
+                      {
+                        "id": "ISSUE-123",
+                        "source": "jira.atlassian.com"
+                      },
+                      {
+                        "id": "FEATURE-123",
+                        "source": "issues.redhat.com"
+                      }
+                    ]
+                  }
+                }
+              }
+              EOF
+    - name: run-task
+      taskRef:
+        name: embargo-check
+      params:
+        - name: dataPath
+          value: data.json
+        - name: pipelineRunUid
+          value: $(context.pipelineRun.uid)
+        - name: taskGitUrl
+          value: "http://localhost"
+        - name: taskGitRevision
+          value: "main"
+      workspaces:
+        - name: data
+          workspace: tests-workspace
+      runAfter:
+        - setup
+    - name: check-result
+      workspaces:
+        - name: data
+          workspace: tests-workspace
+      taskSpec:
+        steps:
+          - name: check-result
+            image: quay.io/konflux-ci/release-service-utils:0f82be4be43294b6a96846d87ef7f7c0b9e34267
+            script: |
+              #!/usr/bin/env bash
+              set -eux
+
+              if [ "$(wc -l < "$(workspaces.data.path)"/mock_curl.txt)" != 2 ]; then
+                  echo Error: curl was expected to be called 2 times. Actual calls:
+                  cat "$(workspaces.data.path)"/mock_curl.txt
+                  exit 1
+              fi
+
+              [[ $(head -n 1 "$(workspaces.data.path)/mock_curl.txt") == *"ISSUE-123"* ]]
+              [[ $(tail -n 1 "$(workspaces.data.path)/mock_curl.txt") == *"FEATURE-123"* ]]
+      runAfter:
+        - run-task
diff --git a/tasks/managed/embargo-check/tests/test-embargo-check-nonexistent-rh-issue.yaml b/tasks/managed/embargo-check/tests/test-embargo-check-nonexistent-rh-issue.yaml
new file mode 100644
index 0000000000..14f6c442be
--- /dev/null
+++ b/tasks/managed/embargo-check/tests/test-embargo-check-nonexistent-rh-issue.yaml
@@ -0,0 +1,61 @@
+---
+apiVersion: tekton.dev/v1
+kind: Pipeline
+metadata:
+  name: test-embargo-check-nonexistent-rh-issue
+  annotations:
+    test/assert-task-failure: "run-task"
+spec:
+  description: Test for embargo-check where a issues.redhat.com issue cannot be found
+  workspaces:
+    - name: tests-workspace
+  tasks:
+    - name: setup
+      workspaces:
+        - name: data
+          workspace: tests-workspace
+      taskSpec:
+        workspaces:
+          - name: data
+        steps:
+          - name: setup-values
+            image: quay.io/konflux-ci/release-service-utils:0f82be4be43294b6a96846d87ef7f7c0b9e34267
+            script: |
+              #!/usr/bin/env sh
+              set -eux
+
+              cat > "$(workspaces.data.path)/data.json" << EOF
+              {
+                "releaseNotes": {
+                  "issues": {
+                    "fixed": [
+                      {
+                        "id": "MISSINGRH-123",
+                        "source": "issues.redhat.com"
+                      },
+                      {
+                        "id": "12345",
+                        "source": "bugzilla.redhat.com"
+                      }
+                    ]
+                  }
+                }
+              }
+              EOF
+    - name: run-task
+      taskRef:
+        name: embargo-check
+      params:
+        - name: dataPath
+          value: data.json
+        - name: pipelineRunUid
+          value: $(context.pipelineRun.uid)
+        - name: taskGitUrl
+          value: "http://localhost"
+        - name: taskGitRevision
+          value: "main"
+      workspaces:
+        - name: data
+          workspace: tests-workspace
+      runAfter:
+        - setup
diff --git a/tasks/managed/embargo-check/tests/test-embargo-check-public-issues.yaml b/tasks/managed/embargo-check/tests/test-embargo-check-public-issues.yaml
index a180cb2cb3..5fecec5edb 100644
--- a/tasks/managed/embargo-check/tests/test-embargo-check-public-issues.yaml
+++ b/tasks/managed/embargo-check/tests/test-embargo-check-public-issues.yaml
@@ -75,9 +75,7 @@ spec:
                   exit 1
               fi
 
-              [[ $(cat $(workspaces.data.path)/mock_curl.txt | head -n 1) \
-                  == *"ISSUE-123"* ]]
-              [[ $(cat $(workspaces.data.path)/mock_curl.txt | head -n 2 | tail -n 1) \
-                  == *"12345"* ]]
+              [[ $(head -n 1 "$(workspaces.data.path)/mock_curl.txt") == *"ISSUE-123"* ]]
+              [[ $(tail -n 1 "$(workspaces.data.path)/mock_curl.txt") == *"12345"* ]]
       runAfter:
         - run-task
diff --git a/tasks/managed/embargo-check/tests/test-embargo-check-rh-issue-missing-cve.yaml b/tasks/managed/embargo-check/tests/test-embargo-check-rh-issue-missing-cve.yaml
new file mode 100644
index 0000000000..662ad89499
--- /dev/null
+++ b/tasks/managed/embargo-check/tests/test-embargo-check-rh-issue-missing-cve.yaml
@@ -0,0 +1,80 @@
+---
+apiVersion: tekton.dev/v1
+kind: Pipeline
+metadata:
+  name: test-embargo-check-rh-issue-missing-cve
+  annotations:
+    test/assert-task-failure: "run-task"
+spec:
+  description: |
+    Test for embargo-check where a issues.redhat.com issue has a Downstream Component Name value
+    that matches a component in the releaseNotes.content.images section, but said images section
+    does not list CVE-123, which is what the mocks return
+  workspaces:
+    - name: tests-workspace
+  tasks:
+    - name: setup
+      workspaces:
+        - name: data
+          workspace: tests-workspace
+      taskSpec:
+        workspaces:
+          - name: data
+        steps:
+          - name: setup-values
+            image: quay.io/konflux-ci/release-service-utils:0f82be4be43294b6a96846d87ef7f7c0b9e34267
+            script: |
+              #!/usr/bin/env sh
+              set -eux
+
+              cat > "$(workspaces.data.path)/data.json" << EOF
+              {
+                "releaseNotes": {
+                  "issues": {
+                    "fixed": [
+                      {
+                        "id": "CVE-123",
+                        "source": "issues.redhat.com"
+                      },
+                      {
+                        "id": "12345",
+                        "source": "bugzilla.redhat.com"
+                      }
+                    ]
+                  },
+                  "content": {
+                    "images": [
+                      {
+                        "component": "my-component",
+                        "architecture": "x86_64",
+                        "containerImage": "registry.io/org/repo",
+                        "cves": {
+                          "fixed": {
+                            "CVE-987": {
+                              "packages": []
+                            }
+                          }
+                        }
+                      }
+                    ]
+                  }
+                }
+              }
+              EOF
+    - name: run-task
+      taskRef:
+        name: embargo-check
+      params:
+        - name: dataPath
+          value: data.json
+        - name: pipelineRunUid
+          value: $(context.pipelineRun.uid)
+        - name: taskGitUrl
+          value: "http://localhost"
+        - name: taskGitRevision
+          value: "main"
+      workspaces:
+        - name: data
+          workspace: tests-workspace
+      runAfter:
+        - setup
diff --git a/tasks/managed/embargo-check/tests/test-embargo-check-rh-issue-wrong-component.yaml b/tasks/managed/embargo-check/tests/test-embargo-check-rh-issue-wrong-component.yaml
new file mode 100644
index 0000000000..9f64e3fe8d
--- /dev/null
+++ b/tasks/managed/embargo-check/tests/test-embargo-check-rh-issue-wrong-component.yaml
@@ -0,0 +1,73 @@
+---
+apiVersion: tekton.dev/v1
+kind: Pipeline
+metadata:
+  name: test-embargo-check-rh-issue-wrong-component
+  annotations:
+    test/assert-task-failure: "run-task"
+spec:
+  description: |
+    Test for embargo-check where a issues.redhat.com issue has a Downstream Component Name value
+    that does not match any component in the releaseNotes.content.images section. The mocks set the
+    Downstream Component Name to my-component
+  workspaces:
+    - name: tests-workspace
+  tasks:
+    - name: setup
+      workspaces:
+        - name: data
+          workspace: tests-workspace
+      taskSpec:
+        workspaces:
+          - name: data
+        steps:
+          - name: setup-values
+            image: quay.io/konflux-ci/release-service-utils:0f82be4be43294b6a96846d87ef7f7c0b9e34267
+            script: |
+              #!/usr/bin/env sh
+              set -eux
+
+              cat > "$(workspaces.data.path)/data.json" << EOF
+              {
+                "releaseNotes": {
+                  "issues": {
+                    "fixed": [
+                      {
+                        "id": "CVE-123",
+                        "source": "issues.redhat.com"
+                      },
+                      {
+                        "id": "12345",
+                        "source": "bugzilla.redhat.com"
+                      }
+                    ]
+                  },
+                  "content": {
+                    "images": [
+                      {
+                        "component": "not-my-component",
+                        "architecture": "x86_64",
+                        "containerImage": "registry.io/org/repo"
+                      }
+                    ]
+                  }
+                }
+              }
+              EOF
+    - name: run-task
+      taskRef:
+        name: embargo-check
+      params:
+        - name: dataPath
+          value: data.json
+        - name: pipelineRunUid
+          value: $(context.pipelineRun.uid)
+        - name: taskGitUrl
+          value: "http://localhost"
+        - name: taskGitRevision
+          value: "main"
+      workspaces:
+        - name: data
+          workspace: tests-workspace
+      runAfter:
+        - setup
diff --git a/tasks/managed/embargo-check/tests/test-embargo-check-rh-issue.yaml b/tasks/managed/embargo-check/tests/test-embargo-check-rh-issue.yaml
new file mode 100644
index 0000000000..dcffb52ecb
--- /dev/null
+++ b/tasks/managed/embargo-check/tests/test-embargo-check-rh-issue.yaml
@@ -0,0 +1,100 @@
+---
+apiVersion: tekton.dev/v1
+kind: Pipeline
+metadata:
+  name: test-embargo-check-rh-issue
+spec:
+  description: |
+    Test for embargo-check where a issues.redhat.com issue has a Downstream Component Name value
+    that matches a component in the releaseNotes.content.images section and said images section
+    lists CVE-123, which is what the mocks return. The task should succeed
+  workspaces:
+    - name: tests-workspace
+  tasks:
+    - name: setup
+      workspaces:
+        - name: data
+          workspace: tests-workspace
+      taskSpec:
+        workspaces:
+          - name: data
+        steps:
+          - name: setup-values
+            image: quay.io/konflux-ci/release-service-utils:0f82be4be43294b6a96846d87ef7f7c0b9e34267
+            script: |
+              #!/usr/bin/env sh
+              set -eux
+
+              cat > "$(workspaces.data.path)/data.json" << EOF
+              {
+                "releaseNotes": {
+                  "issues": {
+                    "fixed": [
+                      {
+                        "id": "CVE-123",
+                        "source": "issues.redhat.com"
+                      },
+                      {
+                        "id": "12345",
+                        "source": "bugzilla.redhat.com"
+                      }
+                    ]
+                  },
+                  "content": {
+                    "images": [
+                      {
+                        "component": "my-component",
+                        "architecture": "x86_64",
+                        "containerImage": "registry.io/org/repo",
+                        "cves": {
+                          "fixed": {
+                            "CVE-123": {
+                              "packages": []
+                            }
+                          }
+                        }
+                      }
+                    ]
+                  }
+                }
+              }
+              EOF
+    - name: run-task
+      taskRef:
+        name: embargo-check
+      params:
+        - name: dataPath
+          value: data.json
+        - name: pipelineRunUid
+          value: $(context.pipelineRun.uid)
+        - name: taskGitUrl
+          value: "http://localhost"
+        - name: taskGitRevision
+          value: "main"
+      workspaces:
+        - name: data
+          workspace: tests-workspace
+      runAfter:
+        - setup
+    - name: check-result
+      workspaces:
+        - name: data
+          workspace: tests-workspace
+      taskSpec:
+        steps:
+          - name: check-result
+            image: quay.io/konflux-ci/release-service-utils:0f82be4be43294b6a96846d87ef7f7c0b9e34267
+            script: |
+              #!/usr/bin/env bash
+              set -eux
+
+              if [ "$(wc -l < "$(workspaces.data.path)"/mock_curl.txt)" != 2 ]; then
+                  echo Error: curl was expected to be called 2 times. Actual calls:
+                  cat "$(workspaces.data.path)"/mock_curl.txt
+                  exit 1
+              fi
+
+              [[ $(head -n 1 "$(workspaces.data.path)/mock_curl.txt") == *"CVE-123"* ]]
+              [[ $(tail -n 1 "$(workspaces.data.path)/mock_curl.txt") == *"12345"* ]]
+      runAfter:
+        - run-task


Reviews:
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-05T21:48:31Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T09:27:59Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T09:29:26Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T09:36:49Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T09:43:11Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T09:45:18Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T09:46:19Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T09:53:40Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T13:02:02Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T13:02:50Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T13:11:42Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T13:11:46Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T13:11:51Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T13:12:04Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T13:12:14Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T13:12:41Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T13:17:30Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T13:22:45Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T13:25:12Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T13:25:16Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T13:25:49Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T13:26:55Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T13:30:09Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T13:32:23Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T13:56:52Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T14:01:36Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T14:01:45Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T14:01:52Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-06T14:02:04Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T14:04:15Z
user: login: happybhati
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-02-18T01:56:47Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T15:32:20Z
user: login: johnbieren
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-06T15:33:35Z
user: login: happybhati
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T15:34:14Z
user: login: mmalina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T15:35:59Z
user: login: mmalina
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T15:36:20Z

Review comments:
diff_hunk: @@ -36,6 +39,12 @@ spec:
   steps:
     - name: check-issues
       image: quay.io/konflux-ci/release-service-utils:0f82be4be43294b6a96846d87ef7f7c0b9e34267
+      env:
+        - name: ACCESS_TOKEN
+          valueFrom:
+            secretKeyRef:
+              name: todo
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: This should not be merged with the name and key as todo (e2e) won't pass anyways. It is also in the mocks. Waiting on Rogue to provide the key and releng to add it to update this
created_at: 2025-02-05T21:48:31Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: I think more importantly you would leak the token, no? :)
created_at: 2025-02-06T09:27:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: Couldn't these be just hardcoded? That's what we did in Vitals. It's not like the id is gonna change randomly.
created_at: 2025-02-06T09:29:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: At this point I think `API_URL` is no longer a good name, since it contains args. So maybe `CURL_ARGS`? But also, I wonder how this can work with `curl --fail "${API_URL}"`? Because the `""`, it would be one long argument. Instead, a bash array should be used like we do elsewhere.

Actually, I think you would be better off leaving `API_URL` for just the url. And then do:
```
AUTH_ARGS=()
if [ "$server" = "issues.redhat.com" ] ; then
  AUTH_ARGS=(-H "Authorization: Bearer $ACCESS_TOKEN")
fi
...
OUTPUT=$(curl --fail "${AUTH_ARGS[@]}" "${API_URL}")
```
created_at: 2025-02-06T09:36:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
+            fi
+            API_URL="${API_URL}$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
+            OUTPUT=$(curl --fail "${API_URL}")
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: Maybe add some `--retry`? I think Jira is a service that is not always 100 % reliable.
created_at: 2025-02-06T09:43:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
+            fi
+            API_URL="${API_URL}$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
+            OUTPUT=$(curl --fail "${API_URL}")
             if [ $? -ne 0 ] ; then
-                echo "${issue} is not publicly visible. Assuming it is embargoed and stopping pipelineRun execution."
+                echo "${issue} is not visible. Assuming it is embargoed and stopping pipelineRun execution."
                 RC=1
             fi
+
+            # Perform additional checks only for Vulnerability issues for issues.redhat.com
+            if [ "$server" != "issues.redhat.com" ] ; then
+                continue
+            fi
+            ISSUE_TYPE=$(jq -r '.fields.issuetype.name' <<< "$OUTPUT")
+            if [ "$ISSUE_TYPE" != "Vulnerability" ] ; then
+                continue
+            fi
+            CVE_ID=$(jq -r --arg field "$CVE_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            COMPONENT_NAME=$(jq -r --arg field "$COMPONENT_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            if ! COMPONENT_IN_RELEASE_NOTES="$(jq -ec --arg name "$COMPONENT_NAME" \
+              '.releaseNotes.content.images[] | select(.component==$name)' "$DATA_FILE")"; then
+                echo -n "Issue $issue lists 'Downstream Component Name' $COMPONENT_NAME but that component does"
+                echo " not appear in releaseNotes.content.images. Failing"
+                exit 2
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: Shouldn't this also just do `RC=1` (and same a few lines down)?
created_at: 2025-02-06T09:45:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
+            fi
+            API_URL="${API_URL}$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
+            OUTPUT=$(curl --fail "${API_URL}")
             if [ $? -ne 0 ] ; then
-                echo "${issue} is not publicly visible. Assuming it is embargoed and stopping pipelineRun execution."
+                echo "${issue} is not visible. Assuming it is embargoed and stopping pipelineRun execution."
                 RC=1
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: This should probably also have `continue` after this line? Because otherwise you will try to read from OUTPUT which you failed to obtain.
created_at: 2025-02-06T09:46:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: Also, both the `AUTH_ARGS=` and `OUTPUT=` would leak the token, so you'll need `set +x` here.
created_at: 2025-02-06T09:53:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: Probably? This is my first time working with the Jira API. It did seem a bit weird to me to hardcode something like "customfield_4940302"
created_at: 2025-02-06T13:02:02Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: Completely forgot about that, nice call
created_at: 2025-02-06T13:02:49Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
+            fi
+            API_URL="${API_URL}$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
+            OUTPUT=$(curl --fail "${API_URL}")
             if [ $? -ne 0 ] ; then
-                echo "${issue} is not publicly visible. Assuming it is embargoed and stopping pipelineRun execution."
+                echo "${issue} is not visible. Assuming it is embargoed and stopping pipelineRun execution."
                 RC=1
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: Yeah, I didn't realize I was changing the behavior to exit early now. I switched to just setting RC and adding in continues. Thanks for catching that
created_at: 2025-02-06T13:11:41Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
+            fi
+            API_URL="${API_URL}$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
+            OUTPUT=$(curl --fail "${API_URL}")
             if [ $? -ne 0 ] ; then
-                echo "${issue} is not publicly visible. Assuming it is embargoed and stopping pipelineRun execution."
+                echo "${issue} is not visible. Assuming it is embargoed and stopping pipelineRun execution."
                 RC=1
             fi
+
+            # Perform additional checks only for Vulnerability issues for issues.redhat.com
+            if [ "$server" != "issues.redhat.com" ] ; then
+                continue
+            fi
+            ISSUE_TYPE=$(jq -r '.fields.issuetype.name' <<< "$OUTPUT")
+            if [ "$ISSUE_TYPE" != "Vulnerability" ] ; then
+                continue
+            fi
+            CVE_ID=$(jq -r --arg field "$CVE_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            COMPONENT_NAME=$(jq -r --arg field "$COMPONENT_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            if ! COMPONENT_IN_RELEASE_NOTES="$(jq -ec --arg name "$COMPONENT_NAME" \
+              '.releaseNotes.content.images[] | select(.component==$name)' "$DATA_FILE")"; then
+                echo -n "Issue $issue lists 'Downstream Component Name' $COMPONENT_NAME but that component does"
+                echo " not appear in releaseNotes.content.images. Failing"
+                exit 2
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: fixed
created_at: 2025-02-06T13:11:46Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
+            fi
+            API_URL="${API_URL}$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
+            OUTPUT=$(curl --fail "${API_URL}")
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: added
created_at: 2025-02-06T13:11:51Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: Not addressed yet but I will soon
created_at: 2025-02-06T13:12:04Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: Updated comment to mention that too
created_at: 2025-02-06T13:12:14Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: Yeah, I would do it. It seems like an unnecessary overhead to always pull it from the server (especially when there are so many, so the resulting json is pretty big).

BTW, in the past when I needed to figure out which customfield id to use, I would just check the source of a loaded jira web page and search for my field and the id would be there somewhere :) Using the API sure seems better. But IMHO no need to do it every time.
created_at: 2025-02-06T13:12:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: I am going to have to add more `set -x` stuff too around the actual curl call for this
created_at: 2025-02-06T13:17:30Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,58 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs or leak the ACCESS_TOKEN
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
+            fi
+            API_URL="${API_URL}$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
+            OUTPUT=$(curl --retry 3 --fail "${API_URL}")
             if [ $? -ne 0 ] ; then
-                echo "${issue} is not publicly visible. Assuming it is embargoed and stopping pipelineRun execution."
+                echo "${issue} is not visible. Assuming it is embargoed and stopping pipelineRun execution."
                 RC=1
+                continue
+            fi
+
+            # Perform additional checks only for Vulnerability issues for issues.redhat.com
+            if [ "$server" != "issues.redhat.com" ] ; then
+                continue
+            fi
+            ISSUE_TYPE=$(jq -r '.fields.issuetype.name' <<< "$OUTPUT")
+            if [ "$ISSUE_TYPE" != "Vulnerability" ] ; then
+                continue
+            fi
+            CVE_ID=$(jq -r --arg field "$CVE_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            COMPONENT_NAME=$(jq -r --arg field "$COMPONENT_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            if ! COMPONENT_IN_RELEASE_NOTES="$(jq -ec --arg name "$COMPONENT_NAME" \
+              '.releaseNotes.content.images[] | select(.component==$name)' "$DATA_FILE")"; then
+                echo -n "Issue $issue lists 'Downstream Component Name' $COMPONENT_NAME but that component does"
+                echo " not appear in releaseNotes.content.images. Failing"
+                RC=2
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: If we're here, then the next check is also pointless, right? Because it tries to check something in `"$COMPONENT_IN_RELEASE_NOTES"` which might be empty? So probably also a `continue` here? 
created_at: 2025-02-06T13:20:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,58 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs or leak the ACCESS_TOKEN
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
+            fi
+            API_URL="${API_URL}$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
+            OUTPUT=$(curl --retry 3 --fail "${API_URL}")
             if [ $? -ne 0 ] ; then
-                echo "${issue} is not publicly visible. Assuming it is embargoed and stopping pipelineRun execution."
+                echo "${issue} is not visible. Assuming it is embargoed and stopping pipelineRun execution."
                 RC=1
+                continue
+            fi
+
+            # Perform additional checks only for Vulnerability issues for issues.redhat.com
+            if [ "$server" != "issues.redhat.com" ] ; then
+                continue
+            fi
+            ISSUE_TYPE=$(jq -r '.fields.issuetype.name' <<< "$OUTPUT")
+            if [ "$ISSUE_TYPE" != "Vulnerability" ] ; then
+                continue
+            fi
+            CVE_ID=$(jq -r --arg field "$CVE_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            COMPONENT_NAME=$(jq -r --arg field "$COMPONENT_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            if ! COMPONENT_IN_RELEASE_NOTES="$(jq -ec --arg name "$COMPONENT_NAME" \
+              '.releaseNotes.content.images[] | select(.component==$name)' "$DATA_FILE")"; then
+                echo -n "Issue $issue lists 'Downstream Component Name' $COMPONENT_NAME but that component does"
+                echo " not appear in releaseNotes.content.images. Failing"
+                RC=2
+            fi
+
+            if [ "$(jq --arg CVE "$CVE_ID" '.cves.fixed | has($CVE)' <<< "$COMPONENT_IN_RELEASE_NOTES")" != "true" ]
+            then
+                echo -n "Issue $issue lists 'Downstream Component Name' $COMPONENT_NAME and 'CVE ID' $CVE_ID"
+                echo " but that CVE is not present in the releaseNotes.content.images section for that component."
+                echo "Failing"
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: I think saying "Failing" made would make more sense if we were exiting here. But we only fail after the loop (so that we could collect and print all the failures), so maybe it would make more sense to add an "Error: " prefix to the messages and remove "Failing"? (This applies elsewhere too.)
created_at: 2025-02-06T13:22:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,58 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs or leak the ACCESS_TOKEN
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
+            fi
+            API_URL="${API_URL}$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
+            OUTPUT=$(curl --retry 3 --fail "${API_URL}")
             if [ $? -ne 0 ] ; then
-                echo "${issue} is not publicly visible. Assuming it is embargoed and stopping pipelineRun execution."
+                echo "${issue} is not visible. Assuming it is embargoed and stopping pipelineRun execution."
                 RC=1
+                continue
+            fi
+
+            # Perform additional checks only for Vulnerability issues for issues.redhat.com
+            if [ "$server" != "issues.redhat.com" ] ; then
+                continue
+            fi
+            ISSUE_TYPE=$(jq -r '.fields.issuetype.name' <<< "$OUTPUT")
+            if [ "$ISSUE_TYPE" != "Vulnerability" ] ; then
+                continue
+            fi
+            CVE_ID=$(jq -r --arg field "$CVE_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            COMPONENT_NAME=$(jq -r --arg field "$COMPONENT_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            if ! COMPONENT_IN_RELEASE_NOTES="$(jq -ec --arg name "$COMPONENT_NAME" \
+              '.releaseNotes.content.images[] | select(.component==$name)' "$DATA_FILE")"; then
+                echo -n "Issue $issue lists 'Downstream Component Name' $COMPONENT_NAME but that component does"
+                echo " not appear in releaseNotes.content.images. Failing"
+                RC=2
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: Yeah, I meant to add that and forgot to. There now
created_at: 2025-02-06T13:25:12Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,58 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs or leak the ACCESS_TOKEN
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
+            fi
+            API_URL="${API_URL}$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
+            OUTPUT=$(curl --retry 3 --fail "${API_URL}")
             if [ $? -ne 0 ] ; then
-                echo "${issue} is not publicly visible. Assuming it is embargoed and stopping pipelineRun execution."
+                echo "${issue} is not visible. Assuming it is embargoed and stopping pipelineRun execution."
                 RC=1
+                continue
+            fi
+
+            # Perform additional checks only for Vulnerability issues for issues.redhat.com
+            if [ "$server" != "issues.redhat.com" ] ; then
+                continue
+            fi
+            ISSUE_TYPE=$(jq -r '.fields.issuetype.name' <<< "$OUTPUT")
+            if [ "$ISSUE_TYPE" != "Vulnerability" ] ; then
+                continue
+            fi
+            CVE_ID=$(jq -r --arg field "$CVE_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            COMPONENT_NAME=$(jq -r --arg field "$COMPONENT_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            if ! COMPONENT_IN_RELEASE_NOTES="$(jq -ec --arg name "$COMPONENT_NAME" \
+              '.releaseNotes.content.images[] | select(.component==$name)' "$DATA_FILE")"; then
+                echo -n "Issue $issue lists 'Downstream Component Name' $COMPONENT_NAME but that component does"
+                echo " not appear in releaseNotes.content.images. Failing"
+                RC=2
+            fi
+
+            if [ "$(jq --arg CVE "$CVE_ID" '.cves.fixed | has($CVE)' <<< "$COMPONENT_IN_RELEASE_NOTES")" != "true" ]
+            then
+                echo -n "Issue $issue lists 'Downstream Component Name' $COMPONENT_NAME and 'CVE ID' $CVE_ID"
+                echo " but that CVE is not present in the releaseNotes.content.images section for that component."
+                echo "Failing"
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: Updated
created_at: 2025-02-06T13:25:16Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: Do you think it is worth leaving the current commands there but commented out just in case they do change? Or it is easy enough to figure out and not worth it
created_at: 2025-02-06T13:25:49Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: You mean inside `$()`? That shouldn't be needed. Because that starts in a subshell and that subshell won't have `set -x` - it will have the defaults. At least in theory :)
created_at: 2025-02-06T13:26:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: I like that idea - to leave the api call in a comment. I would probably just say something like:
```
# To get the custom field ids, you can do: 
# curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field
```
But up to you.
created_at: 2025-02-06T13:30:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,58 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs or leak the ACCESS_TOKEN
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
+            fi
+            API_URL="${API_URL}$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
+            OUTPUT=$(curl --retry 3 --fail "${API_URL}")
             if [ $? -ne 0 ] ; then
-                echo "${issue} is not publicly visible. Assuming it is embargoed and stopping pipelineRun execution."
+                echo "${issue} is not visible. Assuming it is embargoed and stopping pipelineRun execution."
                 RC=1
+                continue
+            fi
+
+            # Perform additional checks only for Vulnerability issues for issues.redhat.com
+            if [ "$server" != "issues.redhat.com" ] ; then
+                continue
+            fi
+            ISSUE_TYPE=$(jq -r '.fields.issuetype.name' <<< "$OUTPUT")
+            if [ "$ISSUE_TYPE" != "Vulnerability" ] ; then
+                continue
+            fi
+            CVE_ID=$(jq -r --arg field "$CVE_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            COMPONENT_NAME=$(jq -r --arg field "$COMPONENT_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            if ! COMPONENT_IN_RELEASE_NOTES="$(jq -ec --arg name "$COMPONENT_NAME" \
+              '.releaseNotes.content.images[] | select(.component==$name)' "$DATA_FILE")"; then
+                echo -n "Issue $issue lists 'Downstream Component Name' $COMPONENT_NAME but that component does"
+                echo " not appear in releaseNotes.content.images. Failing"
+                RC=2
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: OK, cool. BTW, with the late failing, I don't think it makes much sense to use different return codes, because in the end you can only return one code. So personally I'd just change all the non-zero codes to 1. But if you prefer to leave it like this, that's fine with me.
created_at: 2025-02-06T13:32:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: I didn't notice you already commented it, but I was referring to this `Also, both the AUTH_ARGS= and OUTPUT= would leak the token, so you'll need set +x here.`
created_at: 2025-02-06T13:56:52Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: I moved the set command around a bit
created_at: 2025-02-06T14:01:36Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: Hardcoded and comment added
created_at: 2025-02-06T14:01:45Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: Updated
created_at: 2025-02-06T14:01:52Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,58 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs or leak the ACCESS_TOKEN
+        CUSTOM_RH_FIELDS="$(curl -H "Authorization: Bearer $ACCESS_TOKEN" https://issues.redhat.com/rest/api/2/field)"
+        set -x
+        CVE_FIELD="$(jq -r '.[] | select(.name=="CVE ID") | .id' <<< "$CUSTOM_RH_FIELDS")"
+        COMPONENT_FIELD="$(jq -r '.[] | select(.name=="Downstream Component Name") | .id' <<< "$CUSTOM_RH_FIELDS")"
+
         RC=0
 
         NUM_ISSUES=$(jq -cr '.releaseNotes.issues.fixed | length' "${DATA_FILE}")
         for ((i = 0; i < NUM_ISSUES; i++)); do
             issue=$(jq -c --argjson i "$i" '.releaseNotes.issues.fixed[$i]' "${DATA_FILE}")
             server=$(jq -r '.source' <<< "$issue")
             API=$(jq -r '.[] | select(.servers[] | contains("'"$server"'")) | .api' <<< "$SUPPORTED_ISSUE_TRACKERS")
-            API_URL="https://$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
-            curl --fail --output /dev/null "${API_URL}"
+            API_URL="https://"
+            # Add authentication for issues.redhat.com
+            if [ "$server" = "issues.redhat.com" ] ; then
+                API_URL="-H \"Authorization: Bearer $ACCESS_TOKEN\" ${API_URL}"
+            fi
+            API_URL="${API_URL}$(jq -r '.source' <<< "$issue")/${API}/$(jq -r '.id' <<< "$issue")"
+            OUTPUT=$(curl --retry 3 --fail "${API_URL}")
             if [ $? -ne 0 ] ; then
-                echo "${issue} is not publicly visible. Assuming it is embargoed and stopping pipelineRun execution."
+                echo "${issue} is not visible. Assuming it is embargoed and stopping pipelineRun execution."
                 RC=1
+                continue
+            fi
+
+            # Perform additional checks only for Vulnerability issues for issues.redhat.com
+            if [ "$server" != "issues.redhat.com" ] ; then
+                continue
+            fi
+            ISSUE_TYPE=$(jq -r '.fields.issuetype.name' <<< "$OUTPUT")
+            if [ "$ISSUE_TYPE" != "Vulnerability" ] ; then
+                continue
+            fi
+            CVE_ID=$(jq -r --arg field "$CVE_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            COMPONENT_NAME=$(jq -r --arg field "$COMPONENT_FIELD" '.fields[$field]' <<< "$OUTPUT")
+            if ! COMPONENT_IN_RELEASE_NOTES="$(jq -ec --arg name "$COMPONENT_NAME" \
+              '.releaseNotes.content.images[] | select(.component==$name)' "$DATA_FILE")"; then
+                echo -n "Issue $issue lists 'Downstream Component Name' $COMPONENT_NAME but that component does"
+                echo " not appear in releaseNotes.content.images. Failing"
+                RC=2
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: Makes sense, updated to always be 1
created_at: 2025-02-06T14:02:04Z
author_association: COLLABORATOR
diff_hunk: @@ -62,19 +71,56 @@ spec:
             exit 1
         fi
 
+        set +x # There are a lot of custom fields, don't want to pollute the logs
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: ok, looks good, thanks
created_at: 2025-02-06T14:04:15Z
author_association: CONTRIBUTOR
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: This was already approved before, right? Did you just need to fix some rebase conflicts or are there some other changes?
created_at: 2025-03-06T15:32:20Z
author_association: CONTRIBUTOR
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: johnbieren
body: The only change I made was the secret key TODOs were replaced with the actual values now that the secret exists
created_at: 2025-03-06T15:33:35Z
author_association: COLLABORATOR
path: tasks/managed/embargo-check/embargo-check.yaml
user: login: mmalina
body: oh I see, thanks
created_at: 2025-03-06T15:35:59Z
author_association: CONTRIBUTOR

PR comments:
user: login: openshift-ci[bot]
created_at: 2025-02-05T20:01:44Z
body: Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with `/test all`
author_association: NONE
user: login: johnbieren
created_at: 2025-03-06T18:18:43Z
body: /retest
author_association: COLLABORATOR
user: login: openshift-ci[bot]
created_at: 2025-03-06T20:18:44Z
body: New changes are detected. LGTM label has been removed.
author_association: NONE
user: login: johnbieren
created_at: 2025-03-06T23:57:33Z
body: /retest
failed to provision cluster
author_association: COLLABORATOR
user: login: johnbieren
created_at: 2025-03-07T00:57:28Z
body: /retest
unrelated error
author_association: COLLABORATOR
user: login: johnbieren
created_at: 2025-03-07T01:46:22Z
body: /retest
author_association: COLLABORATOR