mirror of
https://github.com/gradle/gradle-build-action.git
synced 2025-10-21 00:08:55 +08:00
Compare commits
120 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
3f3947669a | ||
|
579711fd3c | ||
|
7336529ec5 | ||
|
88af98fab4 | ||
|
01bfa29846 | ||
|
0206df026c | ||
|
41aebc770d | ||
|
bc4d6bddd4 | ||
|
1f57b4dd2d | ||
|
02d4f46354 | ||
|
b9684c0cf5 | ||
|
5423935c9b | ||
|
41ca2299a5 | ||
|
33e91b639d | ||
|
e4ec586f46 | ||
|
15a8123fbc | ||
|
f0c6ac01d3 | ||
|
63fea55da4 | ||
|
26b92e3f5c | ||
|
643092d2fc | ||
|
18c8a679dc | ||
|
13d33a88ca | ||
|
738bda9866 | ||
|
47c9af9d7d | ||
|
3fba6132b4 | ||
|
127b9b6624 | ||
|
8189d29e96 | ||
|
eb7aa853fa | ||
|
15bf8034d6 | ||
|
6bf2690b23 | ||
|
ced6c34563 | ||
|
2efcc22ff5 | ||
|
cb2742a00b | ||
|
c8c53f54bb | ||
|
863daedf86 | ||
|
55871cbb47 | ||
|
e3d60b3873 | ||
|
2dd6cc1801 | ||
|
f11e7d60d7 | ||
|
7137b09ae2 | ||
|
053f389907 | ||
|
4f9b5202aa | ||
|
466a737d16 | ||
|
eb7eb78d95 | ||
|
682d7347f7 | ||
|
3c43b6525f | ||
|
aefd8348d2 | ||
|
f2de61db4e | ||
|
4c7d97cca4 | ||
|
806543fb3a | ||
|
2afa86ca9f | ||
|
ae50675399 | ||
|
d7a54a26c7 | ||
|
02a8a21e55 | ||
|
3abad5567a | ||
|
7c8cc1a9ef | ||
|
355e9c1f86 | ||
|
26dd4cb9bb | ||
|
317ca35dca | ||
|
053762c1c1 | ||
|
95e20daa83 | ||
|
fcc1683d01 | ||
|
059f2e7791 | ||
|
692fda9de7 | ||
|
e8885a31b8 | ||
|
12e24e843d | ||
|
b35e929b1d | ||
|
c839ac993c | ||
|
83e6d042d7 | ||
|
b995a7b937 | ||
|
1c1db193aa | ||
|
9675f09de6 | ||
|
392bcac1c1 | ||
|
a2ba1beedb | ||
|
42e2fed267 | ||
|
8e2fd532f1 | ||
|
2bf5eec3b6 | ||
|
43efc20423 | ||
|
4a9a0a05a3 | ||
|
1647b85e82 | ||
|
6cee865aea | ||
|
5c61ab77ec | ||
|
a31de8476d | ||
|
b2c379621c | ||
|
04a5ee4df2 | ||
|
a188e7cd61 | ||
|
e0644c97f9 | ||
|
9cc76cdea7 | ||
|
b55d63f1f8 | ||
|
8f6be44bf5 | ||
|
469bf6123e | ||
|
9cbb22e130 | ||
|
4c65920ab9 | ||
|
bad0f7d376 | ||
|
ab09ae8fad | ||
|
2f66fb5679 | ||
|
1a6a8efda2 | ||
|
e5b01ed062 | ||
|
3d5e31b7a4 | ||
|
4336c6b886 | ||
|
f25026ba74 | ||
|
9f5ce3593a | ||
|
a5009d1aec | ||
|
ae5079ecac | ||
|
38fdc3f684 | ||
|
0821518fd9 | ||
|
c8b76ea3f7 | ||
|
bf26498bc4 | ||
|
15e064da79 | ||
|
c5e1979a6b | ||
|
dc882d2669 | ||
|
f9f0422c72 | ||
|
38eaee068d | ||
|
0a56b592f2 | ||
|
091093ee61 | ||
|
7a4f128c22 | ||
|
f943246fd9 | ||
|
8337949d80 | ||
|
76166f0035 | ||
|
a9718db8ba |
3
.eslintignore
Normal file
3
.eslintignore
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
dist/
|
||||||
|
lib/
|
||||||
|
node_modules/
|
52
.eslintrc.json
Normal file
52
.eslintrc.json
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["jest", "@typescript-eslint"],
|
||||||
|
"extends": ["plugin:github/recommended"],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 9,
|
||||||
|
"sourceType": "module",
|
||||||
|
"project": "./tsconfig.json"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"eslint-comments/no-use": "off",
|
||||||
|
"import/no-namespace": "off",
|
||||||
|
"no-unused-vars": "off",
|
||||||
|
"@typescript-eslint/no-unused-vars": "error",
|
||||||
|
"@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}],
|
||||||
|
"@typescript-eslint/no-require-imports": "error",
|
||||||
|
"@typescript-eslint/array-type": "error",
|
||||||
|
"@typescript-eslint/await-thenable": "error",
|
||||||
|
"camelcase": "off",
|
||||||
|
"@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
|
||||||
|
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
||||||
|
"@typescript-eslint/no-array-constructor": "error",
|
||||||
|
"@typescript-eslint/no-empty-interface": "error",
|
||||||
|
"@typescript-eslint/no-explicit-any": "error",
|
||||||
|
"@typescript-eslint/no-extraneous-class": "error",
|
||||||
|
"@typescript-eslint/no-for-in-array": "error",
|
||||||
|
"@typescript-eslint/no-inferrable-types": "error",
|
||||||
|
"@typescript-eslint/no-misused-new": "error",
|
||||||
|
"@typescript-eslint/no-namespace": "error",
|
||||||
|
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||||
|
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
||||||
|
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
||||||
|
"@typescript-eslint/no-useless-constructor": "error",
|
||||||
|
"@typescript-eslint/no-var-requires": "error",
|
||||||
|
"@typescript-eslint/prefer-for-of": "warn",
|
||||||
|
"@typescript-eslint/prefer-function-type": "warn",
|
||||||
|
"@typescript-eslint/prefer-includes": "error",
|
||||||
|
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
||||||
|
"@typescript-eslint/promise-function-async": "error",
|
||||||
|
"@typescript-eslint/require-array-sort-compare": ["error", {"ignoreStringArrays": true}],
|
||||||
|
"@typescript-eslint/restrict-plus-operands": "error",
|
||||||
|
"semi": "off",
|
||||||
|
"@typescript-eslint/semi": ["error", "never"],
|
||||||
|
"@typescript-eslint/type-annotation-spacing": "error",
|
||||||
|
"@typescript-eslint/unbound-method": "error"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"node": true,
|
||||||
|
"es6": true,
|
||||||
|
"jest/globals": true
|
||||||
|
}
|
||||||
|
}
|
@@ -1,25 +1,24 @@
|
|||||||
name: "PR Checks"
|
# make sure the build works and doesn't produce spurious changes
|
||||||
on: [pull_request, push]
|
name: dev
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check_pr:
|
check:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v2
|
||||||
- name: "npm ci"
|
- name: Build
|
||||||
run: npm ci
|
run: |
|
||||||
|
npm install
|
||||||
- name: "npm run build"
|
npm run all
|
||||||
run: npm run build
|
- name: Check for uncommitted changes
|
||||||
|
|
||||||
- name: "npm run test"
|
|
||||||
run: npm run test
|
|
||||||
|
|
||||||
- name: "check for uncommitted changes"
|
|
||||||
# Ensure no changes, but ignore node_modules dir since dev/fresh ci deps installed.
|
# Ensure no changes, but ignore node_modules dir since dev/fresh ci deps installed.
|
||||||
run: |
|
run: |
|
||||||
git diff --exit-code --stat -- . ':!node_modules' \
|
git diff --exit-code --stat -- . ':!node_modules' \
|
||||||
|| (echo "##[error] found changed files after build. please 'npm run build && npm run format'" \
|
|| (echo "##[error] found changed files after build. please 'npm run all'" \
|
||||||
"and check in all changes" \
|
"and check in all changes" \
|
||||||
&& exit 1)
|
&& exit 1)
|
93
.github/workflows/prod.yml
vendored
Normal file
93
.github/workflows/prod.yml
vendored
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
# make sure the action works on a clean machine without building
|
||||||
|
name: prod
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
gradle-execution:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
include:
|
||||||
|
- os: windows-latest
|
||||||
|
script-suffix: '.bat'
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Test use Gradle wrapper
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
build-root-directory: __tests__/samples/basic
|
||||||
|
arguments: test
|
||||||
|
- name: Test use defined Gradle version
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
gradle-version: 6.9
|
||||||
|
build-root-directory: __tests__/samples/no-wrapper
|
||||||
|
arguments: help
|
||||||
|
- name: Test use Gradle version alias
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
gradle-version: release-candidate
|
||||||
|
build-root-directory: __tests__/samples/no-wrapper
|
||||||
|
arguments: help
|
||||||
|
- name: Test use defined Gradle executable
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
gradle-executable: __tests__/samples/basic/gradlew${{ matrix.script-suffix }}
|
||||||
|
build-root-directory: __tests__/samples/no-wrapper
|
||||||
|
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
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Test wrapper missing
|
||||||
|
uses: ./
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
build-root-directory: __tests__/samples/no-wrapper
|
||||||
|
arguments: help
|
20
.gitignore
vendored
20
.gitignore
vendored
@@ -1,5 +1,5 @@
|
|||||||
__tests__/runner/*
|
# Dependency directory
|
||||||
lib/
|
node_modules
|
||||||
|
|
||||||
# Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
# Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
||||||
# Logs
|
# Logs
|
||||||
@@ -42,7 +42,6 @@ bower_components
|
|||||||
build/Release
|
build/Release
|
||||||
|
|
||||||
# Dependency directories
|
# Dependency directories
|
||||||
node_modules/
|
|
||||||
jspm_packages/
|
jspm_packages/
|
||||||
|
|
||||||
# TypeScript v1 declaration files
|
# TypeScript v1 declaration files
|
||||||
@@ -90,3 +89,18 @@ typings/
|
|||||||
|
|
||||||
# DynamoDB Local files
|
# DynamoDB Local files
|
||||||
.dynamodb/
|
.dynamodb/
|
||||||
|
|
||||||
|
# OS metadata
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Ignore built ts files
|
||||||
|
__tests__/runner/*
|
||||||
|
# lib/**/*
|
||||||
|
|
||||||
|
# IntelliJ IDEA config files
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# ASDF tool configuration
|
||||||
|
.tool-versions
|
||||||
|
3
.prettierignore
Normal file
3
.prettierignore
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
dist/
|
||||||
|
lib/
|
||||||
|
node_modules/
|
11
.prettierrc.json
Normal file
11
.prettierrc.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 80,
|
||||||
|
"tabWidth": 4,
|
||||||
|
"useTabs": false,
|
||||||
|
"semi": false,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"bracketSpacing": false,
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"parser": "typescript"
|
||||||
|
}
|
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as
|
||||||
|
contributors and maintainers pledge to making participation in our project and
|
||||||
|
our community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||||
|
level of experience, education, socio-economic status, nationality, personal
|
||||||
|
appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment
|
||||||
|
include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||||
|
advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic
|
||||||
|
address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable
|
||||||
|
behavior and are expected to take appropriate and fair corrective action in
|
||||||
|
response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces
|
||||||
|
when an individual is representing the project or its community. Examples of
|
||||||
|
representing a project or community include using an official project e-mail
|
||||||
|
address, posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event. Representation of a project may be
|
||||||
|
further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting the project team at paul@nosphere.org. All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. The project team is
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||||
|
faith may face temporary or permanent repercussions as determined by other
|
||||||
|
members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||||
|
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see
|
||||||
|
https://www.contributor-covenant.org/faq
|
172
README.md
172
README.md
@@ -1,16 +1,15 @@
|
|||||||
# Execute Gradle commands in Github Actions workflows
|
# Execute Gradle builds in GitHub Actions workflows
|
||||||
|
|
||||||
This Github Action can be used to run arbitrary Gradle commands on any platform supported by Github Actions.
|
|
||||||
|
|
||||||
|
This GitHub Action can be used to execute a Gradle build on any platform supported by GitHub Actions.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The following workflow will run `gradle build` using the wrapper from the repository on ubuntu, macos and windows:
|
The following workflow will run `./gradlew build` using the wrapper from the repository on ubuntu, macos and windows. The only prerequisite is to have Java installed: you define the version of Java you need to run the build using the `actions/setup-java` action.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
// .github/workflows/gradle-build-pr.yml
|
# .github/workflows/gradle-build-pr.yml
|
||||||
name: Run Gradle on PRs
|
name: Run Gradle on PRs
|
||||||
on: pull-request
|
on: pull_request
|
||||||
jobs:
|
jobs:
|
||||||
gradle:
|
gradle:
|
||||||
strategy:
|
strategy:
|
||||||
@@ -18,11 +17,11 @@ jobs:
|
|||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
- uses: eskatos/gradle-command-action@v1
|
- uses: gradle/gradle-build-action@v1
|
||||||
with:
|
with:
|
||||||
arguments: build
|
arguments: build
|
||||||
```
|
```
|
||||||
@@ -43,10 +42,10 @@ arguments: build -DsystemProperty=bar
|
|||||||
|
|
||||||
See `gradle --help` for more information.
|
See `gradle --help` for more information.
|
||||||
|
|
||||||
If you need to pass environment variables, simply use the Github Actions workflow syntax:
|
If you need to pass environment variables, simply use the GitHub Actions workflow syntax:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: eskatos/gradle-command-action@v1
|
- uses: gradle/gradle-build-action@v1
|
||||||
env:
|
env:
|
||||||
CI: true
|
CI: true
|
||||||
```
|
```
|
||||||
@@ -54,33 +53,35 @@ If you need to pass environment variables, simply use the Github Actions workflo
|
|||||||
## Run a build from a different directory
|
## Run a build from a different directory
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: eskatos/gradle-command-action@v1
|
- uses: gradle/gradle-build-action@v1
|
||||||
with:
|
with:
|
||||||
build-root-directory: some/subdirectory
|
build-root-directory: some/subdirectory
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Use a specific `gradle` executable
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- uses: gradle/gradle-build-action@v1
|
||||||
|
with:
|
||||||
|
gradle-executable: path/to/gradle
|
||||||
|
```
|
||||||
|
|
||||||
## Use a Gradle wrapper from a different directory
|
## Use a Gradle wrapper from a different directory
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: eskatos/gradle-command-action@v1
|
- uses: gradle/gradle-build-action@v1
|
||||||
with:
|
with:
|
||||||
wrapper-directory: path/to/wrapper-directory
|
gradle-executable: path/to/gradlew
|
||||||
```
|
```
|
||||||
|
|
||||||
## Use a specific `gradle` executable
|
NOTE: The `wrapper-directory` input has been deprecated. Use `gradle-executable` instead.
|
||||||
|
|
||||||
```yaml
|
|
||||||
- uses: eskatos/gradle-command-action@v1
|
|
||||||
with:
|
|
||||||
gradle-executable: path/to/gradle
|
|
||||||
```
|
|
||||||
|
|
||||||
## Setup and use a declared Gradle version
|
## Setup and use a declared Gradle version
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: eskatos/gradle-command-action@v1
|
- uses: gradle/gradle-build-action@v1
|
||||||
with:
|
with:
|
||||||
gradle-version: 5.6.2
|
gradle-version: 6.5
|
||||||
```
|
```
|
||||||
|
|
||||||
`gradle-version` can be set to any valid Gradle version.
|
`gradle-version` can be set to any valid Gradle version.
|
||||||
@@ -89,15 +90,16 @@ Moreover, you can use the following aliases:
|
|||||||
|
|
||||||
| Alias | Selects |
|
| Alias | Selects |
|
||||||
| --- |---|
|
| --- |---|
|
||||||
| `current` | The current [stable release](https://gradle.org/install/) |
|
| `wrapper` | The Gradle wrapper's version (default, useful for matrix builds) |
|
||||||
| `rc` | The current [release candidate](https://gradle.org/release-candidate/) if any, otherwise fallback to `current` |
|
| `current` | The current [stable release](https://gradle.org/install/) |
|
||||||
| `nightly` | The latest [nightly](https://gradle.org/nightly/), fails if none. |
|
| `release-candidate` | The current [release candidate](https://gradle.org/release-candidate/) if any, otherwise fallback to `current` |
|
||||||
| `release-nightly` | The latest [release nightly](https://gradle.org/release-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. |
|
||||||
|
|
||||||
This can be handy to automatically test your build with the next Gradle version once a release candidate is out:
|
This can be handy to, for example, automatically test your build with the next Gradle version once a release candidate is out:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
// .github/workflows/test-gradle-rc.yml
|
# .github/workflows/test-gradle-rc.yml
|
||||||
name: Test latest Gradle RC
|
name: Test latest Gradle RC
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
@@ -106,18 +108,122 @@ jobs:
|
|||||||
gradle-rc:
|
gradle-rc:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
- uses: eskatos/gradle-command-action@v1
|
- uses: gradle/gradle-build-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
|
||||||
```
|
```
|
||||||
|
|
||||||
# Build scans
|
## Caching
|
||||||
|
|
||||||
If your build publishes a [build scan](https://gradle.com/build-scans/) the `gradle-command-action` action will emit the link to the published build scan as an output named `build-scan-url`.
|
This action provides 3 levels of caching to help speed up your GitHub Actions:
|
||||||
|
|
||||||
|
- `distributions` caches any downloaded Gradle zips, including any downloaded [wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html) versions, saving time downloading Gradle distributions ;
|
||||||
|
- `dependencies` caches the [dependencies](https://docs.gradle.org/current/userguide/dependency_resolution.html#sub:cache_copy), saving time downloading dependencies ;
|
||||||
|
- `configuration` caches the [build configuration](https://docs.gradle.org/nightly/userguide/configuration_cache.html), saving time configuring the build.
|
||||||
|
|
||||||
|
Only the first one, caching downloaded distributions, is enabled by default.
|
||||||
|
Future versions of this action will enable all caching by default.
|
||||||
|
|
||||||
|
You can control which level is enabled as follows:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
distributions-cache-enabled: true
|
||||||
|
dependencies-cache-enabled: true
|
||||||
|
configuration-cache-enabled: true
|
||||||
|
```
|
||||||
|
|
||||||
|
NOTE: The `wrapper-cache-enabled` flag has been deprecated, replaced by `distributions-cache-enabled` which enables caching for all downloaded distributions, including Gradle wrapper downloads.
|
||||||
|
|
||||||
|
The distributions cache is simple and can't be configured further.
|
||||||
|
|
||||||
|
The dependencies and configuration cache will compute a cache key in a best effort manner.
|
||||||
|
Keep reading to learn how to better control how they work.
|
||||||
|
|
||||||
|
Note that enabling configuration cache without thee dependencies cache is not permitted, since a hit in the configuration cache assumes that dependencies are already present in the local dependencies cache.
|
||||||
|
|
||||||
|
### Configuring the dependencies and configuration caches
|
||||||
|
|
||||||
|
Both the dependencies and configuration caches use the same default configuration:
|
||||||
|
|
||||||
|
They use the following inputs to calculate the cache key:
|
||||||
|
|
||||||
|
```text
|
||||||
|
**/*.gradle
|
||||||
|
**/*.gradle.kts
|
||||||
|
**/gradle.properties
|
||||||
|
gradle/**
|
||||||
|
```
|
||||||
|
|
||||||
|
This is a good enough approximation.
|
||||||
|
They restore cached state even if there isn't an exact match.
|
||||||
|
|
||||||
|
If the defaults don't suit your needs you can override them with the following inputs:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
dependencies-cache-key: |
|
||||||
|
**/gradle.properties
|
||||||
|
gradle/dependency-locks/**
|
||||||
|
dependencies-cache-exact: true
|
||||||
|
configuration-cache-key: |
|
||||||
|
**/gradle.properties
|
||||||
|
gradle/dependency-locks/**
|
||||||
|
configuration-cache-exact: true
|
||||||
|
```
|
||||||
|
|
||||||
|
Coming up with a good cache key isn't trivial and depends on your build.
|
||||||
|
The above example isn't realistic.
|
||||||
|
Stick to the defaults unless you know what you are doing.
|
||||||
|
|
||||||
|
If you happen to use Gradle [dependency locking](https://docs.gradle.org/current/userguide/dependency_locking.html) you can make the dependencies cache more precise with the following configuration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
dependencies-cache-enabled: true
|
||||||
|
dependencies-cache-key: gradle/dependency-locks/**
|
||||||
|
dependencies-cache-exact: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build scans
|
||||||
|
|
||||||
|
If your build publishes a [build scan](https://gradle.com/build-scans/) the `gradle-build-action` action will emit the link to the published build scan as an output named `build-scan-url`.
|
||||||
|
|
||||||
You can then use that link in subsequent actions of your workflow.
|
You can then use that link in subsequent actions of your workflow.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# .github/workflows/gradle-build-pr.yml
|
||||||
|
name: Run Gradle on PRs
|
||||||
|
on: pull_request
|
||||||
|
jobs:
|
||||||
|
gradle:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: 11
|
||||||
|
- uses: gradle/gradle-build-action@v1
|
||||||
|
with:
|
||||||
|
arguments: build
|
||||||
|
id: gradle
|
||||||
|
- name: "Comment build scan url"
|
||||||
|
uses: actions/github-script@v3
|
||||||
|
if: github.event_name == 'pull_request' && failure()
|
||||||
|
with:
|
||||||
|
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
script: |
|
||||||
|
github.issues.createComment({
|
||||||
|
issue_number: context.issue.number,
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
body: '❌ ${{ github.workflow }} failed: ${{ steps.gradle.outputs.build-scan-url }}'
|
||||||
|
})
|
||||||
|
```
|
||||||
|
33
__tests__/cache-wrapper.test.ts
Normal file
33
__tests__/cache-wrapper.test.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import * as cacheWrapper from '../src/cache-wrapper'
|
||||||
|
import * as path from 'path'
|
||||||
|
|
||||||
|
describe('cache', () => {
|
||||||
|
describe('can extract gradle wrapper slug', () => {
|
||||||
|
it('from wrapper properties file', async () => {
|
||||||
|
const version = cacheWrapper.extractGradleWrapperSlugFrom(
|
||||||
|
path.resolve(
|
||||||
|
'__tests__/data/cache-wrapper-test/gradle-wrapper.properties'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
expect(version).toBe('6.6.1-bin')
|
||||||
|
})
|
||||||
|
it('for -bin dist', async () => {
|
||||||
|
const version = cacheWrapper.extractGradleWrapperSlugFromDistUri(
|
||||||
|
'distributionUrl=https\\://services.gradle.org/distributions/gradle-6.6.1-bin.zip'
|
||||||
|
)
|
||||||
|
expect(version).toBe('6.6.1-bin')
|
||||||
|
})
|
||||||
|
it('for -all dist', async () => {
|
||||||
|
const version = cacheWrapper.extractGradleWrapperSlugFromDistUri(
|
||||||
|
'distributionUrl=https\\://services.gradle.org/distributions/gradle-6.6.1-all.zip'
|
||||||
|
)
|
||||||
|
expect(version).toBe('6.6.1-all')
|
||||||
|
})
|
||||||
|
it('for milestone', async () => {
|
||||||
|
const version = cacheWrapper.extractGradleWrapperSlugFromDistUri(
|
||||||
|
'distributionUrl=https\\://services.gradle.org/distributions/gradle-6.6-milestone-1-all.zip'
|
||||||
|
)
|
||||||
|
expect(version).toBe('6.6-milestone-1-all')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
39
__tests__/crypto-utils.test.ts
Normal file
39
__tests__/crypto-utils.test.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import * as cryptoUtils from '../src/crypto-utils'
|
||||||
|
import * as path from 'path'
|
||||||
|
|
||||||
|
describe('crypto-utils', () => {
|
||||||
|
describe('can hash', () => {
|
||||||
|
it('a directory', async () => {
|
||||||
|
const hash = await cryptoUtils.hashFiles(
|
||||||
|
path.resolve('__tests__/data/crypto-utils-test/gradle')
|
||||||
|
)
|
||||||
|
expect(hash).toBe(
|
||||||
|
process.platform === 'win32'
|
||||||
|
? '3364336e94e746ce65a31748a6371b7efd7d499e18ad605c74c91cde0edc0a44'
|
||||||
|
: '63b9f14f65d014e585099c9c274b9dcbddf5cfd1a8978e5a24efb89ff9304348'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
it('a directory with a glob', async () => {
|
||||||
|
const hash = await cryptoUtils.hashFiles(
|
||||||
|
path.resolve('__tests__/data/crypto-utils-test/'),
|
||||||
|
['gradle/**']
|
||||||
|
)
|
||||||
|
expect(hash).toBe(
|
||||||
|
process.platform === 'win32'
|
||||||
|
? '3364336e94e746ce65a31748a6371b7efd7d499e18ad605c74c91cde0edc0a44'
|
||||||
|
: '63b9f14f65d014e585099c9c274b9dcbddf5cfd1a8978e5a24efb89ff9304348'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
it('a directory with globs', async () => {
|
||||||
|
const hash = await cryptoUtils.hashFiles(
|
||||||
|
path.resolve('__tests__/data/crypto-utils-test/'),
|
||||||
|
['**/*.gradle', 'gradle/**']
|
||||||
|
)
|
||||||
|
expect(hash).toBe(
|
||||||
|
process.platform === 'win32'
|
||||||
|
? 'd9b66fded38f79f601ce745d64ed726a8df8c0b242b02bcd2c1d331f54742ad6'
|
||||||
|
: 'f42cd10636f09799f4e01cc84e7ae906cc1d9140f1446f8dcd054d19cbc44c2b'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
@@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
6
__tests__/data/crypto-utils-test/.gitattributes
vendored
Normal file
6
__tests__/data/crypto-utils-test/.gitattributes
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
# https://help.github.com/articles/dealing-with-line-endings/
|
||||||
|
#
|
||||||
|
# These are explicitly windows files and should use crlf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
|
5
__tests__/data/crypto-utils-test/.gitignore
vendored
Normal file
5
__tests__/data/crypto-utils-test/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Ignore Gradle project-specific cache directory
|
||||||
|
.gradle
|
||||||
|
|
||||||
|
# Ignore Gradle build output directory
|
||||||
|
build
|
11
__tests__/data/crypto-utils-test/build.gradle
Normal file
11
__tests__/data/crypto-utils-test/build.gradle
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testImplementation('junit:junit:4.12')
|
||||||
|
}
|
BIN
__tests__/data/crypto-utils-test/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
__tests__/data/crypto-utils-test/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
__tests__/data/crypto-utils-test/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
__tests__/data/crypto-utils-test/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
185
__tests__/data/crypto-utils-test/gradlew
vendored
Executable file
185
__tests__/data/crypto-utils-test/gradlew
vendored
Executable file
@@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=`expr $i + 1`
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
0) set -- ;;
|
||||||
|
1) set -- "$args0" ;;
|
||||||
|
2) set -- "$args0" "$args1" ;;
|
||||||
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
104
__tests__/data/crypto-utils-test/gradlew.bat
vendored
Normal file
104
__tests__/data/crypto-utils-test/gradlew.bat
vendored
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
10
__tests__/data/crypto-utils-test/settings.gradle
Normal file
10
__tests__/data/crypto-utils-test/settings.gradle
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* This file was generated by the Gradle 'init' task.
|
||||||
|
*
|
||||||
|
* The settings file is used to specify which projects to include in your build.
|
||||||
|
*
|
||||||
|
* Detailed information about configuring a multi-project build in Gradle can be found
|
||||||
|
* in the user manual at https://docs.gradle.org/6.5/userguide/multi_project_builds.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
rootProject.name = 'basic'
|
@@ -0,0 +1,10 @@
|
|||||||
|
package basic;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class BasicTest {
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
assert true;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,3 +0,0 @@
|
|||||||
describe('TODO - Add a test suite', () => {
|
|
||||||
it('TODO - Add a test', async () => {});
|
|
||||||
});
|
|
6
__tests__/samples/basic/.gitattributes
vendored
Normal file
6
__tests__/samples/basic/.gitattributes
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
# https://help.github.com/articles/dealing-with-line-endings/
|
||||||
|
#
|
||||||
|
# These are explicitly windows files and should use crlf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
|
5
__tests__/samples/basic/.gitignore
vendored
Normal file
5
__tests__/samples/basic/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Ignore Gradle project-specific cache directory
|
||||||
|
.gradle
|
||||||
|
|
||||||
|
# Ignore Gradle build output directory
|
||||||
|
build
|
11
__tests__/samples/basic/build.gradle
Normal file
11
__tests__/samples/basic/build.gradle
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testImplementation('junit:junit:4.12')
|
||||||
|
}
|
BIN
__tests__/samples/basic/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
__tests__/samples/basic/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
__tests__/samples/basic/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
__tests__/samples/basic/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
185
__tests__/samples/basic/gradlew
vendored
Executable file
185
__tests__/samples/basic/gradlew
vendored
Executable file
@@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=`expr $i + 1`
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
0) set -- ;;
|
||||||
|
1) set -- "$args0" ;;
|
||||||
|
2) set -- "$args0" "$args1" ;;
|
||||||
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
104
__tests__/samples/basic/gradlew.bat
vendored
Normal file
104
__tests__/samples/basic/gradlew.bat
vendored
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
1
__tests__/samples/basic/settings.gradle
Normal file
1
__tests__/samples/basic/settings.gradle
Normal file
@@ -0,0 +1 @@
|
|||||||
|
rootProject.name = 'basic'
|
10
__tests__/samples/basic/src/test/java/basic/BasicTest.java
Normal file
10
__tests__/samples/basic/src/test/java/basic/BasicTest.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package basic;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class BasicTest {
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
assert true;
|
||||||
|
}
|
||||||
|
}
|
6
__tests__/samples/no-wrapper/.gitattributes
vendored
Normal file
6
__tests__/samples/no-wrapper/.gitattributes
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
# https://help.github.com/articles/dealing-with-line-endings/
|
||||||
|
#
|
||||||
|
# These are explicitly windows files and should use crlf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
|
5
__tests__/samples/no-wrapper/.gitignore
vendored
Normal file
5
__tests__/samples/no-wrapper/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Ignore Gradle project-specific cache directory
|
||||||
|
.gradle
|
||||||
|
|
||||||
|
# Ignore Gradle build output directory
|
||||||
|
build
|
3
__tests__/samples/no-wrapper/settings.gradle
Normal file
3
__tests__/samples/no-wrapper/settings.gradle
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
rootProject.name = 'no-wrapper'
|
||||||
|
|
||||||
|
println "Using Gradle version: ${gradle.gradleVersion}"
|
41
action.yml
41
action.yml
@@ -1,6 +1,5 @@
|
|||||||
name: "Gradle Command"
|
name: "Gradle Build Action"
|
||||||
description: 'Execute Gradle Command Line'
|
description: 'Execute Gradle Build'
|
||||||
author: 'Paul Merlin <paul@nospere.org>'
|
|
||||||
|
|
||||||
# https://help.github.com/en/articles/metadata-syntax-for-github-actions
|
# https://help.github.com/en/articles/metadata-syntax-for-github-actions
|
||||||
|
|
||||||
@@ -8,6 +7,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
|
||||||
@@ -20,6 +20,37 @@ inputs:
|
|||||||
arguments:
|
arguments:
|
||||||
description: Gradle command line arguments, see gradle --help
|
description: Gradle command line arguments, see gradle --help
|
||||||
required: false
|
required: false
|
||||||
|
distributions-cache-enabled:
|
||||||
|
description: Whether caching downloaded Gradle distributions is enabled or not, default to 'true'
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
wrapper-cache-enabled:
|
||||||
|
description: Whether caching wrapper installation is enabled or not, default to 'true'
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
deprecationMessage: Replaced by 'distributions-cache-enabled' which enables caching for all downloaded Gradle distributions
|
||||||
|
dependencies-cache-enabled:
|
||||||
|
description: Whether caching dependencies is enabled or not, default to 'false'
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
dependencies-cache-key:
|
||||||
|
description: Globs of files to hash in the build root directory, separated by new lines, use best-effort if unset
|
||||||
|
required: false
|
||||||
|
dependencies-cache-exact:
|
||||||
|
description: Whether to restore only if exact match, default to 'false'
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
configuration-cache-enabled:
|
||||||
|
description: Whether caching build configuration is enabled or not, default to 'false'
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
configuration-cache-key:
|
||||||
|
description: Globs of files to hash in the build root directory, separated by new lines, use best-effort if unset
|
||||||
|
required: false
|
||||||
|
configuration-cache-exact:
|
||||||
|
description: Whether to restore only if exact match, default to 'false'
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
build-scan-url:
|
build-scan-url:
|
||||||
@@ -27,7 +58,9 @@ outputs:
|
|||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: 'node12'
|
using: 'node12'
|
||||||
main: 'lib/main.js'
|
main: 'dist/main/index.js'
|
||||||
|
post: 'dist/post/index.js'
|
||||||
|
post-if: success()
|
||||||
|
|
||||||
branding:
|
branding:
|
||||||
icon: 'box'
|
icon: 'box'
|
||||||
|
1
dist/main/index.js
vendored
Normal file
1
dist/main/index.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/post/index.js
vendored
Normal file
1
dist/post/index.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,11 +1,12 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
clearMocks: true,
|
clearMocks: true,
|
||||||
moduleFileExtensions: ['js', 'ts'],
|
moduleFileExtensions: ['js', 'ts', 'json'],
|
||||||
testEnvironment: 'node',
|
testEnvironment: 'node',
|
||||||
testMatch: ['**/*.test.ts'],
|
testMatch: ['**/*.test.ts'],
|
||||||
testRunner: 'jest-circus/runner',
|
testRunner: 'jest-circus/runner',
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.ts$': 'ts-jest'
|
'^.+\\.ts$': 'ts-jest'
|
||||||
},
|
},
|
||||||
verbose: true
|
verbose: true,
|
||||||
}
|
setupFilesAfterEnv: ['./jest.setup.js']
|
||||||
|
}
|
||||||
|
1
jest.setup.js
Normal file
1
jest.setup.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
jest.setTimeout(10000) // in milliseconds
|
7414
package-lock.json
generated
7414
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
51
package.json
51
package.json
@@ -1,15 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "gradle-command-action",
|
"name": "gradle-build-action",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Execute Gradle Command Line",
|
"private": true,
|
||||||
"main": "lib/main.js",
|
"description": "Execute Gradle Build",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"format": "prettier --write **/*.ts",
|
||||||
"test": "jest"
|
"format-check": "prettier --check **/*.ts",
|
||||||
|
"lint": "eslint src/**/*.ts",
|
||||||
|
"build": "ncc build src/main.ts --out dist/main --minify && ncc build src/post.ts --out dist/post --minify",
|
||||||
|
"test": "jest",
|
||||||
|
"all": "npm run format && npm run lint && npm run build && npm test"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/eskatos/gradle-command-action.git"
|
"url": "git+https://github.com/gradle/gradle-build-action.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"github",
|
"github",
|
||||||
@@ -20,21 +24,28 @@
|
|||||||
"author": "Paul Merlin <paul@nosphere.org>",
|
"author": "Paul Merlin <paul@nosphere.org>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "1.1.1",
|
"@actions/cache": "1.0.7",
|
||||||
"@actions/exec": "1.0.1",
|
"@actions/core": "1.4.0",
|
||||||
"@actions/io": "1.0.1",
|
"@actions/exec": "1.1.0",
|
||||||
"@actions/tool-cache": "1.1.1",
|
"@actions/glob": "0.2.0",
|
||||||
"string-argv": "0.3.1",
|
"@actions/http-client": "1.0.11",
|
||||||
"typed-rest-client": "1.5.0",
|
"@actions/tool-cache": "1.7.1",
|
||||||
"unzipper": "0.10.5"
|
"string-argv": "0.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "24.0.18",
|
"@types/jest": "26.0.23",
|
||||||
"@types/node": "12.7.5",
|
"@types/node": "14.17.3",
|
||||||
"@types/unzipper": "0.10.0",
|
"@types/unzipper": "0.10.4",
|
||||||
"jest": "24.9.0",
|
"@typescript-eslint/parser": "4.28.2",
|
||||||
"jest-circus": "24.9.0",
|
"@zeit/ncc": "0.22.3",
|
||||||
"ts-jest": "24.1.0",
|
"eslint": "7.30.0",
|
||||||
"typescript": "3.6.3"
|
"eslint-plugin-github": "4.1.3",
|
||||||
|
"eslint-plugin-jest": "24.3.6",
|
||||||
|
"jest": "26.6.3",
|
||||||
|
"jest-circus": "26.6.3",
|
||||||
|
"js-yaml": "3.14.1",
|
||||||
|
"prettier": "2.3.2",
|
||||||
|
"ts-jest": "26.5.6",
|
||||||
|
"typescript": "4.3.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
106
src/cache-configuration.ts
Normal file
106
src/cache-configuration.ts
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import path from 'path'
|
||||||
|
import fs from 'fs'
|
||||||
|
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import * as cache from '@actions/cache'
|
||||||
|
|
||||||
|
import * as crypto from './crypto-utils'
|
||||||
|
|
||||||
|
import {
|
||||||
|
inputCacheKeyGlobs,
|
||||||
|
tryDeleteFiles,
|
||||||
|
isDependenciesCacheDisabled
|
||||||
|
} from './cache-dependencies'
|
||||||
|
|
||||||
|
const CONFIGURATION_CACHE_PATH = 'CONFIGURATION_CACHE_PATH'
|
||||||
|
const CONFIGURATION_CACHE_KEY = 'CONFIGURATION_CACHE_KEY'
|
||||||
|
const CONFIGURATION_CACHE_RESULT = 'CONFIGURATION_CACHE_RESULT'
|
||||||
|
|
||||||
|
export async function restoreCachedConfiguration(
|
||||||
|
rootDir: string
|
||||||
|
): Promise<void> {
|
||||||
|
if (isConfigurationCacheDisabled()) return
|
||||||
|
|
||||||
|
if (isDependenciesCacheDisabled()) {
|
||||||
|
throw new Error(
|
||||||
|
`Must enable dependencies-cache when configuration-cache is enabled`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const cachePath = path.resolve(rootDir, '.gradle/configuration-cache')
|
||||||
|
if (fs.existsSync(cachePath)) return
|
||||||
|
core.saveState(CONFIGURATION_CACHE_PATH, cachePath)
|
||||||
|
|
||||||
|
const inputCacheExact = core.getBooleanInput('configuration-cache-exact')
|
||||||
|
const cacheKeyGlobs = inputCacheKeyGlobs('configuration-cache-key')
|
||||||
|
|
||||||
|
const hash = await crypto.hashFiles(rootDir, cacheKeyGlobs)
|
||||||
|
const cacheKeyPrefix = 'configuration-'
|
||||||
|
const cacheKey = `${cacheKeyPrefix}${hash}`
|
||||||
|
core.saveState(CONFIGURATION_CACHE_KEY, cacheKey)
|
||||||
|
|
||||||
|
const cacheResult = await cache.restoreCache(
|
||||||
|
[cachePath],
|
||||||
|
cacheKey,
|
||||||
|
inputCacheExact ? [] : [cacheKeyPrefix]
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!cacheResult) {
|
||||||
|
core.info(
|
||||||
|
'Configuration cache not found, expect task graph calculation.'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
core.saveState(CONFIGURATION_CACHE_RESULT, cacheResult)
|
||||||
|
core.info(`Configuration restored from cache key: ${cacheResult}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function cacheConfiguration(): Promise<void> {
|
||||||
|
if (isConfigurationCacheDisabled()) return
|
||||||
|
|
||||||
|
const cachePath = core.getState(CONFIGURATION_CACHE_PATH)
|
||||||
|
const cacheKey = core.getState(CONFIGURATION_CACHE_KEY)
|
||||||
|
const cacheResult = core.getState(CONFIGURATION_CACHE_RESULT)
|
||||||
|
|
||||||
|
if (!cachePath || !fs.existsSync(cachePath)) {
|
||||||
|
core.debug('No configuration to cache.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cacheResult && cacheKey === cacheResult) {
|
||||||
|
core.info(
|
||||||
|
`Configuration cache hit occurred on the cache key ${cacheKey}, not saving cache.`
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const locksDeleted = tryDeleteFiles([
|
||||||
|
path.resolve(cachePath, 'configuration-cache.lock')
|
||||||
|
])
|
||||||
|
if (!locksDeleted) {
|
||||||
|
core.warning(
|
||||||
|
'Unable to delete configuration lock files, try using --no-daemon or stopping the daemon last if you have several Gradle steps, not saving cache.'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await cache.saveCache([cachePath], cacheKey)
|
||||||
|
} catch (error) {
|
||||||
|
if (error.name === cache.ValidationError.name) {
|
||||||
|
throw error
|
||||||
|
} else if (error.name === cache.ReserveCacheError.name) {
|
||||||
|
core.info(error.message)
|
||||||
|
} else {
|
||||||
|
core.info(`[warning] ${error.message}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
function isConfigurationCacheDisabled(): boolean {
|
||||||
|
return !core.getBooleanInput('configuration-cache-enabled')
|
||||||
|
}
|
119
src/cache-dependencies.ts
Normal file
119
src/cache-dependencies.ts
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
import * as path from 'path'
|
||||||
|
import * as fs from 'fs'
|
||||||
|
import * as os from 'os'
|
||||||
|
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import * as cache from '@actions/cache'
|
||||||
|
|
||||||
|
import * as crypto from './crypto-utils'
|
||||||
|
|
||||||
|
const DEPENDENCIES_CACHE_PATH = 'DEPENDENCIES_CACHE_PATH'
|
||||||
|
const DEPENDENCIES_CACHE_KEY = 'DEPENDENCIES_CACHE_KEY'
|
||||||
|
const DEPENDENCIES_CACHE_RESULT = 'DEPENDENCIES_CACHE_RESULT'
|
||||||
|
|
||||||
|
export async function restoreCachedDependencies(
|
||||||
|
rootDir: string
|
||||||
|
): Promise<void> {
|
||||||
|
if (isDependenciesCacheDisabled()) return
|
||||||
|
|
||||||
|
const cachePath = path.resolve(os.homedir(), '.gradle/caches/modules-2')
|
||||||
|
if (fs.existsSync(cachePath)) return
|
||||||
|
core.saveState(DEPENDENCIES_CACHE_PATH, cachePath)
|
||||||
|
|
||||||
|
const inputCacheExact = core.getBooleanInput('dependencies-cache-exact')
|
||||||
|
const cacheKeyGlobs = inputCacheKeyGlobs('dependencies-cache-key')
|
||||||
|
|
||||||
|
const hash = await crypto.hashFiles(rootDir, cacheKeyGlobs)
|
||||||
|
const cacheKeyPrefix = 'dependencies-'
|
||||||
|
const cacheKey = `${cacheKeyPrefix}${hash}`
|
||||||
|
core.saveState(DEPENDENCIES_CACHE_KEY, cacheKey)
|
||||||
|
|
||||||
|
const cacheResult = await cache.restoreCache(
|
||||||
|
[cachePath],
|
||||||
|
cacheKey,
|
||||||
|
inputCacheExact ? [] : [cacheKeyPrefix]
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!cacheResult) {
|
||||||
|
core.info('Dependencies cache not found, expect dependencies download.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
core.saveState(DEPENDENCIES_CACHE_RESULT, cacheResult)
|
||||||
|
core.info(`Dependencies restored from cache key: ${cacheResult}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function cacheDependencies(): Promise<void> {
|
||||||
|
if (isDependenciesCacheDisabled()) return
|
||||||
|
|
||||||
|
const cachePath = core.getState(DEPENDENCIES_CACHE_PATH)
|
||||||
|
const cacheKey = core.getState(DEPENDENCIES_CACHE_KEY)
|
||||||
|
const cacheResult = core.getState(DEPENDENCIES_CACHE_RESULT)
|
||||||
|
|
||||||
|
if (!cachePath || !fs.existsSync(cachePath)) {
|
||||||
|
core.debug('No dependencies to cache.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cacheResult && cacheKey === cacheResult) {
|
||||||
|
core.info(
|
||||||
|
`Dependencies cache hit occurred on the cache key ${cacheKey}, not saving cache.`
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const locksDeleted = tryDeleteFiles([
|
||||||
|
path.resolve(cachePath, 'modules-2.lock')
|
||||||
|
])
|
||||||
|
if (!locksDeleted) {
|
||||||
|
core.warning(
|
||||||
|
'Unable to delete dependencies lock files, try using --no-daemon or stopping the daemon last if you have several Gradle steps, not saving cache.'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await cache.saveCache([cachePath], cacheKey)
|
||||||
|
} catch (error) {
|
||||||
|
if (error.name === cache.ValidationError.name) {
|
||||||
|
throw error
|
||||||
|
} else if (error.name === cache.ReserveCacheError.name) {
|
||||||
|
core.info(error.message)
|
||||||
|
} else {
|
||||||
|
core.info(`[warning] ${error.message}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
export function tryDeleteFiles(filePaths: string[]): boolean {
|
||||||
|
let failure = false
|
||||||
|
for (const filePath of filePaths) {
|
||||||
|
if (fs.existsSync(filePath)) {
|
||||||
|
try {
|
||||||
|
fs.unlinkSync(filePath)
|
||||||
|
} catch (error) {
|
||||||
|
failure = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !failure
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isDependenciesCacheDisabled(): boolean {
|
||||||
|
return !core.getBooleanInput('dependencies-cache-enabled')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function inputCacheKeyGlobs(input: string): string[] {
|
||||||
|
const inputValue = core.getMultilineInput(input)
|
||||||
|
return inputValue.length > 0
|
||||||
|
? inputValue
|
||||||
|
: [
|
||||||
|
'**/*.gradle',
|
||||||
|
'**/*.gradle.kts',
|
||||||
|
'**/gradle.properties',
|
||||||
|
'gradle/**'
|
||||||
|
]
|
||||||
|
}
|
132
src/cache-wrapper.ts
Normal file
132
src/cache-wrapper.ts
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
import * as path from 'path'
|
||||||
|
import * as fs from 'fs'
|
||||||
|
import * as os from 'os'
|
||||||
|
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import * as cache from '@actions/cache'
|
||||||
|
|
||||||
|
const WRAPPER_SLUG = 'WRAPPER_SLUG'
|
||||||
|
|
||||||
|
export async function restoreCachedWrapperDist(
|
||||||
|
gradlewDirectory: string | null
|
||||||
|
): Promise<void> {
|
||||||
|
if (isWrapperCacheDisabled()) return
|
||||||
|
if (gradlewDirectory == null) return
|
||||||
|
|
||||||
|
const wrapperProperties = path.join(
|
||||||
|
path.resolve(gradlewDirectory),
|
||||||
|
'gradle/wrapper/gradle-wrapper.properties'
|
||||||
|
)
|
||||||
|
const wrapperSlug = extractGradleWrapperSlugFrom(wrapperProperties)
|
||||||
|
if (!wrapperSlug) {
|
||||||
|
core.warning(
|
||||||
|
`Could not calculate wrapper version from ${wrapperProperties}`
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const wrapperDir = getWrapperDir(wrapperSlug)
|
||||||
|
const cacheKey = getCacheKey(wrapperSlug)
|
||||||
|
const cachePath = getCachePath(wrapperSlug)
|
||||||
|
|
||||||
|
// Check if the wrapper has already been downloaded to Gradle User Home
|
||||||
|
if (fs.existsSync(wrapperDir)) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
const restoredKey = await cache.restoreCache([cachePath], cacheKey)
|
||||||
|
|
||||||
|
if (restoredKey) {
|
||||||
|
core.info(
|
||||||
|
`Wrapper installation restored from cache key: ${restoredKey}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
core.info(
|
||||||
|
`Wrapper installation cache not found. Will download and cache with key: ${cacheKey}.`
|
||||||
|
)
|
||||||
|
// Save the slug to trigger caching of the downloaded wrapper
|
||||||
|
core.saveState(WRAPPER_SLUG, wrapperSlug)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
core.info(
|
||||||
|
`Wrapper installation cache restore failed for key: ${cacheKey}.\n ${error}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function cacheWrapperDist(): Promise<void> {
|
||||||
|
if (isWrapperCacheDisabled()) return
|
||||||
|
|
||||||
|
const wrapperSlug = core.getState(WRAPPER_SLUG)
|
||||||
|
if (!wrapperSlug) return
|
||||||
|
|
||||||
|
const wrapperDir = getWrapperDir(wrapperSlug)
|
||||||
|
const cacheKey = getCacheKey(wrapperSlug)
|
||||||
|
const cachePath = getCachePath(wrapperSlug)
|
||||||
|
|
||||||
|
if (!fs.existsSync(wrapperDir)) {
|
||||||
|
core.warning(`No wrapper installation to cache at ${wrapperDir}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
core.info(`Will cache wrapper zip ${cachePath} with key ${cacheKey}`)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await cache.saveCache([cachePath], cacheKey)
|
||||||
|
} catch (error) {
|
||||||
|
if (error.name === cache.ValidationError.name) {
|
||||||
|
throw error
|
||||||
|
} else if (error.name === cache.ReserveCacheError.name) {
|
||||||
|
core.info(error.message)
|
||||||
|
} else {
|
||||||
|
core.info(`[warning] ${error.message}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
export function extractGradleWrapperSlugFrom(
|
||||||
|
wrapperProperties: string
|
||||||
|
): string | null {
|
||||||
|
const props = fs.readFileSync(wrapperProperties, {encoding: 'utf8'})
|
||||||
|
const distUrlLine = props
|
||||||
|
.split('\n')
|
||||||
|
.find(line => line.startsWith('distributionUrl'))
|
||||||
|
if (!distUrlLine) return null
|
||||||
|
return extractGradleWrapperSlugFromDistUri(distUrlLine.substr(16).trim())
|
||||||
|
}
|
||||||
|
|
||||||
|
export function extractGradleWrapperSlugFromDistUri(
|
||||||
|
distUri: string
|
||||||
|
): string | null {
|
||||||
|
const regex = /.*gradle-(.*-(bin|all))\.zip/
|
||||||
|
const match = distUri.match(regex)
|
||||||
|
return match ? match[1] : null
|
||||||
|
}
|
||||||
|
|
||||||
|
function isWrapperCacheDisabled(): boolean {
|
||||||
|
// Check if either 'distributions' or 'wrapper' cache has been disabled
|
||||||
|
const wrapperCacheEnabled = core.getBooleanInput('wrapper-cache-enabled')
|
||||||
|
const distributionsCacheEnabled = core.getBooleanInput(
|
||||||
|
'distributions-cache-enabled'
|
||||||
|
)
|
||||||
|
return !wrapperCacheEnabled || !distributionsCacheEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCacheKey(wrapperSlug: string): string {
|
||||||
|
return `wrapper-v1-${wrapperSlug}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWrapperDir(wrapperSlug: string): string {
|
||||||
|
return path.resolve(
|
||||||
|
os.homedir(),
|
||||||
|
`.gradle/wrapper/dists/gradle-${wrapperSlug}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCachePath(wrapperSlug: string): string {
|
||||||
|
return path.resolve(
|
||||||
|
os.homedir(),
|
||||||
|
`.gradle/wrapper/dists/gradle-${wrapperSlug}/*/gradle-${wrapperSlug}.zip`
|
||||||
|
)
|
||||||
|
}
|
13
src/crypto-utils.ts
Normal file
13
src/crypto-utils.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import * as path from 'path'
|
||||||
|
import * as glob from '@actions/glob'
|
||||||
|
|
||||||
|
export async function hashFiles(
|
||||||
|
baseDir: string,
|
||||||
|
patterns: string[] = ['**'],
|
||||||
|
followSymbolicLinks = false
|
||||||
|
): Promise<string | null> {
|
||||||
|
const combinedPatterns = patterns
|
||||||
|
.map(pattern => `${baseDir}${path.sep}${pattern}`)
|
||||||
|
.join('\n')
|
||||||
|
return glob.hashFiles(combinedPatterns, {followSymbolicLinks})
|
||||||
|
}
|
@@ -1,40 +1,42 @@
|
|||||||
import * as exec from "@actions/exec";
|
import * as exec from '@actions/exec'
|
||||||
|
import * as cacheDependencies from './cache-dependencies'
|
||||||
|
import * as cacheConfiguration from './cache-configuration'
|
||||||
|
|
||||||
|
export async function execute(
|
||||||
|
executable: string,
|
||||||
|
root: string,
|
||||||
|
argv: string[]
|
||||||
|
): Promise<BuildResult> {
|
||||||
|
await cacheDependencies.restoreCachedDependencies(root)
|
||||||
|
await cacheConfiguration.restoreCachedConfiguration(root)
|
||||||
|
|
||||||
export async function execute(executable: string, root: string, argv: string[]): Promise<BuildResult> {
|
let publishing = false
|
||||||
|
let buildScanUrl: string | undefined
|
||||||
|
|
||||||
let publishing = false;
|
const status: number = await exec.exec(executable, argv, {
|
||||||
let buildScanLink: any = null;
|
|
||||||
|
|
||||||
await exec.exec(executable, argv, {
|
|
||||||
cwd: root,
|
cwd: root,
|
||||||
|
ignoreReturnCode: true,
|
||||||
listeners: {
|
listeners: {
|
||||||
stdline: (line: string) => {
|
stdline: (line: string) => {
|
||||||
if (line.startsWith("Publishing build scan...")) {
|
if (line.includes('Publishing build scan...')) {
|
||||||
publishing = true;
|
publishing = true
|
||||||
}
|
}
|
||||||
if (publishing && line.length == 0) {
|
if (publishing && line.startsWith('http')) {
|
||||||
publishing = false
|
buildScanUrl = line.trim()
|
||||||
}
|
|
||||||
if (publishing && line.startsWith("http")) {
|
|
||||||
buildScanLink = line.trim();
|
|
||||||
publishing = false
|
publishing = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
if (buildScanLink != null) {
|
return new BuildResultImpl(status, buildScanUrl)
|
||||||
return new BuildResultImpl(buildScanLink.toString());
|
|
||||||
}
|
|
||||||
return new BuildResultImpl(null as unknown as string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BuildResult {
|
export interface BuildResult {
|
||||||
buildScanUrl: string
|
readonly status: number
|
||||||
|
readonly buildScanUrl?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
class BuildResultImpl implements BuildResult {
|
class BuildResultImpl implements BuildResult {
|
||||||
constructor(readonly buildScanUrl: string) {
|
constructor(readonly status: number, readonly buildScanUrl?: string) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,24 @@
|
|||||||
export function wrapperFilename() {
|
import * as path from 'path'
|
||||||
const isWindows = process.platform === "win32";
|
import fs from 'fs'
|
||||||
return isWindows ? "gradlew.bat" : "gradlew";
|
|
||||||
|
const IS_WINDOWS = process.platform === 'win32'
|
||||||
|
|
||||||
|
export function wrapperFilename(): string {
|
||||||
|
return IS_WINDOWS ? 'gradlew.bat' : 'gradlew'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function installScriptFilename() {
|
export function installScriptFilename(): string {
|
||||||
const isWindows = process.platform === "win32";
|
return IS_WINDOWS ? 'gradle.bat' : 'gradle'
|
||||||
return isWindows ? "gradle.bat" : "gradle";
|
}
|
||||||
|
|
||||||
|
export function validateGradleWrapper(gradlewDirectory: string): void {
|
||||||
|
const wrapperProperties = path.resolve(
|
||||||
|
gradlewDirectory,
|
||||||
|
'gradle/wrapper/gradle-wrapper.properties'
|
||||||
|
)
|
||||||
|
if (!fs.existsSync(wrapperProperties)) {
|
||||||
|
throw new Error(
|
||||||
|
`Cannot locate a Gradle wrapper properties file at '${wrapperProperties}'. Specify 'gradle-version' or 'gradle-executable' for projects without Gradle wrapper configured.`
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
106
src/main.ts
106
src/main.ts
@@ -1,74 +1,82 @@
|
|||||||
import * as core from "@actions/core";
|
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 execution from "./execution";
|
import * as cacheWrapper from './cache-wrapper'
|
||||||
import * as gradlew from "./gradlew";
|
import * as execution from './execution'
|
||||||
import * as provision from "./provision";
|
import * as gradlew from './gradlew'
|
||||||
|
import * as provision from './provision'
|
||||||
|
|
||||||
|
// Invoked by GitHub Actions
|
||||||
// Invoked by Github Actions
|
export async function run(): Promise<void> {
|
||||||
async function run() {
|
|
||||||
try {
|
try {
|
||||||
|
const workspaceDirectory = process.env[`GITHUB_WORKSPACE`] || ''
|
||||||
|
const buildRootDirectory = resolveBuildRootDirectory(workspaceDirectory)
|
||||||
|
|
||||||
const baseDirectory = process.env[`GITHUB_WORKSPACE`] || "";
|
const result = await execution.execute(
|
||||||
|
await resolveGradleExecutable(
|
||||||
let result = await execution.execute(
|
workspaceDirectory,
|
||||||
await resolveGradleExecutable(baseDirectory),
|
buildRootDirectory
|
||||||
resolveBuildRootDirectory(baseDirectory),
|
),
|
||||||
|
buildRootDirectory,
|
||||||
parseCommandLineArguments()
|
parseCommandLineArguments()
|
||||||
);
|
)
|
||||||
|
|
||||||
if (result.buildScanUrl != null) {
|
if (result.buildScanUrl) {
|
||||||
core.setOutput("build-scan-url", result.buildScanUrl);
|
core.setOutput('build-scan-url', result.buildScanUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result.status !== 0) {
|
||||||
|
core.setFailed(`Gradle process exited with status ${result.status}`)
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run()
|
||||||
|
|
||||||
run();
|
async function resolveGradleExecutable(
|
||||||
|
workspaceDirectory: string,
|
||||||
|
buildRootDirectory: string
|
||||||
async function resolveGradleExecutable(baseDirectory: string): Promise<string> {
|
): Promise<string> {
|
||||||
|
const gradleVersion = core.getInput('gradle-version')
|
||||||
const gradleVersion = inputOrNull("gradle-version");
|
if (gradleVersion !== '' && gradleVersion !== 'wrapper') {
|
||||||
if (gradleVersion != null) {
|
return path.resolve(await provision.gradleVersion(gradleVersion))
|
||||||
return provision.gradleVersion(gradleVersion)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const gradleExecutable = inputOrNull("gradle-executable");
|
const gradleExecutable = core.getInput('gradle-executable')
|
||||||
if (gradleExecutable != null) {
|
if (gradleExecutable !== '') {
|
||||||
return path.join(baseDirectory, gradleExecutable)
|
if (gradleExecutable.endsWith(gradlew.wrapperFilename())) {
|
||||||
|
await cacheWrapper.restoreCachedWrapperDist(
|
||||||
|
path.resolve(gradleExecutable, '..')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return path.resolve(workspaceDirectory, gradleExecutable)
|
||||||
}
|
}
|
||||||
|
|
||||||
const wrapperDirectory = inputOrNull("wrapper-directory");
|
const wrapperDirectory = core.getInput('wrapper-directory')
|
||||||
const executableDirectory = wrapperDirectory != null
|
const gradlewDirectory =
|
||||||
? path.join(baseDirectory, wrapperDirectory)
|
wrapperDirectory !== ''
|
||||||
: baseDirectory;
|
? path.resolve(workspaceDirectory, wrapperDirectory)
|
||||||
|
: buildRootDirectory
|
||||||
|
|
||||||
return path.join(executableDirectory, gradlew.wrapperFilename());
|
gradlew.validateGradleWrapper(gradlewDirectory)
|
||||||
|
await cacheWrapper.restoreCachedWrapperDist(gradlewDirectory)
|
||||||
|
|
||||||
|
return path.resolve(gradlewDirectory, gradlew.wrapperFilename())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function resolveBuildRootDirectory(baseDirectory: string): string {
|
function resolveBuildRootDirectory(baseDirectory: string): string {
|
||||||
let buildRootDirectory = inputOrNull("build-root-directory");
|
const buildRootDirectory = core.getInput('build-root-directory')
|
||||||
return buildRootDirectory == null ? baseDirectory : path.join(baseDirectory, buildRootDirectory);
|
const resolvedBuildRootDirectory =
|
||||||
|
buildRootDirectory === ''
|
||||||
|
? path.resolve(baseDirectory)
|
||||||
|
: path.resolve(baseDirectory, buildRootDirectory)
|
||||||
|
return resolvedBuildRootDirectory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function parseCommandLineArguments(): string[] {
|
function parseCommandLineArguments(): string[] {
|
||||||
const input = inputOrNull("arguments");
|
const input = core.getInput('arguments')
|
||||||
return input == null ? [] : parseArgsStringToArgv(input)
|
return parseArgsStringToArgv(input)
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function inputOrNull(name: string): string | null {
|
|
||||||
const inputString = core.getInput(name);
|
|
||||||
if (inputString.length == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return inputString
|
|
||||||
}
|
}
|
||||||
|
12
src/post.ts
Normal file
12
src/post.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import * as cacheWrapper from './cache-wrapper'
|
||||||
|
import * as cacheDependencies from './cache-dependencies'
|
||||||
|
import * as cacheConfiguration from './cache-configuration'
|
||||||
|
|
||||||
|
// Invoked by GitHub Actions
|
||||||
|
export async function run(): Promise<void> {
|
||||||
|
await cacheWrapper.cacheWrapperDist()
|
||||||
|
await cacheDependencies.cacheDependencies()
|
||||||
|
await cacheConfiguration.cacheConfiguration()
|
||||||
|
}
|
||||||
|
|
||||||
|
run()
|
270
src/provision.ts
270
src/provision.ts
@@ -1,163 +1,193 @@
|
|||||||
import * as fs from "fs";
|
import * as fs from 'fs'
|
||||||
import * as path from "path";
|
import * as os from 'os'
|
||||||
import * as httpm from 'typed-rest-client/HttpClient';
|
import * as path from 'path'
|
||||||
import * as unzip from "unzipper"
|
import * as httpm from '@actions/http-client'
|
||||||
import * as core from "@actions/core";
|
import * as core from '@actions/core'
|
||||||
import * as io from '@actions/io';
|
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'
|
||||||
|
|
||||||
|
const gradleVersionsBaseUrl = 'https://services.gradle.org/versions'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Gradle executable
|
* @return Gradle executable path
|
||||||
*/
|
*/
|
||||||
export async function gradleVersion(gradleVersion: string): Promise<string> {
|
export async function gradleVersion(version: string): Promise<string> {
|
||||||
switch (gradleVersion) {
|
switch (version) {
|
||||||
case "current":
|
case 'current':
|
||||||
return gradleCurrent();
|
return gradleCurrent()
|
||||||
case "rc":
|
case 'rc':
|
||||||
return gradleReleaseCandidate();
|
core.warning(
|
||||||
case "nightly":
|
`Specifying gradle-version 'rc' has been deprecated. Use 'release-candidate' instead.`
|
||||||
return gradleNightly();
|
)
|
||||||
case "release-nightly":
|
return gradleReleaseCandidate()
|
||||||
return gradleReleaseNightly();
|
case 'release-candidate':
|
||||||
|
return gradleReleaseCandidate()
|
||||||
|
case 'nightly':
|
||||||
|
return gradleNightly()
|
||||||
|
case 'release-nightly':
|
||||||
|
return gradleReleaseNightly()
|
||||||
default:
|
default:
|
||||||
return gradle(gradleVersion);
|
return gradle(version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const gradleVersionsBaseUrl = "https://services.gradle.org/versions";
|
|
||||||
|
|
||||||
|
|
||||||
async function gradleCurrent(): Promise<string> {
|
async function gradleCurrent(): Promise<string> {
|
||||||
const json = await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/current`);
|
const versionInfo = await gradleVersionDeclaration(
|
||||||
return provisionGradle(json.version, json.downloadUrl);
|
`${gradleVersionsBaseUrl}/current`
|
||||||
|
)
|
||||||
|
return provisionGradle(versionInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function gradleReleaseCandidate(): Promise<string> {
|
async function gradleReleaseCandidate(): Promise<string> {
|
||||||
const json = await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/release-candidate`);
|
const versionInfo = await gradleVersionDeclaration(
|
||||||
if (json != null) {
|
`${gradleVersionsBaseUrl}/release-candidate`
|
||||||
return provisionGradle(json.version, json.downloadUrl);
|
)
|
||||||
|
if (versionInfo && versionInfo.version && versionInfo.downloadUrl) {
|
||||||
|
return provisionGradle(versionInfo)
|
||||||
}
|
}
|
||||||
return gradleCurrent();
|
core.info('No current release-candidate found, will fallback to current')
|
||||||
|
return gradleCurrent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function gradleNightly(): Promise<string> {
|
async function gradleNightly(): Promise<string> {
|
||||||
const json = await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/nightly`);
|
const versionInfo = await gradleVersionDeclaration(
|
||||||
return provisionGradle(json.version, json.downloadUrl);
|
`${gradleVersionsBaseUrl}/nightly`
|
||||||
|
)
|
||||||
|
return provisionGradle(versionInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function gradleReleaseNightly(): Promise<string> {
|
async function gradleReleaseNightly(): Promise<string> {
|
||||||
const json = await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/release-nightly`);
|
const versionInfo = await gradleVersionDeclaration(
|
||||||
return provisionGradle(json.version, json.downloadUrl);
|
`${gradleVersionsBaseUrl}/release-nightly`
|
||||||
|
)
|
||||||
|
return provisionGradle(versionInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function gradle(version: string): Promise<string> {
|
async function gradle(version: string): Promise<string> {
|
||||||
const declaration = await findGradleVersionDeclaration(version);
|
const versionInfo = await findGradleVersionDeclaration(version)
|
||||||
if (declaration == null) {
|
if (!versionInfo) {
|
||||||
throw new Error(`Gradle version ${version} does not exists`);
|
throw new Error(`Gradle version ${version} does not exists`)
|
||||||
}
|
}
|
||||||
return provisionGradle(declaration.version, declaration.downloadUrl);
|
return provisionGradle(versionInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function gradleVersionDeclaration(
|
||||||
async function gradleVersionDeclaration(url: string): Promise<any | null> {
|
url: string
|
||||||
const httpc = new httpm.HttpClient("gradle-github-action");
|
): Promise<GradleVersionInfo> {
|
||||||
const response = await httpc.get(url);
|
return await httpGetGradleVersion(url)
|
||||||
const body = await response.readBody();
|
|
||||||
const json = JSON.parse(body);
|
|
||||||
return (json == null || json.version == null || json.version.length <= 0)
|
|
||||||
? null
|
|
||||||
: json
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function findGradleVersionDeclaration(
|
||||||
async function findGradleVersionDeclaration(version: string): Promise<any | null> {
|
version: string
|
||||||
const httpc = new httpm.HttpClient("gradle-github-action");
|
): Promise<GradleVersionInfo | undefined> {
|
||||||
const response = await httpc.get(`${gradleVersionsBaseUrl}/all`);
|
const gradleVersions = await httpGetGradleVersions(
|
||||||
const body = await response.readBody();
|
`${gradleVersionsBaseUrl}/all`
|
||||||
const json = JSON.parse(body);
|
)
|
||||||
const found = json.find(entry => {
|
return gradleVersions.find((entry: GradleVersionInfo) => {
|
||||||
return entry.version == version;
|
return entry.version === version
|
||||||
});
|
})
|
||||||
return found != undefined ? found : null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function provisionGradle(version: string, url: string): Promise<string> {
|
async function provisionGradle(
|
||||||
|
versionInfo: GradleVersionInfo
|
||||||
const cachedInstall: string = toolCache.find("gradle", version);
|
): Promise<string> {
|
||||||
if (cachedInstall != null && cachedInstall.length > 0) {
|
const installsDir = path.join(os.homedir(), 'gradle-installations/installs')
|
||||||
const cachedExecutable = executableFrom(cachedInstall);
|
const installDir = path.join(installsDir, `gradle-${versionInfo.version}`)
|
||||||
core.info(`Provisioned Gradle executable ${cachedExecutable}`);
|
if (fs.existsSync(installDir)) {
|
||||||
return cachedExecutable;
|
core.info(`Gradle installation already exists at ${installDir}`)
|
||||||
|
return executableFrom(installDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
const home = process.env["HOME"] || "";
|
const downloadPath = await downloadAndCacheGradleDistribution(versionInfo)
|
||||||
const tmpdir = path.join(home, "gradle-provision-tmpdir");
|
await toolCache.extractZip(downloadPath, installsDir)
|
||||||
const downloadsDir = path.join(tmpdir, "downloads");
|
core.info(`Extracted Gradle ${versionInfo.version} to ${installDir}`)
|
||||||
const installsDir = path.join(tmpdir, "installs");
|
|
||||||
await io.mkdirP(downloadsDir);
|
|
||||||
await io.mkdirP(installsDir);
|
|
||||||
|
|
||||||
core.info(`Downloading ${url}`);
|
const executable = executableFrom(installDir)
|
||||||
|
fs.chmodSync(executable, '755')
|
||||||
|
core.info(`Provisioned Gradle executable ${executable}`)
|
||||||
|
|
||||||
const downloadPath = path.join(downloadsDir, `gradle-${version}-bin.zip`);
|
return executable
|
||||||
await httpDownload(url, downloadPath);
|
|
||||||
core.info(`Downloaded at ${downloadPath}, size ${fs.statSync(downloadPath).size}`);
|
|
||||||
|
|
||||||
await extractZip(downloadPath, installsDir);
|
|
||||||
const installDir = path.join(installsDir, `gradle-${version}`);
|
|
||||||
core.info(`Extracted in ${installDir}`);
|
|
||||||
|
|
||||||
const executable = executableFrom(installDir);
|
|
||||||
fs.chmodSync(executable, "755");
|
|
||||||
core.info(`Provisioned Gradle executable ${executable}`);
|
|
||||||
|
|
||||||
toolCache.cacheDir(installDir, "gradle", version);
|
|
||||||
|
|
||||||
return executable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function downloadAndCacheGradleDistribution(
|
||||||
|
versionInfo: GradleVersionInfo
|
||||||
|
): Promise<string> {
|
||||||
|
const downloadPath = path.join(
|
||||||
|
os.homedir(),
|
||||||
|
`gradle-installations/downloads/gradle-${versionInfo.version}-bin.zip`
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isDistributionsCacheDisabled()) {
|
||||||
|
await downloadGradleDistribution(versionInfo, downloadPath)
|
||||||
|
return downloadPath
|
||||||
|
}
|
||||||
|
|
||||||
|
const cacheKey = `gradle-${versionInfo.version}`
|
||||||
|
const restoreKey = await cache.restoreCache([downloadPath], cacheKey)
|
||||||
|
if (restoreKey) {
|
||||||
|
core.info(
|
||||||
|
`Restored Gradle distribution ${cacheKey} from cache to ${downloadPath}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
core.info(
|
||||||
|
`Gradle distribution ${versionInfo.version} not found in cache. Will download.`
|
||||||
|
)
|
||||||
|
await downloadGradleDistribution(versionInfo, downloadPath)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await cache.saveCache([downloadPath], cacheKey)
|
||||||
|
} catch (error) {
|
||||||
|
if (error.name === cache.ValidationError.name) {
|
||||||
|
throw error
|
||||||
|
} else if (error.name === cache.ReserveCacheError.name) {
|
||||||
|
core.info(error.message)
|
||||||
|
} else {
|
||||||
|
core.info(`[warning] ${error.message}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return downloadPath
|
||||||
|
}
|
||||||
|
|
||||||
|
async function downloadGradleDistribution(
|
||||||
|
versionInfo: GradleVersionInfo,
|
||||||
|
downloadPath: string
|
||||||
|
): Promise<void> {
|
||||||
|
await toolCache.downloadTool(versionInfo.downloadUrl, downloadPath)
|
||||||
|
core.info(
|
||||||
|
`Downloaded ${versionInfo.downloadUrl} to ${downloadPath} (size ${
|
||||||
|
fs.statSync(downloadPath).size
|
||||||
|
})`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function executableFrom(installDir: string): string {
|
function executableFrom(installDir: string): string {
|
||||||
return path.join(installDir, "bin", `${gradlew.installScriptFilename()}`);
|
return path.join(installDir, 'bin', `${gradlew.installScriptFilename()}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function httpGetGradleVersion(url: string): Promise<GradleVersionInfo> {
|
||||||
async function httpDownload(url: string, path: string): Promise<void> {
|
return JSON.parse(await httpGetString(url))
|
||||||
return new Promise<void>(function (resolve, reject) {
|
|
||||||
const httpc = new httpm.HttpClient("gradle-github-action");
|
|
||||||
const writeStream = fs.createWriteStream(path);
|
|
||||||
httpc.get(url).then(response => {
|
|
||||||
response.message.pipe(writeStream)
|
|
||||||
.on("close", () => {
|
|
||||||
resolve();
|
|
||||||
})
|
|
||||||
.on("error", err => {
|
|
||||||
reject(err)
|
|
||||||
});
|
|
||||||
}).catch(reason => {
|
|
||||||
reject(reason);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function httpGetGradleVersions(
|
||||||
async function extractZip(zip: string, destination: string): Promise<void> {
|
url: string
|
||||||
return new Promise<void>(function (resolve, reject) {
|
): Promise<GradleVersionInfo[]> {
|
||||||
fs.createReadStream(zip)
|
return JSON.parse(await httpGetString(url))
|
||||||
.pipe(unzip.Extract({"path": destination}))
|
}
|
||||||
.on("close", () => {
|
|
||||||
resolve();
|
async function httpGetString(url: string): Promise<string> {
|
||||||
})
|
const httpClient = new httpm.HttpClient('gradle/gradle-build-action')
|
||||||
.on("error", err => {
|
const response = await httpClient.get(url)
|
||||||
reject(err)
|
return response.readBody()
|
||||||
});
|
}
|
||||||
});
|
|
||||||
|
function isDistributionsCacheDisabled(): boolean {
|
||||||
|
return !core.getBooleanInput('distributions-cache-enabled')
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GradleVersionInfo {
|
||||||
|
version: string
|
||||||
|
downloadUrl: string
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
/* Basic Options */
|
/* Basic Options */
|
||||||
// "incremental": true, /* Enable incremental compilation */
|
"incremental": false, /* Enable incremental compilation */
|
||||||
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
|
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
|
||||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
||||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||||
// "composite": true, /* Enable project compilation */
|
// "composite": true, /* Enable project compilation */
|
||||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
||||||
// "removeComments": true, /* Do not emit comments to output. */
|
"removeComments": true, /* Do not emit comments to output. */
|
||||||
// "noEmit": true, /* Do not emit outputs. */
|
// "noEmit": true, /* Do not emit outputs. */
|
||||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||||
@@ -23,13 +23,13 @@
|
|||||||
|
|
||||||
/* Strict Type-Checking Options */
|
/* Strict Type-Checking Options */
|
||||||
"strict": true, /* Enable all strict type-checking options. */
|
"strict": true, /* Enable all strict type-checking options. */
|
||||||
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
|
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||||
"strictNullChecks": true, /* Enable strict null checks. */
|
"strictNullChecks": true, /* Enable strict null checks. */
|
||||||
"strictFunctionTypes": true, /* Enable strict checking of function types. */
|
"strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||||
"strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
"strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||||
"strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
"strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||||
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||||
|
|
||||||
/* Additional Checks */
|
/* Additional Checks */
|
||||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||||
|
Reference in New Issue
Block a user