diff --git a/.github/workflows/sonar-scan.yml b/.github/workflows/sonar-scan.yml
index 8abd6e220a..b9bc6e2126 100644
--- a/.github/workflows/sonar-scan.yml
+++ b/.github/workflows/sonar-scan.yml
@@ -4,16 +4,15 @@ on:
types: [opened, synchronize, reopened]
env:
- HEAD_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
- SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ HEAD_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name }}
jobs:
push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Checkout ${{ env.HEAD_REF }} from repository ${{ env.HEAD_REPOSITORY }}
+ name: Checkout ${{ env.HEAD_REPOSITORY }}:${{ env.HEAD_REF }}
with:
ref: ${{ env.HEAD_REF }}
repository: ${{ env.HEAD_REPOSITORY }}
@@ -25,10 +24,10 @@ jobs:
- name: Set up the dev container
uses: ./.github/actions/setup-dev-container
- - name: Scan scanner prototype for openchallenges-app
- run: ./tools/sonar-scanner-for-pr.sh sage-monorepo apps/openchallenges/app ${{github.event.pull_request.number}} "${{env.HEAD_REPOSITORY}}:${{env.HEAD_REF}}"
-
- # - name: Scan the affected projects with Sonar
- # run: |
- # devcontainer exec --workspace-folder ../sage-monorepo bash -c ". ./dev-env.sh \
- # && nx affected --target=sonar"
\ No newline at end of file
+ - name: Scan the affected projects with Sonar
+ env:
+ SONAR_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ run: |
+ devcontainer exec --workspace-folder ../sage-monorepo bash -c ". ./dev-env.sh \
+ && nx affected --target=sonar"
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 1a41e85328..e618a91398 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@
!.yarn/sdks
!.yarn/versions
.nx-container/
+.nx/
.pnpm-store/
.scannerwork/
playwright-report/
diff --git a/apps/openchallenges/app/project.json b/apps/openchallenges/app/project.json
index 25ecfc2c8b..7d49265a12 100644
--- a/apps/openchallenges/app/project.json
+++ b/apps/openchallenges/app/project.json
@@ -15,18 +15,22 @@
"sonar": {
"executor": "nx:run-commands",
"options": {
- "command": "bash $WORKSPACE_DIR/tools/sonar-scanner.sh {projectName}",
+ "command": "bash $WORKSPACE_DIR/tools/sonar-scanner.sh --project-key {projectName} --project-dir .",
"cwd": "{projectRoot}"
}
},
"build": {
"executor": "@angular-devkit/build-angular:browser",
- "outputs": ["{options.outputPath}"],
+ "outputs": [
+ "{options.outputPath}"
+ ],
"options": {
"outputPath": "dist/apps/openchallenges/app/browser/browser",
"index": "apps/openchallenges/app/src/index.html",
"main": "apps/openchallenges/app/src/main.ts",
- "polyfills": ["zone.js"],
+ "polyfills": [
+ "zone.js"
+ ],
"tsConfig": "apps/openchallenges/app/tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
@@ -119,7 +123,10 @@
"lint": {
"executor": "@nx/linter:eslint",
"options": {
- "lintFilePatterns": ["apps/openchallenges/app/**/*.ts", "apps/openchallenges/app/**/*.html"]
+ "lintFilePatterns": [
+ "apps/openchallenges/app/**/*.ts",
+ "apps/openchallenges/app/**/*.html"
+ ]
}
},
"lint-fix": {
@@ -134,7 +141,9 @@
},
"test": {
"executor": "@nx/jest:jest",
- "outputs": ["{workspaceRoot}/coverage/apps/openchallenges/app"],
+ "outputs": [
+ "{workspaceRoot}/coverage/apps/openchallenges/app"
+ ],
"options": {
"jestConfig": "apps/openchallenges/app/jest.config.ts",
"passWithNoTests": true
@@ -145,24 +154,39 @@
"options": {
"context": ".",
"metadata": {
- "images": ["ghcr.io/sage-bionetworks/openchallenges-app"],
- "tags": ["type=edge,branch=main", "type=raw,value=local", "type=sha"]
+ "images": [
+ "ghcr.io/sage-bionetworks/openchallenges-app"
+ ],
+ "tags": [
+ "type=edge,branch=main",
+ "type=raw,value=local",
+ "type=sha"
+ ]
},
"push": false
},
- "dependsOn": ["server"]
+ "dependsOn": [
+ "server"
+ ]
},
"publish-image": {
"executor": "@nx-tools/nx-container:build",
"options": {
"context": ".",
"metadata": {
- "images": ["ghcr.io/sage-bionetworks/openchallenges-app"],
- "tags": ["type=edge,branch=main", "type=sha"]
+ "images": [
+ "ghcr.io/sage-bionetworks/openchallenges-app"
+ ],
+ "tags": [
+ "type=edge,branch=main",
+ "type=sha"
+ ]
},
"push": true
},
- "dependsOn": ["build-image"]
+ "dependsOn": [
+ "build-image"
+ ]
},
"scan-image": {
"executor": "nx:run-commands",
@@ -172,7 +196,9 @@
}
},
"server": {
- "dependsOn": ["build"],
+ "dependsOn": [
+ "build"
+ ],
"executor": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/apps/openchallenges/app/browser/server",
@@ -211,7 +237,9 @@
"prerender": {
"executor": "@nguniversal/builders:prerender",
"options": {
- "routes": ["/"]
+ "routes": [
+ "/"
+ ]
},
"configurations": {
"development": {
@@ -233,16 +261,22 @@
},
"e2e": {
"executor": "@nx/playwright:playwright",
- "outputs": ["{workspaceRoot}/dist/.playwright/apps/openchallenges/app"],
+ "outputs": [
+ "{workspaceRoot}/dist/.playwright/apps/openchallenges/app"
+ ],
"options": {
"config": "apps/openchallenges/app/playwright.config.ts"
}
}
},
- "tags": ["type:app", "scope:client", "language:typescript"],
+ "tags": [
+ "type:app",
+ "scope:client",
+ "language:typescript"
+ ],
"implicitDependencies": [
"openchallenges-styles",
"openchallenges-themes",
"shared-typescript-assets"
]
-}
+}
\ No newline at end of file
diff --git a/apps/openchallenges/app/src/app/app.component.html b/apps/openchallenges/app/src/app/app.component.html
index 390f087df0..968b56dcd4 100644
--- a/apps/openchallenges/app/src/app/app.component.html
+++ b/apps/openchallenges/app/src/app/app.component.html
@@ -1,4 +1,5 @@
+
must be specified."
- exit 1
-fi
-
-PROJECT_KEY="$1"
-SOURCES="$2"
-PULL_REQUEST_KEY="$3"
-PULL_REQUEST_BRANCH="$4"
-PULL_REQUEST_BASE="${5:-main}"
-
-echo "Project key: $PROJECT_KEY"
-echo "Sources: $SOURCES"
-
-sonar-scanner \
- -Dsonar.organization=sage-bionetworks \
- -Dsonar.projectKey=$PROJECT_KEY \
- -Dsonar.sources=$SOURCES \
- -Dsonar.host.url=https://sonarcloud.io \
- -Dsonar.python.coverage.reportPaths=coverage.xml \
- -Dsonar.pullrequest.key=$PULL_REQUEST_KEY \
- -Dsonar.pullrequest.branch=$PULL_REQUEST_BRANCH \
- -Dsonar.pullrequest.base=$PULL_REQUEST_BASE \
\ No newline at end of file
diff --git a/tools/sonar-scanner.sh b/tools/sonar-scanner.sh
index d4cd04a82a..ecf6445467 100755
--- a/tools/sonar-scanner.sh
+++ b/tools/sonar-scanner.sh
@@ -1,20 +1,115 @@
#!/usr/bin/env bash
-if [ $# -lt 1 ]
-then
- echo "The argument must be specified."
- exit 1
-fi
+# This script scan a project of the monorepo with Sonar.
+#
+# Prefer using scanners for specific languages provided by Sonar instead of this script when
+# available. E.g. SonarScanner for Gradle.
+#
+# Requires the environment variable SONAR_TOKEN to be set.
+#
+# Run locally, e.g. nx sonar openchallenges-app
+
+# Default variable values
+## The Sonar host receiving scan results
+sonar_host="https://sonarcloud.io"
+## The organization on SonarCloud that owns the project
+organization="sage-bionetworks"
+## The key of the project on SonarCloud (must match the name of the project in the monorepo)
+project_key=""
+## The path to the project folder
+project_dir=""
+## The pull request number (if the scan is triggered by a PR event)
+pull_request_number="$SONAR_PULL_REQUEST_NUMBER"
+
+# Function to display script usage
+usage() {
+ echo "Usage: $0 [OPTIONS]"
+ echo "Options:"
+ echo " -h, --help Display this help message"
+ echo " --project-key [key] The key of the project on SonarCloud"
+ echo " --project-dir [path] The path to the project folder"
+ echo " --pull-request-number [number] The pull request number (if the scan is triggered by a PR event)"
+}
+
+has_argument() {
+ [[ ("$1" == *=* && -n ${1#*=}) || ( ! -z "$2" && "$2" != -*) ]];
+}
+
+# Note: Does not support --key=value, only --key value
+extract_argument() {
+ echo "${2:-${1#*=}}"
+}
+
+# Function to handle options and arguments
+handle_options() {
+ while [ $# -gt 0 ]; do
+ case $1 in
+ -h | --help)
+ usage
+ exit 0
+ ;;
+ --project-key*)
+ if ! has_argument $@; then
+ echo "Project key not specified." >&2
+ usage
+ exit 1
+ fi
+
+ project_key=$(extract_argument $@)
+
+ shift
+ ;;
+ --project-dir*)
+ if ! has_argument $@; then
+ echo "Project dir not specified." >&2
+ usage
+ exit 1
+ fi
-PROJECT_KEY="$1"
-SOURCES="${2:-$PWD}"
+ project_dir=$(extract_argument $@)
-echo "Project key: $PROJECT_KEY"
-echo "Sources: $SOURCES"
+ shift
+ ;;
+ --pull-request-number*)
+ if ! has_argument $@; then
+ echo "Pull request number not specified." >&2
+ usage
+ exit 1
+ fi
+
+ pull_request_number=$(extract_argument $@)
+
+ shift
+ ;;
+ *)
+ echo "Invalid option: $1" >&2
+ usage
+ exit 1
+ ;;
+ esac
+ shift
+ done
+}
+
+# Main script execution
+handle_options "$@"
+
+# Build the scanner options
+args=(
+ -Dsonar.host.url=$sonar_host
+ -Dsonar.organization=$organization
+ -Dsonar.projectKey=$project_key
+ -Dsonar.sources=$project_dir
+ -Dsonar.python.coverage.reportPaths=${project_dir}/coverage.xml
+)
+
+pull_request_number=2458
+
+# Include the PR key if specified
+if [[ ! -z ${pull_request_number+z} ]];
+then
+ args+=("-Dsonar.pullrequest.key=${pull_request_number}")
+fi
-sonar-scanner \
- -Dsonar.organization=sage-bionetworks \
- -Dsonar.projectKey=$PROJECT_KEY \
- -Dsonar.sources=$SOURCES \
- -Dsonar.host.url=https://sonarcloud.io \
- -Dsonar.python.coverage.reportPaths=coverage.xml
\ No newline at end of file
+# Run the Sonar scanner
+sonar-scanner "${args[@]}"