diff --git a/.azure-pipelines/xvfb.init b/.azure-pipelines/xvfb.init deleted file mode 100644 index c06f32ada9..0000000000 --- a/.azure-pipelines/xvfb.init +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -# -# /etc/rc.d/init.d/xvfbd -# -# chkconfig: 345 95 28 -# description: Starts/Stops X Virtual Framebuffer server -# processname: Xvfb -# -### BEGIN INIT INFO -# Provides: xvfb -# Required-Start: $remote_fs $syslog -# Required-Stop: $remote_fs $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Start xvfb at boot time -# Description: Enable xvfb provided by daemon. -### END INIT INFO - -# Copied from https://github.com/microsoft/vscode/blob/0a9f99aa4b37141d3bf563095c6fff5dad4a3290/build/azure-pipelines/linux/xvfb.init - -[ "${NETWORKING}" = "no" ] && exit 0 - -PROG="/usr/bin/Xvfb" -PROG_OPTIONS=":10 -ac -screen 0 1280x960x24" -PROG_OUTPUT="/tmp/Xvfb.out" - -case "$1" in - start) - echo "Starting : X Virtual Frame Buffer " - $PROG $PROG_OPTIONS>>$PROG_OUTPUT 2>&1 & - disown -ar - ;; - stop) - echo "Shutting down : X Virtual Frame Buffer" - killproc $PROG - RETVAL=$? - [ $RETVAL -eq 0 ] && /bin/rm -f /var/lock/subsys/Xvfb - /var/run/Xvfb.pid - echo - ;; - restart|reload) - $0 stop - $0 start - RETVAL=$? - ;; - status) - status Xvfb - RETVAL=$? - ;; - *) - echo $"Usage: $0 (start|stop|restart|reload|status)" - exit 1 -esac - -exit $RETVAL diff --git a/.cirrus.star b/.cirrus.star new file mode 100644 index 0000000000..2024a148ea --- /dev/null +++ b/.cirrus.star @@ -0,0 +1,4 @@ +load("github.com/SonarSource/cirrus-modules@v2", "load_features") + +def main(ctx): + return load_features(ctx) diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 0000000000..b8edcf87bd --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,289 @@ +env: + CIRRUS_CLONE_DEPTH: "1" + CIRRUS_SHELL: bash + + ARTIFACTORY_URL: VAULT[development/kv/data/repox data.url] + ARTIFACTORY_PRIVATE_USERNAME: vault-${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-private-reader + ARTIFACTORY_PRIVATE_PASSWORD: VAULT[development/artifactory/token/${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-private-reader access_token] + BURGR_URL: VAULT[development/kv/data/burgr data.url] + BURGR_USERNAME: VAULT[development/kv/data/burgr data.cirrus_username] + BURGR_PASSWORD: VAULT[development/kv/data/burgr data.cirrus_password] + SONAR_HOST_URL: VAULT[development/kv/data/next data.url] + SONAR_TOKEN: VAULT[development/kv/data/next data.token] + GRADLE_VERSION: "7.6" + +auto_cancellation: $CIRRUS_BRANCH != $CIRRUS_DEFAULT_BRANCH + +only_if_with_nightly: &ONLY_IF + skip: "changesIncludeOnly('*.txt', '**/README.md')" + only_if: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_TAG == "" + +only_pr_and_maintained_branches: &ONLY_PR_AND_MAINTAINED_BRANCHES + skip: "changesIncludeOnly('*.txt', '**/README.md')" + only_if: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_TAG == "" && $CIRRUS_BUILD_SOURCE != "cron" + && ($CIRRUS_PR != "" || $CIRRUS_BRANCH == $CIRRUS_DEFAULT_BRANCH || $CIRRUS_BRANCH =~ "branch-.*" || $CIRRUS_BRANCH =~ "dogfood-on-.*") + +only_main_branches: &ONLY_MAIN_BRANCHES + skip: "changesIncludeOnly('*.txt', '**/README.md')" + only_if: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_TAG == "" && ($CIRRUS_BRANCH == $CIRRUS_DEFAULT_BRANCH || $CIRRUS_BRANCH =~ "branch-.*") + +eks_container: &CONTAINER_DEFINITION + image: ${CIRRUS_AWS_ACCOUNT}.dkr.ecr.eu-central-1.amazonaws.com/base:j11-g7-latest + region: eu-central-1 + cluster_name: ${CIRRUS_CLUSTER_NAME} + namespace: default + cpu: 4 + memory: 8G + +eks_builder_container: &BUILDER_CONTAINER_DEFINITION + <<: *CONTAINER_DEFINITION + dockerfile: .cirrus/Dockerfile + docker_arguments: + CIRRUS_AWS_ACCOUNT: ${CIRRUS_AWS_ACCOUNT} + JDK_VERSION: ${JDK_VERSION} + builder_role: cirrus-builder + builder_image: docker-builder-v* + builder_instance_type: t2.small + builder_subnet_id: ${CIRRUS_AWS_SUBNET} + +ec2_instance: &WINVM_DEFINITION + experimental: true + image: base-windows-jdk17-v* + platform: windows + region: eu-central-1 + subnet_id: ${CIRRUS_AWS_SUBNET} + type: t3.xlarge + +setup_gradle_cache_template: &SETUP_GRADLE_CACHE + gradle_cache: + folder: ~/.gradle/caches + fingerprint_script: + - echo $CIRRUS_OS + - cat **/*.gradle* **/gradle-wrapper.properties || true + populate_script: + - mkdir -p ~/.gradle/caches + +cleanup_gradle_cache_script_template: &CLEANUP_GRADLE_CACHE_SCRIPT + cleanup_gradle_script: | + rm -rf ~/.gradle/caches/$GRADLE_VERSION/ + rm -rf ~/.gradle/daemon/ + rm -rf ~/.gradle/caches/transforms-* + rm -rf ~/.gradle/caches/journal-* + /usr/bin/find ~/.gradle/caches/ -name "*.lock" -type f -delete + +build_task: + # name: "Build and stage to repox" + <<: *ONLY_IF + eks_container: + <<: *CONTAINER_DEFINITION + env: + ARTIFACTORY_DEPLOY_REPO: sonarsource-public-qa + ARTIFACTORY_DEPLOY_USERNAME: vault-${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-qa-deployer + ARTIFACTORY_DEPLOY_PASSWORD: VAULT[development/artifactory/token/${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-qa-deployer access_token] + ORG_GRADLE_PROJECT_signingKey: VAULT[development/kv/data/sign data.key] + ORG_GRADLE_PROJECT_signingPassword: VAULT[development/kv/data/sign data.passphrase] + ORG_GRADLE_PROJECT_signingKeyId: VAULT[development/kv/data/sign data.key_id] + <<: *SETUP_GRADLE_CACHE + build_script: | + source cirrus-env BUILD-PRIVATE + source .cirrus/use-gradle-wrapper.sh + source .cirrus/set_gradle_build_version + regular_gradle_build_deploy_analyze -x build -x sonarqube :buildPlugin :cyclonedxBom + <<: *CLEANUP_GRADLE_CACHE_SCRIPT + +validate_task: + # name: "Run UTs and trigger SonarQube analysis" + depends_on: + - build + <<: *ONLY_IF + env: + JDK_VERSION: "11" + eks_container: + <<: *BUILDER_CONTAINER_DEFINITION + <<: *SETUP_GRADLE_CACHE + build_script: | + source cirrus-env QA + source .cirrus/use-gradle-wrapper.sh + source .cirrus/set_gradle_build_version + PULL_REQUEST_SHA=$GIT_SHA1 regular_gradle_build_deploy_analyze check -x :its:check -x artifactoryPublish :runPluginVerifier sonarqube jacocoTestReport + <<: *CLEANUP_GRADLE_CACHE_SCRIPT + on_failure: + reports_artifacts: + path: "**/reports/**/*" + junit_artifacts: + path: "**/test-results/**/*.xml" + format: junit + +validate_windows_task: + # name: "Run unit tests on Windows" + depends_on: + - build + <<: *ONLY_IF + ec2_instance: + <<: *WINVM_DEFINITION + <<: *SETUP_GRADLE_CACHE + build_script: | + source cirrus-env QA + source .cirrus/use-gradle-wrapper.sh + source .cirrus/set_gradle_build_version + PULL_REQUEST_SHA=$GIT_SHA1 regular_gradle_build_deploy_analyze check -x :its:check -x artifactoryPublish -x sonarqube :runPluginVerifier jacocoTestReport + <<: *CLEANUP_GRADLE_CACHE_SCRIPT + on_failure: + reports_artifacts: + path: "**/reports/**/*" + junit_artifacts: + path: "**/test-results/**/*.xml" + format: junit + +qa_task: + # name: "Run ITs" + depends_on: + - build + <<: *ONLY_IF + eks_container: + <<: *BUILDER_CONTAINER_DEFINITION + cpu: 4 + memory: 12G + env: + CLION_KEY: VAULT[development/team/sonarlint/kv/data/clion.key data.key] + GOLAND_KEY: VAULT[development/team/sonarlint/kv/data/goland.key data.key] + ARTIFACTORY_ACCESS_TOKEN: VAULT[development/artifactory/token/${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-private-reader access_token] + GITHUB_TOKEN: VAULT[development/github/token/licenses-ro token] + DISPLAY: :10 + JDK_VERSION: "17" + clionKey_file: + path: ${CIRRUS_WORKING_DIR}/its/build/idea-sandbox/config-uiTest/clion.key.b64 + variable_name: CLION_KEY + golandKey_file: + path: ${CIRRUS_WORKING_DIR}/its/build/idea-sandbox/config-uiTest/goland.key.b64 + variable_name: GOLAND_KEY + matrix: + - env: + IDEA_VERSION: 'IC-2021.3.3' + QA_CATEGORY: 'Idea2021' + - env: + IDEA_VERSION: 'CL-2021.3.3' + QA_CATEGORY: 'CLion2021' + - env: + IDEA_VERSION: 'GO-2021.3.3' + QA_CATEGORY: 'GoLand2021' + - env: + IDEA_VERSION: 'IC-2022.3.2' + QA_CATEGORY: 'Idea2022' + - env: + IDEA_VERSION: 'CL-2022.3.2' + QA_CATEGORY: 'CLion2022' + - env: + IDEA_VERSION: 'GO-2022.3.2' + QA_CATEGORY: 'GoLand2022' + <<: *SETUP_GRADLE_CACHE + xvfb_background_script: | + /etc/init.d/xvfb start + prepare_background_script: | + set -euo pipefail + echo "Prepare env and start IDE ${IDEA_VERSION}" + source cirrus-env QA + source .cirrus/use-gradle-wrapper.sh + source .cirrus/set_gradle_build_version + mvn org.apache.maven.plugins:maven-dependency-plugin:3.1.1:unpack -B -Dartifact=org.sonarsource.sonarlint.intellij:sonarlint-intellij:${PROJECT_VERSION}:zip "-DoutputDirectory=${CIRRUS_WORKING_DIR}/staged-plugin" + mkdir -p its/build/idea-sandbox/config-uiTest/ + base64 --decode its/build/idea-sandbox/config-uiTest/clion.key.b64 > its/build/idea-sandbox/config-uiTest/clion.key + base64 --decode its/build/idea-sandbox/config-uiTest/goland.key.b64 > its/build/idea-sandbox/config-uiTest/goland.key + metacity --sm-disable --replace & + sleep 10 # give metacity some time to start + gradle :its:runIdeForUiTests --stacktrace -i -PijVersion=${IDEA_VERSION} -PslPluginDirectory=${CIRRUS_WORKING_DIR}/staged-plugin > ${CIRRUS_WORKING_DIR}/runIdeGradle.log & + wait_ide_script: | + echo "Wait for IDE to start" + .cirrus/wait-for-endpoint.sh http://127.0.0.1:8082 -t 500 + recording_background_script: | + echo 'Recording tests on video' + ffmpeg -loglevel warning -f x11grab -video_size 1280x960 -i ${DISPLAY} -codec:v libx264 -r 12 ${CIRRUS_WORKING_DIR}/recording_${IDEA_VERSION}.mp4 + run_its_script: | + echo "Run ITs on ${IDEA_VERSION}" + source .cirrus/use-gradle-wrapper.sh + gradle :its:check --stacktrace -i -PijVersion=${IDEA_VERSION} -PslPluginDirectory=${CIRRUS_WORKING_DIR}/staged-plugin + stop_recording_script: | + pkill -SIGINT -f ffmpeg + while pgrep ffmpeg >/dev/null; do sleep 1; done + /etc/init.d/xvfb stop + display_log_script: + - cat ${CIRRUS_WORKING_DIR}/runIdeGradle.log + <<: *CLEANUP_GRADLE_CACHE_SCRIPT + always: + test_recording_artifacts: + path: "${CIRRUS_WORKING_DIR}/recording_${IDEA_VERSION}.mp4" + log_artifacts: + path: "its/build/idea-sandbox/system/log" + on_failure: + xvfb_log_artifacts: + path: "${CIRRUS_WORKING_DIR}/Xvfb.out" + reports_artifacts: + path: "**/reports/**/*" + junit_artifacts: + path: "**/test-results/**/*.xml" + format: junit + +mend_scan_task: + depends_on: + - build + <<: *ONLY_MAIN_BRANCHES + eks_container: + <<: *CONTAINER_DEFINITION + cpu: 4 + memory: 2G + env: + WS_APIKEY: VAULT[development/kv/data/mend data.apikey] + <<: *SETUP_GRADLE_CACHE + mend_script: | + source cirrus-env QA + source .cirrus/use-gradle-wrapper.sh + source .cirrus/set_gradle_build_version + source ws_scan.sh + <<: *CLEANUP_GRADLE_CACHE_SCRIPT + allow_failures: "true" + always: + ws_scan_artifacts: + path: "whitesource/**/*" + +promote_task: + depends_on: + - build + - validate + - validate_windows + - qa + - mend_scan + <<: *ONLY_PR_AND_MAINTAINED_BRANCHES + eks_container: + <<: *CONTAINER_DEFINITION + cpu: 3 + memory: 2G + env: + GCF_ACCESS_TOKEN: VAULT[development/kv/data/promote data.token] + PROMOTE_URL: VAULT[development/kv/data/promote data.url] + GITHUB_TOKEN: VAULT[development/github/token/${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-promotion token] + # artifacts which will have downloadable links in burgr + ARTIFACTS: org.sonarsource.sonarlint.intellij:sonarlint-intellij:zip + <<: *SETUP_GRADLE_CACHE + promote_script: | + source .cirrus/use-gradle-wrapper.sh + .cirrus/cirrus_promote_gradle + <<: *CLEANUP_GRADLE_CACHE_SCRIPT + +dogfood_task: + # name: "Update internal dogfooding plugin repo" + # alias: "update_dogfood_repo" + depends_on: + - promote + only_if: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_TAG == "" && $CIRRUS_BRANCH == $CIRRUS_DEFAULT_BRANCH + eks_container: + <<: *BUILDER_CONTAINER_DEFINITION + cpu: 2 + memory: 1G + env: + ARTIFACTORY_API_KEY: VAULT[development/artifactory/token/${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-promoter access_token] + JDK_VERSION: "17" + dogfood_script: | + source cirrus-env QA + envsubst '$ARTIFACTORY_URL,$PROJECT_VERSION' <.cirrus/updatePlugins-template.xml >updatePlugins.xml + jfrog rt u updatePlugins.xml sonarsource-public-builds/org/sonarsource/sonarlint/intellij/sonarlint-intellij/ \ + --url "${ARTIFACTORY_URL}" --access-token "${ARTIFACTORY_API_KEY}" --build-name "$CIRRUS_REPO_NAME" --build-number "$BUILD_NUMBER" diff --git a/.cirrus/Dockerfile b/.cirrus/Dockerfile new file mode 100644 index 0000000000..9bdf3dcc35 --- /dev/null +++ b/.cirrus/Dockerfile @@ -0,0 +1,15 @@ +ARG CIRRUS_AWS_ACCOUNT=275878209202 +ARG JDK_VERSION=17 +FROM ${CIRRUS_AWS_ACCOUNT}.dkr.ecr.eu-central-1.amazonaws.com/base:j${JDK_VERSION}-g7-latest + +USER root + +ENV NODE_VERSION=18 +RUN apt-get update && apt-get install -y metacity xvfb xauth ffmpeg \ + nodejs=${NODE_VERSION}.* \ + build-essential \ + gettext-base + +COPY --chmod=755 .cirrus/xvfb /etc/init.d/ + +USER sonarsource diff --git a/.cirrus/cirrus_promote_gradle b/.cirrus/cirrus_promote_gradle new file mode 100755 index 0000000000..f11cf620cd --- /dev/null +++ b/.cirrus/cirrus_promote_gradle @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +source cirrus-env PROMOTE +source .cirrus/set_gradle_build_version +curl -sfSL -H "Authorization: Bearer $GCF_ACCESS_TOKEN" "$PROMOTE_URL/$GITHUB_REPO/$GITHUB_BRANCH/$BUILD_NUMBER/$PULL_REQUEST" +github-notify-promotion +burgr-notify-promotion diff --git a/.cirrus/set_gradle_build_version b/.cirrus/set_gradle_build_version new file mode 100755 index 0000000000..f647890c85 --- /dev/null +++ b/.cirrus/set_gradle_build_version @@ -0,0 +1,19 @@ +#!/bin/bash + +# Transform Gradle project version to semver-like version without SNAPSHOT and with build number. +# If BUILD_NUMBER is unset, then it must be passed as an argument. + +set -euo pipefail + +BUILD_NUMBER=${BUILD_NUMBER:=$1} + +current_version=$(gradle properties | grep 'version:' | tr --delete "[:space:]" | cut --delimiter=":" --fields=2) +release_version="${current_version/-SNAPSHOT/}" +if [[ "${release_version}" =~ ^[0-9]+\.[0-9]+$ ]]; then + release_version="${release_version}.0" +fi +release_version="${release_version}.${BUILD_NUMBER}" + +echo "Replacing version $current_version with $release_version" +sed -i.bak "s/$current_version/$release_version/g" gradle.properties +export PROJECT_VERSION=$release_version diff --git a/.cirrus/updatePlugins-template.xml b/.cirrus/updatePlugins-template.xml new file mode 100644 index 0000000000..46a1c59d35 --- /dev/null +++ b/.cirrus/updatePlugins-template.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.cirrus/use-gradle-wrapper.sh b/.cirrus/use-gradle-wrapper.sh new file mode 100755 index 0000000000..bcadc2367a --- /dev/null +++ b/.cirrus/use-gradle-wrapper.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +function gradle { + ./gradlew "$@" +} + +export -f gradle diff --git a/.azure-pipelines/wait-for-endpoint.sh b/.cirrus/wait-for-endpoint.sh similarity index 100% rename from .azure-pipelines/wait-for-endpoint.sh rename to .cirrus/wait-for-endpoint.sh diff --git a/.cirrus/xvfb b/.cirrus/xvfb new file mode 100755 index 0000000000..f0873c03da --- /dev/null +++ b/.cirrus/xvfb @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +set -euo pipefail + +XVFB=/usr/bin/Xvfb +XVFB_ARGS="$DISPLAY -listen tcp -ac -screen 0 1280x960x24" +PID_FILE=~/xvfb_${DISPLAY:1}.pid +LOG_FILE=${CIRRUS_WORKING_DIR}/Xvfb.out +case "$1" in + start) + echo -n "Starting virtual X frame buffer: Xvfb" + # shellcheck disable=SC2086 + /sbin/start-stop-daemon --start --quiet --pidfile "$PID_FILE" --make-pidfile --background --exec "$XVFB" --no-close -- $XVFB_ARGS \ + > "$LOG_FILE" 2>&1 + echo "." + ;; + stop) + echo -n "Stopping virtual X frame buffer: Xvfb" + /sbin/start-stop-daemon --stop --quiet --pidfile "$PID_FILE" + echo "." + ;; + restart) + $0 stop + $0 start + ;; + *) + echo "Usage: /etc/init.d/xvfb {start|stop|restart}" + exit 1 +esac +exit 0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a09d447502..7fc079ce0e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,33 +1,17 @@ name: sonar-release -# This workflow is triggered when publishing a new github release +# This workflow is triggered when publishing a new GitHub release on: release: types: - published -env: - PYTHONUNBUFFERED: 1 - jobs: - sonar_release: - runs-on: ubuntu-latest - name: Start release process - steps: - - name: SL release - id: sl_release - with: - publish_to_binaries: false - slack_channel: team-sonarlint-intelliclipse-notifs - env: - ARTIFACTORY_API_KEY: ${{ secrets.ARTIFACTORY_API_KEY }} - BURGRX_USER: ${{ secrets.BURGRX_USER }} - BURGRX_PASSWORD: ${{ secrets.BURGRX_PASSWORD }} - GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }} - SLACK_API_TOKEN: ${{secrets.SLACK_API_TOKEN }} - uses: SonarSource/gh-action_release/main@v4 - - - name: Check outputs - if: always() - run: | - echo "${{ steps.sl_release.outputs.releasability }}" - echo "${{ steps.sl_release.outputs.release }}" + release: + permissions: + id-token: write + contents: write + uses: SonarSource/gh-action_release/.github/workflows/main.yaml@v5 + with: + publishToBinaries: false + mavenCentralSync: true + slackChannel: team-sonarlint-intelliclipse-notifs diff --git a/README.md b/README.md index 82dd38c85f..eeaf5edcc8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ SonarLint IntelliJ Plugin ========================= -[![Build Status](https://dev.azure.com/sonarsource/DotNetTeam%20Project/_apis/build/status/sonarlint/SonarLint%20IntelliJ?branchName=master)](https://dev.azure.com/sonarsource/DotNetTeam%20Project/_build/latest?definitionId=76&branchName=master) [![Quality Gate](https://next.sonarqube.com/sonarqube/api/project_badges/measure?project=org.sonarsource.sonarlint.intellij%3Asonarlint-intellij&metric=alert_status -)](https://next.sonarqube.com/sonarqube/dashboard?id=org.sonarsource.sonarlint.intellij%3Asonarlint-intellij) +[![Build Status](https://api.cirrus-ci.com/github/SonarSource/sonarlint-intellij.svg?branch=master)](https://cirrus-ci.com/github/SonarSource/sonarlint-intellij) +[![Quality Gate](https://next.sonarqube.com/sonarqube/api/project_badges/measure?project=org.sonarsource.sonarlint.intellij%3Asonarlint-intellij&metric=alert_status)](https://next.sonarqube.com/sonarqube/dashboard?id=org.sonarsource.sonarlint.intellij%3Asonarlint-intellij) SonarLint is an IDE extension that helps you detect and fix quality issues as you write code. Like a spell checker, SonarLint squiggles flaws so they can be fixed before committing code. @@ -110,7 +110,7 @@ As the `clean` task may be inconvenient, an easier workaround is to delete the j How to release -------------- -See [release pipeline at Azure DevOps](https://dev.azure.com/sonarsource/DotNetTeam%20Project/_release?definitionId=10). +See [release pipeline at GitHub](https://github.com/SonarSource/sonarlint-intellij/actions/workflows/release.yml). License ------- diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index 090e6f026f..0000000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,321 +0,0 @@ -trigger: -- master - -pool: - vmImage: 'ubuntu-latest' - -variables: - - group: sonarsource-build-variables - -resources: - repositories: - - repository: commonTemplates - type: git - name: pipelines-yaml-templates - ref: refs/tags/v2.0.0 - - -stages: -- template: stage-with-burgr-notifications.yml@commonTemplates - parameters: - burgrName: 'build' - burgrType: 'build' - stageName: 'build' - stageDisplayName: Build and stage to repox - jobs: - - job: build - displayName: Build and stage to repox - variables: - GRADLE_USER_HOME: $(Pipeline.Workspace)/.gradle - fixedBranch: $[replace(variables['Build.SourceBranch'], 'refs/heads/', '')] - steps: - - checkout: self - fetchDepth: 1 - - template: update-gradle-version-steps.yml - - task: DownloadSecureFile@1 - displayName: 'Download the sign key' - name: pgpSignKey - inputs: - secureFile: 'sign-key.asc' - - bash: gpg --dearmor < $(pgpSignKey.secureFilePath) > sign-key.pgp - - task: Gradle@2 - inputs: - options: --stacktrace -i -Psigning.secretKeyRingFile=sign-key.pgp -Psigning.password=$(PGP_PASSPHRASE) -Psigning.keyId=$(PGP_KEYID) - tasks: :buildPlugin :cyclonedxBom :artifactoryPublish - publishJUnitResults: false - jdkVersionOption: '1.11' - env: - CI: true # needed for gradle-intellij-plugin to skip downloading sources - ARTIFACTORY_PRIVATE_READER_USERNAME: $(ARTIFACTORY_PRIVATE_READER_USERNAME) - ARTIFACTORY_PRIVATE_READER_PASSWORD: $(ARTIFACTORY_PRIVATE_READER_PASSWORD) - ARTIFACTORY_DEPLOY_USERNAME: $(ARTIFACTORY_DEPLOY_USERNAME) - ARTIFACTORY_DEPLOY_PASSWORD: $(ARTIFACTORY_DEPLOY_PASSWORD) - GIT_SHA1: $(Build.SourceVersion) - GITHUB_BRANCH: $(fixedBranch) - displayName: 'Run Gradle build and deploy' - - task: Gradle@2 - inputs: - options: --stop - tasks: c - publishJUnitResults: false - jdkVersionOption: '1.11' - displayName: 'Stop Gradle daemon' -- template: stage-with-burgr-notifications.yml@commonTemplates - parameters: - burgrName: 'validate' - burgrType: 'validate' - stageName: 'validate' - stageDisplayName: Run UTs and trigger SonarQube and Mend analysis - jobs: - - job: test_windows - displayName: Run unit tests on Windows - # FIXME tests on Windows are disabled because there is not enough disk space on Azure hosted agents - # pool: - # vmImage: 'windows-latest' - variables: - GRADLE_USER_HOME: $(Pipeline.Workspace)/.gradle - steps: - - checkout: self - fetchDepth: 1 - - task: Gradle@2 - inputs: - options: --stacktrace -i - tasks: check -x :its:check - publishJUnitResults: true - testRunTitle: 'UTs on Windows' - jdkVersionOption: '1.11' - env: - CI: true # needed for gradle-intellij-plugin to skip downloading sources - ARTIFACTORY_PRIVATE_READER_USERNAME: $(ARTIFACTORY_PRIVATE_READER_USERNAME) - ARTIFACTORY_PRIVATE_READER_PASSWORD: $(ARTIFACTORY_PRIVATE_READER_PASSWORD) - displayName: 'Run UTs' - - task: Gradle@2 - inputs: - options: --stacktrace -i - tasks: :runPluginVerifier - jdkVersionOption: '1.11' - env: - CI: true # needed for gradle-intellij-plugin to skip downloading sources - ARTIFACTORY_PRIVATE_READER_USERNAME: $(ARTIFACTORY_PRIVATE_READER_USERNAME) - ARTIFACTORY_PRIVATE_READER_PASSWORD: $(ARTIFACTORY_PRIVATE_READER_PASSWORD) - displayName: 'Run plugin verifier' - - task: Gradle@2 - inputs: - options: --stop - tasks: c - publishJUnitResults: false - jdkVersionOption: '1.11' - displayName: 'Stop Gradle daemon' - - job: sonarqubeAndMend - displayName: SonarQube analysis on Next and Mend analysis - variables: - GRADLE_USER_HOME: $(Pipeline.Workspace)/.gradle - steps: - - template: prepare-sq-analysis-steps.yml - - task: Gradle@2 - inputs: - options: --stacktrace -i - tasks: jacocoTestReport -x :its:check - publishJUnitResults: false - jdkVersionOption: '1.11' - sonarQubeRunAnalysis: true - sqGradlePluginVersionChoice: 'build' - env: - ARTIFACTORY_PRIVATE_READER_USERNAME: $(ARTIFACTORY_PRIVATE_READER_USERNAME) - ARTIFACTORY_PRIVATE_READER_PASSWORD: $(ARTIFACTORY_PRIVATE_READER_PASSWORD) - - task: Gradle@2 - inputs: - options: --stop - tasks: c - publishJUnitResults: false - jdkVersionOption: '1.11' - displayName: 'Stop Gradle daemon' - - - bash: | - set -euo pipefail - VERSION=$(cat gradle.properties | grep version | awk -F= '{print $2}') - echo "Current project version is $VERSION" - - # Remove -SNAPSHOT suffix - VERSION=`echo $VERSION | sed "s/-.*//g"` - - echo "Mend project version is $VERSION" - echo "##vso[task.setvariable variable=MEND_PROJECT_VERSION]$VERSION" - name: getMendProjectVersion - displayName: Get Mend project version - - - template: mend.yml@commonTemplates - parameters: - productName : 'SonarLint/IntelliJ' - releaseVersion: '$(MEND_PROJECT_VERSION)' - -- template: stage-with-burgr-notifications.yml@commonTemplates - parameters: - burgrName: 'qa' - burgrType: 'qa' - stageName: 'qa' - stageDisplayName: Run ITs - stageDependencies: build - jobs: - - job: its - displayName: Run ITs - strategy: - matrix: - Idea2021: - IDEA_VERSION: 'IC-2021.3.3' - CLion2021: - IDEA_VERSION: 'CL-2021.3.3' - GoLand2021: - IDEA_VERSION: 'GO-2021.3.3' - Idea2022: - IDEA_VERSION: 'IC-2022.3.2' - CLion2022: - IDEA_VERSION: 'CL-2022.3.2' - GoLand2022: - IDEA_VERSION: 'GO-2022.3.2' - steps: - - checkout: self - fetchDepth: 1 - - task: JavaToolInstaller@0 - inputs: - versionSpec: '17' - jdkArchitectureOption: 'x64' - jdkSourceOption: 'PreInstalled' - - template: update-gradle-version-steps.yml - - task: DownloadSecureFile@1 - displayName: 'Download Maven settings' - name: mavenSettings - inputs: - secureFile: 'maven-settings.xml' - - bash: | - mvn org.apache.maven.plugins:maven-dependency-plugin:3.1.1:unpack -B --settings "$(mavenSettings.secureFilePath)" -Denable-repo=qa -Dartifact=org.sonarsource.sonarlint.intellij:sonarlint-intellij:$(PROJECT_VERSION):zip "-DoutputDirectory=$(Agent.BuildDirectory)/staged-plugin" - displayName: 'Download staged plugin' - env: - ARTIFACTORY_QA_READER_USERNAME: $(ARTIFACTORY_QA_READER_USERNAME) - ARTIFACTORY_QA_READER_PASSWORD: $(ARTIFACTORY_QA_READER_PASSWORD) - - task: DownloadSecureFile@1 - name: clionKey - displayName: 'Download CLion key' - inputs: - secureFile: 'clion.key' - - task: DownloadSecureFile@1 - name: golandKey - displayName: 'Download GoLand key' - inputs: - secureFile: 'goland.key' - - bash: | - set -e -o pipefail -u - sudo apt-get update - sudo apt-get install -y metacity xvfb xauth ffmpeg - - # init xvfb and metacity - sudo cp .azure-pipelines/xvfb.init /etc/init.d/xvfb - sudo chmod +x /etc/init.d/xvfb - sudo update-rc.d xvfb defaults - sudo service xvfb start - sleep 10 # give xvfb some time to start - export DISPLAY=:10 - metacity --sm-disable --replace & - sleep 10 # give metacity some time to start - - mkdir -p its/build/idea-sandbox/config-uiTest/ - cp $(clionKey.secureFilePath) its/build/idea-sandbox/config-uiTest/clion.key - cp $(golandKey.secureFilePath) its/build/idea-sandbox/config-uiTest/goland.key - - ./gradlew :its:runIdeForUiTests --stacktrace -i -PijVersion=$(IDEA_VERSION) -PslPluginDirectory=$(Agent.BuildDirectory)/staged-plugin > /tmp/runIdeGradle.log & - displayName: 'Prepare env and start IDE $(IDEA_VERSION)' - - bash: | - set -e -o pipefail -u - .azure-pipelines/wait-for-endpoint.sh http://127.0.0.1:8082 -t 500 - displayName: 'Wait for IDE to start' - - bash: | - set -e -o pipefail -u - echo 'Recording tests on video' - ffmpeg -loglevel warning -f x11grab -video_size 1280x960 -framerate 10 -i :10 -q:v 0 /tmp/recording_$(IDEA_VERSION).mp4 & - echo "##vso[task.setvariable variable=recordingPid;isOutput=true]$!" - name: 'startRecording' - displayName: 'Start video recording' - - task: Gradle@2 - displayName: 'Run ITs on $(IDEA_VERSION)' - inputs: - options: --stacktrace -i -PijVersion=$(IDEA_VERSION) -PslPluginDirectory=$(Agent.BuildDirectory)/staged-plugin - tasks: :its:check - publishJUnitResults: true - testRunTitle: 'Run ITs on $(IDEA_VERSION)' - jdkVersionOption: '17' - env: - CI: true # needed for gradle-intellij-plugin to skip downloading sources - ARTIFACTORY_API_KEY: $(ARTIFACTORY_API_KEY) - GITHUB_TOKEN: $(GITHUB_TOKEN) - DISPLAY: :10 - - bash: | - kill -2 $(startRecording.recordingPid) - displayName: 'Stop video recording' - condition: always() - - publish: /tmp/recording_$(IDEA_VERSION).mp4 - displayName: 'Publish video recording' - artifact: ITCaptureScreen_$(IDEA_VERSION)_$(System.JobAttempt) - condition: always() - - publish: its/build/idea-sandbox/system/log - displayName: 'Publish idea log folder' - artifact: idea_log_$(IDEA_VERSION)_$(System.JobAttempt) - condition: always() - - bash: | - cat /tmp/runIdeGradle.log - displayName: 'Log' - condition: always() -- template: promote-stage.yml@commonTemplates - parameters: - stageDependencies: - - validate - - qa -- template: stage-with-burgr-notifications.yml@commonTemplates - parameters: - burgrName: 'dogfood' - burgrType: 'dogfood' - stageName: 'update_dogfood_repo' - stageDisplayName: Update internal dogfooding plugin repo - stageCondition: and(succeeded(), eq(variables['Build.SourceBranchName'], 'master')) - stageDependencies: promote - jobs: - - job: updateInternalSite - displayName: Update internal plugin repo on repox - steps: - - checkout: none - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.x' - - bash: pip3 install requests - - task: PythonScript@0 - name: updateInternalSiteOnRepox - inputs: - scriptSource: 'inline' - script: | - import requests - import os - import sys - import json - - githubSlug = '$(Build.Repository.ID)' - githubProject = githubSlug.split("/", 1)[1] - buildNumber = '$(Build.BuildId)' - - buildInfoUrl = f'$(ARTIFACTORY_URL)/api/build/{githubProject}/{buildNumber}' - buildInfoResp = requests.get(url=buildInfoUrl, auth=('$(ARTIFACTORY_API_USER)', '$(ARTIFACTORY_API_KEY)')) - buildInfoJson = buildInfoResp.json() - - buildInfo = buildInfoJson.get('buildInfo', {}) - buildInfoProperties = buildInfo.get('properties', {}) - - # PROJECT_VERSION is set by the compute-build-version-step.yml - version = buildInfoProperties.get('buildInfo.env.PROJECT_VERSION', 'NOT_FOUND') - - xml = f""" - - """ - - updatePluginsXmlUrl = "$(ARTIFACTORY_URL)/sonarsource-public-builds/org/sonarsource/sonarlint/intellij/sonarlint-intellij/updatePlugins.xml" - response = requests.put(url=updatePluginsXmlUrl, data=xml, auth=('$(ARTIFACTORY_API_USER)', '$(ARTIFACTORY_API_KEY)')) - if not response.status_code == 201: - sys.exit('[!] [{0}] Server Error'.format(response.status_code)) - diff --git a/build.gradle.kts b/build.gradle.kts index 18df4dc41a..ea89f6c33b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -45,11 +45,11 @@ val jettyVersion: String by project val intellijBuildVersion: String by project val omnisharpVersion: String by project -// The environment variables ARTIFACTORY_PRIVATE_USERNAME and ARTIFACTORY_PRIVATE_PASSWORD are used on CI env (Azure) +// The environment variables ARTIFACTORY_PRIVATE_USERNAME and ARTIFACTORY_PRIVATE_PASSWORD are used on CI env // On local box, please add artifactoryUsername and artifactoryPassword to ~/.gradle/gradle.properties -val artifactoryUsername = System.getenv("ARTIFACTORY_PRIVATE_READER_USERNAME") +val artifactoryUsername = System.getenv("ARTIFACTORY_PRIVATE_USERNAME") ?: (if (project.hasProperty("artifactoryUsername")) project.property("artifactoryUsername").toString() else "") -val artifactoryPassword = System.getenv("ARTIFACTORY_PRIVATE_READER_PASSWORD") +val artifactoryPassword = System.getenv("ARTIFACTORY_PRIVATE_PASSWORD") ?: (if (project.hasProperty("artifactoryPassword")) project.property("artifactoryPassword").toString() else "") allprojects { @@ -92,6 +92,7 @@ allprojects { tasks.cyclonedxBom { setIncludeConfigs(listOf("runtimeClasspath", "sqplugins_deps")) + inputs.files(configurations.runtimeClasspath, configurations.archives.get()) } val bomFile = layout.buildDirectory.file("reports/bom.json") @@ -329,6 +330,14 @@ tasks { } } +tasks.artifactoryPublish { + mustRunAfter( + getTasksByName("cyclonedxBom", true), + tasks.buildPlugin, + getTasksByName("buildPluginBlockmap", true) + ) +} + sonarqube { properties { property("sonar.projectName", "SonarLint for IntelliJ IDEA") @@ -337,7 +346,7 @@ sonarqube { artifactory { clientConfig.info.buildName = "sonarlint-intellij" - clientConfig.info.buildNumber = System.getenv("BUILD_BUILDID") + clientConfig.info.buildNumber = System.getenv("BUILD_ID") clientConfig.isIncludeEnvVars = true clientConfig.envVarsExcludePatterns = "*password*,*PASSWORD*,*secret*,*MAVEN_CMD_LINE_ARGS*,sun.java.command,*token*,*TOKEN*,*LOGIN*,*login*,*key*,*KEY*,*PASSPHRASE*,*signing*" clientConfig.info.addEnvironmentProperty( @@ -354,11 +363,11 @@ artifactory { defaults(delegateClosureOf { setProperty( "properties", mapOf( - "vcs.revision" to System.getenv("BUILD_SOURCEVERSION"), - "vcs.branch" to (System.getenv("SYSTEM_PULLREQUEST_TARGETBRANCH") - ?: System.getenv("BUILD_SOURCEBRANCHNAME")), + "vcs.revision" to System.getenv("CIRRUS_CHANGE_IN_REPO"), + "vcs.branch" to (System.getenv("CIRRUS_BASE_BRANCH") + ?: System.getenv("CIRRUS_BRANCH")), "build.name" to "sonarlint-intellij", - "build.number" to System.getenv("BUILD_BUILDID") + "build.number" to System.getenv("BUILD_ID") ) ) invokeMethod("publishConfigs", "archives") @@ -369,9 +378,16 @@ artifactory { } signing { - setRequired({ - gradle.taskGraph.hasTask(":artifactoryPublish") && System.getenv("SYSTEM_PULLREQUEST_TARGETBRANCH") == null; - }) + setRequired { + val branch = System.getenv("CIRRUS_BRANCH") ?: "" + val pr = System.getenv("CIRRUS_PR") ?: "" + (branch == "master" || branch.matches("branch-[\\d.]+".toRegex())) && + pr == "" && + gradle.taskGraph.hasTask(":artifactoryPublish") + } + val signingKeyId: String? by project + val signingKey: String? by project + val signingPassword: String? by project + useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword) sign(configurations.archives.get()) } - diff --git a/gradle.properties b/gradle.properties index 119ad40436..0554604bfc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ version=8.5-SNAPSHOT -org.gradle.jvmargs=-XX:MaxMetaspaceSize=512M +org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=512M sonarlintCoreVersion=9.0.0.74108 intellijBuildVersion=IC-2021.3 clionBuildVersion=CL-2021.3 @@ -9,3 +9,4 @@ protobufVersion=3.21.9 jettyVersion=11.0.12 omnisharpVersion=1.39.6 projectType=application +org.gradle.caching=true diff --git a/settings.gradle.kts b/settings.gradle.kts index 8cbe313424..219a17ec59 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -14,3 +14,17 @@ dependencyResolutionManagement { } } } + +val isCiServer = System.getenv().containsKey("CIRRUS_CI") +val isMasterBranch = System.getenv()["CIRRUS_BRANCH"] == "master" +val buildCacheHost: String = System.getenv().getOrDefault("CIRRUS_HTTP_CACHE_HOST", "localhost:12321") +buildCache { + local { + isEnabled = !isCiServer + } + remote { + url = uri("http://${buildCacheHost}/") + isEnabled = isCiServer + isPush = isMasterBranch + } +} diff --git a/src/test/java/org/sonarlint/intellij/analysis/JavaAnalysisConfiguratorTests.java b/src/test/java/org/sonarlint/intellij/analysis/JavaAnalysisConfiguratorTests.java index 0c0f4188d4..90d11b1b09 100644 --- a/src/test/java/org/sonarlint/intellij/analysis/JavaAnalysisConfiguratorTests.java +++ b/src/test/java/org/sonarlint/intellij/analysis/JavaAnalysisConfiguratorTests.java @@ -208,28 +208,28 @@ void testSourceAndTarget_with_different_target() { } @Test - void testClasspath() { + void testClasspath() throws IOException { final var props = underTest.configure(getModule(), Collections.emptyList()).extraProperties; assertThat(props) - .containsEntry("sonar.java.binaries", "\"" + compilerOutputDirPath + "\"") + .containsEntry("sonar.java.binaries", "\"" + compilerOutputDirPath.toRealPath() + "\"") .containsEntry("sonar.java.libraries", String.join(",", - guavaLibPath.toString(), - FAKE_JDK_ROOT_PATH.resolve("jdk1.8/lib/rt.jar").toString(), - FAKE_JDK_ROOT_PATH.resolve("jdk1.8/lib/another.jar").toString(), - dependentModCompilerOutputDirPath.toString(), - exportedLibInDependentModulePath.toString())) - .containsEntry("sonar.java.test.binaries", compilerTestOutputDirPath.toString()) + guavaLibPath.toRealPath().toString(), + FAKE_JDK_ROOT_PATH.resolve("jdk1.8/lib/rt.jar").toRealPath().toString(), + FAKE_JDK_ROOT_PATH.resolve("jdk1.8/lib/another.jar").toRealPath().toString(), + dependentModCompilerOutputDirPath.toRealPath().toString(), + exportedLibInDependentModulePath.toRealPath().toString())) + .containsEntry("sonar.java.test.binaries", compilerTestOutputDirPath.toRealPath().toString()) .containsEntry("sonar.java.test.libraries", String.join(",", - "\"" + compilerOutputDirPath + "\"", - junitLibPath.toString(), - guavaLibPath.toString(), - FAKE_JDK_ROOT_PATH.resolve("jdk1.8/lib/rt.jar").toString(), - FAKE_JDK_ROOT_PATH.resolve("jdk1.8/lib/another.jar").toString(), - dependentModCompilerOutputDirPath.toString(), - exportedLibInDependentModulePath.toString(), - testDependentModCompilerOutputDirPath.toString(), - exportedLibInTestDependentModulePath.toString())) - .containsEntry("sonar.java.jdkHome", FAKE_JDK_ROOT_PATH.resolve("jdk1.8").toString()); + "\"" + compilerOutputDirPath.toRealPath() + "\"", + junitLibPath.toRealPath().toString(), + guavaLibPath.toRealPath().toString(), + FAKE_JDK_ROOT_PATH.resolve("jdk1.8/lib/rt.jar").toRealPath().toString(), + FAKE_JDK_ROOT_PATH.resolve("jdk1.8/lib/another.jar").toRealPath().toString(), + dependentModCompilerOutputDirPath.toRealPath().toString(), + exportedLibInDependentModulePath.toRealPath().toString(), + testDependentModCompilerOutputDirPath.toRealPath().toString(), + exportedLibInTestDependentModulePath.toRealPath().toString())) + .containsEntry("sonar.java.jdkHome", FAKE_JDK_ROOT_PATH.resolve("jdk1.8").toRealPath().toString()); } private static Sdk addRtJarTo(@NotNull Sdk jdk) { diff --git a/wss-unified-agent.config b/wss-unified-agent.config index dbac5cad36..362a6f4e54 100644 --- a/wss-unified-agent.config +++ b/wss-unified-agent.config @@ -1,6 +1,6 @@ -# WhiteSource agent config for sonarlint-intellij +# Mend agent config for sonarlint-intellij -# WhiteSource documentation https://whitesource.atlassian.net/wiki/spaces/WD/pages/1544880156/Unified+Agent+Configuration+Parameters +# Mend documentation: https://docs.mend.io/en-US/bundle/unified_agent/page/getting_started_with_the_unified_agent.html # Exclude tests - only scan product code excludes=**/*sources.jar **/*javadoc.jar its/projects/** src/test/** @@ -19,3 +19,4 @@ wss.url=https://saas-eu.whitesourcesoftware.com/agent forceUpdate=true checkPolicies=true forceUpdate.failBuildOnPolicyViolation=false +productName=SonarLint/IntelliJ