From 5488645aa5d72da0cc2698be570c4084b4919c8e Mon Sep 17 00:00:00 2001 From: GabinL21 <67428953+GabinL21@users.noreply.github.com> Date: Thu, 7 Nov 2024 08:57:03 +0100 Subject: [PATCH] SONARPHP-1523 Migrate CI pipeline to Starlak (#1300) --- .cirrus.star | 38 +++++- .cirrus.yml | 212 ---------------------------------- .cirrus/modules/build.star | 144 +++++++++++++++++++++++ .cirrus/modules/env.star | 24 ++++ .cirrus/modules/promote.star | 32 +++++ .cirrus/modules/qa.star | 172 +++++++++++++++++++++++++++ .cirrus/use-gradle-wrapper.sh | 7 ++ 7 files changed, 415 insertions(+), 214 deletions(-) delete mode 100644 .cirrus.yml create mode 100644 .cirrus/modules/build.star create mode 100644 .cirrus/modules/env.star create mode 100644 .cirrus/modules/promote.star create mode 100644 .cirrus/modules/qa.star create mode 100644 .cirrus/use-gradle-wrapper.sh diff --git a/.cirrus.star b/.cirrus.star index 28b17b70fc..24ea07b24d 100644 --- a/.cirrus.star +++ b/.cirrus.star @@ -1,4 +1,38 @@ -load("github.com/SonarSource/cirrus-modules@v2", "load_features") +# Check Starlark specs: https://github.com/bazelbuild/starlark/blob/master/spec.md +# DevInfra modules +load("github.com/SonarSource/cirrus-modules@v3", "load_features") +# Modules +load( + "github.com/SonarSource/cirrus-modules/cloud-native/helper.star@analysis/master", + "merge_dict" +) +load(".cirrus/modules/env.star", "env") +load( + ".cirrus/modules/build.star", + "build_task", + "build_test_analyze_task", + "sca_scan_task" +) +load( + ".cirrus/modules/qa.star", + "qa_os_win_task", + "qa_plugin_task", + "qa_ruling_task", + "qa_pr_analysis_task" +) +load(".cirrus/modules/promote.star", "promote_task") + def main(ctx): - return load_features(ctx) + conf = dict() + merge_dict(conf, load_features(ctx)) + merge_dict(conf, env()) + merge_dict(conf, build_task()) + merge_dict(conf, build_test_analyze_task()) + merge_dict(conf, qa_os_win_task()) + merge_dict(conf, sca_scan_task()) + merge_dict(conf, qa_plugin_task()) + merge_dict(conf, qa_ruling_task()) + merge_dict(conf, qa_pr_analysis_task()) + merge_dict(conf, promote_task()) + return conf diff --git a/.cirrus.yml b/.cirrus.yml deleted file mode 100644 index dc22a53d63..0000000000 --- a/.cirrus.yml +++ /dev/null @@ -1,212 +0,0 @@ -env: - CIRRUS_VAULT_URL: https://vault.sonar.build:8200 - CIRRUS_VAULT_AUTH_PATH: jwt-cirrusci - CIRRUS_VAULT_ROLE: cirrusci-${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME} - - 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] - 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] - #Possible values for ARTIFACTORY_DEPLOY_REPO: sonarsource-private-qa, sonarsource-public-qa - ARTIFACTORY_DEPLOY_REPO: sonarsource-public-qa - ARTIFACTORY_ACCESS_TOKEN: VAULT[development/artifactory/token/${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-private-reader access_token] - PATH: ${CIRRUS_WORKING_DIR}/.cirrus:${PATH} - # Use bash (instead of sh on linux or cmd.exe on windows) - CIRRUS_SHELL: bash - -build_secrets: &BUILD_SECRETS - SIGN_KEY: VAULT[development/kv/data/sign data.key] - PGP_PASSPHRASE: VAULT[development/kv/data/sign data.passphrase] - # analysis on next - SONAR_TOKEN: VAULT[development/kv/data/next data.token] - SONAR_HOST_URL: https://next.sonarqube.com/sonarqube - -pr_analysis_secrets: &PR_ANALYSIS_SECRETS - GITHUB_TOKEN: VAULT[development/github/token/licenses-ro token] - -mend_scan_secrets: &MEND_SCAN_SECRETS - WS_APIKEY: VAULT[development/kv/data/mend data.apikey] - -promote_secrets: &PROMOTE_SECRETS - ARTIFACTORY_PROMOTE_ACCESS_TOKEN: VAULT[development/artifactory/token/${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-promoter access_token] - GITHUB_TOKEN: VAULT[development/github/token/${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-promotion token] - -# ---------------------------------------------- -# ------------------CACHING--------------------- -# ---------------------------------------------- - -setup_orchestrator_cache: &SETUP_ORCHESTRATOR_CACHE - set_orchestrator_home_script: | - export TODAY=$(date '+%Y-%m-%d') - echo "TODAY=${TODAY}" >> $CIRRUS_ENV - echo "ORCHESTRATOR_HOME=${CIRRUS_WORKING_DIR}/orchestrator/${TODAY}" >> $CIRRUS_ENV - mkdir_orchestrator_home_script: | - echo "Create dir ${ORCHESTRATOR_HOME} if needed" - mkdir -p ${ORCHESTRATOR_HOME} - orchestrator_cache: - folder: ${ORCHESTRATOR_HOME} - fingerprint_script: echo ${TODAY} - reupload_on_changes: "true" - -# ---------------------------------------------- -# -------------CONTAINER DEFINITIONS------------ -# ---------------------------------------------- - -default_container_definition: &DEFAULT_CONTAINER_DEFINITION - cluster_name: ${CIRRUS_CLUSTER_NAME} - region: eu-central-1 - namespace: default - -container_definition: &CONTAINER_DEFINITION - eks_container: - image: ${CIRRUS_AWS_ACCOUNT}.dkr.ecr.eu-central-1.amazonaws.com/base:j17-latest - <<: *DEFAULT_CONTAINER_DEFINITION - cpu: 2 - memory: 2G - -qa_container_definition: &QA_CONTAINER_DEFINITION - eks_container: - image: ${CIRRUS_AWS_ACCOUNT}.dkr.ecr.eu-central-1.amazonaws.com/base:j17-latest - <<: *DEFAULT_CONTAINER_DEFINITION - cpu: 4 - memory: 8G - -win_vm_definition: &WINDOWS_VM_DEFINITION - ec2_instance: - experimental: true # see https://github.com/cirruslabs/cirrus-ci-docs/issues/1051 - image: base-windows-jdk17-v* - platform: windows - region: eu-central-1 - type: t3.xlarge - subnet_id: ${CIRRUS_AWS_SUBNET} - use_ssd: true - -# ---------------------------------------------- -# ------------------FILTERS--------------------- -# ---------------------------------------------- - -depends_on_build: &DEPENDS_ON_BUILD - depends_on: - - build - -only_sonarsource_qa: &ONLY_SONARSOURCE_QA - only_if: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_TAG == "" && - ($CIRRUS_PR != "" || $CIRRUS_BRANCH == "master" || $CIRRUS_BRANCH =~ "branch-.*" || $CIRRUS_BRANCH =~ "dogfood-on-.*" || $CIRRUS_BRANCH =~ "release.*") - -only_main_branches_filter: &ONLY_MAIN_BRANCHES - only_if: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_TAG == "" && - ($CIRRUS_BRANCH == $CIRRUS_DEFAULT_BRANCH || $CIRRUS_BRANCH =~ "branch-.*") - - -# ---------------------------------------------- -# -------------------TASKS---------------------- -# ---------------------------------------------- - -build_task: - <<: *CONTAINER_DEFINITION - eks_container: - memory: 3G - env: - <<: *BUILD_SECRETS - 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] - #allow deployment of pull request artifacts to repox - DEPLOY_PULL_REQUEST: true - CIRRUS_CLONE_DEPTH: 50 - build_script: - - git submodule update --init - - source cirrus-env BUILD - - regular_gradle_build_deploy_analyze - -build_win_task: - <<: *WINDOWS_VM_DEFINITION - <<: *ONLY_SONARSOURCE_QA - <<: *DEPENDS_ON_BUILD - build_script: - - git config --global core.autocrlf input - - source cirrus-env CI - - ./gradlew clean build - -plugin_qa_task: - <<: *ONLY_SONARSOURCE_QA - <<: *DEPENDS_ON_BUILD - <<: *QA_CONTAINER_DEFINITION - <<: *SETUP_ORCHESTRATOR_CACHE - env: - CIRRUS_CLONE_DEPTH: 1 - matrix: - - SQ_VERSION: LATEST_RELEASE - - SQ_VERSION: DEV - submodules_script: - - git submodule update --init - qa_script: - - source cirrus-env QA - - source set_gradle_build_version $BUILD_NUMBER - - ./gradlew -Drevision=${PROJECT_VERSION} -Dsonar.runtimeVersion=${SQ_VERSION} its:plugin:tests:integrationTest --info --console plain --no-daemon - -ruling_task: - <<: *ONLY_SONARSOURCE_QA - <<: *DEPENDS_ON_BUILD - <<: *QA_CONTAINER_DEFINITION - <<: *SETUP_ORCHESTRATOR_CACHE - env: - CIRRUS_CLONE_DEPTH: 1 - matrix: - - PHP_PROJECT: "Flysystem" - - PHP_PROJECT: "Monica" - - PHP_PROJECT: "PhpCodeSniffer" - - PHP_PROJECT: "PhpMailer" - - PHP_PROJECT: "Psysh" - - PHP_PROJECT: "PhpWord" - - PHP_PROJECT: "RubixML" - - PHP_PROJECT: "PhpSpreadsheet" - submodules_script: - - git submodule update --init - ruling_script: - - source cirrus-env QA - - source set_gradle_build_version $BUILD_NUMBER - - ./gradlew -Drevision=${PROJECT_VERSION} -Dsonar.runtimeVersion=LATEST_RELEASE its:ruling:integrationTest --tests PhpGeneralRulingTest.test${PHP_PROJECT} --info --console plain --no-daemon - -pr_analysis_task: - <<: *ONLY_SONARSOURCE_QA - <<: *DEPENDS_ON_BUILD - <<: *QA_CONTAINER_DEFINITION - env: - <<: *PR_ANALYSIS_SECRETS - CIRRUS_CLONE_DEPTH: 1 - submodules_script: - - git submodule update --init - ruling_script: - - source cirrus-env QA - - source set_gradle_build_version $BUILD_NUMBER - - ./gradlew its:ruling:integrationTest --tests PhpPrAnalysisTest --info --console plain --no-daemon - -ws_scan_task: - <<: *ONLY_MAIN_BRANCHES - <<: *DEPENDS_ON_BUILD - <<: *CONTAINER_DEFINITION - env: - <<: *MEND_SCAN_SECRETS - whitesource_script: - - source cirrus-env QA - - source set_gradle_build_version $BUILD_NUMBER - - ./gradlew clean build -x test - - source ws_scan.sh - allow_failures: "true" - always: - ws_artifacts: - path: "whitesource/**/*" - - -promote_task: - depends_on: - - ruling - - pr_analysis - - plugin_qa - <<: *ONLY_SONARSOURCE_QA - <<: *CONTAINER_DEFINITION - env: - <<: *PROMOTE_SECRETS - script: cirrus_promote_gradle diff --git a/.cirrus/modules/build.star b/.cirrus/modules/build.star new file mode 100644 index 0000000000..831d14466d --- /dev/null +++ b/.cirrus/modules/build.star @@ -0,0 +1,144 @@ +load( + "github.com/SonarSource/cirrus-modules/cloud-native/env.star@analysis/master", + "pgp_signing_env", + "next_env", + "whitesource_api_env" +) +load( + "github.com/SonarSource/cirrus-modules/cloud-native/conditions.star@analysis/master", + "is_main_branch", + "is_branch_qa_eligible" +) +load( + "github.com/SonarSource/cirrus-modules/cloud-native/platform.star@analysis/master", + "base_image_container_builder" +) +load( + "github.com/SonarSource/cirrus-modules/cloud-native/cache.star@analysis/master", + "gradle_cache", + "cleanup_gradle_script", + "gradle_wrapper_cache", + "project_version_cache", + "store_project_version_script" +) + + +# +# Common +# + +def profile_report_artifacts(): + return { + "profile_report_artifacts": { + "path": "build/reports/profile/profile-*.html" + } + } + + +# +# Build +# + +def build_script(): + return [ + "source cirrus-env BUILD", + "source .cirrus/use-gradle-wrapper.sh", + "regular_gradle_build_deploy_analyze ${BUILD_ARGUMENTS}", + "source set_gradle_build_version ${BUILD_NUMBER}", + "echo export PROJECT_VERSION=${PROJECT_VERSION} >> ~/.profile" + ] + + +def build_env(): + env = pgp_signing_env() + env |= next_env() + env |= { + "DEPLOY_PULL_REQUEST": "true", + "BUILD_ARGUMENTS": "-x test -x sonar" + } + return env + + +def build_task(): + return { + "build_task": { + "env": build_env(), + "eks_container": base_image_container_builder(cpu=2, memory="4G"), + "project_version_cache": project_version_cache(), + "gradle_cache": gradle_cache(), + "gradle_wrapper_cache": gradle_wrapper_cache(), + "build_script": build_script(), + "cleanup_gradle_script": cleanup_gradle_script(), + "store_project_version_script": store_project_version_script() + } + } + + +# +# Build test analyze +# + +def build_test_env(): + env = pgp_signing_env() + env |= next_env() + env |= { + "DEPLOY_PULL_REQUEST": "false", + "BUILD_ARGUMENTS": "-x artifactoryPublish" + } + return env + + +def build_test_analyze_task(): + return { + "build_test_analyze_task": { + "only_if": is_branch_qa_eligible(), + "depends_on": "build", + "env": build_test_env(), + "eks_container": base_image_container_builder(cpu=2, memory="4G"), + "gradle_cache": gradle_cache(), + "gradle_wrapper_cache": gradle_wrapper_cache(), + "build_script": build_script(), + "on_failure": { + "junit_artifacts": { + "path": "**/test-results/**/*.xml", + "format": "junit" + } + }, + "cleanup_gradle_script": cleanup_gradle_script(), + } + } + + +# +# WhiteSource scan +# + +def whitesource_script(): + return [ + "source cirrus-env QA", + "source .cirrus/use-gradle-wrapper.sh", + "source ${PROJECT_VERSION_CACHE_DIR}/evaluated_project_version.txt", + "GRADLE_OPTS=\"-Xmx64m -Dorg.gradle.jvmargs='-Xmx3G' -Dorg.gradle.daemon=false\" ./gradlew ${GRADLE_COMMON_FLAGS} :php-frontend:processResources -Pkotlin.compiler.execution.strategy=in-process", + "source ws_scan.sh" + ] + + +def sca_scan_task(): + return { + "sca_scan_task": { + "only_if": is_main_branch(), + "depends_on": "build", + "env": whitesource_api_env(), + "eks_container": base_image_container_builder(cpu=1, memory="4G"), + "gradle_cache": gradle_cache(), + "gradle_wrapper_cache": gradle_wrapper_cache(), + "whitesource_script": whitesource_script(), + "cleanup_gradle_script": cleanup_gradle_script(), + "allow_failures": "true", + "always": { + "ws_artifacts": { + "path": "whitesource/**/*" + } + }, + } + } diff --git a/.cirrus/modules/env.star b/.cirrus/modules/env.star new file mode 100644 index 0000000000..8bd09bde9f --- /dev/null +++ b/.cirrus/modules/env.star @@ -0,0 +1,24 @@ +load( + "github.com/SonarSource/cirrus-modules/cloud-native/env.star@analysis/master", + "artifactory_env", + "cirrus_env", + "gradle_signing_env", + "next_env", + "gradle_env", +) + + +def project_version_env(): + return { + "PROJECT_VERSION_CACHE_DIR": "project-version", + } + + +def env(): + vars = artifactory_env() + vars |= cirrus_env(depth=1) + vars |= gradle_env() + vars |= gradle_signing_env() + vars |= next_env() + vars |= project_version_env() + return {"env": vars} diff --git a/.cirrus/modules/promote.star b/.cirrus/modules/promote.star new file mode 100644 index 0000000000..c4c052de2e --- /dev/null +++ b/.cirrus/modules/promote.star @@ -0,0 +1,32 @@ +load("github.com/SonarSource/cirrus-modules/cloud-native/env.star@analysis/master", "promotion_env") +load("github.com/SonarSource/cirrus-modules/cloud-native/platform.star@analysis/master", "base_image_container_builder") +load("github.com/SonarSource/cirrus-modules/cloud-native/cache.star@analysis/master", "project_version_cache") +load("github.com/SonarSource/cirrus-modules/cloud-native/conditions.star@analysis/master", "is_branch_qa_eligible") + + +def promote_script(): + return [ + "source cirrus-env PROMOTE", + "cirrus_jfrog_promote", + "source ${PROJECT_VERSION_CACHE_DIR}/evaluated_project_version.txt", + "github-notify-promotion", + ] + + +def promote_task(): + return { + "promote_task": { + "only_if": is_branch_qa_eligible(), + "depends_on": [ + "build", + "qa_os_win", + "qa_ruling", + "qa_plugin", + "qa_pr_analysis" + ], + "env": promotion_env(), + "eks_container": base_image_container_builder(cpu=1, memory="2G"), + "project_version_cache": project_version_cache(), + "script": promote_script() + } + } diff --git a/.cirrus/modules/qa.star b/.cirrus/modules/qa.star new file mode 100644 index 0000000000..7e3ba392ff --- /dev/null +++ b/.cirrus/modules/qa.star @@ -0,0 +1,172 @@ +load("github.com/SonarSource/cirrus-modules/cloud-native/actions.star@analysis/master", "default_gradle_on_failure") +load("github.com/SonarSource/cirrus-modules/cloud-native/platform.star@analysis/master", "base_image_container_builder", + "ec2_instance_builder") +load("github.com/SonarSource/cirrus-modules/cloud-native/conditions.star@analysis/master", "is_branch_qa_eligible") +load("github.com/SonarSource/cirrus-modules/cloud-native/env.star@analysis/master", "artifactory_reader_env") +load("build.star", "profile_report_artifacts") +load( + "github.com/SonarSource/cirrus-modules/cloud-native/cache.star@analysis/master", + "gradle_cache", + "cleanup_gradle_script", + "gradle_wrapper_cache", + "orchestrator_cache", + "set_orchestrator_home_script", + "mkdir_orchestrator_home_script", +) + +QA_PLUGIN_GRADLE_TASK = "its:plugin:tests:integrationTest" +QA_RULING_GRADLE_TASK = "its:ruling:integrationTest" +QA_QUBE_LATEST_RELEASE = "LATEST_RELEASE" + + +def on_failure(): + return default_gradle_on_failure() | { + "junit_artifacts": { + "path": "**/test-results/**/*.xml", + "format": "junit" + } + } + + +# +# Windows +# + +def qa_win_script(): + return [ + "source cirrus-env CI", + "./gradlew ${GRADLE_COMMON_FLAGS} test" + ] + + +def qa_os_win_task(): + return { + "qa_os_win_task": { + "only_if": is_branch_qa_eligible(), + "depends_on": "build", + "ec2_instance": ec2_instance_builder(), + "env": artifactory_reader_env(), + "gradle_cache": gradle_cache(), + "gradle_wrapper_cache": gradle_wrapper_cache(), + "build_script": qa_win_script(), + "on_failure": on_failure(), + } + } + + +# +# Commons +# + +def qa_task(env, run_its_script): + return { + "only_if": is_branch_qa_eligible(), + "depends_on": "build", + "eks_container": base_image_container_builder(cpu=4, memory="10G"), + "env": env, + "gradle_cache": gradle_cache(), + "gradle_wrapper_cache": gradle_wrapper_cache(), + "set_orchestrator_home_script": set_orchestrator_home_script(), + "mkdir_orchestrator_home_script": mkdir_orchestrator_home_script(), + "orchestrator_cache": orchestrator_cache(), + "run_its_script": run_its_script, + "on_failure": on_failure(), + "cleanup_gradle_script": cleanup_gradle_script(), + } + + +# +# Plugin +# + +def qa_plugin_env(): + return { + "GRADLE_TASK": QA_PLUGIN_GRADLE_TASK, + "KEEP_ORCHESTRATOR_RUNNING": "true", + "matrix": [ + {"SQ_VERSION": QA_QUBE_LATEST_RELEASE}, + {"SQ_VERSION": "DEV"}, + ], + "GITHUB_TOKEN": "VAULT[development/github/token/licenses-ro token]", + } + + +def qa_plugin_script(): + return [ + "git submodule update --init --depth 1", + "source cirrus-env QA", + "source .cirrus/use-gradle-wrapper.sh", + "./gradlew \"${GRADLE_TASK}\" \"-Dsonar.runtimeVersion=${SQ_VERSION}\" --info --build-cache --console plain --no-daemon" + ] + + +def qa_plugin_task(): + return { + "qa_plugin_task": qa_task(qa_plugin_env(), qa_plugin_script()) + } + + +# +# Ruling +# + +def qa_ruling_env(): + return { + "GRADLE_TASK": QA_RULING_GRADLE_TASK, + "SQ_VERSION": QA_QUBE_LATEST_RELEASE, + "KEEP_ORCHESTRATOR_RUNNING": "true", + "matrix": [ + {"PHP_PROJECT": "Flysystem"}, + {"PHP_PROJECT": "Monica"}, + {"PHP_PROJECT": "PhpCodeSniffer"}, + {"PHP_PROJECT": "PhpMailer"}, + {"PHP_PROJECT": "Psysh"}, + {"PHP_PROJECT": "PhpWord"}, + {"PHP_PROJECT": "RubixML"}, + {"PHP_PROJECT": "PhpSpreadsheet"}, + ], + "GITHUB_TOKEN": "VAULT[development/github/token/licenses-ro token]", + } + + +def qa_ruling_script(): + return [ + "git submodule update --init --depth 1", + "source cirrus-env QA", + "source .cirrus/use-gradle-wrapper.sh", + "./gradlew \"${GRADLE_TASK}\" \"-Dsonar.runtimeVersion=${SQ_VERSION}\" --tests \"PhpGeneralRulingTest.test${PHP_PROJECT}\" --info --build-cache --console plain --no-daemon" + ] + + +def qa_ruling_task(): + return { + "qa_ruling_task": qa_task(qa_ruling_env(), qa_ruling_script()) + } + + +# +# PR Analysis +# + +def qa_pr_analysis_env(): + return { + "GRADLE_TASK": QA_RULING_GRADLE_TASK, + "SQ_VERSION": QA_QUBE_LATEST_RELEASE, + "KEEP_ORCHESTRATOR_RUNNING": "true", + "GITHUB_TOKEN": "VAULT[development/github/token/licenses-ro token]", + } + + +def qa_pr_analysis_script(): + return [ + "git submodule update --init --depth 1", + "source cirrus-env QA", + "source .cirrus/use-gradle-wrapper.sh", + "./gradlew \"${GRADLE_TASK}\" \"-Dsonar.runtimeVersion=${SQ_VERSION}\" --tests \"PhpPrAnalysisTest\" --info --build-cache --console plain --no-daemon" + ] + + +def qa_pr_analysis_task(): + return { + "qa_pr_analysis_task": qa_task(qa_pr_analysis_env(), qa_pr_analysis_script()) + } diff --git a/.cirrus/use-gradle-wrapper.sh b/.cirrus/use-gradle-wrapper.sh new file mode 100644 index 0000000000..bcadc2367a --- /dev/null +++ b/.cirrus/use-gradle-wrapper.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +function gradle { + ./gradlew "$@" +} + +export -f gradle