diff --git a/.gitlab/pipelines/deployment-pipeline.yml b/.gitlab/pipelines/deployment-pipeline.yml index b96b3b463f50a7d71fe8f2b56609ec1b11a6052f..0f24e8fa8a80b148ec4fa4a62f3c137f90ebb772 100644 --- a/.gitlab/pipelines/deployment-pipeline.yml +++ b/.gitlab/pipelines/deployment-pipeline.yml @@ -90,6 +90,15 @@ check-commit-msg: - pull-mr allow_failure: true +check-code-security: + extends: + - .check-code-security + stage: code-quality + rules: + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + when: manual + allow_failure: true + banned-api: extends: - .banned-api diff --git a/.gitlab/templates/linting.yml b/.gitlab/templates/linting.yml index 89a97778d08dae6b41a4b4992f596cc945ffd105..265f25adba149cf8bfe43acc7e7251f1b132c6ee 100644 --- a/.gitlab/templates/linting.yml +++ b/.gitlab/templates/linting.yml @@ -57,3 +57,62 @@ expire_in: 1 day reports: junit: commit_msg_validation.xml # Attach XML report for GitLab MR + +.check-code-security: + image: ${CONTAINER_REGISTRY_PATH}/security:${DOCKER_IMAGE_TAG} + tags: + - amd64 + script: + - git diff "${CI_MERGE_REQUEST_DIFF_BASE_SHA:-$(git merge-base HEAD origin/main)}" > new_functionality.diff + - git apply -R new_functionality.diff + - python3 /app/code_review.py review --patch-file new_functionality.diff --chroma-db /app/chroma_db --codebase-path . + - | + if [ ! -f review_output.json ]; then + echo "Error: review_output.json not found. The review command might have failed." + exit 1 + fi + if jq -e '.reviews[] | select(.review | type == "array")' review_output.json > /dev/null; then + echo "Security issues found, posting comments..." + else + echo "No security issues found in the patch." + curl --fail --location --request POST \ + "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes" \ + --header "PRIVATE-TOKEN:${INTERNAL_REPO_API_KEY}" \ + --header "Content-Type:application/json" \ + --data '{"body":"No security issues found in the MR."}' + exit 0 + fi + COMMENT='' + while read -r line; do + file=$(echo "$line" | jq -r '.file') + issue=$(echo "$line" | jq -r '.issue') + mitigation=$(echo "$line" | jq -r '.mitigation') + confidence=$(echo "$line" | jq -r '.confidence') + explanation=$(echo "$line" | jq -r '.explanation') + COMMENT+=$'**File:** '"$file"$'\n\n' + COMMENT+=$'**Potential Security Issues:** '"$issue"$'\n\n' + COMMENT+=$'**Mitigation:** '"$mitigation"$'\n\n' + COMMENT+=$'**Confidence:** '"$confidence"$'\n\n' + COMMENT+=$'**Explanation:** '"$explanation"$'\n\n' + COMMENT+=$'---\n' + done < <( + jq -c '.reviews[] | select(.review | type == "array") | .file as $file | .review[] | {file: $file, issue, confidence, mitigation, explanation}' review_output.json + ) + if [ -z "$COMMENT" ]; then + echo "No comment to post." + exit 0 + else + echo "Final Formatted COMMENT:" + echo "$COMMENT" + fi + jq -n --arg body "$COMMENT" '{body: $body}' > payload.json + curl --fail --location --request POST \ + "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes" \ + --header "PRIVATE-TOKEN:${INTERNAL_REPO_API_KEY}" \ + --header "Content-Type:application/json" \ + --data @payload.json + artifacts: + when: always + paths: + - review_output.json + expire_in: 1 day