diff --git a/incubating/jira-issue-manager/Dockerfile b/incubating/jira-issue-manager/Dockerfile index ff8631512..d7c68d734 100644 --- a/incubating/jira-issue-manager/Dockerfile +++ b/incubating/jira-issue-manager/Dockerfile @@ -1,10 +1,10 @@ -FROM python:3.7.9-slim-buster +FROM python:3.14-slim-trixie -ENV LANG C.UTF-8 +ENV LANG=C.UTF-8 -RUN pip install --no-cache-dir jira +RUN pip install --no-cache-dir jira==3.10.5 certifi==2026.10.23 COPY script/. / ENTRYPOINT ["python", "/jira_issue_manager.py"] -CMD [""] \ No newline at end of file +CMD [""] diff --git a/incubating/jira-issue-manager/step.yaml b/incubating/jira-issue-manager/step.yaml index 2a47f05ce..c86561c5c 100644 --- a/incubating/jira-issue-manager/step.yaml +++ b/incubating/jira-issue-manager/step.yaml @@ -2,7 +2,7 @@ kind: step-type version: '1.0' metadata: name: jira-issue-manager - version: 1.0.13 + version: 1.0.14 title: Jira Issue Manager isPublic: true description: Create, Update, & Validate Jira Issues @@ -246,7 +246,7 @@ spec: stepsTemplate: |- main: name: jira-issue-manager - image: quay.io/codefreshplugins/jira-issue-manager:1.0.13 + image: quay.io/codefreshplugins/jira-issue-manager:1.0.14 environment: [[ range $key, $val := .Arguments ]] - '[[ $key ]]=[[ $val ]]' diff --git a/incubating/sonar-quality-gates-checker-cf/Dockerfile b/incubating/sonar-quality-gates-checker-cf/Dockerfile deleted file mode 100644 index 93a74c357..000000000 --- a/incubating/sonar-quality-gates-checker-cf/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM python:3.9.1-alpine3.13 - -RUN pip install --no-cache-dir python-sonarqube-api - -COPY lib/sonarqube-api.py /sonarqube-api.py diff --git a/incubating/sonar-quality-gates-checker-cf/lib/sonarqube-api.py b/incubating/sonar-quality-gates-checker-cf/lib/sonarqube-api.py deleted file mode 100644 index 597578cbc..000000000 --- a/incubating/sonar-quality-gates-checker-cf/lib/sonarqube-api.py +++ /dev/null @@ -1,64 +0,0 @@ -import os -import sys -from sonarqube import SonarCloudClient -from sonarqube import SonarQubeClient -import json - - -def exportResults(status): - print("\nExporting Results") - - qualitygates_status_json = json.dumps(status) - qualitygates_status= status['projectStatus']['status'] - - env_file_path = "/meta/env_vars_to_export" - - if not os.path.exists(env_file_path): - print(f"Quality Gates status is \n'{qualitygates_status}'") - print(f"Quality Gates status JSON is \n'{qualitygates_status_json}'") - else: - env_file = open(env_file_path, "a") - qualitygates_status_json_file_path = f"/codefresh/volume/sonarqualitygates-{os.getenv('CF_SHORT_REVISION')}.json" - env_file.write("SONAR_QUALITYGATES_STATUS=" + qualitygates_status + "\n") - env_file.write("SONAR_QUALITYGATES_STATUS_JSON_PATH=" + qualitygates_status_json_file_path + "\n") - env_file.close() - - qualitygates_status_json_file = open(qualitygates_status_json_file_path, "w") - json.dump(status, qualitygates_status_json_file, indent = 4) - qualitygates_status_json_file.close() - -def actBasedOnStatus(status): - qualitygates_status = status['projectStatus']['status'] - if qualitygates_status == 'ERROR': - print(f"Quality Gates status is '{qualitygates_status}'. FAILLING THE PROCESS") - print(f'This the full Quality Gate report:\n { json.dumps(status, indent=4, sort_keys=True) }') - sys.exit(1) - if qualitygates_status == 'WARN': - print(f"Quality Gate status is '{qualitygates_status}'.") - print(f'This the full Quality Gate report:\n { json.dumps(status, indent=4, sort_keys=True) }') - - if qualitygates_status == 'OK': - print(f"Quality Gate status is '{qualitygates_status}'.") - - -def main(): - branch = os.getenv('CF_BRANCH', 'main') - sonar_project = os.getenv('SONAR_PROJECT_KEY') - sonarcloud_token = os.getenv('SONAR_TOKEN') - sonarqube_password = os.getenv('SONAR_PASSWORD') - sonarqube_username = os.getenv('SONAR_USERNAME') - sonar_url = os.getenv('SONAR_HOST_URL', 'https://sonarcloud.io') - - if sonarcloud_token: - sonar = SonarCloudClient(sonarcloud_url=sonar_url, token=sonarcloud_token) - else: - sonar = SonarQubeClient(sonarqube_url=sonar_url, username=sonarqube_username, password=sonarqube_password) - - # Code: https://github.com/shijl0925/python-sonarqube-api/blob/376cf1d6ef231ee084694c77dadf551733395d4f/sonarqube/community/qualitygates.py#L182 - # Docs: https://python-sonarqube-api.readthedocs.io/en/1.2.1/examples/qualitygates.html# - qualitygates_status = sonar.qualitygates.get_project_qualitygates_status(projectKey=sonar_project, branch=branch) - exportResults(qualitygates_status) - actBasedOnStatus(qualitygates_status) - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/incubating/sonar-quality-gates-checker-cf/step.yaml b/incubating/sonar-quality-gates-checker-cf/step.yaml deleted file mode 100644 index 78ac08912..000000000 --- a/incubating/sonar-quality-gates-checker-cf/step.yaml +++ /dev/null @@ -1,100 +0,0 @@ -kind: step-type -version: '1.0' -metadata: - name: sonar-quality-gates-checker - version: 0.1.1 - isPublic: true - description: Check Quality Gates from Sonarqube or Sonarcloud - sources: - - https://github.com/codefresh-io/steps/tree/master/incubating/sonarqube - stage: incubating - maintainers: - - name: Dustin Van Buskirk - email: dustin@codefresh.io - categories: - - utilities - official: true - tags: [] - icon: - type: svg - url: https://raw.githubusercontent.com/codefresh-io/steps/master/incubating/sonar-scanner-cli/icon.svg - background: "#f4f4f4" - examples: - - description: Get Quality Gates from a SonarCloud Project - workflow: - check_quality_gates: - type: sonar-quality-gates-checker - arguments: - SONAR_TOKEN: ${{MY_SONAR_TOKEN}} - SONAR_PROJECT_KEY: ${{MY_SONAR_PROJECT}} -spec: - arguments: |- - { - "definitions": {}, - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": false, - "patterns": [], - "required": [ - "SONAR_PROJECT_KEY" - ], - "properties": { - "SONAR_HOST_URL": { - "type": "string", - "default": "https://sonarcloud.io", - "description": "SonarCloud or SonarQube URL." - }, - "SONAR_TOKEN": { - "type": "string", - "description": "SonarCloud Token." - }, - "SONAR_PASSWORD": { - "type": "string", - "description": "SonarQube Passsword." - }, - "SONAR_USERNAME": { - "type": "string", - "description": "SonarQube Username." - }, - "SONAR_PROJECT_KEY": { - "type": "string", - "description": "SonarQube|Cloud Project." - }, - } - } - - returns: |- - { - "definitions": {}, - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": true, - "patterns": [], - "required": [ - "SONAR_QUALITYGATES_STATUS" - ] - , - "properties": { - "SONAR_QUALITYGATES_STATUS": { - "type": "string", - "description": "Quality Gates status of a Project" - }, - "SONAR_QUALITYGATES_STATUS_JSON_PATH": { - "type": "string", - "description": "Path to the JSON file response of the Quality Gates status of a Project" - } - } - } - stepsTemplate: |- - sonar: - name: sonar - image: codefreshplugins/sonar-quality-gates-checker:0.1.1 - environment: - [[ range $key, $val := .Arguments ]] - - '[[ $key ]]=[[ $val ]]' - [[- end ]] - commands: - - python3 /sonarqube-api.py - delimiters: - left: '[[' - right: ']]' diff --git a/incubating/sonar-quality-gates-checker/Dockerfile b/incubating/sonar-quality-gates-checker/Dockerfile index 93a74c357..7c176af76 100644 --- a/incubating/sonar-quality-gates-checker/Dockerfile +++ b/incubating/sonar-quality-gates-checker/Dockerfile @@ -1,5 +1,5 @@ -FROM python:3.9.1-alpine3.13 +FROM python:3.14-alpine3.24 -RUN pip install --no-cache-dir python-sonarqube-api +RUN pip install --no-cache-dir requests==2.34.2 certifi==2026.10.23 COPY lib/sonarqube-api.py /sonarqube-api.py diff --git a/incubating/sonar-quality-gates-checker/codefresh.yml b/incubating/sonar-quality-gates-checker/codefresh.yml index 7790c49c4..d32605b8b 100644 --- a/incubating/sonar-quality-gates-checker/codefresh.yml +++ b/incubating/sonar-quality-gates-checker/codefresh.yml @@ -1,7 +1,7 @@ version: '1.0' steps: Clone: - title: Cloning jira issue manager repository + title: Cloning steps repository type: "git-clone" arguments: repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' @@ -12,30 +12,30 @@ steps: title: Getting Plugin Version image: codefresh/cli commands: - - cf_export PLUGIN_VERSION=$(yq -r .metadata.version ./steps/incubating/sonarqube/step.yaml) + - cf_export PLUGIN_VERSION=$(yq -r .metadata.version ./steps/incubating/sonar-quality-gates-checker/step.yaml) BuildImage: title: Building Docker Image type: build - working_directory: "./steps/incubating/sonarqube" + working_directory: "./steps/incubating/sonar-quality-gates-checker" dockerfile: "Dockerfile" - image_name: codefreshplugins/sonarqube + image_name: codefreshplugins/sonar-quality-gates-checker -PushingToRegistries: - title: Pushing to Registry - type: push - candidate: ${{BuildImage}} - tags: - - "latest" - - "${{PLUGIN_VERSION}}" - when: - branch: - only: - - master - scale: - PushingToDockerHubRegistry: - title: Pushing To DockerHub Registry - registry: dockerhub - PushingToQuayRegistry: - title: Pushing To Quay Registry - registry: cfpluginmgr-quay \ No newline at end of file + PushingToRegistries: + title: Pushing to Registry + type: push + candidate: ${{BuildImage}} + tags: + - "latest" + - "${{PLUGIN_VERSION}}" + when: + branch: + only: + - master + scale: + PushingToDockerHubRegistry: + title: Pushing To DockerHub Registry + registry: dockerhub + PushingToQuayRegistry: + title: Pushing To Quay Registry + registry: cfpluginmgr-quay \ No newline at end of file diff --git a/incubating/sonar-quality-gates-checker/lib/sonarqube-api.py b/incubating/sonar-quality-gates-checker/lib/sonarqube-api.py index 3ae1a1ae8..3d35daeae 100644 --- a/incubating/sonar-quality-gates-checker/lib/sonarqube-api.py +++ b/incubating/sonar-quality-gates-checker/lib/sonarqube-api.py @@ -1,31 +1,30 @@ import os import sys -from sonarqube import SonarCloudClient -from sonarqube import SonarQubeClient import json +import requests -def exportResults(status): +def exportResults(status): print("\nExporting Results") - qualitygates_status_json = json.dumps(status) + qualitygates_status_json = json.dumps(status) qualitygates_status= status['projectStatus']['status'] env_file_path = "/meta/env_vars_to_export" if not os.path.exists(env_file_path): - print(f"Quality Gates status is \n'{qualitygates_status}'") - print(f"Quality Gates status JSON is \n'{qualitygates_status_json}'") + print(f"Quality Gates status is \n'{qualitygates_status}'") + print(f"Quality Gates status JSON is \n'{qualitygates_status_json}'") else: env_file = open(env_file_path, "a") - qualitygates_status_json_file_path = f"/codefresh/volume/sonarqualitygates-{os.getenv('CF_SHORT_REVISION')}.json" + qualitygates_status_json_file_path = f"/codefresh/volume/sonarqualitygates-{os.getenv('CF_SHORT_REVISION')}.json" env_file.write("SONAR_QUALITYGATES_STATUS=" + qualitygates_status + "\n") env_file.write("SONAR_QUALITYGATES_STATUS_JSON_PATH=" + qualitygates_status_json_file_path + "\n") env_file.close() - qualitygates_status_json_file = open(qualitygates_status_json_file_path, "w") - json.dump(status, qualitygates_status_json_file, indent = 4) - qualitygates_status_json_file.close() + qualitygates_status_json_file = open(qualitygates_status_json_file_path, "w") + json.dump(status, qualitygates_status_json_file, indent = 4) + qualitygates_status_json_file.close() def actBasedOnStatus(status): qualitygates_status = status['projectStatus']['status'] @@ -51,18 +50,31 @@ def main(): sonar_url = os.getenv('SONAR_HOST_URL', 'https://sonarcloud.io') if sonarcloud_token: - sonar = SonarCloudClient(sonarcloud_url=sonar_url, token=sonarcloud_token) + auth = (sonarcloud_token, "") + elif sonarqube_username and sonarqube_password: + auth = (sonarqube_username, sonarqube_password) else: - sonar = SonarQubeClient(sonarqube_url=sonar_url, username=sonarqube_username, password=sonarqube_password) + auth = None - # Code: https://github.com/shijl0925/python-sonarqube-api/blob/376cf1d6ef231ee084694c77dadf551733395d4f/sonarqube/community/qualitygates.py#L182 - # Docs: https://python-sonarqube-api.readthedocs.io/en/1.2.1/examples/qualitygates.html# - if pr is not None: + if pr is not None: print(f"PR Quality Gate for PR #{pr}") branch = None # since the QG check accepts only branch or PR - qualitygates_status = sonar.qualitygates.get_project_qualitygates_status(projectKey=sonar_project, branch=branch, pullRequest=pr) + + # Docs: https://next.sonarqube.com/sonarqube/web_api/api/qualitygates/project_status + # requests drops parameters whose value is None, so only one of branch/pullRequest is sent. + url = sonar_url.rstrip("/") + "/api/qualitygates/project_status" + params = {"projectKey": sonar_project, "branch": branch, "pullRequest": pr} + try: + response = requests.get(url, params=params, auth=auth, timeout=60) + except requests.exceptions.RequestException as exc: + print(f"Failed to call {url}: {exc}") + sys.exit(1) + if not response.ok: + print(f"Failed to get Quality Gates status: HTTP {response.status_code} from {url}\n{response.text}") + sys.exit(1) + qualitygates_status = response.json() exportResults(qualitygates_status) actBasedOnStatus(qualitygates_status) if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/incubating/sonar-quality-gates-checker/step.yaml b/incubating/sonar-quality-gates-checker/step.yaml index 8003e0b94..c8b20dbae 100644 --- a/incubating/sonar-quality-gates-checker/step.yaml +++ b/incubating/sonar-quality-gates-checker/step.yaml @@ -2,7 +2,7 @@ kind: step-type version: '1.0' metadata: name: sonar-quality-gates-checker - version: 0.1.3 + version: 0.1.4 isPublic: true description: Check Quality Gates from Sonarqube or Sonarcloud sources: @@ -84,11 +84,11 @@ spec: "description": "Path to the JSON file response of the Quality Gates status of a Project" } } - } + } stepsTemplate: |- sonar: name: sonar - image: quay.io/codefreshplugins/sonar-quality-gates-checker:0.1.2 + image: quay.io/codefreshplugins/sonar-quality-gates-checker:0.1.4 environment: [[ range $key, $val := .Arguments ]] - '[[ $key ]]=[[ $val ]]'