mirror of
https://github.com/gradle/actions.git
synced 2025-11-26 17:09:10 +08:00
Compare commits
49 Commits
v2.2.0-rc.
...
v2.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67421db6bd | ||
|
|
ce3874fec9 | ||
|
|
67f42d16a1 | ||
|
|
56036f8577 | ||
|
|
1903bd4674 | ||
|
|
df4c1902a6 | ||
|
|
132237ba05 | ||
|
|
2335d51128 | ||
|
|
2f7e5c0d4b | ||
|
|
2248b3f239 | ||
|
|
7d8a9a65e5 | ||
|
|
bc39e4abaa | ||
|
|
26cd1c9794 | ||
|
|
5ccc7fa6a6 | ||
|
|
badf18c0a6 | ||
|
|
1ee84620f9 | ||
|
|
f1c1269910 | ||
|
|
c09f41c4bd | ||
|
|
829c7a236d | ||
|
|
c1ed8b1925 | ||
|
|
3d091fa7a8 | ||
|
|
a8d44c9749 | ||
|
|
6125b490f2 | ||
|
|
f75a77b009 | ||
|
|
3510b43886 | ||
|
|
61ba2ad220 | ||
|
|
4b449e5b54 | ||
|
|
b8f0ecc408 | ||
|
|
c2bd86551b | ||
|
|
92087b6bb6 | ||
|
|
9355458b6c | ||
|
|
4ec1021d58 | ||
|
|
f3e4903860 | ||
|
|
c5d80a628f | ||
|
|
ee54c1fd71 | ||
|
|
f33d84950e | ||
|
|
d20c5c0356 | ||
|
|
c207cf448f | ||
|
|
a534572737 | ||
|
|
acf6027bd2 | ||
|
|
f6ab09b0bf | ||
|
|
55ddd21594 | ||
|
|
33ed11e54c | ||
|
|
93c31ca3b5 | ||
|
|
7a15005377 | ||
|
|
e88ed3e650 | ||
|
|
de51428ba5 | ||
|
|
8096e65e0a | ||
|
|
9cd70b5460 |
2
.github/dependabot.yml
vendored
2
.github/dependabot.yml
vendored
@@ -9,7 +9,7 @@ updates:
|
|||||||
- package-ecosystem: "npm"
|
- package-ecosystem: "npm"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "weekly"
|
||||||
open-pull-requests-limit: 10
|
open-pull-requests-limit: 10
|
||||||
ignore:
|
ignore:
|
||||||
- dependency-name: "@types/node"
|
- dependency-name: "@types/node"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "com.gradle.enterprise" version "3.10.1"
|
id "com.gradle.enterprise" version "3.10.2"
|
||||||
|
id "com.gradle.common-custom-user-data-gradle-plugin" version "1.7.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
gradleEnterprise {
|
gradleEnterprise {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("com.gradle.enterprise") version "3.10.1"
|
id("com.gradle.enterprise") version "3.10.2"
|
||||||
|
id("com.gradle.common-custom-user-data-gradle-plugin") version "1.7.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
gradleEnterprise {
|
gradleEnterprise {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "com.gradle.build-scan" version "3.10.1"
|
id "com.gradle.build-scan" version "3.10.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
gradleEnterprise {
|
gradleEnterprise {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "com.gradle.enterprise" version "3.10.1"
|
id "com.gradle.enterprise" version "3.10.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
gradleEnterprise {
|
gradleEnterprise {
|
||||||
|
|||||||
7
.github/workflows/ci-init-script-check.yml
vendored
7
.github/workflows/ci-init-script-check.yml
vendored
@@ -2,6 +2,11 @@ name: CI-init-script-check
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/**'
|
||||||
|
- 'src/resources/init-scripts/**'
|
||||||
|
- 'test/init-script-check/**'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-init-scripts:
|
test-init-scripts:
|
||||||
@@ -17,5 +22,5 @@ jobs:
|
|||||||
- name: Setup Gradle
|
- name: Setup Gradle
|
||||||
uses: gradle/gradle-build-action@v2 # Use a released version to avoid breakages
|
uses: gradle/gradle-build-action@v2 # Use a released version to avoid breakages
|
||||||
- name: Run integration tests
|
- name: Run integration tests
|
||||||
working-directory: test/test-init-scripts
|
working-directory: test/init-scripts
|
||||||
run: ./gradlew check
|
run: ./gradlew check
|
||||||
|
|||||||
3
.github/workflows/ci-verify-outputs.yml
vendored
3
.github/workflows/ci-verify-outputs.yml
vendored
@@ -8,9 +8,6 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
paths:
|
|
||||||
- '.github/workflows/**'
|
|
||||||
- 'dist/**'
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
check:
|
||||||
|
|||||||
5
.github/workflows/demo-job-summary.yml
vendored
5
.github/workflows/demo-job-summary.yml
vendored
@@ -25,7 +25,10 @@ jobs:
|
|||||||
run: ./gradlew assemble
|
run: ./gradlew assemble
|
||||||
- name: Build kotlin-dsl project without build scan
|
- name: Build kotlin-dsl project without build scan
|
||||||
working-directory: .github/workflow-samples/kotlin-dsl
|
working-directory: .github/workflow-samples/kotlin-dsl
|
||||||
run: ./gradlew check --no-scan
|
run: ./gradlew assemble check --no-scan
|
||||||
|
- name: Build kotlin-dsl project with build scan publish failure
|
||||||
|
working-directory: .github/workflow-samples/kotlin-dsl
|
||||||
|
run: ./gradlew check -Dgradle.enterprise.url=https://not.valid.server
|
||||||
- name: Build groovy-dsl project
|
- name: Build groovy-dsl project
|
||||||
working-directory: .github/workflow-samples/groovy-dsl
|
working-directory: .github/workflow-samples/groovy-dsl
|
||||||
run: ./gradlew assemble
|
run: ./gradlew assemble
|
||||||
|
|||||||
29
README.md
29
README.md
@@ -85,6 +85,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-java@v3
|
- uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
|
distribution: temurin
|
||||||
java-version: 11
|
java-version: 11
|
||||||
- uses: gradle/gradle-build-action@v2
|
- uses: gradle/gradle-build-action@v2
|
||||||
with:
|
with:
|
||||||
@@ -111,6 +112,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-java@v3
|
- uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
|
distribution: temurin
|
||||||
java-version: 11
|
java-version: 11
|
||||||
|
|
||||||
- name: Setup and execute Gradle 'test' task
|
- name: Setup and execute Gradle 'test' task
|
||||||
@@ -218,15 +220,18 @@ For example, this means that all jobs executing a particular version of the Grad
|
|||||||
|
|
||||||
### Using the caches read-only
|
### Using the caches read-only
|
||||||
|
|
||||||
In some circumstances, it makes sense for a Gradle invocation to read any existing cache entries but not to write changes back.
|
By default, the `gradle-build-action` will only write to the cache from Jobs on the default (`main`/`master`) branch.
|
||||||
For example, you may want to write cache entries for builds on your `main` branch, but not for any PR build invocations.
|
Jobs on other branches will read entries from the cache but will not write updated entries.
|
||||||
|
See [Optimizing cache effectiveness](#optimizing-cache-effectiveness) for a more detailed explanation.
|
||||||
|
|
||||||
You can enable read-only caching for any of the caches as follows:
|
In some circumstances it makes sense to change this default, and to configure a workflow Job to read existing cache entries but not to write changes back.
|
||||||
|
|
||||||
|
You can configure read-only caching for the `gradle-build-action` as follows:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# Only write to the cache for builds on the 'main' branch.
|
# Only write to the cache for builds on the 'main' and 'release' branches. (Default is 'main' only.)
|
||||||
# Builds on other branches will only read existing entries from the cache.
|
# Builds on other branches will only read existing entries from the cache.
|
||||||
cache-read-only: ${{ github.ref != 'refs/heads/main' }}
|
cache-read-only: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/release' }}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Gradle User Home cache tuning
|
### Gradle User Home cache tuning
|
||||||
@@ -272,13 +277,19 @@ Eviction of shared cache entries can reduce cache effectiveness, slowing down yo
|
|||||||
|
|
||||||
There are a number of actions you can take if your cache use is less effective due to entry eviction.
|
There are a number of actions you can take if your cache use is less effective due to entry eviction.
|
||||||
|
|
||||||
#### Only write to the cache from the default branch
|
#### Select branches that should write to the cache
|
||||||
|
|
||||||
GitHub cache entries are not shared between builds on different branches. This means that identical cache entries will be stored separately for different branches.
|
GitHub cache entries are not shared between builds on different branches. This means that identical cache entries will be stored separately for different branches.
|
||||||
The exception to the is cache entries for the default (`master`/`main`) branch can be read by actions invoked for other branches.
|
An exception to this is that cache entries for the default (`master`/`main`) branch can be read by actions invoked for other branches.
|
||||||
|
|
||||||
An easy way to reduce cache usage when you run builds on many different branches is to only permit your default branch to write to the cache,
|
By default, the `gradle-build-action` will only _write_ to the cache for builds run on the default branch.
|
||||||
with all other branch builds using `cache-read-only`. See [Using the caches read-only](#using-the-caches-read-only) for more details.
|
Jobs run on other branches will only read from the cache. In most cases, this is the desired behaviour,
|
||||||
|
because Jobs run against other branches will benefit from the cache Gradle User Home from `main`,
|
||||||
|
without writing private cache entries that could lead to evicting shared entries.
|
||||||
|
|
||||||
|
If you have other long-lived development branches that would benefit from writing to the cache,
|
||||||
|
you can configure these by overriding the `cache-read-only` action parameter.
|
||||||
|
See [Using the caches read-only](#using-the-caches-read-only) for more details.
|
||||||
|
|
||||||
Similarly, you could use `cache-read-only` for certain jobs in the workflow, and instead have these jobs reuse the cache content from upstream jobs.
|
Similarly, you could use `cache-read-only` for certain jobs in the workflow, and instead have these jobs reuse the cache content from upstream jobs.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
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
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#
|
|
||||||
# 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
5
__tests__/data/crypto-utils-test/.gitignore
vendored
@@ -1,5 +0,0 @@
|
|||||||
# Ignore Gradle project-specific cache directory
|
|
||||||
.gradle
|
|
||||||
|
|
||||||
# Ignore Gradle build output directory
|
|
||||||
build
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'java'
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
testImplementation('junit:junit:4.12')
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,5 +0,0 @@
|
|||||||
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
185
__tests__/data/crypto-utils-test/gradlew
vendored
@@ -1,185 +0,0 @@
|
|||||||
#!/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
104
__tests__/data/crypto-utils-test/gradlew.bat
vendored
@@ -1,104 +0,0 @@
|
|||||||
@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,10 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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'
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package basic;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class BasicTest {
|
|
||||||
@Test
|
|
||||||
public void test() {
|
|
||||||
assert true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
145
dist/main/index.js
vendored
145
dist/main/index.js
vendored
@@ -1134,6 +1134,8 @@ function createTar(archiveFolder, sourceDirectories, compressionMethod) {
|
|||||||
...getCompressionProgram(),
|
...getCompressionProgram(),
|
||||||
'-cf',
|
'-cf',
|
||||||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
|
'--exclude',
|
||||||
|
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
'-P',
|
'-P',
|
||||||
'-C',
|
'-C',
|
||||||
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
@@ -64909,10 +64911,17 @@ class GradleStateCache {
|
|||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const cacheKey = (0, cache_utils_1.generateCacheKey)(this.cacheName).key;
|
const cacheKey = (0, cache_utils_1.generateCacheKey)(this.cacheName).key;
|
||||||
const restoredCacheKey = core.getState(RESTORED_CACHE_KEY_KEY);
|
const restoredCacheKey = core.getState(RESTORED_CACHE_KEY_KEY);
|
||||||
const entryListener = listener.entry(this.cacheDescription);
|
const gradleHomeEntryListener = listener.entry(this.cacheDescription);
|
||||||
if (restoredCacheKey && cacheKey === restoredCacheKey) {
|
if (restoredCacheKey && cacheKey === restoredCacheKey) {
|
||||||
core.info(`Cache hit occurred on the cache key ${cacheKey}, not saving cache.`);
|
core.info(`Cache hit occurred on the cache key ${cacheKey}, not saving cache.`);
|
||||||
entryListener.markUnchanged('cache key not changed');
|
for (const entryListener of listener.cacheEntries) {
|
||||||
|
if (entryListener === gradleHomeEntryListener) {
|
||||||
|
entryListener.markUnsaved('cache key not changed');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
entryListener.markUnsaved(`referencing '${this.cacheDescription}' cache entry not saved`);
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -64924,7 +64933,7 @@ class GradleStateCache {
|
|||||||
}
|
}
|
||||||
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`);
|
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`);
|
||||||
const cachePath = this.getCachePath();
|
const cachePath = this.getCachePath();
|
||||||
yield (0, cache_utils_1.saveCache)(cachePath, cacheKey, entryListener);
|
yield (0, cache_utils_1.saveCache)(cachePath, cacheKey, gradleHomeEntryListener);
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -64964,13 +64973,13 @@ class GradleStateCache {
|
|||||||
initializeGradleUserHome(gradleUserHome, initScriptsDir) {
|
initializeGradleUserHome(gradleUserHome, initScriptsDir) {
|
||||||
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy'];
|
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy'];
|
||||||
for (const initScriptFilename of initScriptFilenames) {
|
for (const initScriptFilename of initScriptFilenames) {
|
||||||
const initScriptContent = this.readResourceAsString(initScriptFilename);
|
const initScriptContent = this.readInitScriptAsString(initScriptFilename);
|
||||||
const initScriptPath = path_1.default.resolve(initScriptsDir, initScriptFilename);
|
const initScriptPath = path_1.default.resolve(initScriptsDir, initScriptFilename);
|
||||||
fs_1.default.writeFileSync(initScriptPath, initScriptContent);
|
fs_1.default.writeFileSync(initScriptPath, initScriptContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
readResourceAsString(resource) {
|
readInitScriptAsString(resource) {
|
||||||
const absolutePath = path_1.default.resolve(__dirname, '..', '..', 'src', 'resources', resource);
|
const absolutePath = path_1.default.resolve(__dirname, '..', '..', 'src', 'resources', 'init-scripts', resource);
|
||||||
return fs_1.default.readFileSync(absolutePath, 'utf8');
|
return fs_1.default.readFileSync(absolutePath, 'utf8');
|
||||||
}
|
}
|
||||||
debugReportGradleUserHomeSize(label) {
|
debugReportGradleUserHomeSize(label) {
|
||||||
@@ -65154,7 +65163,7 @@ class AbstractEntryExtractor {
|
|||||||
const previouslyRestoredKey = (_a = previouslyRestoredEntries.find(x => x.artifactType === artifactType && x.pattern === pattern)) === null || _a === void 0 ? void 0 : _a.cacheKey;
|
const previouslyRestoredKey = (_a = previouslyRestoredEntries.find(x => x.artifactType === artifactType && x.pattern === pattern)) === null || _a === void 0 ? void 0 : _a.cacheKey;
|
||||||
if (previouslyRestoredKey === cacheKey) {
|
if (previouslyRestoredKey === cacheKey) {
|
||||||
(0, cache_utils_1.cacheDebug)(`No change to previously restored ${artifactType}. Not saving.`);
|
(0, cache_utils_1.cacheDebug)(`No change to previously restored ${artifactType}. Not saving.`);
|
||||||
entryListener.markUnchanged('contents unchanged');
|
entryListener.markUnsaved('contents unchanged');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`);
|
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`);
|
||||||
@@ -65232,9 +65241,9 @@ class GradleHomeEntryExtractor extends AbstractEntryExtractor {
|
|||||||
implicitDescendants: false,
|
implicitDescendants: false,
|
||||||
followSymbolicLinks: false
|
followSymbolicLinks: false
|
||||||
});
|
});
|
||||||
for (const p of yield globber.glob()) {
|
for (const wrapperZip of yield globber.glob()) {
|
||||||
(0, cache_utils_1.cacheDebug)(`Deleting wrapper zip: ${p}`);
|
(0, cache_utils_1.cacheDebug)(`Deleting wrapper zip: ${wrapperZip}`);
|
||||||
(0, cache_utils_1.tryDelete)(p);
|
yield (0, cache_utils_1.tryDelete)(wrapperZip);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -65399,8 +65408,8 @@ class CacheEntryListener {
|
|||||||
this.savedSize = 0;
|
this.savedSize = 0;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
markUnchanged(message) {
|
markUnsaved(message) {
|
||||||
this.unchanged = message;
|
this.unsaved = message;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65452,8 +65461,8 @@ function getRestoredMessage(entry, isCacheWriteOnly) {
|
|||||||
return '(Entry restored: partial match found)';
|
return '(Entry restored: partial match found)';
|
||||||
}
|
}
|
||||||
function getSavedMessage(entry, isCacheReadOnly) {
|
function getSavedMessage(entry, isCacheReadOnly) {
|
||||||
if (entry.unchanged) {
|
if (entry.unsaved) {
|
||||||
return `(Entry not saved: ${entry.unchanged})`;
|
return `(Entry not saved: ${entry.unsaved})`;
|
||||||
}
|
}
|
||||||
if (entry.savedKey === undefined) {
|
if (entry.savedKey === undefined) {
|
||||||
if (isCacheReadOnly) {
|
if (isCacheReadOnly) {
|
||||||
@@ -65474,12 +65483,9 @@ function getSize(cacheEntries, predicate) {
|
|||||||
return Math.round(bytes / (1024 * 1024));
|
return Math.round(bytes / (1024 * 1024));
|
||||||
}
|
}
|
||||||
function formatSize(bytes) {
|
function formatSize(bytes) {
|
||||||
if (bytes === undefined) {
|
if (bytes === undefined || bytes === 0) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
if (bytes === 0) {
|
|
||||||
return '0 (Entry already exists)';
|
|
||||||
}
|
|
||||||
return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)`;
|
return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65528,6 +65534,7 @@ exports.tryDelete = exports.handleCacheFailure = exports.cacheDebug = exports.sa
|
|||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const cache = __importStar(__nccwpck_require__(7799));
|
const cache = __importStar(__nccwpck_require__(7799));
|
||||||
const github = __importStar(__nccwpck_require__(5438));
|
const github = __importStar(__nccwpck_require__(5438));
|
||||||
|
const exec = __importStar(__nccwpck_require__(1514));
|
||||||
const crypto = __importStar(__nccwpck_require__(6113));
|
const crypto = __importStar(__nccwpck_require__(6113));
|
||||||
const path = __importStar(__nccwpck_require__(1017));
|
const path = __importStar(__nccwpck_require__(1017));
|
||||||
const fs = __importStar(__nccwpck_require__(7147));
|
const fs = __importStar(__nccwpck_require__(7147));
|
||||||
@@ -65639,7 +65646,7 @@ function saveCache(cachePath, cacheKey, listener) {
|
|||||||
if (error instanceof cache.ReserveCacheError) {
|
if (error instanceof cache.ReserveCacheError) {
|
||||||
listener.markAlreadyExists(cacheKey);
|
listener.markAlreadyExists(cacheKey);
|
||||||
}
|
}
|
||||||
handleCacheFailure(error, `Failed to save cache entry ${cacheKey}`);
|
handleCacheFailure(error, `Failed to save cache entry with path '${cachePath}' and key: ${cacheKey}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -65670,9 +65677,13 @@ function handleCacheFailure(error, message) {
|
|||||||
exports.handleCacheFailure = handleCacheFailure;
|
exports.handleCacheFailure = handleCacheFailure;
|
||||||
function tryDelete(file) {
|
function tryDelete(file) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const stat = fs.lstatSync(file);
|
const maxAttempts = 5;
|
||||||
for (let count = 0; count < 3; count++) {
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||||
|
if (!fs.existsSync(file)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
|
const stat = fs.lstatSync(file);
|
||||||
if (stat.isDirectory()) {
|
if (stat.isDirectory()) {
|
||||||
fs.rmdirSync(file, { recursive: true });
|
fs.rmdirSync(file, { recursive: true });
|
||||||
}
|
}
|
||||||
@@ -65682,11 +65693,14 @@ function tryDelete(file) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
if (count === 2) {
|
if (attempt === maxAttempts) {
|
||||||
|
core.warning(`Failed to delete ${file}, which will impact caching.
|
||||||
|
It is likely locked by another process. Output of 'jps -ml':
|
||||||
|
${yield getJavaProcesses()}`);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core.warning(String(error));
|
cacheDebug(`Attempt to delete ${file} failed. Will try again.`);
|
||||||
yield delay(1000);
|
yield delay(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65699,6 +65713,12 @@ function delay(ms) {
|
|||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function getJavaProcesses() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const jpsOutput = yield exec.getExecOutput('jps', ['-lm']);
|
||||||
|
return jpsOutput.stdout;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -65968,6 +65988,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
__setModuleDefault(result, mod);
|
__setModuleDefault(result, mod);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
@@ -65978,6 +66007,7 @@ const fs_1 = __importDefault(__nccwpck_require__(7147));
|
|||||||
const path_1 = __importDefault(__nccwpck_require__(1017));
|
const path_1 = __importDefault(__nccwpck_require__(1017));
|
||||||
const cache_reporting_1 = __nccwpck_require__(6674);
|
const cache_reporting_1 = __nccwpck_require__(6674);
|
||||||
function writeJobSummary(buildResults, cacheListener) {
|
function writeJobSummary(buildResults, cacheListener) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
core.info('Writing job summary');
|
core.info('Writing job summary');
|
||||||
if (buildResults.length === 0) {
|
if (buildResults.length === 0) {
|
||||||
core.debug('No Gradle build results found. Summary table will not be generated.');
|
core.debug('No Gradle build results found. Summary table will not be generated.');
|
||||||
@@ -65986,7 +66016,8 @@ function writeJobSummary(buildResults, cacheListener) {
|
|||||||
writeSummaryTable(buildResults);
|
writeSummaryTable(buildResults);
|
||||||
}
|
}
|
||||||
(0, cache_reporting_1.logCachingReport)(cacheListener);
|
(0, cache_reporting_1.logCachingReport)(cacheListener);
|
||||||
core.summary.write();
|
yield core.summary.write();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
exports.writeJobSummary = writeJobSummary;
|
exports.writeJobSummary = writeJobSummary;
|
||||||
function loadBuildResults() {
|
function loadBuildResults() {
|
||||||
@@ -66003,28 +66034,43 @@ function loadBuildResults() {
|
|||||||
exports.loadBuildResults = loadBuildResults;
|
exports.loadBuildResults = loadBuildResults;
|
||||||
function writeSummaryTable(results) {
|
function writeSummaryTable(results) {
|
||||||
core.summary.addHeading('Gradle Builds', 3);
|
core.summary.addHeading('Gradle Builds', 3);
|
||||||
core.summary.addTable([
|
core.summary.addRaw(`
|
||||||
[
|
<table>
|
||||||
{ data: 'Root Project', header: true },
|
<tr>
|
||||||
{ data: 'Tasks', header: true },
|
<th>Root Project</th>
|
||||||
{ data: 'Gradle Version', header: true },
|
<th>Requested Tasks</th>
|
||||||
{ data: 'Outcome', header: true }
|
<th>Gradle Version</th>
|
||||||
],
|
<th>Build Outcome</th>
|
||||||
...results.map(result => [
|
<th>Build Scan™</th>
|
||||||
result.rootProjectName,
|
</tr>${results.map(result => renderBuildResultRow(result)).join('')}
|
||||||
result.requestedTasks,
|
</table>
|
||||||
result.gradleVersion,
|
`);
|
||||||
renderOutcome(result)
|
}
|
||||||
])
|
function renderBuildResultRow(result) {
|
||||||
]);
|
return `
|
||||||
core.summary.addRaw('\n');
|
<tr>
|
||||||
|
<td>${result.rootProjectName}</td>
|
||||||
|
<td>${result.requestedTasks}</td>
|
||||||
|
<td align='center'>${result.gradleVersion}</td>
|
||||||
|
<td align='center'>${renderOutcome(result)}</td>
|
||||||
|
<td>${renderBuildScan(result)}</td>
|
||||||
|
</tr>`;
|
||||||
}
|
}
|
||||||
function renderOutcome(result) {
|
function renderOutcome(result) {
|
||||||
const labelPart = result.buildScanUri ? 'Build%20Scan%E2%84%A2' : 'Build';
|
return result.buildFailed ? ':x:' : ':white_check_mark:';
|
||||||
const outcomePart = result.buildFailed ? 'FAILED-red' : 'SUCCESS-brightgreen';
|
}
|
||||||
const badgeUrl = `https://img.shields.io/badge/${labelPart}-${outcomePart}?logo=Gradle`;
|
function renderBuildScan(result) {
|
||||||
const badgeHtml = `<img src="${badgeUrl}" alt="Gradle Build">`;
|
if (result.buildScanFailed) {
|
||||||
const targetUrl = result.buildScanUri ? result.buildScanUri : '#';
|
return renderBuildScanBadge('PUBLISH_FAILED', 'orange', 'https://docs.gradle.com/enterprise/gradle-plugin/#troubleshooting');
|
||||||
|
}
|
||||||
|
if (result.buildScanUri) {
|
||||||
|
return renderBuildScanBadge('PUBLISHED', '06A0CE', result.buildScanUri);
|
||||||
|
}
|
||||||
|
return renderBuildScanBadge('NOT_PUBLISHED', 'lightgrey', 'https://scans.gradle.com');
|
||||||
|
}
|
||||||
|
function renderBuildScanBadge(outcomeText, outcomeColor, targetUrl) {
|
||||||
|
const badgeUrl = `https://img.shields.io/badge/Build%20Scan%E2%84%A2-${outcomeText}-${outcomeColor}?logo=Gradle`;
|
||||||
|
const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />`;
|
||||||
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`;
|
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66372,6 +66418,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|||||||
exports.complete = exports.setup = void 0;
|
exports.complete = exports.setup = void 0;
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const exec = __importStar(__nccwpck_require__(1514));
|
const exec = __importStar(__nccwpck_require__(1514));
|
||||||
|
const summary_1 = __nccwpck_require__(1327);
|
||||||
const fs = __importStar(__nccwpck_require__(7147));
|
const fs = __importStar(__nccwpck_require__(7147));
|
||||||
const path = __importStar(__nccwpck_require__(1017));
|
const path = __importStar(__nccwpck_require__(1017));
|
||||||
const os = __importStar(__nccwpck_require__(2037));
|
const os = __importStar(__nccwpck_require__(2037));
|
||||||
@@ -66381,6 +66428,13 @@ const job_summary_1 = __nccwpck_require__(7345);
|
|||||||
const GRADLE_SETUP_VAR = 'GRADLE_BUILD_ACTION_SETUP_COMPLETED';
|
const GRADLE_SETUP_VAR = 'GRADLE_BUILD_ACTION_SETUP_COMPLETED';
|
||||||
const GRADLE_USER_HOME = 'GRADLE_USER_HOME';
|
const GRADLE_USER_HOME = 'GRADLE_USER_HOME';
|
||||||
const CACHE_LISTENER = 'CACHE_LISTENER';
|
const CACHE_LISTENER = 'CACHE_LISTENER';
|
||||||
|
const JOB_SUMMARY_ENABLED_PARAMETER = 'generate-job-summary';
|
||||||
|
function shouldGenerateJobSummary() {
|
||||||
|
if (!process.env[summary_1.SUMMARY_ENV_VAR]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return core.getBooleanInput(JOB_SUMMARY_ENABLED_PARAMETER);
|
||||||
|
}
|
||||||
function setup(buildRootDirectory) {
|
function setup(buildRootDirectory) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const gradleUserHome = yield determineGradleUserHome(buildRootDirectory);
|
const gradleUserHome = yield determineGradleUserHome(buildRootDirectory);
|
||||||
@@ -66399,7 +66453,6 @@ function setup(buildRootDirectory) {
|
|||||||
exports.setup = setup;
|
exports.setup = setup;
|
||||||
function complete() {
|
function complete() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
core.info('Inside setupGradle.complete()');
|
|
||||||
if (!core.getState(GRADLE_SETUP_VAR)) {
|
if (!core.getState(GRADLE_SETUP_VAR)) {
|
||||||
core.info('Gradle setup post-action only performed for first gradle-build-action step in workflow.');
|
core.info('Gradle setup post-action only performed for first gradle-build-action step in workflow.');
|
||||||
return;
|
return;
|
||||||
@@ -66411,7 +66464,9 @@ function complete() {
|
|||||||
const cacheListener = cache_reporting_1.CacheListener.rehydrate(core.getState(CACHE_LISTENER));
|
const cacheListener = cache_reporting_1.CacheListener.rehydrate(core.getState(CACHE_LISTENER));
|
||||||
const gradleUserHome = core.getState(GRADLE_USER_HOME);
|
const gradleUserHome = core.getState(GRADLE_USER_HOME);
|
||||||
yield caches.save(gradleUserHome, cacheListener);
|
yield caches.save(gradleUserHome, cacheListener);
|
||||||
|
if (shouldGenerateJobSummary()) {
|
||||||
(0, job_summary_1.writeJobSummary)(buildResults, cacheListener);
|
(0, job_summary_1.writeJobSummary)(buildResults, cacheListener);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.complete = complete;
|
exports.complete = complete;
|
||||||
|
|||||||
2
dist/main/index.js.map
vendored
2
dist/main/index.js.map
vendored
File diff suppressed because one or more lines are too long
145
dist/post/index.js
vendored
145
dist/post/index.js
vendored
@@ -1134,6 +1134,8 @@ function createTar(archiveFolder, sourceDirectories, compressionMethod) {
|
|||||||
...getCompressionProgram(),
|
...getCompressionProgram(),
|
||||||
'-cf',
|
'-cf',
|
||||||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
|
'--exclude',
|
||||||
|
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
'-P',
|
'-P',
|
||||||
'-C',
|
'-C',
|
||||||
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||||
@@ -63960,10 +63962,17 @@ class GradleStateCache {
|
|||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const cacheKey = (0, cache_utils_1.generateCacheKey)(this.cacheName).key;
|
const cacheKey = (0, cache_utils_1.generateCacheKey)(this.cacheName).key;
|
||||||
const restoredCacheKey = core.getState(RESTORED_CACHE_KEY_KEY);
|
const restoredCacheKey = core.getState(RESTORED_CACHE_KEY_KEY);
|
||||||
const entryListener = listener.entry(this.cacheDescription);
|
const gradleHomeEntryListener = listener.entry(this.cacheDescription);
|
||||||
if (restoredCacheKey && cacheKey === restoredCacheKey) {
|
if (restoredCacheKey && cacheKey === restoredCacheKey) {
|
||||||
core.info(`Cache hit occurred on the cache key ${cacheKey}, not saving cache.`);
|
core.info(`Cache hit occurred on the cache key ${cacheKey}, not saving cache.`);
|
||||||
entryListener.markUnchanged('cache key not changed');
|
for (const entryListener of listener.cacheEntries) {
|
||||||
|
if (entryListener === gradleHomeEntryListener) {
|
||||||
|
entryListener.markUnsaved('cache key not changed');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
entryListener.markUnsaved(`referencing '${this.cacheDescription}' cache entry not saved`);
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -63975,7 +63984,7 @@ class GradleStateCache {
|
|||||||
}
|
}
|
||||||
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`);
|
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`);
|
||||||
const cachePath = this.getCachePath();
|
const cachePath = this.getCachePath();
|
||||||
yield (0, cache_utils_1.saveCache)(cachePath, cacheKey, entryListener);
|
yield (0, cache_utils_1.saveCache)(cachePath, cacheKey, gradleHomeEntryListener);
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -64015,13 +64024,13 @@ class GradleStateCache {
|
|||||||
initializeGradleUserHome(gradleUserHome, initScriptsDir) {
|
initializeGradleUserHome(gradleUserHome, initScriptsDir) {
|
||||||
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy'];
|
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy'];
|
||||||
for (const initScriptFilename of initScriptFilenames) {
|
for (const initScriptFilename of initScriptFilenames) {
|
||||||
const initScriptContent = this.readResourceAsString(initScriptFilename);
|
const initScriptContent = this.readInitScriptAsString(initScriptFilename);
|
||||||
const initScriptPath = path_1.default.resolve(initScriptsDir, initScriptFilename);
|
const initScriptPath = path_1.default.resolve(initScriptsDir, initScriptFilename);
|
||||||
fs_1.default.writeFileSync(initScriptPath, initScriptContent);
|
fs_1.default.writeFileSync(initScriptPath, initScriptContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
readResourceAsString(resource) {
|
readInitScriptAsString(resource) {
|
||||||
const absolutePath = path_1.default.resolve(__dirname, '..', '..', 'src', 'resources', resource);
|
const absolutePath = path_1.default.resolve(__dirname, '..', '..', 'src', 'resources', 'init-scripts', resource);
|
||||||
return fs_1.default.readFileSync(absolutePath, 'utf8');
|
return fs_1.default.readFileSync(absolutePath, 'utf8');
|
||||||
}
|
}
|
||||||
debugReportGradleUserHomeSize(label) {
|
debugReportGradleUserHomeSize(label) {
|
||||||
@@ -64205,7 +64214,7 @@ class AbstractEntryExtractor {
|
|||||||
const previouslyRestoredKey = (_a = previouslyRestoredEntries.find(x => x.artifactType === artifactType && x.pattern === pattern)) === null || _a === void 0 ? void 0 : _a.cacheKey;
|
const previouslyRestoredKey = (_a = previouslyRestoredEntries.find(x => x.artifactType === artifactType && x.pattern === pattern)) === null || _a === void 0 ? void 0 : _a.cacheKey;
|
||||||
if (previouslyRestoredKey === cacheKey) {
|
if (previouslyRestoredKey === cacheKey) {
|
||||||
(0, cache_utils_1.cacheDebug)(`No change to previously restored ${artifactType}. Not saving.`);
|
(0, cache_utils_1.cacheDebug)(`No change to previously restored ${artifactType}. Not saving.`);
|
||||||
entryListener.markUnchanged('contents unchanged');
|
entryListener.markUnsaved('contents unchanged');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`);
|
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`);
|
||||||
@@ -64283,9 +64292,9 @@ class GradleHomeEntryExtractor extends AbstractEntryExtractor {
|
|||||||
implicitDescendants: false,
|
implicitDescendants: false,
|
||||||
followSymbolicLinks: false
|
followSymbolicLinks: false
|
||||||
});
|
});
|
||||||
for (const p of yield globber.glob()) {
|
for (const wrapperZip of yield globber.glob()) {
|
||||||
(0, cache_utils_1.cacheDebug)(`Deleting wrapper zip: ${p}`);
|
(0, cache_utils_1.cacheDebug)(`Deleting wrapper zip: ${wrapperZip}`);
|
||||||
(0, cache_utils_1.tryDelete)(p);
|
yield (0, cache_utils_1.tryDelete)(wrapperZip);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -64450,8 +64459,8 @@ class CacheEntryListener {
|
|||||||
this.savedSize = 0;
|
this.savedSize = 0;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
markUnchanged(message) {
|
markUnsaved(message) {
|
||||||
this.unchanged = message;
|
this.unsaved = message;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64503,8 +64512,8 @@ function getRestoredMessage(entry, isCacheWriteOnly) {
|
|||||||
return '(Entry restored: partial match found)';
|
return '(Entry restored: partial match found)';
|
||||||
}
|
}
|
||||||
function getSavedMessage(entry, isCacheReadOnly) {
|
function getSavedMessage(entry, isCacheReadOnly) {
|
||||||
if (entry.unchanged) {
|
if (entry.unsaved) {
|
||||||
return `(Entry not saved: ${entry.unchanged})`;
|
return `(Entry not saved: ${entry.unsaved})`;
|
||||||
}
|
}
|
||||||
if (entry.savedKey === undefined) {
|
if (entry.savedKey === undefined) {
|
||||||
if (isCacheReadOnly) {
|
if (isCacheReadOnly) {
|
||||||
@@ -64525,12 +64534,9 @@ function getSize(cacheEntries, predicate) {
|
|||||||
return Math.round(bytes / (1024 * 1024));
|
return Math.round(bytes / (1024 * 1024));
|
||||||
}
|
}
|
||||||
function formatSize(bytes) {
|
function formatSize(bytes) {
|
||||||
if (bytes === undefined) {
|
if (bytes === undefined || bytes === 0) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
if (bytes === 0) {
|
|
||||||
return '0 (Entry already exists)';
|
|
||||||
}
|
|
||||||
return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)`;
|
return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64579,6 +64585,7 @@ exports.tryDelete = exports.handleCacheFailure = exports.cacheDebug = exports.sa
|
|||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const cache = __importStar(__nccwpck_require__(7799));
|
const cache = __importStar(__nccwpck_require__(7799));
|
||||||
const github = __importStar(__nccwpck_require__(5438));
|
const github = __importStar(__nccwpck_require__(5438));
|
||||||
|
const exec = __importStar(__nccwpck_require__(1514));
|
||||||
const crypto = __importStar(__nccwpck_require__(6113));
|
const crypto = __importStar(__nccwpck_require__(6113));
|
||||||
const path = __importStar(__nccwpck_require__(1017));
|
const path = __importStar(__nccwpck_require__(1017));
|
||||||
const fs = __importStar(__nccwpck_require__(7147));
|
const fs = __importStar(__nccwpck_require__(7147));
|
||||||
@@ -64690,7 +64697,7 @@ function saveCache(cachePath, cacheKey, listener) {
|
|||||||
if (error instanceof cache.ReserveCacheError) {
|
if (error instanceof cache.ReserveCacheError) {
|
||||||
listener.markAlreadyExists(cacheKey);
|
listener.markAlreadyExists(cacheKey);
|
||||||
}
|
}
|
||||||
handleCacheFailure(error, `Failed to save cache entry ${cacheKey}`);
|
handleCacheFailure(error, `Failed to save cache entry with path '${cachePath}' and key: ${cacheKey}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -64721,9 +64728,13 @@ function handleCacheFailure(error, message) {
|
|||||||
exports.handleCacheFailure = handleCacheFailure;
|
exports.handleCacheFailure = handleCacheFailure;
|
||||||
function tryDelete(file) {
|
function tryDelete(file) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const stat = fs.lstatSync(file);
|
const maxAttempts = 5;
|
||||||
for (let count = 0; count < 3; count++) {
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||||
|
if (!fs.existsSync(file)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
|
const stat = fs.lstatSync(file);
|
||||||
if (stat.isDirectory()) {
|
if (stat.isDirectory()) {
|
||||||
fs.rmdirSync(file, { recursive: true });
|
fs.rmdirSync(file, { recursive: true });
|
||||||
}
|
}
|
||||||
@@ -64733,11 +64744,14 @@ function tryDelete(file) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
if (count === 2) {
|
if (attempt === maxAttempts) {
|
||||||
|
core.warning(`Failed to delete ${file}, which will impact caching.
|
||||||
|
It is likely locked by another process. Output of 'jps -ml':
|
||||||
|
${yield getJavaProcesses()}`);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core.warning(String(error));
|
cacheDebug(`Attempt to delete ${file} failed. Will try again.`);
|
||||||
yield delay(1000);
|
yield delay(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64750,6 +64764,12 @@ function delay(ms) {
|
|||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function getJavaProcesses() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const jpsOutput = yield exec.getExecOutput('jps', ['-lm']);
|
||||||
|
return jpsOutput.stdout;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -64888,6 +64908,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
__setModuleDefault(result, mod);
|
__setModuleDefault(result, mod);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
@@ -64898,6 +64927,7 @@ const fs_1 = __importDefault(__nccwpck_require__(7147));
|
|||||||
const path_1 = __importDefault(__nccwpck_require__(1017));
|
const path_1 = __importDefault(__nccwpck_require__(1017));
|
||||||
const cache_reporting_1 = __nccwpck_require__(6674);
|
const cache_reporting_1 = __nccwpck_require__(6674);
|
||||||
function writeJobSummary(buildResults, cacheListener) {
|
function writeJobSummary(buildResults, cacheListener) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
core.info('Writing job summary');
|
core.info('Writing job summary');
|
||||||
if (buildResults.length === 0) {
|
if (buildResults.length === 0) {
|
||||||
core.debug('No Gradle build results found. Summary table will not be generated.');
|
core.debug('No Gradle build results found. Summary table will not be generated.');
|
||||||
@@ -64906,7 +64936,8 @@ function writeJobSummary(buildResults, cacheListener) {
|
|||||||
writeSummaryTable(buildResults);
|
writeSummaryTable(buildResults);
|
||||||
}
|
}
|
||||||
(0, cache_reporting_1.logCachingReport)(cacheListener);
|
(0, cache_reporting_1.logCachingReport)(cacheListener);
|
||||||
core.summary.write();
|
yield core.summary.write();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
exports.writeJobSummary = writeJobSummary;
|
exports.writeJobSummary = writeJobSummary;
|
||||||
function loadBuildResults() {
|
function loadBuildResults() {
|
||||||
@@ -64923,28 +64954,43 @@ function loadBuildResults() {
|
|||||||
exports.loadBuildResults = loadBuildResults;
|
exports.loadBuildResults = loadBuildResults;
|
||||||
function writeSummaryTable(results) {
|
function writeSummaryTable(results) {
|
||||||
core.summary.addHeading('Gradle Builds', 3);
|
core.summary.addHeading('Gradle Builds', 3);
|
||||||
core.summary.addTable([
|
core.summary.addRaw(`
|
||||||
[
|
<table>
|
||||||
{ data: 'Root Project', header: true },
|
<tr>
|
||||||
{ data: 'Tasks', header: true },
|
<th>Root Project</th>
|
||||||
{ data: 'Gradle Version', header: true },
|
<th>Requested Tasks</th>
|
||||||
{ data: 'Outcome', header: true }
|
<th>Gradle Version</th>
|
||||||
],
|
<th>Build Outcome</th>
|
||||||
...results.map(result => [
|
<th>Build Scan™</th>
|
||||||
result.rootProjectName,
|
</tr>${results.map(result => renderBuildResultRow(result)).join('')}
|
||||||
result.requestedTasks,
|
</table>
|
||||||
result.gradleVersion,
|
`);
|
||||||
renderOutcome(result)
|
}
|
||||||
])
|
function renderBuildResultRow(result) {
|
||||||
]);
|
return `
|
||||||
core.summary.addRaw('\n');
|
<tr>
|
||||||
|
<td>${result.rootProjectName}</td>
|
||||||
|
<td>${result.requestedTasks}</td>
|
||||||
|
<td align='center'>${result.gradleVersion}</td>
|
||||||
|
<td align='center'>${renderOutcome(result)}</td>
|
||||||
|
<td>${renderBuildScan(result)}</td>
|
||||||
|
</tr>`;
|
||||||
}
|
}
|
||||||
function renderOutcome(result) {
|
function renderOutcome(result) {
|
||||||
const labelPart = result.buildScanUri ? 'Build%20Scan%E2%84%A2' : 'Build';
|
return result.buildFailed ? ':x:' : ':white_check_mark:';
|
||||||
const outcomePart = result.buildFailed ? 'FAILED-red' : 'SUCCESS-brightgreen';
|
}
|
||||||
const badgeUrl = `https://img.shields.io/badge/${labelPart}-${outcomePart}?logo=Gradle`;
|
function renderBuildScan(result) {
|
||||||
const badgeHtml = `<img src="${badgeUrl}" alt="Gradle Build">`;
|
if (result.buildScanFailed) {
|
||||||
const targetUrl = result.buildScanUri ? result.buildScanUri : '#';
|
return renderBuildScanBadge('PUBLISH_FAILED', 'orange', 'https://docs.gradle.com/enterprise/gradle-plugin/#troubleshooting');
|
||||||
|
}
|
||||||
|
if (result.buildScanUri) {
|
||||||
|
return renderBuildScanBadge('PUBLISHED', '06A0CE', result.buildScanUri);
|
||||||
|
}
|
||||||
|
return renderBuildScanBadge('NOT_PUBLISHED', 'lightgrey', 'https://scans.gradle.com');
|
||||||
|
}
|
||||||
|
function renderBuildScanBadge(outcomeText, outcomeColor, targetUrl) {
|
||||||
|
const badgeUrl = `https://img.shields.io/badge/Build%20Scan%E2%84%A2-${outcomeText}-${outcomeColor}?logo=Gradle`;
|
||||||
|
const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />`;
|
||||||
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`;
|
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65056,6 +65102,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|||||||
exports.complete = exports.setup = void 0;
|
exports.complete = exports.setup = void 0;
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const exec = __importStar(__nccwpck_require__(1514));
|
const exec = __importStar(__nccwpck_require__(1514));
|
||||||
|
const summary_1 = __nccwpck_require__(1327);
|
||||||
const fs = __importStar(__nccwpck_require__(7147));
|
const fs = __importStar(__nccwpck_require__(7147));
|
||||||
const path = __importStar(__nccwpck_require__(1017));
|
const path = __importStar(__nccwpck_require__(1017));
|
||||||
const os = __importStar(__nccwpck_require__(2037));
|
const os = __importStar(__nccwpck_require__(2037));
|
||||||
@@ -65065,6 +65112,13 @@ const job_summary_1 = __nccwpck_require__(7345);
|
|||||||
const GRADLE_SETUP_VAR = 'GRADLE_BUILD_ACTION_SETUP_COMPLETED';
|
const GRADLE_SETUP_VAR = 'GRADLE_BUILD_ACTION_SETUP_COMPLETED';
|
||||||
const GRADLE_USER_HOME = 'GRADLE_USER_HOME';
|
const GRADLE_USER_HOME = 'GRADLE_USER_HOME';
|
||||||
const CACHE_LISTENER = 'CACHE_LISTENER';
|
const CACHE_LISTENER = 'CACHE_LISTENER';
|
||||||
|
const JOB_SUMMARY_ENABLED_PARAMETER = 'generate-job-summary';
|
||||||
|
function shouldGenerateJobSummary() {
|
||||||
|
if (!process.env[summary_1.SUMMARY_ENV_VAR]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return core.getBooleanInput(JOB_SUMMARY_ENABLED_PARAMETER);
|
||||||
|
}
|
||||||
function setup(buildRootDirectory) {
|
function setup(buildRootDirectory) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const gradleUserHome = yield determineGradleUserHome(buildRootDirectory);
|
const gradleUserHome = yield determineGradleUserHome(buildRootDirectory);
|
||||||
@@ -65083,7 +65137,6 @@ function setup(buildRootDirectory) {
|
|||||||
exports.setup = setup;
|
exports.setup = setup;
|
||||||
function complete() {
|
function complete() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
core.info('Inside setupGradle.complete()');
|
|
||||||
if (!core.getState(GRADLE_SETUP_VAR)) {
|
if (!core.getState(GRADLE_SETUP_VAR)) {
|
||||||
core.info('Gradle setup post-action only performed for first gradle-build-action step in workflow.');
|
core.info('Gradle setup post-action only performed for first gradle-build-action step in workflow.');
|
||||||
return;
|
return;
|
||||||
@@ -65095,7 +65148,9 @@ function complete() {
|
|||||||
const cacheListener = cache_reporting_1.CacheListener.rehydrate(core.getState(CACHE_LISTENER));
|
const cacheListener = cache_reporting_1.CacheListener.rehydrate(core.getState(CACHE_LISTENER));
|
||||||
const gradleUserHome = core.getState(GRADLE_USER_HOME);
|
const gradleUserHome = core.getState(GRADLE_USER_HOME);
|
||||||
yield caches.save(gradleUserHome, cacheListener);
|
yield caches.save(gradleUserHome, cacheListener);
|
||||||
|
if (shouldGenerateJobSummary()) {
|
||||||
(0, job_summary_1.writeJobSummary)(buildResults, cacheListener);
|
(0, job_summary_1.writeJobSummary)(buildResults, cacheListener);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.complete = complete;
|
exports.complete = complete;
|
||||||
|
|||||||
2
dist/post/index.js.map
vendored
2
dist/post/index.js.map
vendored
File diff suppressed because one or more lines are too long
1541
package-lock.json
generated
1541
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
@@ -25,7 +25,7 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/cache": "2.0.5",
|
"@actions/cache": "2.0.6",
|
||||||
"@actions/core": "1.8.2",
|
"@actions/core": "1.8.2",
|
||||||
"@actions/exec": "1.1.1",
|
"@actions/exec": "1.1.1",
|
||||||
"@actions/github": "5.0.3",
|
"@actions/github": "5.0.3",
|
||||||
@@ -35,19 +35,19 @@
|
|||||||
"string-argv": "0.3.1"
|
"string-argv": "0.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "28.1.0",
|
"@types/jest": "28.1.1",
|
||||||
"@types/node": "16.11.21",
|
"@types/node": "16.11.21",
|
||||||
"@types/unzipper": "0.10.5",
|
"@types/unzipper": "0.10.5",
|
||||||
"@typescript-eslint/parser": "5.27.0",
|
"@typescript-eslint/parser": "5.28.0",
|
||||||
"@vercel/ncc": "0.34.0",
|
"@vercel/ncc": "0.34.0",
|
||||||
"eslint": "8.17.0",
|
"eslint": "8.17.0",
|
||||||
"eslint-plugin-github": "4.3.6",
|
"eslint-plugin-github": "4.3.6",
|
||||||
"eslint-plugin-jest": "26.4.6",
|
"eslint-plugin-jest": "26.5.3",
|
||||||
"jest": "28.1.0",
|
"jest": "28.1.1",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
"patch-package": "6.4.7",
|
"patch-package": "6.4.7",
|
||||||
"prettier": "2.6.2",
|
"prettier": "2.7.0",
|
||||||
"ts-jest": "28.0.4",
|
"ts-jest": "28.0.5",
|
||||||
"typescript": "4.7.3"
|
"typescript": "4.7.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,11 +94,18 @@ export class GradleStateCache {
|
|||||||
async save(listener: CacheListener): Promise<void> {
|
async save(listener: CacheListener): Promise<void> {
|
||||||
const cacheKey = generateCacheKey(this.cacheName).key
|
const cacheKey = generateCacheKey(this.cacheName).key
|
||||||
const restoredCacheKey = core.getState(RESTORED_CACHE_KEY_KEY)
|
const restoredCacheKey = core.getState(RESTORED_CACHE_KEY_KEY)
|
||||||
const entryListener = listener.entry(this.cacheDescription)
|
const gradleHomeEntryListener = listener.entry(this.cacheDescription)
|
||||||
|
|
||||||
if (restoredCacheKey && cacheKey === restoredCacheKey) {
|
if (restoredCacheKey && cacheKey === restoredCacheKey) {
|
||||||
core.info(`Cache hit occurred on the cache key ${cacheKey}, not saving cache.`)
|
core.info(`Cache hit occurred on the cache key ${cacheKey}, not saving cache.`)
|
||||||
entryListener.markUnchanged('cache key not changed')
|
|
||||||
|
for (const entryListener of listener.cacheEntries) {
|
||||||
|
if (entryListener === gradleHomeEntryListener) {
|
||||||
|
entryListener.markUnsaved('cache key not changed')
|
||||||
|
} else {
|
||||||
|
entryListener.markUnsaved(`referencing '${this.cacheDescription}' cache entry not saved`)
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +118,7 @@ export class GradleStateCache {
|
|||||||
|
|
||||||
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`)
|
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`)
|
||||||
const cachePath = this.getCachePath()
|
const cachePath = this.getCachePath()
|
||||||
await saveCache(cachePath, cacheKey, entryListener)
|
await saveCache(cachePath, cacheKey, gradleHomeEntryListener)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -168,15 +175,15 @@ export class GradleStateCache {
|
|||||||
private initializeGradleUserHome(gradleUserHome: string, initScriptsDir: string): void {
|
private initializeGradleUserHome(gradleUserHome: string, initScriptsDir: string): void {
|
||||||
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy']
|
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy']
|
||||||
for (const initScriptFilename of initScriptFilenames) {
|
for (const initScriptFilename of initScriptFilenames) {
|
||||||
const initScriptContent = this.readResourceAsString(initScriptFilename)
|
const initScriptContent = this.readInitScriptAsString(initScriptFilename)
|
||||||
const initScriptPath = path.resolve(initScriptsDir, initScriptFilename)
|
const initScriptPath = path.resolve(initScriptsDir, initScriptFilename)
|
||||||
fs.writeFileSync(initScriptPath, initScriptContent)
|
fs.writeFileSync(initScriptPath, initScriptContent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readResourceAsString(resource: string): string {
|
private readInitScriptAsString(resource: string): string {
|
||||||
// Resolving relative to __dirname will allow node to find the resource at runtime
|
// Resolving relative to __dirname will allow node to find the resource at runtime
|
||||||
const absolutePath = path.resolve(__dirname, '..', '..', 'src', 'resources', resource)
|
const absolutePath = path.resolve(__dirname, '..', '..', 'src', 'resources', 'init-scripts', resource)
|
||||||
return fs.readFileSync(absolutePath, 'utf8')
|
return fs.readFileSync(absolutePath, 'utf8')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ abstract class AbstractEntryExtractor {
|
|||||||
|
|
||||||
if (previouslyRestoredKey === cacheKey) {
|
if (previouslyRestoredKey === cacheKey) {
|
||||||
cacheDebug(`No change to previously restored ${artifactType}. Not saving.`)
|
cacheDebug(`No change to previously restored ${artifactType}. Not saving.`)
|
||||||
entryListener.markUnchanged('contents unchanged')
|
entryListener.markUnsaved('contents unchanged')
|
||||||
} else {
|
} else {
|
||||||
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`)
|
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`)
|
||||||
await saveCache([pattern], cacheKey, entryListener)
|
await saveCache([pattern], cacheKey, entryListener)
|
||||||
@@ -312,9 +312,9 @@ export class GradleHomeEntryExtractor extends AbstractEntryExtractor {
|
|||||||
followSymbolicLinks: false
|
followSymbolicLinks: false
|
||||||
})
|
})
|
||||||
|
|
||||||
for (const p of await globber.glob()) {
|
for (const wrapperZip of await globber.glob()) {
|
||||||
cacheDebug(`Deleting wrapper zip: ${p}`)
|
cacheDebug(`Deleting wrapper zip: ${wrapperZip}`)
|
||||||
tryDelete(p)
|
await tryDelete(wrapperZip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export class CacheEntryListener {
|
|||||||
savedKey: string | undefined
|
savedKey: string | undefined
|
||||||
savedSize: number | undefined
|
savedSize: number | undefined
|
||||||
|
|
||||||
unchanged: string | undefined
|
unsaved: string | undefined
|
||||||
|
|
||||||
constructor(entryName: string) {
|
constructor(entryName: string) {
|
||||||
this.entryName = entryName
|
this.entryName = entryName
|
||||||
@@ -98,8 +98,8 @@ export class CacheEntryListener {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
markUnchanged(message: string): CacheEntryListener {
|
markUnsaved(message: string): CacheEntryListener {
|
||||||
this.unchanged = message
|
this.unsaved = message
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,8 +159,8 @@ function getRestoredMessage(entry: CacheEntryListener, isCacheWriteOnly: boolean
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getSavedMessage(entry: CacheEntryListener, isCacheReadOnly: boolean): string {
|
function getSavedMessage(entry: CacheEntryListener, isCacheReadOnly: boolean): string {
|
||||||
if (entry.unchanged) {
|
if (entry.unsaved) {
|
||||||
return `(Entry not saved: ${entry.unchanged})`
|
return `(Entry not saved: ${entry.unsaved})`
|
||||||
}
|
}
|
||||||
if (entry.savedKey === undefined) {
|
if (entry.savedKey === undefined) {
|
||||||
if (isCacheReadOnly) {
|
if (isCacheReadOnly) {
|
||||||
@@ -190,11 +190,8 @@ function getSize(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function formatSize(bytes: number | undefined): string {
|
function formatSize(bytes: number | undefined): string {
|
||||||
if (bytes === undefined) {
|
if (bytes === undefined || bytes === 0) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
if (bytes === 0) {
|
|
||||||
return '0 (Entry already exists)'
|
|
||||||
}
|
|
||||||
return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)`
|
return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as cache from '@actions/cache'
|
import * as cache from '@actions/cache'
|
||||||
import * as github from '@actions/github'
|
import * as github from '@actions/github'
|
||||||
|
import * as exec from '@actions/exec'
|
||||||
|
|
||||||
import * as crypto from 'crypto'
|
import * as crypto from 'crypto'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
@@ -162,7 +164,7 @@ export async function saveCache(cachePath: string[], cacheKey: string, listener:
|
|||||||
if (error instanceof cache.ReserveCacheError) {
|
if (error instanceof cache.ReserveCacheError) {
|
||||||
listener.markAlreadyExists(cacheKey)
|
listener.markAlreadyExists(cacheKey)
|
||||||
}
|
}
|
||||||
handleCacheFailure(error, `Failed to save cache entry ${cacheKey}`)
|
handleCacheFailure(error, `Failed to save cache entry with path '${cachePath}' and key: ${cacheKey}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,9 +197,13 @@ export function handleCacheFailure(error: unknown, message: string): void {
|
|||||||
* Attempt to delete a file or directory, waiting to allow locks to be released
|
* Attempt to delete a file or directory, waiting to allow locks to be released
|
||||||
*/
|
*/
|
||||||
export async function tryDelete(file: string): Promise<void> {
|
export async function tryDelete(file: string): Promise<void> {
|
||||||
const stat = fs.lstatSync(file)
|
const maxAttempts = 5
|
||||||
for (let count = 0; count < 3; count++) {
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||||
|
if (!fs.existsSync(file)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
|
const stat = fs.lstatSync(file)
|
||||||
if (stat.isDirectory()) {
|
if (stat.isDirectory()) {
|
||||||
fs.rmdirSync(file, {recursive: true})
|
fs.rmdirSync(file, {recursive: true})
|
||||||
} else {
|
} else {
|
||||||
@@ -205,10 +211,13 @@ export async function tryDelete(file: string): Promise<void> {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (count === 2) {
|
if (attempt === maxAttempts) {
|
||||||
|
core.warning(`Failed to delete ${file}, which will impact caching.
|
||||||
|
It is likely locked by another process. Output of 'jps -ml':
|
||||||
|
${await getJavaProcesses()}`)
|
||||||
throw error
|
throw error
|
||||||
} else {
|
} else {
|
||||||
core.warning(String(error))
|
cacheDebug(`Attempt to delete ${file} failed. Will try again.`)
|
||||||
await delay(1000)
|
await delay(1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,3 +227,8 @@ export async function tryDelete(file: string): Promise<void> {
|
|||||||
async function delay(ms: number): Promise<void> {
|
async function delay(ms: number): Promise<void> {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms))
|
return new Promise(resolve => setTimeout(resolve, ms))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getJavaProcesses(): Promise<string> {
|
||||||
|
const jpsOutput = await exec.getExecOutput('jps', ['-lm'])
|
||||||
|
return jpsOutput.stdout
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ export interface BuildResult {
|
|||||||
get gradleHomeDir(): string
|
get gradleHomeDir(): string
|
||||||
get buildFailed(): boolean
|
get buildFailed(): boolean
|
||||||
get buildScanUri(): string
|
get buildScanUri(): string
|
||||||
|
get buildScanFailed(): boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function writeJobSummary(buildResults: BuildResult[], cacheListener: CacheListener): void {
|
export async function writeJobSummary(buildResults: BuildResult[], cacheListener: CacheListener): Promise<void> {
|
||||||
core.info('Writing job summary')
|
core.info('Writing job summary')
|
||||||
|
|
||||||
if (buildResults.length === 0) {
|
if (buildResults.length === 0) {
|
||||||
@@ -24,7 +25,7 @@ export function writeJobSummary(buildResults: BuildResult[], cacheListener: Cach
|
|||||||
|
|
||||||
logCachingReport(cacheListener)
|
logCachingReport(cacheListener)
|
||||||
|
|
||||||
core.summary.write()
|
await core.summary.write()
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadBuildResults(): BuildResult[] {
|
export function loadBuildResults(): BuildResult[] {
|
||||||
@@ -43,28 +44,51 @@ export function loadBuildResults(): BuildResult[] {
|
|||||||
|
|
||||||
function writeSummaryTable(results: BuildResult[]): void {
|
function writeSummaryTable(results: BuildResult[]): void {
|
||||||
core.summary.addHeading('Gradle Builds', 3)
|
core.summary.addHeading('Gradle Builds', 3)
|
||||||
core.summary.addTable([
|
|
||||||
[
|
core.summary.addRaw(`
|
||||||
{data: 'Root Project', header: true},
|
<table>
|
||||||
{data: 'Tasks', header: true},
|
<tr>
|
||||||
{data: 'Gradle Version', header: true},
|
<th>Root Project</th>
|
||||||
{data: 'Outcome', header: true}
|
<th>Requested Tasks</th>
|
||||||
],
|
<th>Gradle Version</th>
|
||||||
...results.map(result => [
|
<th>Build Outcome</th>
|
||||||
result.rootProjectName,
|
<th>Build Scan™</th>
|
||||||
result.requestedTasks,
|
</tr>${results.map(result => renderBuildResultRow(result)).join('')}
|
||||||
result.gradleVersion,
|
</table>
|
||||||
renderOutcome(result)
|
`)
|
||||||
])
|
}
|
||||||
])
|
|
||||||
core.summary.addRaw('\n')
|
function renderBuildResultRow(result: BuildResult): string {
|
||||||
|
return `
|
||||||
|
<tr>
|
||||||
|
<td>${result.rootProjectName}</td>
|
||||||
|
<td>${result.requestedTasks}</td>
|
||||||
|
<td align='center'>${result.gradleVersion}</td>
|
||||||
|
<td align='center'>${renderOutcome(result)}</td>
|
||||||
|
<td>${renderBuildScan(result)}</td>
|
||||||
|
</tr>`
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderOutcome(result: BuildResult): string {
|
function renderOutcome(result: BuildResult): string {
|
||||||
const labelPart = result.buildScanUri ? 'Build%20Scan%E2%84%A2' : 'Build'
|
return result.buildFailed ? ':x:' : ':white_check_mark:'
|
||||||
const outcomePart = result.buildFailed ? 'FAILED-red' : 'SUCCESS-brightgreen'
|
}
|
||||||
const badgeUrl = `https://img.shields.io/badge/${labelPart}-${outcomePart}?logo=Gradle`
|
|
||||||
const badgeHtml = `<img src="${badgeUrl}" alt="Gradle Build">`
|
function renderBuildScan(result: BuildResult): string {
|
||||||
const targetUrl = result.buildScanUri ? result.buildScanUri : '#'
|
if (result.buildScanFailed) {
|
||||||
|
return renderBuildScanBadge(
|
||||||
|
'PUBLISH_FAILED',
|
||||||
|
'orange',
|
||||||
|
'https://docs.gradle.com/enterprise/gradle-plugin/#troubleshooting'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (result.buildScanUri) {
|
||||||
|
return renderBuildScanBadge('PUBLISHED', '06A0CE', result.buildScanUri)
|
||||||
|
}
|
||||||
|
return renderBuildScanBadge('NOT_PUBLISHED', 'lightgrey', 'https://scans.gradle.com')
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderBuildScanBadge(outcomeText: string, outcomeColor: string, targetUrl: string): string {
|
||||||
|
const badgeUrl = `https://img.shields.io/badge/Build%20Scan%E2%84%A2-${outcomeText}-${outcomeColor}?logo=Gradle`
|
||||||
|
const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />`
|
||||||
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`
|
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ abstract class BuildResultsRecorder implements BuildService<BuildResultsRecorder
|
|||||||
gradleVersion: GradleVersion.current().version,
|
gradleVersion: GradleVersion.current().version,
|
||||||
gradleHomeDir: getParameters().getGradleHomeDir().get(),
|
gradleHomeDir: getParameters().getGradleHomeDir().get(),
|
||||||
buildFailed: buildFailed,
|
buildFailed: buildFailed,
|
||||||
buildScanUri: null
|
buildScanUri: null,
|
||||||
|
buildScanFailed: false
|
||||||
]
|
]
|
||||||
|
|
||||||
def buildResultsDir = new File(System.getenv("RUNNER_TEMP"), ".build-results")
|
def buildResultsDir = new File(System.getenv("RUNNER_TEMP"), ".build-results")
|
||||||
@@ -40,65 +40,33 @@ if (isTopLevelBuild) {
|
|||||||
|
|
||||||
def captureUsingBuildScanPublished(buildScanExtension, rootProject, invocationId) {
|
def captureUsingBuildScanPublished(buildScanExtension, rootProject, invocationId) {
|
||||||
buildScanExtension.with {
|
buildScanExtension.with {
|
||||||
def requestedTasks = gradle.startParameter.taskNames.join(" ")
|
def buildResults = new BuildResults(invocationId, gradle, rootProject)
|
||||||
def rootProjectName = rootProject.name
|
|
||||||
def rootProjectDir = rootProject.projectDir.absolutePath
|
|
||||||
def gradleVersion = GradleVersion.current().version
|
|
||||||
def gradleHomeDir = gradle.gradleHomeDir.absolutePath
|
|
||||||
def buildFailed = false
|
|
||||||
|
|
||||||
buildFinished { result ->
|
buildFinished { result ->
|
||||||
buildFailed = (result.failure != null)
|
buildResults.setBuildResult(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
buildScanPublished { buildScan ->
|
buildScanPublished { buildScan ->
|
||||||
|
buildResults.setBuildScanUri(buildScan.buildScanUri.toASCIIString())
|
||||||
def buildScanUri = buildScan.buildScanUri.toASCIIString()
|
buildResults.writeToResultsFile(true)
|
||||||
def buildResults = [
|
|
||||||
rootProjectName: rootProjectName,
|
|
||||||
rootProjectDir: rootProjectDir,
|
|
||||||
requestedTasks: requestedTasks,
|
|
||||||
gradleVersion: gradleVersion,
|
|
||||||
gradleHomeDir: gradleHomeDir,
|
|
||||||
buildFailed: buildFailed,
|
|
||||||
buildScanUri: buildScanUri
|
|
||||||
]
|
|
||||||
|
|
||||||
def buildResultsDir = new File(System.getenv("RUNNER_TEMP"), ".build-results")
|
|
||||||
buildResultsDir.mkdirs()
|
|
||||||
def buildResultsFile = new File(buildResultsDir, System.getenv("GITHUB_ACTION") + invocationId + ".json")
|
|
||||||
|
|
||||||
// Overwrite any contents written by buildFinished or build service, since this result is a superset.
|
|
||||||
if (buildResultsFile.exists()) {
|
|
||||||
buildResultsFile.text = groovy.json.JsonOutput.toJson(buildResults)
|
|
||||||
} else {
|
|
||||||
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
|
|
||||||
}
|
|
||||||
|
|
||||||
println("::set-output name=build-scan-url::${buildScan.buildScanUri}")
|
println("::set-output name=build-scan-url::${buildScan.buildScanUri}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onError { error ->
|
||||||
|
buildResults.setBuildScanFailed()
|
||||||
|
buildResults.writeToResultsFile(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def captureUsingBuildFinished(gradle, invocationId) {
|
def captureUsingBuildFinished(gradle, invocationId) {
|
||||||
gradle.buildFinished { result ->
|
gradle.buildFinished { result ->
|
||||||
def buildResults = [
|
def buildResults = new BuildResults(invocationId, gradle, gradle.rootProject)
|
||||||
rootProjectName: gradle.rootProject.name,
|
buildResults.setBuildResult(result)
|
||||||
rootProjectDir: gradle.rootProject.rootDir.absolutePath,
|
|
||||||
requestedTasks: gradle.startParameter.taskNames.join(" "),
|
buildResults.writeToResultsFile(false)
|
||||||
gradleVersion: GradleVersion.current().version,
|
|
||||||
gradleHomeDir: gradle.gradleHomeDir.absolutePath,
|
|
||||||
buildFailed: result.failure != null,
|
|
||||||
buildScanUri: null
|
|
||||||
]
|
|
||||||
|
|
||||||
def buildResultsDir = new File(System.getenv("RUNNER_TEMP"), ".build-results")
|
|
||||||
buildResultsDir.mkdirs()
|
|
||||||
def buildResultsFile = new File(buildResultsDir, System.getenv("GITHUB_ACTION") + invocationId + ".json")
|
|
||||||
// Don't overwrite file generated by build-scan plugin if present (which has build-scan-uri)
|
|
||||||
if (!buildResultsFile.exists()) {
|
|
||||||
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,3 +74,49 @@ def captureUsingBuildService(settings, invocationId) {
|
|||||||
gradle.ext.invocationId = invocationId
|
gradle.ext.invocationId = invocationId
|
||||||
apply from: 'build-result-capture-service.plugin.groovy'
|
apply from: 'build-result-capture-service.plugin.groovy'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BuildResults {
|
||||||
|
def invocationId
|
||||||
|
def buildResults
|
||||||
|
|
||||||
|
BuildResults(String invocationId, def gradle, def rootProject) {
|
||||||
|
this.invocationId = invocationId
|
||||||
|
buildResults = [
|
||||||
|
rootProjectName: rootProject.name,
|
||||||
|
rootProjectDir: rootProject.projectDir.absolutePath,
|
||||||
|
requestedTasks: gradle.startParameter.taskNames.join(" "),
|
||||||
|
gradleVersion: GradleVersion.current().version,
|
||||||
|
gradleHomeDir: gradle.gradleHomeDir.absolutePath,
|
||||||
|
buildFailed: false,
|
||||||
|
buildScanUri: null,
|
||||||
|
buildScanFailed: false
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
def setBuildResult(def result) {
|
||||||
|
buildResults['buildFailed'] = result.failure != null
|
||||||
|
}
|
||||||
|
|
||||||
|
def setBuildScanUri(def buildScanUrl) {
|
||||||
|
buildResults['buildScanUri'] = buildScanUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
def setBuildScanFailed() {
|
||||||
|
buildResults['buildScanFailed'] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
def writeToResultsFile(boolean overwrite) {
|
||||||
|
def buildResultsDir = new File(System.getenv("RUNNER_TEMP"), ".build-results")
|
||||||
|
buildResultsDir.mkdirs()
|
||||||
|
def buildResultsFile = new File(buildResultsDir, System.getenv("GITHUB_ACTION") + invocationId + ".json")
|
||||||
|
|
||||||
|
// Overwrite any contents written by buildFinished or build service, since this result is a superset.
|
||||||
|
if (buildResultsFile.exists()) {
|
||||||
|
if (overwrite) {
|
||||||
|
buildResultsFile.text = groovy.json.JsonOutput.toJson(buildResults)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as exec from '@actions/exec'
|
import * as exec from '@actions/exec'
|
||||||
|
import {SUMMARY_ENV_VAR} from '@actions/core/lib/summary'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as os from 'os'
|
import * as os from 'os'
|
||||||
@@ -13,7 +14,12 @@ const GRADLE_USER_HOME = 'GRADLE_USER_HOME'
|
|||||||
const CACHE_LISTENER = 'CACHE_LISTENER'
|
const CACHE_LISTENER = 'CACHE_LISTENER'
|
||||||
const JOB_SUMMARY_ENABLED_PARAMETER = 'generate-job-summary'
|
const JOB_SUMMARY_ENABLED_PARAMETER = 'generate-job-summary'
|
||||||
|
|
||||||
function generateJobSummary(): boolean {
|
function shouldGenerateJobSummary(): boolean {
|
||||||
|
// Check if Job Summary is supported on this platform
|
||||||
|
if (!process.env[SUMMARY_ENV_VAR]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return core.getBooleanInput(JOB_SUMMARY_ENABLED_PARAMETER)
|
return core.getBooleanInput(JOB_SUMMARY_ENABLED_PARAMETER)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +62,7 @@ export async function complete(): Promise<void> {
|
|||||||
const gradleUserHome = core.getState(GRADLE_USER_HOME)
|
const gradleUserHome = core.getState(GRADLE_USER_HOME)
|
||||||
await caches.save(gradleUserHome, cacheListener)
|
await caches.save(gradleUserHome, cacheListener)
|
||||||
|
|
||||||
if (generateJobSummary()) {
|
if (shouldGenerateJobSummary()) {
|
||||||
writeJobSummary(buildResults, cacheListener)
|
writeJobSummary(buildResults, cacheListener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class BaseInitScriptTest extends Specification {
|
|||||||
static final String PUBLIC_BUILD_SCAN_ID = 'i2wepy2gr7ovw'
|
static final String PUBLIC_BUILD_SCAN_ID = 'i2wepy2gr7ovw'
|
||||||
static final String DEFAULT_SCAN_UPLOAD_TOKEN = 'scan-upload-token'
|
static final String DEFAULT_SCAN_UPLOAD_TOKEN = 'scan-upload-token'
|
||||||
static final String ROOT_PROJECT_NAME = 'test-init-script'
|
static final String ROOT_PROJECT_NAME = 'test-init-script'
|
||||||
|
boolean failScanUpload = false
|
||||||
|
|
||||||
File settingsFile
|
File settingsFile
|
||||||
File buildFile
|
File buildFile
|
||||||
@@ -59,6 +60,10 @@ class BaseInitScriptTest extends Specification {
|
|||||||
|
|
||||||
handlers {
|
handlers {
|
||||||
post('in/:gradleVersion/:pluginVersion') {
|
post('in/:gradleVersion/:pluginVersion') {
|
||||||
|
if (failScanUpload) {
|
||||||
|
context.response.status(401).send()
|
||||||
|
return
|
||||||
|
}
|
||||||
def scanUrlString = "${mockScansServer.address}s/$PUBLIC_BUILD_SCAN_ID"
|
def scanUrlString = "${mockScansServer.address}s/$PUBLIC_BUILD_SCAN_ID"
|
||||||
def body = [
|
def body = [
|
||||||
id : PUBLIC_BUILD_SCAN_ID,
|
id : PUBLIC_BUILD_SCAN_ID,
|
||||||
@@ -72,6 +77,10 @@ class BaseInitScriptTest extends Specification {
|
|||||||
}
|
}
|
||||||
prefix('scans/publish') {
|
prefix('scans/publish') {
|
||||||
post('gradle/:pluginVersion/token') {
|
post('gradle/:pluginVersion/token') {
|
||||||
|
if (failScanUpload) {
|
||||||
|
context.response.status(401).send()
|
||||||
|
return
|
||||||
|
}
|
||||||
def pluginVersion = context.pathTokens.pluginVersion
|
def pluginVersion = context.pathTokens.pluginVersion
|
||||||
def scanUrlString = "${mockScansServer.address}s/$PUBLIC_BUILD_SCAN_ID"
|
def scanUrlString = "${mockScansServer.address}s/$PUBLIC_BUILD_SCAN_ID"
|
||||||
def body = [
|
def body = [
|
||||||
@@ -85,6 +94,10 @@ class BaseInitScriptTest extends Specification {
|
|||||||
.send(jsonWriter.writeValueAsBytes(body))
|
.send(jsonWriter.writeValueAsBytes(body))
|
||||||
}
|
}
|
||||||
post('gradle/:pluginVersion/upload') {
|
post('gradle/:pluginVersion/upload') {
|
||||||
|
if (failScanUpload) {
|
||||||
|
context.response.status(401).send()
|
||||||
|
return
|
||||||
|
}
|
||||||
context.request.getBody(1024 * 1024 * 10).then {
|
context.request.getBody(1024 * 1024 * 10).then {
|
||||||
context.response
|
context.response
|
||||||
.contentType('application/vnd.gradle.scan-upload-ack+json')
|
.contentType('application/vnd.gradle.scan-upload-ack+json')
|
||||||
@@ -100,7 +113,7 @@ class BaseInitScriptTest extends Specification {
|
|||||||
settingsFile = new File(testProjectDir, 'settings.gradle')
|
settingsFile = new File(testProjectDir, 'settings.gradle')
|
||||||
buildFile = new File(testProjectDir, 'build.gradle')
|
buildFile = new File(testProjectDir, 'build.gradle')
|
||||||
|
|
||||||
File srcInitScriptsDir = new File("../../src/resources")
|
File srcInitScriptsDir = new File("../../src/resources/init-scripts")
|
||||||
File targetInitScriptsDir = new File(testProjectDir, "initScripts")
|
File targetInitScriptsDir = new File(testProjectDir, "initScripts")
|
||||||
targetInitScriptsDir.mkdirs()
|
targetInitScriptsDir.mkdirs()
|
||||||
|
|
||||||
@@ -118,7 +118,23 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
|
|||||||
testGradleVersion << CONFIGURATION_CACHE_VERSIONS
|
testGradleVersion << CONFIGURATION_CACHE_VERSIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
void assertResults(String task, TestGradleVersion testGradleVersion, boolean hasFailure, boolean hasBuildScan) {
|
def "produces build results file for failing build on #testGradleVersion when build scan publish fails"() {
|
||||||
|
assumeTrue testGradleVersion.compatibleWithCurrentJvm
|
||||||
|
|
||||||
|
when:
|
||||||
|
declareGePluginApplication(testGradleVersion.gradleVersion)
|
||||||
|
addFailingTaskToBuild()
|
||||||
|
failScanUpload = true
|
||||||
|
runAndFail(['expectFailure'], initScript, testGradleVersion.gradleVersion)
|
||||||
|
|
||||||
|
then:
|
||||||
|
assertResults('expectFailure', testGradleVersion, true, false, true)
|
||||||
|
|
||||||
|
where:
|
||||||
|
testGradleVersion << ALL_VERSIONS
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertResults(String task, TestGradleVersion testGradleVersion, boolean hasFailure, boolean hasBuildScan, boolean scanUploadFailed = false) {
|
||||||
def results = new JsonSlurper().parse(buildResultFile)
|
def results = new JsonSlurper().parse(buildResultFile)
|
||||||
assert results['rootProjectName'] == ROOT_PROJECT_NAME
|
assert results['rootProjectName'] == ROOT_PROJECT_NAME
|
||||||
assert results['rootProjectDir'] == testProjectDir.canonicalPath
|
assert results['rootProjectDir'] == testProjectDir.canonicalPath
|
||||||
@@ -127,6 +143,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
|
|||||||
assert results['gradleHomeDir'] != null
|
assert results['gradleHomeDir'] != null
|
||||||
assert results['buildFailed'] == hasFailure
|
assert results['buildFailed'] == hasFailure
|
||||||
assert results['buildScanUri'] == (hasBuildScan ? "${mockScansServer.address}s/${PUBLIC_BUILD_SCAN_ID}" : null)
|
assert results['buildScanUri'] == (hasBuildScan ? "${mockScansServer.address}s/${PUBLIC_BUILD_SCAN_ID}" : null)
|
||||||
|
assert results['buildScanFailed'] == scanUploadFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getBuildResultFile() {
|
private File getBuildResultFile() {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import {CacheEntryListener, CacheListener} from '../src/cache-reporting'
|
import {CacheEntryListener, CacheListener} from '../../src/cache-reporting'
|
||||||
|
|
||||||
describe('caching report', () => {
|
describe('caching report', () => {
|
||||||
describe('reports not fully restored', () => {
|
describe('reports not fully restored', () => {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as cacheUtils from '../src/cache-utils'
|
import * as cacheUtils from '../../src/cache-utils'
|
||||||
|
|
||||||
describe('cacheUtils-utils', () => {
|
describe('cacheUtils-utils', () => {
|
||||||
describe('can hash', () => {
|
describe('can hash', () => {
|
||||||
Reference in New Issue
Block a user