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"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: "@types/node"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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 {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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 {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id "com.gradle.build-scan" version "3.10.1"
|
||||
id "com.gradle.build-scan" version "3.10.2"
|
||||
}
|
||||
|
||||
gradleEnterprise {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id "com.gradle.enterprise" version "3.10.1"
|
||||
id "com.gradle.enterprise" version "3.10.2"
|
||||
}
|
||||
|
||||
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:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/**'
|
||||
- 'src/resources/init-scripts/**'
|
||||
- 'test/init-script-check/**'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
test-init-scripts:
|
||||
@@ -17,5 +22,5 @@ jobs:
|
||||
- name: Setup Gradle
|
||||
uses: gradle/gradle-build-action@v2 # Use a released version to avoid breakages
|
||||
- name: Run integration tests
|
||||
working-directory: test/test-init-scripts
|
||||
working-directory: test/init-scripts
|
||||
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:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- '.github/workflows/**'
|
||||
- 'dist/**'
|
||||
|
||||
jobs:
|
||||
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
|
||||
- name: Build kotlin-dsl project without build scan
|
||||
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
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: ./gradlew assemble
|
||||
|
||||
29
README.md
29
README.md
@@ -85,6 +85,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 11
|
||||
- uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
@@ -111,6 +112,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 11
|
||||
|
||||
- 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
|
||||
|
||||
In some circumstances, it makes sense for a Gradle invocation to read any existing cache entries but not to write changes back.
|
||||
For example, you may want to write cache entries for builds on your `main` branch, but not for any PR build invocations.
|
||||
By default, the `gradle-build-action` will only write to the cache from Jobs on the default (`main`/`master`) branch.
|
||||
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
|
||||
# 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.
|
||||
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
|
||||
@@ -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.
|
||||
|
||||
#### 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.
|
||||
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,
|
||||
with all other branch builds using `cache-read-only`. See [Using the caches read-only](#using-the-caches-read-only) for more details.
|
||||
By default, the `gradle-build-action` will only _write_ to the cache for builds run on the default branch.
|
||||
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.
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
163
dist/main/index.js
vendored
163
dist/main/index.js
vendored
@@ -1134,6 +1134,8 @@ function createTar(archiveFolder, sourceDirectories, compressionMethod) {
|
||||
...getCompressionProgram(),
|
||||
'-cf',
|
||||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||
'--exclude',
|
||||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||
'-P',
|
||||
'-C',
|
||||
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||
@@ -64909,10 +64911,17 @@ class GradleStateCache {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const cacheKey = (0, cache_utils_1.generateCacheKey)(this.cacheName).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) {
|
||||
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;
|
||||
}
|
||||
try {
|
||||
@@ -64924,7 +64933,7 @@ class GradleStateCache {
|
||||
}
|
||||
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`);
|
||||
const cachePath = this.getCachePath();
|
||||
yield (0, cache_utils_1.saveCache)(cachePath, cacheKey, entryListener);
|
||||
yield (0, cache_utils_1.saveCache)(cachePath, cacheKey, gradleHomeEntryListener);
|
||||
return;
|
||||
});
|
||||
}
|
||||
@@ -64964,13 +64973,13 @@ class GradleStateCache {
|
||||
initializeGradleUserHome(gradleUserHome, initScriptsDir) {
|
||||
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy'];
|
||||
for (const initScriptFilename of initScriptFilenames) {
|
||||
const initScriptContent = this.readResourceAsString(initScriptFilename);
|
||||
const initScriptContent = this.readInitScriptAsString(initScriptFilename);
|
||||
const initScriptPath = path_1.default.resolve(initScriptsDir, initScriptFilename);
|
||||
fs_1.default.writeFileSync(initScriptPath, initScriptContent);
|
||||
}
|
||||
}
|
||||
readResourceAsString(resource) {
|
||||
const absolutePath = path_1.default.resolve(__dirname, '..', '..', 'src', 'resources', resource);
|
||||
readInitScriptAsString(resource) {
|
||||
const absolutePath = path_1.default.resolve(__dirname, '..', '..', 'src', 'resources', 'init-scripts', resource);
|
||||
return fs_1.default.readFileSync(absolutePath, 'utf8');
|
||||
}
|
||||
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;
|
||||
if (previouslyRestoredKey === cacheKey) {
|
||||
(0, cache_utils_1.cacheDebug)(`No change to previously restored ${artifactType}. Not saving.`);
|
||||
entryListener.markUnchanged('contents unchanged');
|
||||
entryListener.markUnsaved('contents unchanged');
|
||||
}
|
||||
else {
|
||||
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`);
|
||||
@@ -65232,9 +65241,9 @@ class GradleHomeEntryExtractor extends AbstractEntryExtractor {
|
||||
implicitDescendants: false,
|
||||
followSymbolicLinks: false
|
||||
});
|
||||
for (const p of yield globber.glob()) {
|
||||
(0, cache_utils_1.cacheDebug)(`Deleting wrapper zip: ${p}`);
|
||||
(0, cache_utils_1.tryDelete)(p);
|
||||
for (const wrapperZip of yield globber.glob()) {
|
||||
(0, cache_utils_1.cacheDebug)(`Deleting wrapper zip: ${wrapperZip}`);
|
||||
yield (0, cache_utils_1.tryDelete)(wrapperZip);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -65399,8 +65408,8 @@ class CacheEntryListener {
|
||||
this.savedSize = 0;
|
||||
return this;
|
||||
}
|
||||
markUnchanged(message) {
|
||||
this.unchanged = message;
|
||||
markUnsaved(message) {
|
||||
this.unsaved = message;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -65452,8 +65461,8 @@ function getRestoredMessage(entry, isCacheWriteOnly) {
|
||||
return '(Entry restored: partial match found)';
|
||||
}
|
||||
function getSavedMessage(entry, isCacheReadOnly) {
|
||||
if (entry.unchanged) {
|
||||
return `(Entry not saved: ${entry.unchanged})`;
|
||||
if (entry.unsaved) {
|
||||
return `(Entry not saved: ${entry.unsaved})`;
|
||||
}
|
||||
if (entry.savedKey === undefined) {
|
||||
if (isCacheReadOnly) {
|
||||
@@ -65474,12 +65483,9 @@ function getSize(cacheEntries, predicate) {
|
||||
return Math.round(bytes / (1024 * 1024));
|
||||
}
|
||||
function formatSize(bytes) {
|
||||
if (bytes === undefined) {
|
||||
if (bytes === undefined || bytes === 0) {
|
||||
return '';
|
||||
}
|
||||
if (bytes === 0) {
|
||||
return '0 (Entry already exists)';
|
||||
}
|
||||
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 cache = __importStar(__nccwpck_require__(7799));
|
||||
const github = __importStar(__nccwpck_require__(5438));
|
||||
const exec = __importStar(__nccwpck_require__(1514));
|
||||
const crypto = __importStar(__nccwpck_require__(6113));
|
||||
const path = __importStar(__nccwpck_require__(1017));
|
||||
const fs = __importStar(__nccwpck_require__(7147));
|
||||
@@ -65639,7 +65646,7 @@ function saveCache(cachePath, cacheKey, listener) {
|
||||
if (error instanceof cache.ReserveCacheError) {
|
||||
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;
|
||||
function tryDelete(file) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stat = fs.lstatSync(file);
|
||||
for (let count = 0; count < 3; count++) {
|
||||
const maxAttempts = 5;
|
||||
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||
if (!fs.existsSync(file)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const stat = fs.lstatSync(file);
|
||||
if (stat.isDirectory()) {
|
||||
fs.rmdirSync(file, { recursive: true });
|
||||
}
|
||||
@@ -65682,11 +65693,14 @@ function tryDelete(file) {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
else {
|
||||
core.warning(String(error));
|
||||
cacheDebug(`Attempt to delete ${file} failed. Will try again.`);
|
||||
yield delay(1000);
|
||||
}
|
||||
}
|
||||
@@ -65699,6 +65713,12 @@ function delay(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);
|
||||
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) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
@@ -65978,15 +66007,17 @@ const fs_1 = __importDefault(__nccwpck_require__(7147));
|
||||
const path_1 = __importDefault(__nccwpck_require__(1017));
|
||||
const cache_reporting_1 = __nccwpck_require__(6674);
|
||||
function writeJobSummary(buildResults, cacheListener) {
|
||||
core.info('Writing job summary');
|
||||
if (buildResults.length === 0) {
|
||||
core.debug('No Gradle build results found. Summary table will not be generated.');
|
||||
}
|
||||
else {
|
||||
writeSummaryTable(buildResults);
|
||||
}
|
||||
(0, cache_reporting_1.logCachingReport)(cacheListener);
|
||||
core.summary.write();
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
core.info('Writing job summary');
|
||||
if (buildResults.length === 0) {
|
||||
core.debug('No Gradle build results found. Summary table will not be generated.');
|
||||
}
|
||||
else {
|
||||
writeSummaryTable(buildResults);
|
||||
}
|
||||
(0, cache_reporting_1.logCachingReport)(cacheListener);
|
||||
yield core.summary.write();
|
||||
});
|
||||
}
|
||||
exports.writeJobSummary = writeJobSummary;
|
||||
function loadBuildResults() {
|
||||
@@ -66003,28 +66034,43 @@ function loadBuildResults() {
|
||||
exports.loadBuildResults = loadBuildResults;
|
||||
function writeSummaryTable(results) {
|
||||
core.summary.addHeading('Gradle Builds', 3);
|
||||
core.summary.addTable([
|
||||
[
|
||||
{ data: 'Root Project', header: true },
|
||||
{ data: 'Tasks', header: true },
|
||||
{ data: 'Gradle Version', header: true },
|
||||
{ data: 'Outcome', header: true }
|
||||
],
|
||||
...results.map(result => [
|
||||
result.rootProjectName,
|
||||
result.requestedTasks,
|
||||
result.gradleVersion,
|
||||
renderOutcome(result)
|
||||
])
|
||||
]);
|
||||
core.summary.addRaw('\n');
|
||||
core.summary.addRaw(`
|
||||
<table>
|
||||
<tr>
|
||||
<th>Root Project</th>
|
||||
<th>Requested Tasks</th>
|
||||
<th>Gradle Version</th>
|
||||
<th>Build Outcome</th>
|
||||
<th>Build Scan™</th>
|
||||
</tr>${results.map(result => renderBuildResultRow(result)).join('')}
|
||||
</table>
|
||||
`);
|
||||
}
|
||||
function renderBuildResultRow(result) {
|
||||
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) {
|
||||
const labelPart = result.buildScanUri ? 'Build%20Scan%E2%84%A2' : 'Build';
|
||||
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">`;
|
||||
const targetUrl = result.buildScanUri ? result.buildScanUri : '#';
|
||||
return result.buildFailed ? ':x:' : ':white_check_mark:';
|
||||
}
|
||||
function renderBuildScan(result) {
|
||||
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, 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>`;
|
||||
}
|
||||
|
||||
@@ -66372,6 +66418,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.complete = exports.setup = void 0;
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const exec = __importStar(__nccwpck_require__(1514));
|
||||
const summary_1 = __nccwpck_require__(1327);
|
||||
const fs = __importStar(__nccwpck_require__(7147));
|
||||
const path = __importStar(__nccwpck_require__(1017));
|
||||
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_USER_HOME = 'GRADLE_USER_HOME';
|
||||
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) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const gradleUserHome = yield determineGradleUserHome(buildRootDirectory);
|
||||
@@ -66399,7 +66453,6 @@ function setup(buildRootDirectory) {
|
||||
exports.setup = setup;
|
||||
function complete() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
core.info('Inside setupGradle.complete()');
|
||||
if (!core.getState(GRADLE_SETUP_VAR)) {
|
||||
core.info('Gradle setup post-action only performed for first gradle-build-action step in workflow.');
|
||||
return;
|
||||
@@ -66411,7 +66464,9 @@ function complete() {
|
||||
const cacheListener = cache_reporting_1.CacheListener.rehydrate(core.getState(CACHE_LISTENER));
|
||||
const gradleUserHome = core.getState(GRADLE_USER_HOME);
|
||||
yield caches.save(gradleUserHome, cacheListener);
|
||||
(0, job_summary_1.writeJobSummary)(buildResults, cacheListener);
|
||||
if (shouldGenerateJobSummary()) {
|
||||
(0, job_summary_1.writeJobSummary)(buildResults, cacheListener);
|
||||
}
|
||||
});
|
||||
}
|
||||
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
163
dist/post/index.js
vendored
163
dist/post/index.js
vendored
@@ -1134,6 +1134,8 @@ function createTar(archiveFolder, sourceDirectories, compressionMethod) {
|
||||
...getCompressionProgram(),
|
||||
'-cf',
|
||||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||
'--exclude',
|
||||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||
'-P',
|
||||
'-C',
|
||||
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
|
||||
@@ -63960,10 +63962,17 @@ class GradleStateCache {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const cacheKey = (0, cache_utils_1.generateCacheKey)(this.cacheName).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) {
|
||||
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;
|
||||
}
|
||||
try {
|
||||
@@ -63975,7 +63984,7 @@ class GradleStateCache {
|
||||
}
|
||||
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`);
|
||||
const cachePath = this.getCachePath();
|
||||
yield (0, cache_utils_1.saveCache)(cachePath, cacheKey, entryListener);
|
||||
yield (0, cache_utils_1.saveCache)(cachePath, cacheKey, gradleHomeEntryListener);
|
||||
return;
|
||||
});
|
||||
}
|
||||
@@ -64015,13 +64024,13 @@ class GradleStateCache {
|
||||
initializeGradleUserHome(gradleUserHome, initScriptsDir) {
|
||||
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy'];
|
||||
for (const initScriptFilename of initScriptFilenames) {
|
||||
const initScriptContent = this.readResourceAsString(initScriptFilename);
|
||||
const initScriptContent = this.readInitScriptAsString(initScriptFilename);
|
||||
const initScriptPath = path_1.default.resolve(initScriptsDir, initScriptFilename);
|
||||
fs_1.default.writeFileSync(initScriptPath, initScriptContent);
|
||||
}
|
||||
}
|
||||
readResourceAsString(resource) {
|
||||
const absolutePath = path_1.default.resolve(__dirname, '..', '..', 'src', 'resources', resource);
|
||||
readInitScriptAsString(resource) {
|
||||
const absolutePath = path_1.default.resolve(__dirname, '..', '..', 'src', 'resources', 'init-scripts', resource);
|
||||
return fs_1.default.readFileSync(absolutePath, 'utf8');
|
||||
}
|
||||
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;
|
||||
if (previouslyRestoredKey === cacheKey) {
|
||||
(0, cache_utils_1.cacheDebug)(`No change to previously restored ${artifactType}. Not saving.`);
|
||||
entryListener.markUnchanged('contents unchanged');
|
||||
entryListener.markUnsaved('contents unchanged');
|
||||
}
|
||||
else {
|
||||
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`);
|
||||
@@ -64283,9 +64292,9 @@ class GradleHomeEntryExtractor extends AbstractEntryExtractor {
|
||||
implicitDescendants: false,
|
||||
followSymbolicLinks: false
|
||||
});
|
||||
for (const p of yield globber.glob()) {
|
||||
(0, cache_utils_1.cacheDebug)(`Deleting wrapper zip: ${p}`);
|
||||
(0, cache_utils_1.tryDelete)(p);
|
||||
for (const wrapperZip of yield globber.glob()) {
|
||||
(0, cache_utils_1.cacheDebug)(`Deleting wrapper zip: ${wrapperZip}`);
|
||||
yield (0, cache_utils_1.tryDelete)(wrapperZip);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -64450,8 +64459,8 @@ class CacheEntryListener {
|
||||
this.savedSize = 0;
|
||||
return this;
|
||||
}
|
||||
markUnchanged(message) {
|
||||
this.unchanged = message;
|
||||
markUnsaved(message) {
|
||||
this.unsaved = message;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -64503,8 +64512,8 @@ function getRestoredMessage(entry, isCacheWriteOnly) {
|
||||
return '(Entry restored: partial match found)';
|
||||
}
|
||||
function getSavedMessage(entry, isCacheReadOnly) {
|
||||
if (entry.unchanged) {
|
||||
return `(Entry not saved: ${entry.unchanged})`;
|
||||
if (entry.unsaved) {
|
||||
return `(Entry not saved: ${entry.unsaved})`;
|
||||
}
|
||||
if (entry.savedKey === undefined) {
|
||||
if (isCacheReadOnly) {
|
||||
@@ -64525,12 +64534,9 @@ function getSize(cacheEntries, predicate) {
|
||||
return Math.round(bytes / (1024 * 1024));
|
||||
}
|
||||
function formatSize(bytes) {
|
||||
if (bytes === undefined) {
|
||||
if (bytes === undefined || bytes === 0) {
|
||||
return '';
|
||||
}
|
||||
if (bytes === 0) {
|
||||
return '0 (Entry already exists)';
|
||||
}
|
||||
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 cache = __importStar(__nccwpck_require__(7799));
|
||||
const github = __importStar(__nccwpck_require__(5438));
|
||||
const exec = __importStar(__nccwpck_require__(1514));
|
||||
const crypto = __importStar(__nccwpck_require__(6113));
|
||||
const path = __importStar(__nccwpck_require__(1017));
|
||||
const fs = __importStar(__nccwpck_require__(7147));
|
||||
@@ -64690,7 +64697,7 @@ function saveCache(cachePath, cacheKey, listener) {
|
||||
if (error instanceof cache.ReserveCacheError) {
|
||||
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;
|
||||
function tryDelete(file) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stat = fs.lstatSync(file);
|
||||
for (let count = 0; count < 3; count++) {
|
||||
const maxAttempts = 5;
|
||||
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||
if (!fs.existsSync(file)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const stat = fs.lstatSync(file);
|
||||
if (stat.isDirectory()) {
|
||||
fs.rmdirSync(file, { recursive: true });
|
||||
}
|
||||
@@ -64733,11 +64744,14 @@ function tryDelete(file) {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
else {
|
||||
core.warning(String(error));
|
||||
cacheDebug(`Attempt to delete ${file} failed. Will try again.`);
|
||||
yield delay(1000);
|
||||
}
|
||||
}
|
||||
@@ -64750,6 +64764,12 @@ function delay(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);
|
||||
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) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
@@ -64898,15 +64927,17 @@ const fs_1 = __importDefault(__nccwpck_require__(7147));
|
||||
const path_1 = __importDefault(__nccwpck_require__(1017));
|
||||
const cache_reporting_1 = __nccwpck_require__(6674);
|
||||
function writeJobSummary(buildResults, cacheListener) {
|
||||
core.info('Writing job summary');
|
||||
if (buildResults.length === 0) {
|
||||
core.debug('No Gradle build results found. Summary table will not be generated.');
|
||||
}
|
||||
else {
|
||||
writeSummaryTable(buildResults);
|
||||
}
|
||||
(0, cache_reporting_1.logCachingReport)(cacheListener);
|
||||
core.summary.write();
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
core.info('Writing job summary');
|
||||
if (buildResults.length === 0) {
|
||||
core.debug('No Gradle build results found. Summary table will not be generated.');
|
||||
}
|
||||
else {
|
||||
writeSummaryTable(buildResults);
|
||||
}
|
||||
(0, cache_reporting_1.logCachingReport)(cacheListener);
|
||||
yield core.summary.write();
|
||||
});
|
||||
}
|
||||
exports.writeJobSummary = writeJobSummary;
|
||||
function loadBuildResults() {
|
||||
@@ -64923,28 +64954,43 @@ function loadBuildResults() {
|
||||
exports.loadBuildResults = loadBuildResults;
|
||||
function writeSummaryTable(results) {
|
||||
core.summary.addHeading('Gradle Builds', 3);
|
||||
core.summary.addTable([
|
||||
[
|
||||
{ data: 'Root Project', header: true },
|
||||
{ data: 'Tasks', header: true },
|
||||
{ data: 'Gradle Version', header: true },
|
||||
{ data: 'Outcome', header: true }
|
||||
],
|
||||
...results.map(result => [
|
||||
result.rootProjectName,
|
||||
result.requestedTasks,
|
||||
result.gradleVersion,
|
||||
renderOutcome(result)
|
||||
])
|
||||
]);
|
||||
core.summary.addRaw('\n');
|
||||
core.summary.addRaw(`
|
||||
<table>
|
||||
<tr>
|
||||
<th>Root Project</th>
|
||||
<th>Requested Tasks</th>
|
||||
<th>Gradle Version</th>
|
||||
<th>Build Outcome</th>
|
||||
<th>Build Scan™</th>
|
||||
</tr>${results.map(result => renderBuildResultRow(result)).join('')}
|
||||
</table>
|
||||
`);
|
||||
}
|
||||
function renderBuildResultRow(result) {
|
||||
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) {
|
||||
const labelPart = result.buildScanUri ? 'Build%20Scan%E2%84%A2' : 'Build';
|
||||
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">`;
|
||||
const targetUrl = result.buildScanUri ? result.buildScanUri : '#';
|
||||
return result.buildFailed ? ':x:' : ':white_check_mark:';
|
||||
}
|
||||
function renderBuildScan(result) {
|
||||
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, 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>`;
|
||||
}
|
||||
|
||||
@@ -65056,6 +65102,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.complete = exports.setup = void 0;
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const exec = __importStar(__nccwpck_require__(1514));
|
||||
const summary_1 = __nccwpck_require__(1327);
|
||||
const fs = __importStar(__nccwpck_require__(7147));
|
||||
const path = __importStar(__nccwpck_require__(1017));
|
||||
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_USER_HOME = 'GRADLE_USER_HOME';
|
||||
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) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const gradleUserHome = yield determineGradleUserHome(buildRootDirectory);
|
||||
@@ -65083,7 +65137,6 @@ function setup(buildRootDirectory) {
|
||||
exports.setup = setup;
|
||||
function complete() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
core.info('Inside setupGradle.complete()');
|
||||
if (!core.getState(GRADLE_SETUP_VAR)) {
|
||||
core.info('Gradle setup post-action only performed for first gradle-build-action step in workflow.');
|
||||
return;
|
||||
@@ -65095,7 +65148,9 @@ function complete() {
|
||||
const cacheListener = cache_reporting_1.CacheListener.rehydrate(core.getState(CACHE_LISTENER));
|
||||
const gradleUserHome = core.getState(GRADLE_USER_HOME);
|
||||
yield caches.save(gradleUserHome, cacheListener);
|
||||
(0, job_summary_1.writeJobSummary)(buildResults, cacheListener);
|
||||
if (shouldGenerateJobSummary()) {
|
||||
(0, job_summary_1.writeJobSummary)(buildResults, cacheListener);
|
||||
}
|
||||
});
|
||||
}
|
||||
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
1545
package-lock.json
generated
1545
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",
|
||||
"dependencies": {
|
||||
"@actions/cache": "2.0.5",
|
||||
"@actions/cache": "2.0.6",
|
||||
"@actions/core": "1.8.2",
|
||||
"@actions/exec": "1.1.1",
|
||||
"@actions/github": "5.0.3",
|
||||
@@ -35,19 +35,19 @@
|
||||
"string-argv": "0.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "28.1.0",
|
||||
"@types/jest": "28.1.1",
|
||||
"@types/node": "16.11.21",
|
||||
"@types/unzipper": "0.10.5",
|
||||
"@typescript-eslint/parser": "5.27.0",
|
||||
"@typescript-eslint/parser": "5.28.0",
|
||||
"@vercel/ncc": "0.34.0",
|
||||
"eslint": "8.17.0",
|
||||
"eslint-plugin-github": "4.3.6",
|
||||
"eslint-plugin-jest": "26.4.6",
|
||||
"jest": "28.1.0",
|
||||
"eslint-plugin-jest": "26.5.3",
|
||||
"jest": "28.1.1",
|
||||
"js-yaml": "4.1.0",
|
||||
"patch-package": "6.4.7",
|
||||
"prettier": "2.6.2",
|
||||
"ts-jest": "28.0.4",
|
||||
"prettier": "2.7.0",
|
||||
"ts-jest": "28.0.5",
|
||||
"typescript": "4.7.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,11 +94,18 @@ export class GradleStateCache {
|
||||
async save(listener: CacheListener): Promise<void> {
|
||||
const cacheKey = generateCacheKey(this.cacheName).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) {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -111,7 +118,7 @@ export class GradleStateCache {
|
||||
|
||||
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`)
|
||||
const cachePath = this.getCachePath()
|
||||
await saveCache(cachePath, cacheKey, entryListener)
|
||||
await saveCache(cachePath, cacheKey, gradleHomeEntryListener)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -168,15 +175,15 @@ export class GradleStateCache {
|
||||
private initializeGradleUserHome(gradleUserHome: string, initScriptsDir: string): void {
|
||||
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy']
|
||||
for (const initScriptFilename of initScriptFilenames) {
|
||||
const initScriptContent = this.readResourceAsString(initScriptFilename)
|
||||
const initScriptContent = this.readInitScriptAsString(initScriptFilename)
|
||||
const initScriptPath = path.resolve(initScriptsDir, initScriptFilename)
|
||||
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
|
||||
const absolutePath = path.resolve(__dirname, '..', '..', 'src', 'resources', resource)
|
||||
const absolutePath = path.resolve(__dirname, '..', '..', 'src', 'resources', 'init-scripts', resource)
|
||||
return fs.readFileSync(absolutePath, 'utf8')
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ abstract class AbstractEntryExtractor {
|
||||
|
||||
if (previouslyRestoredKey === cacheKey) {
|
||||
cacheDebug(`No change to previously restored ${artifactType}. Not saving.`)
|
||||
entryListener.markUnchanged('contents unchanged')
|
||||
entryListener.markUnsaved('contents unchanged')
|
||||
} else {
|
||||
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`)
|
||||
await saveCache([pattern], cacheKey, entryListener)
|
||||
@@ -312,9 +312,9 @@ export class GradleHomeEntryExtractor extends AbstractEntryExtractor {
|
||||
followSymbolicLinks: false
|
||||
})
|
||||
|
||||
for (const p of await globber.glob()) {
|
||||
cacheDebug(`Deleting wrapper zip: ${p}`)
|
||||
tryDelete(p)
|
||||
for (const wrapperZip of await globber.glob()) {
|
||||
cacheDebug(`Deleting wrapper zip: ${wrapperZip}`)
|
||||
await tryDelete(wrapperZip)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ export class CacheEntryListener {
|
||||
savedKey: string | undefined
|
||||
savedSize: number | undefined
|
||||
|
||||
unchanged: string | undefined
|
||||
unsaved: string | undefined
|
||||
|
||||
constructor(entryName: string) {
|
||||
this.entryName = entryName
|
||||
@@ -98,8 +98,8 @@ export class CacheEntryListener {
|
||||
return this
|
||||
}
|
||||
|
||||
markUnchanged(message: string): CacheEntryListener {
|
||||
this.unchanged = message
|
||||
markUnsaved(message: string): CacheEntryListener {
|
||||
this.unsaved = message
|
||||
return this
|
||||
}
|
||||
}
|
||||
@@ -159,8 +159,8 @@ function getRestoredMessage(entry: CacheEntryListener, isCacheWriteOnly: boolean
|
||||
}
|
||||
|
||||
function getSavedMessage(entry: CacheEntryListener, isCacheReadOnly: boolean): string {
|
||||
if (entry.unchanged) {
|
||||
return `(Entry not saved: ${entry.unchanged})`
|
||||
if (entry.unsaved) {
|
||||
return `(Entry not saved: ${entry.unsaved})`
|
||||
}
|
||||
if (entry.savedKey === undefined) {
|
||||
if (isCacheReadOnly) {
|
||||
@@ -190,11 +190,8 @@ function getSize(
|
||||
}
|
||||
|
||||
function formatSize(bytes: number | undefined): string {
|
||||
if (bytes === undefined) {
|
||||
if (bytes === undefined || bytes === 0) {
|
||||
return ''
|
||||
}
|
||||
if (bytes === 0) {
|
||||
return '0 (Entry already exists)'
|
||||
}
|
||||
return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)`
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as cache from '@actions/cache'
|
||||
import * as github from '@actions/github'
|
||||
import * as exec from '@actions/exec'
|
||||
|
||||
import * as crypto from 'crypto'
|
||||
import * as path from 'path'
|
||||
import * as fs from 'fs'
|
||||
@@ -162,7 +164,7 @@ export async function saveCache(cachePath: string[], cacheKey: string, listener:
|
||||
if (error instanceof cache.ReserveCacheError) {
|
||||
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
|
||||
*/
|
||||
export async function tryDelete(file: string): Promise<void> {
|
||||
const stat = fs.lstatSync(file)
|
||||
for (let count = 0; count < 3; count++) {
|
||||
const maxAttempts = 5
|
||||
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||
if (!fs.existsSync(file)) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
const stat = fs.lstatSync(file)
|
||||
if (stat.isDirectory()) {
|
||||
fs.rmdirSync(file, {recursive: true})
|
||||
} else {
|
||||
@@ -205,10 +211,13 @@ export async function tryDelete(file: string): Promise<void> {
|
||||
}
|
||||
return
|
||||
} 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
|
||||
} else {
|
||||
core.warning(String(error))
|
||||
cacheDebug(`Attempt to delete ${file} failed. Will try again.`)
|
||||
await delay(1000)
|
||||
}
|
||||
}
|
||||
@@ -218,3 +227,8 @@ export async function tryDelete(file: string): Promise<void> {
|
||||
async function delay(ms: number): Promise<void> {
|
||||
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 buildFailed(): boolean
|
||||
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')
|
||||
|
||||
if (buildResults.length === 0) {
|
||||
@@ -24,7 +25,7 @@ export function writeJobSummary(buildResults: BuildResult[], cacheListener: Cach
|
||||
|
||||
logCachingReport(cacheListener)
|
||||
|
||||
core.summary.write()
|
||||
await core.summary.write()
|
||||
}
|
||||
|
||||
export function loadBuildResults(): BuildResult[] {
|
||||
@@ -43,28 +44,51 @@ export function loadBuildResults(): BuildResult[] {
|
||||
|
||||
function writeSummaryTable(results: BuildResult[]): void {
|
||||
core.summary.addHeading('Gradle Builds', 3)
|
||||
core.summary.addTable([
|
||||
[
|
||||
{data: 'Root Project', header: true},
|
||||
{data: 'Tasks', header: true},
|
||||
{data: 'Gradle Version', header: true},
|
||||
{data: 'Outcome', header: true}
|
||||
],
|
||||
...results.map(result => [
|
||||
result.rootProjectName,
|
||||
result.requestedTasks,
|
||||
result.gradleVersion,
|
||||
renderOutcome(result)
|
||||
])
|
||||
])
|
||||
core.summary.addRaw('\n')
|
||||
|
||||
core.summary.addRaw(`
|
||||
<table>
|
||||
<tr>
|
||||
<th>Root Project</th>
|
||||
<th>Requested Tasks</th>
|
||||
<th>Gradle Version</th>
|
||||
<th>Build Outcome</th>
|
||||
<th>Build Scan™</th>
|
||||
</tr>${results.map(result => renderBuildResultRow(result)).join('')}
|
||||
</table>
|
||||
`)
|
||||
}
|
||||
|
||||
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 {
|
||||
const labelPart = result.buildScanUri ? 'Build%20Scan%E2%84%A2' : 'Build'
|
||||
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">`
|
||||
const targetUrl = result.buildScanUri ? result.buildScanUri : '#'
|
||||
return result.buildFailed ? ':x:' : ':white_check_mark:'
|
||||
}
|
||||
|
||||
function renderBuildScan(result: BuildResult): string {
|
||||
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>`
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@ abstract class BuildResultsRecorder implements BuildService<BuildResultsRecorder
|
||||
gradleVersion: GradleVersion.current().version,
|
||||
gradleHomeDir: getParameters().getGradleHomeDir().get(),
|
||||
buildFailed: buildFailed,
|
||||
buildScanUri: null
|
||||
buildScanUri: null,
|
||||
buildScanFailed: false
|
||||
]
|
||||
|
||||
def buildResultsDir = new File(System.getenv("RUNNER_TEMP"), ".build-results")
|
||||
@@ -40,65 +40,33 @@ if (isTopLevelBuild) {
|
||||
|
||||
def captureUsingBuildScanPublished(buildScanExtension, rootProject, invocationId) {
|
||||
buildScanExtension.with {
|
||||
def requestedTasks = gradle.startParameter.taskNames.join(" ")
|
||||
def rootProjectName = rootProject.name
|
||||
def rootProjectDir = rootProject.projectDir.absolutePath
|
||||
def gradleVersion = GradleVersion.current().version
|
||||
def gradleHomeDir = gradle.gradleHomeDir.absolutePath
|
||||
def buildFailed = false
|
||||
def buildResults = new BuildResults(invocationId, gradle, rootProject)
|
||||
|
||||
buildFinished { result ->
|
||||
buildFailed = (result.failure != null)
|
||||
buildResults.setBuildResult(result)
|
||||
}
|
||||
|
||||
buildScanPublished { buildScan ->
|
||||
|
||||
def buildScanUri = buildScan.buildScanUri.toASCIIString()
|
||||
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)
|
||||
}
|
||||
buildResults.setBuildScanUri(buildScan.buildScanUri.toASCIIString())
|
||||
buildResults.writeToResultsFile(true)
|
||||
|
||||
println("::set-output name=build-scan-url::${buildScan.buildScanUri}")
|
||||
}
|
||||
|
||||
onError { error ->
|
||||
buildResults.setBuildScanFailed()
|
||||
buildResults.writeToResultsFile(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def captureUsingBuildFinished(gradle, invocationId) {
|
||||
gradle.buildFinished { result ->
|
||||
def buildResults = [
|
||||
rootProjectName: gradle.rootProject.name,
|
||||
rootProjectDir: gradle.rootProject.rootDir.absolutePath,
|
||||
requestedTasks: gradle.startParameter.taskNames.join(" "),
|
||||
gradleVersion: GradleVersion.current().version,
|
||||
gradleHomeDir: gradle.gradleHomeDir.absolutePath,
|
||||
buildFailed: result.failure != null,
|
||||
buildScanUri: null
|
||||
]
|
||||
def buildResults = new BuildResults(invocationId, gradle, gradle.rootProject)
|
||||
buildResults.setBuildResult(result)
|
||||
|
||||
buildResults.writeToResultsFile(false)
|
||||
|
||||
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
|
||||
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 exec from '@actions/exec'
|
||||
import {SUMMARY_ENV_VAR} from '@actions/core/lib/summary'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import * as os from 'os'
|
||||
@@ -13,7 +14,12 @@ const GRADLE_USER_HOME = 'GRADLE_USER_HOME'
|
||||
const CACHE_LISTENER = 'CACHE_LISTENER'
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -56,7 +62,7 @@ export async function complete(): Promise<void> {
|
||||
const gradleUserHome = core.getState(GRADLE_USER_HOME)
|
||||
await caches.save(gradleUserHome, cacheListener)
|
||||
|
||||
if (generateJobSummary()) {
|
||||
if (shouldGenerateJobSummary()) {
|
||||
writeJobSummary(buildResults, cacheListener)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ class BaseInitScriptTest extends Specification {
|
||||
static final String PUBLIC_BUILD_SCAN_ID = 'i2wepy2gr7ovw'
|
||||
static final String DEFAULT_SCAN_UPLOAD_TOKEN = 'scan-upload-token'
|
||||
static final String ROOT_PROJECT_NAME = 'test-init-script'
|
||||
boolean failScanUpload = false
|
||||
|
||||
File settingsFile
|
||||
File buildFile
|
||||
@@ -59,6 +60,10 @@ class BaseInitScriptTest extends Specification {
|
||||
|
||||
handlers {
|
||||
post('in/:gradleVersion/:pluginVersion') {
|
||||
if (failScanUpload) {
|
||||
context.response.status(401).send()
|
||||
return
|
||||
}
|
||||
def scanUrlString = "${mockScansServer.address}s/$PUBLIC_BUILD_SCAN_ID"
|
||||
def body = [
|
||||
id : PUBLIC_BUILD_SCAN_ID,
|
||||
@@ -72,6 +77,10 @@ class BaseInitScriptTest extends Specification {
|
||||
}
|
||||
prefix('scans/publish') {
|
||||
post('gradle/:pluginVersion/token') {
|
||||
if (failScanUpload) {
|
||||
context.response.status(401).send()
|
||||
return
|
||||
}
|
||||
def pluginVersion = context.pathTokens.pluginVersion
|
||||
def scanUrlString = "${mockScansServer.address}s/$PUBLIC_BUILD_SCAN_ID"
|
||||
def body = [
|
||||
@@ -85,6 +94,10 @@ class BaseInitScriptTest extends Specification {
|
||||
.send(jsonWriter.writeValueAsBytes(body))
|
||||
}
|
||||
post('gradle/:pluginVersion/upload') {
|
||||
if (failScanUpload) {
|
||||
context.response.status(401).send()
|
||||
return
|
||||
}
|
||||
context.request.getBody(1024 * 1024 * 10).then {
|
||||
context.response
|
||||
.contentType('application/vnd.gradle.scan-upload-ack+json')
|
||||
@@ -100,7 +113,7 @@ class BaseInitScriptTest extends Specification {
|
||||
settingsFile = new File(testProjectDir, 'settings.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")
|
||||
targetInitScriptsDir.mkdirs()
|
||||
|
||||
@@ -118,7 +118,23 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
|
||||
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)
|
||||
assert results['rootProjectName'] == ROOT_PROJECT_NAME
|
||||
assert results['rootProjectDir'] == testProjectDir.canonicalPath
|
||||
@@ -127,6 +143,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
|
||||
assert results['gradleHomeDir'] != null
|
||||
assert results['buildFailed'] == hasFailure
|
||||
assert results['buildScanUri'] == (hasBuildScan ? "${mockScansServer.address}s/${PUBLIC_BUILD_SCAN_ID}" : null)
|
||||
assert results['buildScanFailed'] == scanUploadFailed
|
||||
}
|
||||
|
||||
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('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('can hash', () => {
|
||||
Reference in New Issue
Block a user