tfa-next: add unsafe checks

Change-Id: Idc6357e228e997fdee12cb6f8c711cf183fb9a6b
Signed-off-by: Tomás González <tomasagustin.gonzalezorlando@arm.com>
diff --git a/scripts/clone.sh b/scripts/clone.sh
index 979c3c3..10bc33d 100755
--- a/scripts/clone.sh
+++ b/scripts/clone.sh
@@ -47,6 +47,7 @@
 SPM_GERRIT_PROJECT="${SPM_GERRIT_PROJECT:-hafnium/hafnium}"
 RMM_GERRIT_PROJECT="${RMM_GERRIT_PROJECT:-TF-RMM/tf-rmm}"
 CI_GERRIT_PROJECT="${CI_GERRIT_PROJECT:-ci/tf-a-ci-scripts}"
+RF_GERRIT_PROJECT="${RF_GERRIT_PROJECT:-RF-A/rusted-firmware-a}"
 ARM_FFA_GERRIT_PROJECT="${ARM_FFA_GERRIT_PROJECT:-rust-spmc/arm-ffa}"
 ARM_PL011_UART_GERRIT_PROJECT="${ARM_PL011_UART_GERRIT_PROJECT:-rust-spmc/arm-pl011-uart}"
 ARM_PSCI_GERRIT_PROJECT="${ARM_PSCI_GERRIT_PROJECT:-rust-spmc/arm-psci}"
@@ -64,6 +65,7 @@
 TF_M_TESTS_GERRIT_REFSPEC="${TF_M_TESTS_GERRIT_REFSPEC:-${REFSPEC_TF_M_TESTS}}"
 TF_M_EXTRAS_GERRIT_REFSPEC="${TF_M_EXTRAS_GERRIT_REFSPEC:-${REFSPEC_TF_M_EXTRAS}}"
 CI_REFSPEC="${CI_REFSPEC:-${REFSPEC_MASTER}}"
+RF_GERRIT_REFSPEC="${RF_GERRIT_REFSPEC:-${REFSPEC_MAIN}}"
 ARM_FFA_GERRIT_REFSPEC="${ARM_FFA_GERRIT_REFSPEC:-${REFSPEC_MAIN}}"
 ARM_PL011_UART_GERRIT_REFSPEC="${ARM_PL011_UART_GERRIT_REFSPEC:-${REFSPEC_MAIN}}"
 ARM_PSCI_GERRIT_REFSPEC="${ARM_PSCI_GERRIT_REFSPEC:-${REFSPEC_MAIN}}"
@@ -84,6 +86,7 @@
   ["tf-rmm"]="${GERRIT_HOST};${RMM_GERRIT_PROJECT};${RMM_REFSPEC}"
   ["tf-m-tests"]="${GERRIT_HOST};${TF_M_TESTS_GERRIT_PROJECT};${TF_M_TESTS_GERRIT_REFSPEC}"
   ["tf-m-extras"]="${GERRIT_HOST};${TF_M_EXTRAS_GERRIT_PROJECT};${TF_M_EXTRAS_GERRIT_REFSPEC}"
+  ["rusted-firmware-a"]="${GERRIT_HOST};${RF_GERRIT_PROJECT};${RF_GERRIT_REFSPEC}"
   ["arm-ffa"]="${GERRIT_HOST};${ARM_FFA_GERRIT_PROJECT};${ARM_FFA_GERRIT_REFSPEC}"
   ["arm-pl011-uart"]="${GERRIT_HOST};${ARM_PL011_UART_GERRIT_PROJECT};${ARM_PL011_UART_GERRIT_REFSPEC}"
   ["arm-psci"]="${GERRIT_HOST};${ARM_PSCI_GERRIT_PROJECT};${ARM_PSCI_GERRIT_REFSPEC}"
@@ -94,6 +97,7 @@
   ["firmware-development-guide"]="${GERRIT_HOST};${ARM_FW_DEV_GUIDE_GERRIT_PROJECT};${ARM_FW_DEV_GUIDE_REFSPEC}"
 )
 
+
 test_desc="${test_desc:-$TEST_DESC}"
 if [ -n "${test_desc}" ]; then
     build_config="$(echo "${test_desc%%:*}" | cut -d'%' -f3)"
@@ -158,8 +162,14 @@
 
     # clone and checkout in case it does not exist
     if [ ! -d ${SHARE_FOLDER}/${REPO_NAME} ]; then
-        git clone ${GIT_CLONE_PARAMS} ${REPO_URL} ${SHARE_FOLDER}/${REPO_NAME} \
+        if [[ ${FETCH_SSH} ]]; then
+            GIT_SSH_COMMAND="ssh ${SSH_PARAMS}" git clone ${GIT_CLONE_PARAMS} ${REPO_SSH_URL} ${SHARE_FOLDER}/${REPO_NAME} \
                     --depth 1 --recurse-submodules --shallow-submodules
+        else
+            git clone ${GIT_CLONE_PARAMS} ${REPO_URL} ${SHARE_FOLDER}/${REPO_NAME} \
+                    --depth 1 --recurse-submodules --shallow-submodules
+        fi
+
         # If the Gerrit review that triggered the CI had a topic, it will be used to synchronize the other repositories
         if [ -n "${GERRIT_TOPIC}" -a "${REPO_HOST}" = "${GERRIT_HOST}" -a "${GERRIT_PROJECT}" != "${REPO_PROJECT}" ]; then
             echo "Got Gerrit Topic: ${GERRIT_TOPIC}"
