--- name: Configure Gradle description: GitHub Action to configure Gradle build environment with build number, authentication, and default settings inputs: working-directory: description: Relative path under github.workspace to execute the build in default: . artifactory-reader-role: description: Suffix for the Artifactory reader role in Vault. Defaults to `private-reader` for private repositories, and `public-reader` for public repositories. default: '' repox-url: description: URL for Repox used to resolve dependencies. Defaults to SaaS on GitHub-hosted runners and the production Edge on self-hosted runners. Explicit URLs override runner selection. default: ${{ runner.environment == 'github-hosted' && 'https://repox.jfrog.io' || 'https://repox-internal.sonar.build' }} use-develocity: description: Whether to use Develocity for build tracking. default: 'false' develocity-url: description: URL for Develocity default: https://develocity.sonar.build/ cache-paths: description: Cache paths to use (multiline). default: |- ~/.gradle/caches ~/.gradle/wrapper disable-caching: description: Whether to disable Gradle caching entirely default: 'false' host-actions-root: description: Path to the actions folder on the host (used when called from another local action) default: '' outputs: BUILD_NUMBER: description: The current build number. Also set as environment variable BUILD_NUMBER value: ${{ steps.get-build-number.outputs.BUILD_NUMBER }} current-version: description: The project version set in the gradle.properties (before replacement). Also set as environment variable CURRENT_VERSION value: ${{ steps.set-version.outputs.current-version }} project-version: description: The project version with build number (after replacement). Also set as environment variable PROJECT_VERSION value: ${{ steps.set-version.outputs.project-version }} runs: using: composite steps: - name: Set local action paths id: set-path shell: bash run: | echo "::group::Fix for using local actions" echo "GITHUB_ACTION_PATH=$GITHUB_ACTION_PATH" echo "github.action_path=${{ github.action_path }}" ACTION_PATH_CONFIG_GRADLE="${{ github.action_path }}" host_actions_root="${{ inputs.host-actions-root }}" if [[ -z "$host_actions_root" ]]; then host_actions_root="$(dirname "$ACTION_PATH_CONFIG_GRADLE")" else ACTION_PATH_CONFIG_GRADLE="$host_actions_root/config-gradle" fi echo "ACTION_PATH_CONFIG_GRADLE=$ACTION_PATH_CONFIG_GRADLE" echo "ACTION_PATH_CONFIG_GRADLE=$ACTION_PATH_CONFIG_GRADLE" >> "$GITHUB_ENV" echo "host_actions_root=$host_actions_root" >> "$GITHUB_OUTPUT" # Windows Git-Bash's ln -sf can't re-link over an existing symlink-to-directory; clear it first. rm -rf .actions/get-build-number .actions/shared mkdir -p ".actions" ln -sf "$host_actions_root/get-build-number" .actions/get-build-number ln -sf "$host_actions_root/shared" .actions/shared ls -la .actions/* echo "::endgroup::" - uses: ./.actions/get-build-number id: get-build-number with: host-actions-root: ${{ steps.set-path.outputs.host_actions_root }} - id: config-gradle-completed if: env.CONFIG_GRADLE_COMPLETED != '' shell: bash run: | echo "Action already called by $CONFIG_GRADLE_COMPLETED, execution skipped." echo "skip=true" >> $GITHUB_OUTPUT - name: Set parameter for Vault if: steps.config-gradle-completed.outputs.skip != 'true' shell: bash env: ARTIFACTORY_READER_ROLE: ${{ inputs.artifactory-reader-role != '' && inputs.artifactory-reader-role || (github.event.repository.visibility == 'public' && 'public-reader' || 'private-reader') }} run: | echo "ARTIFACTORY_READER_ROLE=${ARTIFACTORY_READER_ROLE}" >> "$GITHUB_ENV" - uses: SonarSource/vault-action-wrapper@a7fa5fd4a4e4e0f2593f6137c0812cac196cf4ce # 3.7.0 if: steps.config-gradle-completed.outputs.skip != 'true' id: artifactory with: # yamllint disable rule:line-length url: ${{ contains(inputs.repox-url, '.dev.sonar.build') && 'https://vault.dev.sonar.build' || 'https://vault.sonar.build' }} secrets: | development/${{ contains(inputs.repox-url, 'jfrog.io') && 'artifactory' || (contains(inputs.repox-url, '.dev.sonar.build') && 'artifactory-edge-dev' || 'artifactory-edge-prod') }}/token/{REPO_OWNER_NAME_DASH}-${{ env.ARTIFACTORY_READER_ROLE }} username | ARTIFACTORY_USERNAME; development/${{ contains(inputs.repox-url, 'jfrog.io') && 'artifactory' || (contains(inputs.repox-url, '.dev.sonar.build') && 'artifactory-edge-dev' || 'artifactory-edge-prod') }}/token/{REPO_OWNER_NAME_DASH}-${{ env.ARTIFACTORY_READER_ROLE }} access_token | ARTIFACTORY_ACCESS_TOKEN; # yamllint enable rule:line-length - uses: SonarSource/vault-action-wrapper@a7fa5fd4a4e4e0f2593f6137c0812cac196cf4ce # 3.7.0 if: steps.config-gradle-completed.outputs.skip != 'true' && inputs.use-develocity == 'true' id: secrets with: secrets: | development/kv/data/develocity token | DEVELOCITY_TOKEN; - name: Extract Develocity hostname id: develocity-hostname if: steps.config-gradle-completed.outputs.skip != 'true' && inputs.use-develocity == 'true' shell: bash env: DEVELOCITY_URL: ${{ inputs.develocity-url }} run: echo "hostname=$(echo "${DEVELOCITY_URL}" | sed -e 's|https://||' -e 's|/$||')" >> $GITHUB_OUTPUT - name: Set environment variables for Artifactory authentication if: steps.config-gradle-completed.outputs.skip != 'true' shell: bash env: ARTIFACTORY_URL: ${{ format('{0}/artifactory', inputs.repox-url) }} # yamllint disable rule:line-length ARTIFACTORY_USERNAME: ${{ steps.artifactory.outputs.vault && fromJSON(steps.artifactory.outputs.vault).ARTIFACTORY_USERNAME || '' }} ARTIFACTORY_ACCESS_TOKEN: ${{ steps.artifactory.outputs.vault && fromJSON(steps.artifactory.outputs.vault).ARTIFACTORY_ACCESS_TOKEN || '' }} # yamllint enable rule:line-length DEVELOCITY_TOKEN: ${{ inputs.use-develocity == 'true' && steps.secrets.outputs.vault && fromJSON(steps.secrets.outputs.vault).DEVELOCITY_TOKEN || '' }} run: | if [[ "${DEVELOCITY_ACCESS_KEY:-}" == "${{ steps.develocity-hostname.outputs.hostname }}=" ]]; then echo "::warning title=Found invalid DEVELOCITY_ACCESS_KEY::DEVELOCITY_ACCESS_KEY should not be set manually" \ "in the environment." >&2 echo "[WARNING] DEVELOCITY_ACCESS_KEY is set in the environment with an empty token. This is a deprecated configuration." \ "The Develocity token is configured by config-gradle. Please remove external configuration of DEVELOCITY_ACCESS_KEY." fi echo "ARTIFACTORY_URL=$ARTIFACTORY_URL" >> "$GITHUB_ENV" # Resolve URL kept separately so build steps can override ARTIFACTORY_URL for deploy. echo "ARTIFACTORY_RESOLVE_URL=$ARTIFACTORY_URL" >> "$GITHUB_ENV" echo "ARTIFACTORY_USERNAME=$ARTIFACTORY_USERNAME" >> "$GITHUB_ENV" echo "ARTIFACTORY_ACCESS_USERNAME=$ARTIFACTORY_USERNAME" >> "$GITHUB_ENV" # deprecated, backward compliance echo "ARTIFACTORY_ACCESS_TOKEN=$ARTIFACTORY_ACCESS_TOKEN" >> "$GITHUB_ENV" echo "ARTIFACTORY_PASSWORD=$ARTIFACTORY_ACCESS_TOKEN" >> "$GITHUB_ENV" # deprecated, backward compliance if [[ -n "${DEVELOCITY_TOKEN:-}" ]]; then echo "DEVELOCITY_ACCESS_KEY=${{ steps.develocity-hostname.outputs.hostname }}=$DEVELOCITY_TOKEN" >> "$GITHUB_ENV" fi - name: Configure Gradle wrapper download resilience if: steps.config-gradle-completed.outputs.skip != 'true' shell: bash working-directory: ${{ inputs.working-directory }} run: | WRAPPER_PROPS="gradle/wrapper/gradle-wrapper.properties" if [[ ! -f "$WRAPPER_PROPS" ]]; then echo "No ${WRAPPER_PROPS} found, skipping wrapper resilience config" exit 0 fi update_prop() { local key="$1" value="$2" if grep -q "^${key}=" "$WRAPPER_PROPS"; then sed -i.bak "s/^${key}=.*/${key}=${value}/" "$WRAPPER_PROPS" else [[ -s "$WRAPPER_PROPS" && -n "$(tail -c1 "$WRAPPER_PROPS")" ]] && echo >> "$WRAPPER_PROPS" echo "${key}=${value}" >> "$WRAPPER_PROPS" fi } update_prop networkTimeout 60000 update_prop retries 3 update_prop retryBackOffMs 1000 rm -f "${WRAPPER_PROPS}.bak" - name: Configure Gradle if: steps.config-gradle-completed.outputs.skip != 'true' uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0 with: develocity-injection-enabled: ${{ inputs.use-develocity == 'true' }} cache-disabled: true develocity-plugin-version: '4.0' develocity-access-key: ${{ inputs.use-develocity == 'true' && steps.secrets.outputs.vault && fromJSON(steps.secrets.outputs.vault).DEVELOCITY_TOKEN || '' }} # Resolve Develocity plugin via Repox — plugins.gradle.org is blocked during registry brownouts. gradle-plugin-repository-url: ${{ inputs.use-develocity == 'true' && format('{0}/artifactory/plugins.gradle.org/', inputs.repox-url) || '' }} gradle-plugin-repository-username: ${{ inputs.use-develocity == 'true' && env.ARTIFACTORY_USERNAME || '' }} gradle-plugin-repository-password: ${{ inputs.use-develocity == 'true' && env.ARTIFACTORY_ACCESS_TOKEN || '' }} - name: Generate Gradle Cache Key if: steps.config-gradle-completed.outputs.skip != 'true' && inputs.disable-caching != 'true' shell: bash run: | # Generate cache key from all Gradle files /usr/bin/find . \( -name '*.gradle' -o -name '*.gradle.kts' \) -type f -exec md5sum {} \; | sort > gradle-md5-sums.txt md5sum gradle/libs.versions.toml gradle/wrapper/gradle-wrapper.properties 2>/dev/null >> gradle-md5-sums.txt || true GRADLE_CACHE_KEY=$(md5sum gradle-md5-sums.txt | awk '{ print $1 }') echo "🔑 Generated cache key: ${GRADLE_CACHE_KEY}" echo "GRADLE_CACHE_KEY=${GRADLE_CACHE_KEY}" >> "$GITHUB_ENV" rm -f gradle-md5-sums.txt - name: Sanitize workflow name for cache key id: sanitize_workflow if: steps.config-gradle-completed.outputs.skip != 'true' && inputs.disable-caching == 'false' shell: bash env: WORKFLOW_NAME: ${{ github.workflow }} run: echo "workflow_name=${WORKFLOW_NAME// /-}" >> "$GITHUB_OUTPUT" - name: Gradle Cache uses: SonarSource/gh-action_cache@0b86c7a0e6c3cb8238c826be7dd9fdfd02f16f8b # v1.7.3 if: steps.config-gradle-completed.outputs.skip != 'true' && inputs.disable-caching == 'false' with: path: ${{ inputs.cache-paths }} key: gradle-${{ runner.os }}-${{ steps.sanitize_workflow.outputs.workflow_name }}-${{ env.GRADLE_CACHE_KEY }} restore-keys: gradle-${{ runner.os }}-${{ steps.sanitize_workflow.outputs.workflow_name }}- # $GRADLE_USER_HOME is typically set to ~/.gradle/ by gradle/actions/setup-gradle - name: Configure Gradle Authentication if: steps.config-gradle-completed.outputs.skip != 'true' shell: bash run: | GRADLE_INIT_DIR="$GRADLE_USER_HOME/init.d" mkdir -p "$GRADLE_INIT_DIR" cp "$ACTION_PATH_CONFIG_GRADLE/resources/repoxAuth.init.gradle.kts" "$GRADLE_INIT_DIR/" - name: Update project version and set current-version and project-version variables id: set-version shell: bash working-directory: ${{ inputs.working-directory }} env: SKIP: ${{ steps.config-gradle-completed.outputs.skip }} run: $ACTION_PATH_CONFIG_GRADLE/set_gradle_project_version.sh - name: Deactivate UseContainerSupport on github-ubuntu-* runners if: steps.config-gradle-completed.outputs.skip != 'true' && runner.os == 'Linux' && runner.environment == 'github-hosted' shell: bash run: | echo "::warning title=Deactivating UseContainerSupport::The GitHub-hosted Ubuntu runners have an issue with Java's" \ "UseContainerSupport feature." >&2 echo "JAVA_TOOL_OPTIONS=${JAVA_TOOL_OPTIONS:=-XX:-UseContainerSupport}" >> "$GITHUB_ENV" - name: Set Config Gradle completed if: steps.config-gradle-completed.outputs.skip != 'true' shell: bash run: echo "CONFIG_GRADLE_COMPLETED=$GITHUB_ACTION" >> "$GITHUB_ENV"