mirror of
https://github.com/gradle/gradle-build-action.git
synced 2024-11-22 17:12:51 +00:00
Merge pull request #59 from eskatos/dd/v1-improved
Minor cleanups, simplifications and improvements
This commit is contained in:
commit
0206df026c
11 changed files with 91 additions and 78 deletions
49
.github/workflows/prod.yml
vendored
49
.github/workflows/prod.yml
vendored
|
@ -6,7 +6,7 @@ on:
|
||||||
push:
|
push:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
gradle-execution:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
@ -22,12 +22,6 @@ jobs:
|
||||||
with:
|
with:
|
||||||
build-root-directory: __tests__/samples/basic
|
build-root-directory: __tests__/samples/basic
|
||||||
arguments: test
|
arguments: test
|
||||||
- name: Test custom wrapper location
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
build-root-directory: __tests__/samples/no-wrapper
|
|
||||||
wrapper-directory: __tests__/samples/basic
|
|
||||||
arguments: help
|
|
||||||
- name: Test use defined Gradle version
|
- name: Test use defined Gradle version
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
|
@ -37,7 +31,7 @@ jobs:
|
||||||
- name: Test use Gradle version alias
|
- name: Test use Gradle version alias
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
gradle-version: rc
|
gradle-version: release-candidate
|
||||||
build-root-directory: __tests__/samples/no-wrapper
|
build-root-directory: __tests__/samples/no-wrapper
|
||||||
arguments: help
|
arguments: help
|
||||||
- name: Test use defined Gradle executable
|
- name: Test use defined Gradle executable
|
||||||
|
@ -46,6 +40,45 @@ jobs:
|
||||||
gradle-executable: __tests__/samples/basic/gradlew${{ matrix.script-suffix }}
|
gradle-executable: __tests__/samples/basic/gradlew${{ matrix.script-suffix }}
|
||||||
build-root-directory: __tests__/samples/no-wrapper
|
build-root-directory: __tests__/samples/no-wrapper
|
||||||
arguments: help
|
arguments: help
|
||||||
|
- name: Test custom wrapper location (deprecated)
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
build-root-directory: __tests__/samples/no-wrapper
|
||||||
|
wrapper-directory: __tests__/samples/basic
|
||||||
|
arguments: help
|
||||||
|
|
||||||
|
dependencies-cache:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Test dependencies-cache-enabled
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
build-root-directory: __tests__/samples/basic
|
||||||
|
arguments: test --no-daemon
|
||||||
|
dependencies-cache-enabled: true
|
||||||
|
|
||||||
|
configuration-cache:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Test configuration-cache-enabled
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
build-root-directory: __tests__/samples/basic
|
||||||
|
arguments: test --configuration-cache --no-daemon
|
||||||
|
configuration-cache-enabled: true
|
||||||
|
dependencies-cache-enabled: true
|
||||||
|
# Configuration cache requires dependencies cache, since it assumes dependencies are already downloaded.
|
||||||
|
|
||||||
|
|
||||||
failures: # These build invocations are informational only, and are expected to fail
|
failures: # These build invocations are informational only, and are expected to fail
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
22
README.md
22
README.md
|
@ -60,14 +60,6 @@ If you need to pass environment variables, simply use the GitHub Actions workflo
|
||||||
build-root-directory: some/subdirectory
|
build-root-directory: some/subdirectory
|
||||||
```
|
```
|
||||||
|
|
||||||
## Use a Gradle wrapper from a different directory
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- uses: eskatos/gradle-command-action@v1
|
|
||||||
with:
|
|
||||||
wrapper-directory: path/to/wrapper-directory
|
|
||||||
```
|
|
||||||
|
|
||||||
## Use a specific `gradle` executable
|
## Use a specific `gradle` executable
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -76,6 +68,16 @@ If you need to pass environment variables, simply use the GitHub Actions workflo
|
||||||
gradle-executable: path/to/gradle
|
gradle-executable: path/to/gradle
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Use a Gradle wrapper from a different directory
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- uses: eskatos/gradle-command-action@v1
|
||||||
|
with:
|
||||||
|
gradle-executable: path/to/gradlew
|
||||||
|
```
|
||||||
|
|
||||||
|
NOTE: The `wrapper-directory` input has been deprecated. Use `gradle-executable` instead.
|
||||||
|
|
||||||
## Setup and use a declared Gradle version
|
## Setup and use a declared Gradle version
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -92,7 +94,7 @@ Moreover, you can use the following aliases:
|
||||||
| --- |---|
|
| --- |---|
|
||||||
| `wrapper` | The Gradle wrapper's version (default, useful for matrix builds) |
|
| `wrapper` | The Gradle wrapper's version (default, useful for matrix builds) |
|
||||||
| `current` | The current [stable release](https://gradle.org/install/) |
|
| `current` | The current [stable release](https://gradle.org/install/) |
|
||||||
| `rc` | The current [release candidate](https://gradle.org/release-candidate/) if any, otherwise fallback to `current` |
|
| `release-candidate` | The current [release candidate](https://gradle.org/release-candidate/) if any, otherwise fallback to `current` |
|
||||||
| `nightly` | The latest [nightly](https://gradle.org/nightly/), fails if none. |
|
| `nightly` | The latest [nightly](https://gradle.org/nightly/), fails if none. |
|
||||||
| `release-nightly` | The latest [release nightly](https://gradle.org/release-nightly/), fails if none. |
|
| `release-nightly` | The latest [release nightly](https://gradle.org/release-nightly/), fails if none. |
|
||||||
|
|
||||||
|
@ -114,7 +116,7 @@ jobs:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
- uses: eskatos/gradle-command-action@v1
|
- uses: eskatos/gradle-command-action@v1
|
||||||
with:
|
with:
|
||||||
gradle-version: rc
|
gradle-version: release-candidate
|
||||||
arguments: build --dry-run # just test build configuration
|
arguments: build --dry-run # just test build configuration
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ inputs:
|
||||||
wrapper-directory:
|
wrapper-directory:
|
||||||
description: Path to the Gradle Wrapper directory
|
description: Path to the Gradle Wrapper directory
|
||||||
required: false
|
required: false
|
||||||
|
deprecationMessage: Use 'gradle-executable' to point to a gradlew[.bat] file in a non-default location
|
||||||
gradle-executable:
|
gradle-executable:
|
||||||
description: Path to the Gradle executable
|
description: Path to the Gradle executable
|
||||||
required: false
|
required: false
|
||||||
|
@ -23,28 +24,34 @@ inputs:
|
||||||
distributions-cache-enabled:
|
distributions-cache-enabled:
|
||||||
description: Whether caching downloaded Gradle distributions is enabled or not, default to 'true'
|
description: Whether caching downloaded Gradle distributions is enabled or not, default to 'true'
|
||||||
required: false
|
required: false
|
||||||
|
default: true
|
||||||
wrapper-cache-enabled:
|
wrapper-cache-enabled:
|
||||||
description: Whether caching wrapper installation is enabled or not, default to 'true'
|
description: Whether caching wrapper installation is enabled or not, default to 'true'
|
||||||
required: false
|
required: false
|
||||||
|
default: true
|
||||||
deprecationMessage: Replaced by 'distributions-cache-enabled' which enables caching for all downloaded Gradle distributions
|
deprecationMessage: Replaced by 'distributions-cache-enabled' which enables caching for all downloaded Gradle distributions
|
||||||
dependencies-cache-enabled:
|
dependencies-cache-enabled:
|
||||||
description: Whether caching dependencies is enabled or not, default to 'false'
|
description: Whether caching dependencies is enabled or not, default to 'false'
|
||||||
required: false
|
required: false
|
||||||
|
default: false
|
||||||
dependencies-cache-key:
|
dependencies-cache-key:
|
||||||
description: Globs of files to hash in the build root directory, separated by new lines, use best-effort if unset
|
description: Globs of files to hash in the build root directory, separated by new lines, use best-effort if unset
|
||||||
required: false
|
required: false
|
||||||
dependencies-cache-exact:
|
dependencies-cache-exact:
|
||||||
description: Whether to restore only if exact match, default to 'false'
|
description: Whether to restore only if exact match, default to 'false'
|
||||||
required: false
|
required: false
|
||||||
|
default: false
|
||||||
configuration-cache-enabled:
|
configuration-cache-enabled:
|
||||||
description: Whether caching build configuration is enabled or not, default to 'false'
|
description: Whether caching build configuration is enabled or not, default to 'false'
|
||||||
required: false
|
required: false
|
||||||
|
default: false
|
||||||
configuration-cache-key:
|
configuration-cache-key:
|
||||||
description: Globs of files to hash in the build root directory, separated by new lines, use best-effort if unset
|
description: Globs of files to hash in the build root directory, separated by new lines, use best-effort if unset
|
||||||
required: false
|
required: false
|
||||||
configuration-cache-exact:
|
configuration-cache-exact:
|
||||||
description: Whether to restore only if exact match, default to 'false'
|
description: Whether to restore only if exact match, default to 'false'
|
||||||
required: false
|
required: false
|
||||||
|
default: false
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
build-scan-url:
|
build-scan-url:
|
||||||
|
|
2
dist/main/index.js
vendored
2
dist/main/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/post/index.js
vendored
2
dist/post/index.js
vendored
File diff suppressed because one or more lines are too long
|
@ -4,7 +4,6 @@ import fs from 'fs'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as cache from '@actions/cache'
|
import * as cache from '@actions/cache'
|
||||||
|
|
||||||
import * as github from './github-utils'
|
|
||||||
import * as crypto from './crypto-utils'
|
import * as crypto from './crypto-utils'
|
||||||
|
|
||||||
import {inputCacheKeyGlobs, tryDeleteFiles} from './cache-dependencies'
|
import {inputCacheKeyGlobs, tryDeleteFiles} from './cache-dependencies'
|
||||||
|
@ -22,7 +21,7 @@ export async function restoreCachedConfiguration(
|
||||||
if (fs.existsSync(cachePath)) return
|
if (fs.existsSync(cachePath)) return
|
||||||
core.saveState(CONFIGURATION_CACHE_PATH, cachePath)
|
core.saveState(CONFIGURATION_CACHE_PATH, cachePath)
|
||||||
|
|
||||||
const inputCacheExact = github.inputBoolean('configuration-cache-exact')
|
const inputCacheExact = core.getBooleanInput('configuration-cache-exact')
|
||||||
const cacheKeyGlobs = inputCacheKeyGlobs('configuration-cache-key')
|
const cacheKeyGlobs = inputCacheKeyGlobs('configuration-cache-key')
|
||||||
|
|
||||||
const hash = await crypto.hashFiles(rootDir, cacheKeyGlobs)
|
const hash = await crypto.hashFiles(rootDir, cacheKeyGlobs)
|
||||||
|
@ -93,5 +92,5 @@ export async function cacheConfiguration(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
function isConfigurationCacheDisabled(): boolean {
|
function isConfigurationCacheDisabled(): boolean {
|
||||||
return !github.inputBoolean('configuration-cache-enabled', false)
|
return !core.getBooleanInput('configuration-cache-enabled')
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import * as os from 'os'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as cache from '@actions/cache'
|
import * as cache from '@actions/cache'
|
||||||
|
|
||||||
import * as github from './github-utils'
|
|
||||||
import * as crypto from './crypto-utils'
|
import * as crypto from './crypto-utils'
|
||||||
|
|
||||||
const DEPENDENCIES_CACHE_PATH = 'DEPENDENCIES_CACHE_PATH'
|
const DEPENDENCIES_CACHE_PATH = 'DEPENDENCIES_CACHE_PATH'
|
||||||
|
@ -21,7 +20,7 @@ export async function restoreCachedDependencies(
|
||||||
if (fs.existsSync(cachePath)) return
|
if (fs.existsSync(cachePath)) return
|
||||||
core.saveState(DEPENDENCIES_CACHE_PATH, cachePath)
|
core.saveState(DEPENDENCIES_CACHE_PATH, cachePath)
|
||||||
|
|
||||||
const inputCacheExact = github.inputBoolean('dependencies-cache-exact')
|
const inputCacheExact = core.getBooleanInput('dependencies-cache-exact')
|
||||||
const cacheKeyGlobs = inputCacheKeyGlobs('dependencies-cache-key')
|
const cacheKeyGlobs = inputCacheKeyGlobs('dependencies-cache-key')
|
||||||
|
|
||||||
const hash = await crypto.hashFiles(rootDir, cacheKeyGlobs)
|
const hash = await crypto.hashFiles(rootDir, cacheKeyGlobs)
|
||||||
|
@ -104,12 +103,12 @@ export function tryDeleteFiles(filePaths: string[]): boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDependenciesCacheDisabled(): boolean {
|
function isDependenciesCacheDisabled(): boolean {
|
||||||
return !github.inputBoolean('dependencies-cache-enabled', false)
|
return !core.getBooleanInput('dependencies-cache-enabled')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function inputCacheKeyGlobs(input: string): string[] {
|
export function inputCacheKeyGlobs(input: string): string[] {
|
||||||
const inputValue = github.inputArrayOrNull(input)
|
const inputValue = core.getMultilineInput(input)
|
||||||
return inputValue
|
return inputValue.length > 0
|
||||||
? inputValue
|
? inputValue
|
||||||
: [
|
: [
|
||||||
'**/*.gradle',
|
'**/*.gradle',
|
||||||
|
|
|
@ -5,8 +5,6 @@ import * as os from 'os'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as cache from '@actions/cache'
|
import * as cache from '@actions/cache'
|
||||||
|
|
||||||
import * as github from './github-utils'
|
|
||||||
|
|
||||||
const WRAPPER_SLUG = 'WRAPPER_SLUG'
|
const WRAPPER_SLUG = 'WRAPPER_SLUG'
|
||||||
|
|
||||||
export async function restoreCachedWrapperDist(
|
export async function restoreCachedWrapperDist(
|
||||||
|
@ -108,13 +106,9 @@ export function extractGradleWrapperSlugFromDistUri(
|
||||||
|
|
||||||
function isWrapperCacheDisabled(): boolean {
|
function isWrapperCacheDisabled(): boolean {
|
||||||
// Check if either 'distributions' or 'wrapper' cache has been disabled
|
// Check if either 'distributions' or 'wrapper' cache has been disabled
|
||||||
const wrapperCacheEnabled = github.inputBoolean(
|
const wrapperCacheEnabled = core.getBooleanInput('wrapper-cache-enabled')
|
||||||
'wrapper-cache-enabled',
|
const distributionsCacheEnabled = core.getBooleanInput(
|
||||||
true
|
'distributions-cache-enabled'
|
||||||
)
|
|
||||||
const distributionsCacheEnabled = github.inputBoolean(
|
|
||||||
'distributions-cache-enabled',
|
|
||||||
true
|
|
||||||
)
|
)
|
||||||
return !wrapperCacheEnabled || !distributionsCacheEnabled
|
return !wrapperCacheEnabled || !distributionsCacheEnabled
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
import * as core from '@actions/core'
|
|
||||||
|
|
||||||
export function inputOrNull(name: string): string | null {
|
|
||||||
const inputString = core.getInput(name, {required: false})
|
|
||||||
if (inputString.length === 0) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return inputString
|
|
||||||
}
|
|
||||||
|
|
||||||
export function inputArrayOrNull(name: string): string[] | null {
|
|
||||||
const string = inputOrNull(name)
|
|
||||||
if (!string) return null
|
|
||||||
return string
|
|
||||||
.split('\n')
|
|
||||||
.map(s => s.trim())
|
|
||||||
.filter(s => s !== '')
|
|
||||||
}
|
|
||||||
|
|
||||||
export function inputBoolean(name: string, defaultValue = false): boolean {
|
|
||||||
const string = inputOrNull(name)
|
|
||||||
if (!string) return defaultValue
|
|
||||||
return string === 'true'
|
|
||||||
}
|
|
21
src/main.ts
21
src/main.ts
|
@ -2,7 +2,6 @@ import * as core from '@actions/core'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import {parseArgsStringToArgv} from 'string-argv'
|
import {parseArgsStringToArgv} from 'string-argv'
|
||||||
|
|
||||||
import * as github from './github-utils'
|
|
||||||
import * as cacheWrapper from './cache-wrapper'
|
import * as cacheWrapper from './cache-wrapper'
|
||||||
import * as execution from './execution'
|
import * as execution from './execution'
|
||||||
import * as gradlew from './gradlew'
|
import * as gradlew from './gradlew'
|
||||||
|
@ -41,13 +40,13 @@ async function resolveGradleExecutable(
|
||||||
workspaceDirectory: string,
|
workspaceDirectory: string,
|
||||||
buildRootDirectory: string
|
buildRootDirectory: string
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const gradleVersion = github.inputOrNull('gradle-version')
|
const gradleVersion = core.getInput('gradle-version')
|
||||||
if (gradleVersion !== null && gradleVersion !== 'wrapper') {
|
if (gradleVersion !== '' && gradleVersion !== 'wrapper') {
|
||||||
return path.resolve(await provision.gradleVersion(gradleVersion))
|
return path.resolve(await provision.gradleVersion(gradleVersion))
|
||||||
}
|
}
|
||||||
|
|
||||||
const gradleExecutable = github.inputOrNull('gradle-executable')
|
const gradleExecutable = core.getInput('gradle-executable')
|
||||||
if (gradleExecutable !== null) {
|
if (gradleExecutable !== '') {
|
||||||
if (gradleExecutable.endsWith(gradlew.wrapperFilename())) {
|
if (gradleExecutable.endsWith(gradlew.wrapperFilename())) {
|
||||||
await cacheWrapper.restoreCachedWrapperDist(
|
await cacheWrapper.restoreCachedWrapperDist(
|
||||||
path.resolve(gradleExecutable, '..')
|
path.resolve(gradleExecutable, '..')
|
||||||
|
@ -56,9 +55,9 @@ async function resolveGradleExecutable(
|
||||||
return path.resolve(workspaceDirectory, gradleExecutable)
|
return path.resolve(workspaceDirectory, gradleExecutable)
|
||||||
}
|
}
|
||||||
|
|
||||||
const wrapperDirectory = github.inputOrNull('wrapper-directory')
|
const wrapperDirectory = core.getInput('wrapper-directory')
|
||||||
const gradlewDirectory =
|
const gradlewDirectory =
|
||||||
wrapperDirectory !== null
|
wrapperDirectory !== ''
|
||||||
? path.resolve(workspaceDirectory, wrapperDirectory)
|
? path.resolve(workspaceDirectory, wrapperDirectory)
|
||||||
: buildRootDirectory
|
: buildRootDirectory
|
||||||
|
|
||||||
|
@ -69,15 +68,15 @@ async function resolveGradleExecutable(
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveBuildRootDirectory(baseDirectory: string): string {
|
function resolveBuildRootDirectory(baseDirectory: string): string {
|
||||||
const buildRootDirectory = github.inputOrNull('build-root-directory')
|
const buildRootDirectory = core.getInput('build-root-directory')
|
||||||
const resolvedBuildRootDirectory =
|
const resolvedBuildRootDirectory =
|
||||||
buildRootDirectory === null
|
buildRootDirectory === ''
|
||||||
? path.resolve(baseDirectory)
|
? path.resolve(baseDirectory)
|
||||||
: path.resolve(baseDirectory, buildRootDirectory)
|
: path.resolve(baseDirectory, buildRootDirectory)
|
||||||
return resolvedBuildRootDirectory
|
return resolvedBuildRootDirectory
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseCommandLineArguments(): string[] {
|
function parseCommandLineArguments(): string[] {
|
||||||
const input = github.inputOrNull('arguments')
|
const input = core.getInput('arguments')
|
||||||
return input === null ? [] : parseArgsStringToArgv(input)
|
return parseArgsStringToArgv(input)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import * as cache from '@actions/cache'
|
||||||
import * as toolCache from '@actions/tool-cache'
|
import * as toolCache from '@actions/tool-cache'
|
||||||
|
|
||||||
import * as gradlew from './gradlew'
|
import * as gradlew from './gradlew'
|
||||||
import * as github from './github-utils'
|
|
||||||
|
|
||||||
const gradleVersionsBaseUrl = 'https://services.gradle.org/versions'
|
const gradleVersionsBaseUrl = 'https://services.gradle.org/versions'
|
||||||
|
|
||||||
|
@ -19,6 +18,11 @@ export async function gradleVersion(version: string): Promise<string> {
|
||||||
case 'current':
|
case 'current':
|
||||||
return gradleCurrent()
|
return gradleCurrent()
|
||||||
case 'rc':
|
case 'rc':
|
||||||
|
core.warning(
|
||||||
|
`Specifying gradle-version 'rc' has been deprecated. Use 'release-candidate' instead.`
|
||||||
|
)
|
||||||
|
return gradleReleaseCandidate()
|
||||||
|
case 'release-candidate':
|
||||||
return gradleReleaseCandidate()
|
return gradleReleaseCandidate()
|
||||||
case 'nightly':
|
case 'nightly':
|
||||||
return gradleNightly()
|
return gradleNightly()
|
||||||
|
@ -180,7 +184,7 @@ async function httpGetString(url: string): Promise<string> {
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDistributionsCacheDisabled(): boolean {
|
function isDistributionsCacheDisabled(): boolean {
|
||||||
return !github.inputBoolean('distributions-cache-enabled', true)
|
return !core.getBooleanInput('distributions-cache-enabled')
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GradleVersionInfo {
|
interface GradleVersionInfo {
|
||||||
|
|
Loading…
Reference in a new issue