diff --git a/tf-a-unsafe-tfa-next.yaml b/tf-a-unsafe-tfa-next.yaml
new file mode 100644
index 0000000..2908d92
--- /dev/null
+++ b/tf-a-unsafe-tfa-next.yaml
@@ -0,0 +1,125 @@
+- job:
+    name: tf-a-unsafe-tfa-next
+    node: docker-amd64-tf-a-jammy
+    project-type: freestyle
+    concurrent: true
+    disabled: false
+    defaults: global
+    description: Check for Unsafe changes in Trusted Firmware Next
+    properties:
+        - build-discarder:
+            days-to-keep: 14
+    triggers:
+    - gerrit:
+        server-name: 'review.trustedfirmware.org'
+        projects:
+        - branches:
+          - branch-compare-type: PLAIN
+            branch-pattern: 'main'
+          project-compare-type: PLAIN
+          project-pattern: 'RF-A/rusted-firmware-a'
+        trigger-on:
+            - patchset-created-event:
+                exclude-drafts: true
+                exclude-trivial-rebase: false
+                exclude-no-code-change: true
+                exclude-private: true
+                exclude-wip: true
+            - comment-added-contains-event:
+                comment-contains-value: '^RUN_UNSAFE_CI$'
+        override-votes: true
+        # without explicitly setting these values to 0, the plugin will by
+        # default leave Code Review votes
+        gerrit-build-started-codereview-value: 0
+        gerrit-build-successful-codereview-value: 0
+        gerrit-build-failed-codereview-value: 0
+        gerrit-build-unstable-codereview-value: 0
+        gerrit-build-notbuilt-codereview-value: 0
+        silent: false
+        silent-start: false
+    parameters:
+        # GERRIT_{PROJECT,BRANCH,REFSPEC} are set when triggered by a Gerrit
+        # patchset - defaults below are for manual triggers
+        - string:
+            name: GERRIT_PROJECT
+            default: 'RF-A/rusted-firmware-a'
+        - string:
+            name: GERRIT_BRANCH
+            default: 'refs/heads/main'
+        - string:
+            name: GERRIT_REFSPEC
+            default: '+refs/heads/main:refs/remotes/origin/main'
+            description: |
+              'e.g. refs/changes/13/31138/1'
+        - string:
+            name: RF_GERRIT_REFSPEC
+            default: ${GERRIT_REFSPEC}
+            description: |
+              'do-not-amend: used by scripts/clone.sh to fetch the correct Gerrit patchset - use GERRIT_REFSPEC instead'
+        - string:
+            name: CI_REFSPEC
+            default: '+refs/heads/tfa-next:refs/remotes/origin/tfa-next'
+            description: |
+              'Refs to fetch for the tf-a-ci-scripts repo e.g. refs/changes/13/31138/1'
+        - string:
+            name: JOBS_REFSPEC
+            default: 'refs/heads/master'
+            description: |
+              tf-a-job-configs refspec to use. The master branch is used by default.
+        - string:
+            name: SHARE_FOLDER
+            default: '/srv/shared/${JOB_NAME}/${BUILD_NUMBER}'
+            description: 'Folder containing shared repositories for downstream pipeline jobs'
+        - string:
+            name: CLONE_REPOS
+            default: "rusted-firmware-a"
+            description: |
+              Optional arg to clone only specific projects from default list (tf-a-ci-scripts,rusted-firmware-a,tf-a-tests,spm,tf-m-tests,tf-m-extras)
+        - string:
+            name: FETCH_SSH
+            default: 1
+            description: |
+              Fetch branches with authenticated SSH instead of anonymous HTTPS
+    wrappers:
+        - credentials-binding:
+            - ssh-user-private-key:
+                credential-id: TFA_CI_BOT_USER_SSH_KEY
+                key-file-variable: CI_BOT_KEY
+                username-variable: CI_BOT_USERNAME
+                passphrase-variable: ''
+        - timestamps
+        - timeout:
+            timeout: 240
+            fail: true
+    builders:
+    - shell:
+        !include-raw: scripts/clone.sh
+    - shell: |
+        #!/bin/bash
+        set -ex
+        cat << EOF > tf-a-env.param
+        RF_GERRIT_PROJECT=${GERRIT_PROJECT}
+        RF_GERRIT_REFSPEC=${GERRIT_REFSPEC}
+        SHARE_FOLDER=${SHARE_FOLDER}
+        EOF
+
+        cd ${WORKSPACE}/rusted-firmware-a
+
+        # Vote Unsafe-Review+1 on patches not touching any unsafe code
+
+        # 1. Check if the patch touches unsafe code:
+
+        # if the grep command finds nothing, it will exit 1 and because we have set -e the program
+        # will fail. Doing || true makes it so that the final exit command is always 0 so the flow is not
+        # interrupted and we can check `diff` to know if the program was successful or not.
+        diff=$(echo $(git show -U10 --format=) | grep "unsafe" || true)
+        if [ "$diff" != "" ]; then
+            exit 1
+        fi
+
+        # 2. Cast the Unsafe-Review +1 vote if the patch does NOT touch unsafe code:
+
+        SSH_PARAMS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PubkeyAcceptedKeyTypes=+ssh-rsa -p 29418 -i ${CI_BOT_KEY}"
+        GERRIT_URL="review.trustedfirmware.org"
+        SET_SAFE_CMD="${SSH_PARAMS} ${CI_BOT_USERNAME}@${GERRIT_URL} gerrit review --label Unsafe-Review=1 -m Safe"
+        ssh ${SET_SAFE_CMD} ${GERRIT_CHANGE_NUMBER},${GERRIT_PATCHSET_NUMBER}