mirror of
https://github.com/gradle/actions.git
synced 2025-11-26 17:09:10 +08:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbbdc275be | ||
|
|
ae74429826 | ||
|
|
bdc7162ff9 | ||
|
|
31ae3562f6 | ||
|
|
719985db3d | ||
|
|
b53238971c | ||
|
|
5f1c5827bf | ||
|
|
d9336dac04 | ||
|
|
8dbe9a3802 | ||
|
|
9c3430720d | ||
|
|
30c82f0068 | ||
|
|
e3bc05f224 | ||
|
|
485ea107b7 | ||
|
|
c1091c9c8e | ||
|
|
d0a116fff5 | ||
|
|
e238a7ad22 | ||
|
|
1d2ea6e5a8 | ||
|
|
114c1c234e | ||
|
|
2db3ae936e | ||
|
|
a68381d359 | ||
|
|
52ae27f7bb | ||
|
|
d1cd62d80a | ||
|
|
af6e576724 | ||
|
|
775b4d10d7 | ||
|
|
30610bc983 | ||
|
|
d4d72c9934 | ||
|
|
96b9cb4988 | ||
|
|
db270b9337 | ||
|
|
d91e2960eb | ||
|
|
0498421560 | ||
|
|
edb13383f3 | ||
|
|
cd560aa3ad | ||
|
|
500e0ee5b3 | ||
|
|
eb13cf7170 | ||
|
|
ea14aa9caf | ||
|
|
063cfaf0eb | ||
|
|
35f9242e22 | ||
|
|
90f1de0556 | ||
|
|
da512b52a5 | ||
|
|
db19848a5f | ||
|
|
941b289d84 | ||
|
|
bce7daca54 | ||
|
|
11eaed9738 | ||
|
|
cd62d9c9ef | ||
|
|
a54fb6a5bb | ||
|
|
ef36f81b41 | ||
|
|
18998bc43e | ||
|
|
a772c14b33 | ||
|
|
7763d71170 | ||
|
|
9ab93ee864 | ||
|
|
d124ec149f | ||
|
|
6ccde15122 |
@@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id "com.gradle.develocity" version "3.17.2"
|
||||
id "com.gradle.develocity" version "3.17.5"
|
||||
id "com.gradle.common-custom-user-data-gradle-plugin" version "2.0.1"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -8,7 +8,7 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
api("org.apache.commons:commons-math3:3.6.1")
|
||||
implementation("com.google.guava:guava:33.1.0-jre")
|
||||
implementation("com.google.guava:guava:33.2.1-jre")
|
||||
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("com.gradle.develocity") version "3.17.2"
|
||||
id("com.gradle.develocity") version "3.17.5"
|
||||
id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.1"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id "com.gradle.develocity" version "3.17.2"
|
||||
id "com.gradle.develocity" version "3.17.5"
|
||||
}
|
||||
|
||||
develocity {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id "com.gradle.develocity" version "3.17.2"
|
||||
id "com.gradle.develocity" version "3.17.5"
|
||||
}
|
||||
|
||||
develocity {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id "com.gradle.develocity" version "3.17.2"
|
||||
id "com.gradle.develocity" version "3.17.5"
|
||||
}
|
||||
|
||||
develocity {
|
||||
|
||||
6
.github/workflows/ci-codeql.yml
vendored
6
.github/workflows/ci-codeql.yml
vendored
@@ -5,6 +5,12 @@ on:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'release/**'
|
||||
- 'dev/**' # Allow running Code QL on dev branches without a PR
|
||||
paths-ignore:
|
||||
- 'dist/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'main'
|
||||
paths-ignore:
|
||||
- 'dist/**'
|
||||
schedule:
|
||||
|
||||
2
.github/workflows/ci-init-script-check.yml
vendored
2
.github/workflows/ci-init-script-check.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 8
|
||||
java-version: 11
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3 # Use a released version to avoid breakages
|
||||
- name: Run integration tests
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 8
|
||||
java-version: 11
|
||||
- name: Setup Gradle
|
||||
id: setup-gradle
|
||||
uses: ./setup-gradle
|
||||
|
||||
@@ -18,6 +18,7 @@ permissions:
|
||||
env:
|
||||
SKIP_DIST: ${{ inputs.skip-dist }}
|
||||
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: dependency-graph-${{ inputs.cache-key-prefix }}
|
||||
GITHUB_DEPENDENCY_GRAPH_REF: 'refs/tags/v0.0.1' # Use a different ref to avoid updating the real dependency graph for the repository
|
||||
|
||||
jobs:
|
||||
groovy-generate:
|
||||
|
||||
@@ -15,6 +15,7 @@ on:
|
||||
env:
|
||||
SKIP_DIST: ${{ inputs.skip-dist }}
|
||||
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: dependency-submission-failures-${{ inputs.cache-key-prefix }}
|
||||
GITHUB_DEPENDENCY_GRAPH_REF: 'refs/tags/v0.0.1' # Use a different ref to avoid updating the real dependency graph for the repository
|
||||
|
||||
jobs:
|
||||
failing-build:
|
||||
|
||||
@@ -18,6 +18,7 @@ permissions:
|
||||
env:
|
||||
SKIP_DIST: ${{ inputs.skip-dist }}
|
||||
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: dependency-submission-${{ inputs.cache-key-prefix }}
|
||||
GITHUB_DEPENDENCY_GRAPH_REF: 'refs/tags/v0.0.1' # Use a different ref to avoid updating the real dependency graph for the repository
|
||||
|
||||
jobs:
|
||||
groovy-generate-and-upload:
|
||||
@@ -223,8 +224,6 @@ jobs:
|
||||
with:
|
||||
gradle-version: ${{ matrix.gradle }}
|
||||
build-root-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }}
|
||||
env:
|
||||
GITHUB_DEPENDENCY_GRAPH_REF: 'refs/tags/v0.0.1' # Use a different ref to avoid updating the real dependency graph for the repository
|
||||
|
||||
after-setup-gradle:
|
||||
strategy:
|
||||
|
||||
7
.github/workflows/integ-test-execution.yml
vendored
7
.github/workflows/integ-test-execution.yml
vendored
@@ -61,12 +61,17 @@ jobs:
|
||||
gradle: [7.5.1, 6.9.2, 5.6.4, 4.10.3, 3.5.1]
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
include:
|
||||
- java-version: 11
|
||||
- gradle: 5.6.4
|
||||
build-root-suffix: -gradle-5
|
||||
- gradle: 4.10.3
|
||||
build-root-suffix: -gradle-4
|
||||
- gradle: 3.5.1
|
||||
build-root-suffix: -gradle-4
|
||||
java-version: 8
|
||||
exclude:
|
||||
- os: macos-latest # Java 8 is not supported on macos-latest, so we cannot test Gradle 3.5.1
|
||||
gradle: 3.5.1
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
@@ -78,7 +83,7 @@ jobs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 8
|
||||
java-version: ${{ matrix.java-version }}
|
||||
- name: Run Gradle build
|
||||
uses: ./setup-gradle
|
||||
id: gradle
|
||||
|
||||
145
.github/workflows/integ-test-inject-develocity.yml
vendored
145
.github/workflows/integ-test-inject-develocity.yml
vendored
@@ -26,14 +26,19 @@ jobs:
|
||||
DEVELOCITY_URL: https://ge.solutions-team.gradle.com
|
||||
DEVELOCITY_PLUGIN_VERSION: ${{ matrix.plugin-version }}
|
||||
DEVELOCITY_CCUD_PLUGIN_VERSION: '2.0'
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} # required to test against GE plugin 3.16.2
|
||||
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||
${{matrix.accessKeyEnv}}: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
gradle: [current, 7.6.2, 6.9.4, 5.6.4]
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
plugin-version: [3.16.2, 3.17.2]
|
||||
plugin-version: [3.16.2, 3.17.4]
|
||||
include:
|
||||
- plugin-version: 3.16.2
|
||||
accessKeyEnv: GRADLE_ENTERPRISE_ACCESS_KEY
|
||||
- plugin-version: 3.17.4
|
||||
accessKeyEnv: DEVELOCITY_ACCESS_KEY
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
@@ -45,7 +50,7 @@ jobs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 8
|
||||
java-version: 11
|
||||
- name: Setup Gradle
|
||||
id: setup-gradle
|
||||
uses: ./setup-gradle
|
||||
@@ -62,3 +67,135 @@ jobs:
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('No Build Scan detected')
|
||||
- name: Check short lived token (DEVELOCITY_ACCESS_KEY)
|
||||
run: "[ ${#DEVELOCITY_ACCESS_KEY} -gt 500 ] || (echo 'DEVELOCITY_ACCESS_KEY does not look like a short lived token'; exit 1)"
|
||||
- name: Check short lived token (GRADLE_ENTERPRISE_ACCESS_KEY)
|
||||
run: "[ ${#GRADLE_ENTERPRISE_ACCESS_KEY} -gt 500 ] || (echo 'GRADLE_ENTERPRISE_ACCESS_KEY does not look like a short lived token'; exit 1)"
|
||||
|
||||
inject-develocity-with-access-key:
|
||||
env:
|
||||
DEVELOCITY_INJECTION_ENABLED: true
|
||||
DEVELOCITY_URL: 'https://ge.solutions-team.gradle.com'
|
||||
DEVELOCITY_PLUGIN_VERSION: ${{ matrix.plugin-version }}
|
||||
DEVELOCITY_CCUD_PLUGIN_VERSION: '2.0'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
gradle: [current, 7.6.2, 6.9.4, 5.6.4]
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
plugin-version: [3.16.2, 3.17.4]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Initialize integ-test
|
||||
uses: ./.github/actions/init-integ-test
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 8
|
||||
- name: Setup Gradle
|
||||
id: setup-gradle
|
||||
uses: ./setup-gradle
|
||||
with:
|
||||
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||
gradle-version: ${{ matrix.gradle }}
|
||||
develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||
develocity-token-expiry: 1
|
||||
- name: Run Gradle build
|
||||
id: gradle
|
||||
working-directory: .github/workflow-samples/no-ge
|
||||
run: gradle help
|
||||
- name: Check short lived token (DEVELOCITY_ACCESS_KEY)
|
||||
run: "[ ${#DEVELOCITY_ACCESS_KEY} -gt 500 ] || (echo 'DEVELOCITY_ACCESS_KEY does not look like a short lived token'; exit 1)"
|
||||
- name: Check short lived token (GRADLE_ENTERPRISE_ACCESS_KEY)
|
||||
run: "[ ${#GRADLE_ENTERPRISE_ACCESS_KEY} -gt 500 ] || (echo 'GRADLE_ENTERPRISE_ACCESS_KEY does not look like a short lived token'; exit 1)"
|
||||
- name: Check Build Scan url
|
||||
if: ${{ !steps.gradle.outputs.build-scan-url }}
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('No Build Scan detected')
|
||||
|
||||
inject-develocity-short-lived-token-failed:
|
||||
env:
|
||||
DEVELOCITY_INJECTION_ENABLED: true
|
||||
DEVELOCITY_URL: 'https://localhost:3333/'
|
||||
DEVELOCITY_PLUGIN_VERSION: ${{ matrix.plugin-version }}
|
||||
DEVELOCITY_CCUD_PLUGIN_VERSION: '2.0'
|
||||
# Access key also set as an env var, we want to check it does not leak
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
gradle: [ current, 7.6.2, 6.9.4, 5.6.4 ]
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
plugin-version: [ 3.16.2, 3.17.4 ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Initialize integ-test
|
||||
uses: ./.github/actions/init-integ-test
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 8
|
||||
- name: Setup Gradle
|
||||
id: setup-gradle
|
||||
uses: ./setup-gradle
|
||||
with:
|
||||
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||
develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||
- name: Run Gradle build
|
||||
id: gradle
|
||||
working-directory: .github/workflow-samples/no-ge
|
||||
run: gradle help
|
||||
- name: Check access key is not blank (DEVELOCITY_ACCESS_KEY)
|
||||
run: "[ \"${DEVELOCITY_ACCESS_KEY}\" != \"\" ] || (echo 'using DEVELOCITY_ACCESS_KEY!'; exit 1)"
|
||||
- name: Check access key is not blank (GRADLE_ENTERPRISE_ACCESS_KEY)
|
||||
run: "[ \"${GRADLE_ENTERPRISE_ACCESS_KEY}\" != \"\" ] || (echo 'GRADLE_ENTERPRISE_ACCESS_KEY is still supported in v3!'; exit 1)"
|
||||
|
||||
inject-develocity-with-access-key-from-input-actions:
|
||||
env:
|
||||
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
gradle: [ current, 7.6.2, 6.9.4, 5.6.4 ]
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
plugin-version: [ 3.16.2, 3.17.4 ]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Initialize integ-test
|
||||
uses: ./.github/actions/init-integ-test
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 8
|
||||
- name: Setup Gradle
|
||||
id: setup-gradle
|
||||
uses: ./setup-gradle
|
||||
with:
|
||||
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||
gradle-version: ${{ matrix.gradle }}
|
||||
develocity-injection-enabled: true
|
||||
develocity-url: 'https://ge.solutions-team.gradle.com'
|
||||
develocity-plugin-version: ${{ matrix.plugin-version }}
|
||||
- name: Run Gradle build
|
||||
id: gradle
|
||||
working-directory: .github/workflow-samples/no-ge
|
||||
run: gradle help
|
||||
- name: Check Build Scan url
|
||||
if: ${{ !steps.gradle.outputs.build-scan-url }}
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('No Build Scan detected')
|
||||
|
||||
@@ -76,12 +76,17 @@ jobs:
|
||||
gradle: [7.3, 6.9, 5.6.4, 4.10.3, 3.5.1]
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
include:
|
||||
- java-version: 11
|
||||
- gradle: 5.6.4
|
||||
build-root-suffix: -gradle-5
|
||||
- gradle: 4.10.3
|
||||
build-root-suffix: -gradle-4
|
||||
- gradle: 3.5.1
|
||||
build-root-suffix: -gradle-4
|
||||
java-version: 8
|
||||
exclude:
|
||||
- os: macos-latest # Java 8 is not supported on macos-latest, so we cannot test Gradle 3.5.1
|
||||
gradle: 3.5.1
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
@@ -93,7 +98,7 @@ jobs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 8
|
||||
java-version: ${{ matrix.java-version }}
|
||||
- name: Setup Gradle
|
||||
id: setup-gradle
|
||||
uses: ./setup-gradle
|
||||
|
||||
10
build
10
build
@@ -5,7 +5,7 @@ cd sources
|
||||
case "$1" in
|
||||
all)
|
||||
npm clean-install
|
||||
nprm run all
|
||||
npm run all
|
||||
;;
|
||||
act)
|
||||
# Build and copy outputs to the dist directory
|
||||
@@ -16,12 +16,18 @@ case "$1" in
|
||||
# Run act
|
||||
$@
|
||||
# Revert the changes to the dist directory
|
||||
git co -- dist
|
||||
git checkout -- dist
|
||||
;;
|
||||
init-scripts)
|
||||
cd test/init-scripts
|
||||
./gradlew check
|
||||
;;
|
||||
dist)
|
||||
npm install
|
||||
npm run build
|
||||
cd ..
|
||||
cp -r sources/dist .
|
||||
;;
|
||||
*)
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
@@ -125,6 +125,14 @@ inputs:
|
||||
description: Indicate that you agree to the Build Scan® terms of use. This input value must be "yes".
|
||||
required: false
|
||||
|
||||
develocity-access-key:
|
||||
description: Develocity access key. Should be set to a secret containing the Develocity Access key.
|
||||
required: false
|
||||
|
||||
develocity-token-expiry:
|
||||
description: The Develocity short-lived access tokens expiry in hours. Default is 2 hours.
|
||||
required: false
|
||||
|
||||
# DEPRECATED ACTION INPUTS
|
||||
build-scan-terms-of-service-url:
|
||||
description: The URL to the Build Scan® terms of use. This input must be set to 'https://gradle.com/terms-of-service'.
|
||||
|
||||
391
dist/dependency-submission/main/index.js
vendored
391
dist/dependency-submission/main/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/dependency-submission/main/index.js.map
vendored
2
dist/dependency-submission/main/index.js.map
vendored
File diff suppressed because one or more lines are too long
384
dist/dependency-submission/post/index.js
vendored
384
dist/dependency-submission/post/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/dependency-submission/post/index.js.map
vendored
2
dist/dependency-submission/post/index.js.map
vendored
File diff suppressed because one or more lines are too long
391
dist/setup-gradle/main/index.js
vendored
391
dist/setup-gradle/main/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/setup-gradle/main/index.js.map
vendored
2
dist/setup-gradle/main/index.js.map
vendored
File diff suppressed because one or more lines are too long
391
dist/setup-gradle/post/index.js
vendored
391
dist/setup-gradle/post/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/setup-gradle/post/index.js.map
vendored
2
dist/setup-gradle/post/index.js.map
vendored
File diff suppressed because one or more lines are too long
56
dist/wrapper-validation/main/index.js
vendored
56
dist/wrapper-validation/main/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/wrapper-validation/main/index.js.map
vendored
2
dist/wrapper-validation/main/index.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -95,7 +95,7 @@ In some cases, the default action configuration will not be sufficient, and addi
|
||||
dependency-resolution-task: myDependencyResolutionTask
|
||||
|
||||
# Additional arguments that should be passed to execute Gradle
|
||||
additonal-arguments: --no-configuration-cache
|
||||
additional-arguments: --no-configuration-cache
|
||||
|
||||
# Enable configuration-cache reuse for this build.
|
||||
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||
@@ -367,6 +367,7 @@ on:
|
||||
types: [completed]
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -101,7 +101,7 @@ The exact syntax depends on whether or not your project is configured with the [
|
||||
- name: Setup Gradle for a non-wrapper project
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
with:
|
||||
gradle-version: 8.7
|
||||
gradle-version: 8.8
|
||||
|
||||
- name: Assemble the project
|
||||
run: gradle assemble
|
||||
@@ -143,3 +143,8 @@ to this:
|
||||
build-scan-terms-of-use-agree: "yes"
|
||||
```
|
||||
These deprecated build-scan parameters are scheduled to be removed in `setup-gradle@v4` and `dependency-submission@v4`.
|
||||
|
||||
## The GRADLE_ENTERPRISE_ACCESS_KEY env var is deprecated
|
||||
Gradle Enterprise has been renamed to Develocity starting from Gradle plugin 3.17 and Develocity server 2024.1.
|
||||
In v4 release of the action, it will require setting the access key with the `develocity-access-key` input and Develocity 2024.1 at least to generate short-lived tokens.
|
||||
If those requirements are not met, the `GRADLE_ENTERPRISE_ACCESS_KEY` env var will be cleared out and build scan publication or other authenticated Develocity operations won't be possible.
|
||||
|
||||
@@ -198,7 +198,7 @@ jobs:
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The configuration cache cannot be saved or restored in workflows triggered by a pull requests from a repsitory fork.
|
||||
> The configuration cache cannot be saved or restored in workflows triggered by a pull requests from a repository fork.
|
||||
> This is because [GitHub secrets are not passed to workflows triggered by PRs from forks](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#using-secrets-in-a-workflow).
|
||||
> This prevents a malicious PR from reading the configuration-cache data, which may encode secrets read by Gradle.
|
||||
|
||||
@@ -708,27 +708,49 @@ The same auto-injection behavior is available for the Common Custom User Data Gr
|
||||
|
||||
## Enabling Develocity injection
|
||||
|
||||
To enable Develocity injection for your build, you must provide the required configuration via environment variables.
|
||||
To enable Develocity injection for your build, you must provide the required configuration via inputs.
|
||||
|
||||
Here's a minimal example:
|
||||
|
||||
```yaml
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
with:
|
||||
develocity-injection-enabled: true
|
||||
develocity-url: https://develocity.your-server.com
|
||||
develocity-plugin-version: 3.17.5
|
||||
|
||||
- name: Run a Gradle build with Develocity injection enabled
|
||||
run: ./gradlew build
|
||||
```
|
||||
|
||||
This configuration will automatically apply `v3.17.5` of the [Develocity Gradle plugin](https://docs.gradle.com/develocity/gradle-plugin/), and publish build scans to https://develocity.your-server.com.
|
||||
|
||||
This example assumes that the `develocity.your-server.com` server allows anonymous publishing of build scans.
|
||||
In the likely scenario that your Develocity server requires authentication, you will also need to pass a valid [Develocity access key](https://docs.gradle.com/develocity/gradle-plugin/#via_environment_variable) taken from a secret:
|
||||
|
||||
```yaml
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
with:
|
||||
develocity-access-key: ${{ secrets.MY_DEVELOCITY_ACCESS_KEY }}
|
||||
|
||||
- name: Run a Gradle build with Develocity injection enabled
|
||||
run: ./gradlew build
|
||||
env:
|
||||
DEVELOCITY_INJECTION_ENABLED: true
|
||||
DEVELOCITY_URL: https://develocity.your-server.com
|
||||
DEVELOCITY_PLUGIN_VERSION: 3.17.2
|
||||
DEVELOCITY_PLUGIN_VERSION: 3.17
|
||||
```
|
||||
|
||||
This configuration will automatically apply `v3.17.2` of the [Develocity Gradle plugin](https://docs.gradle.com/develocity/gradle-plugin/), and publish build scans to https://develocity.your-server.com.
|
||||
This access key will be used during the action execution to get a short-lived token and set it to the DEVELOCITY_ACCESS_KEY environment variable.
|
||||
|
||||
This example assumes that the `develocity.your-server.com` server allows anonymous publishing of build scans.
|
||||
In the likely scenario that your Develocity server requires authentication, you will also need to configure an additional environment variable
|
||||
with a valid [Develocity access key](https://docs.gradle.com/develocity/gradle-plugin/#via_environment_variable).
|
||||
### Short-lived access tokens
|
||||
Develocity access keys are long-lived, creating risks if they are leaked. To avoid this, users can use short-lived access tokens to authenticate with Develocity. Access tokens can be used wherever an access key would be used. Access tokens are only valid for the Develocity instance that created them.
|
||||
If a short-lived token fails to be retrieved (for example, if the Develocity server version is lower than `2024.1`):
|
||||
- if a `GRADLE_ENTERPRISE_ACCESS_KEY` env var has been set, we're falling back to it with a deprecation warning
|
||||
- otherwise no access key env var will be set. In that case Develocity authenticated operations like build cache read/write and build scan publication will fail without failing the build.
|
||||
For more information on short-lived tokens, see [Develocity API documentation](https://docs.gradle.com/develocity/api-manual/#short_lived_access_tokens).
|
||||
|
||||
## Configuring Develocity injection
|
||||
|
||||
@@ -736,16 +758,46 @@ The `init-script` supports several additional configuration parameters that you
|
||||
|
||||
| Variable | Required | Description |
|
||||
|--------------------------------------| --- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| DEVELOCITY_INJECTION_ENABLED | :white_check_mark: | enables Develocity injection |
|
||||
| DEVELOCITY_URL | :white_check_mark: | the URL of the Develocity server |
|
||||
| DEVELOCITY_ALLOW_UNTRUSTED_SERVER | | allow communication with an untrusted server; set to _true_ if your Develocity instance is using a self-signed certificate |
|
||||
| DEVELOCITY_CAPTURE_FILE_FINGERPRINTS | | enables capturing the paths and content hashes of each individual input file |
|
||||
| DEVELOCITY_ENFORCE_URL | | enforce the configured Develocity URL over a URL configured in the project's build; set to _true_ to enforce publication of build scans to the configured Develocity URL |
|
||||
| DEVELOCITY_PLUGIN_VERSION | :white_check_mark: | the version of the [Develocity Gradle plugin](https://docs.gradle.com/develocity/gradle-plugin/) to apply |
|
||||
| DEVELOCITY_CCUD_PLUGIN_VERSION | | the version of the [Common Custom User Data Gradle plugin](https://github.com/gradle/common-custom-user-data-gradle-plugin) to apply, if any |
|
||||
| GRADLE_PLUGIN_REPOSITORY_URL | | the URL of the repository to use when resolving the Develocity and CCUD plugins; the Gradle Plugin Portal is used by default |
|
||||
| GRADLE_PLUGIN_REPOSITORY_USERNAME | | the username for the repository URL to use when resolving the Develocity and CCUD plugins |
|
||||
| GRADLE_PLUGIN_REPOSITORY_PASSWORD | | the password for the repository URL to use when resolving the Develocity and CCUD plugins; Consider using secrets to pass the value to this variable |
|
||||
| develocity-injection-enabled | :white_check_mark: | enables Develocity injection |
|
||||
| develocity-url | :white_check_mark: | the URL of the Develocity server |
|
||||
| develocity-allow-untrusted-server | | allow communication with an untrusted server; set to _true_ if your Develocity instance is using a self-signed certificate |
|
||||
| develocity-capture-file-fingerprints | | enables capturing the paths and content hashes of each individual input file |
|
||||
| develocity-enforce-url | | enforce the configured Develocity URL over a URL configured in the project's build; set to _true_ to enforce publication of build scans to the configured Develocity URL |
|
||||
| develocity-plugin-version | :white_check_mark: | the version of the [Develocity Gradle plugin](https://docs.gradle.com/develocity/gradle-plugin/) to apply |
|
||||
| develocity-ccud-plugin-version | | the version of the [Common Custom User Data Gradle plugin](https://github.com/gradle/common-custom-user-data-gradle-plugin) to apply, if any |
|
||||
| gradle-plugin-repository-url | | the URL of the repository to use when resolving the Develocity and CCUD plugins; the Gradle Plugin Portal is used by default |
|
||||
| gradle-plugin-repository-username | | the username for the repository URL to use when resolving the Develocity and CCUD plugins |
|
||||
| gradle-plugin-repository-password | | the password for the repository URL to use when resolving the Develocity and CCUD plugins; Consider using secrets to pass the value to this variable |
|
||||
|
||||
The input parameters can be expressed as environment variables following the relationships outlined in the table below:
|
||||
|
||||
| Input | Environment Variable |
|
||||
|--------------------------------------|--------------------------------------|
|
||||
| develocity-injection-enabled | DEVELOCITY_INJECTION_ENABLED |
|
||||
| develocity-url | DEVELOCITY_URL |
|
||||
| develocity-allow-untrusted-server | DEVELOCITY_ALLOW_UNTRUSTED_SERVER |
|
||||
| develocity-capture-file-fingerprints | DEVELOCITY_CAPTURE_FILE_FINGERPRINTS |
|
||||
| develocity-enforce-url | DEVELOCITY_ENFORCE_URL |
|
||||
| develocity-plugin-version | DEVELOCITY_PLUGIN_VERSION |
|
||||
| develocity-ccud-plugin-version | DEVELOCITY_CCUD_PLUGIN_VERSION |
|
||||
| gradle-plugin-repository-url | GRADLE_PLUGIN_REPOSITORY_URL |
|
||||
| gradle-plugin-repository-username | GRADLE_PLUGIN_REPOSITORY_USERNAME |
|
||||
| gradle-plugin-repository-password | GRADLE_PLUGIN_REPOSITORY_PASSWORD |
|
||||
|
||||
|
||||
Here's an example using the env vars:
|
||||
|
||||
```yaml
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
|
||||
- name: Run a Gradle build with Develocity injection enabled with environment variables
|
||||
run: ./gradlew build
|
||||
env:
|
||||
DEVELOCITY_INJECTION_ENABLED: true
|
||||
DEVELOCITY_URL: https://develocity.your-server.com
|
||||
DEVELOCITY_PLUGIN_VERSION: 3.17.5
|
||||
```
|
||||
|
||||
## Publishing to scans.gradle.com
|
||||
|
||||
|
||||
@@ -100,6 +100,54 @@ inputs:
|
||||
description: Indicate that you agree to the Build Scan® terms of use. This input value must be "yes".
|
||||
required: false
|
||||
|
||||
develocity-access-key:
|
||||
description: Develocity access key. Should be set to a secret containing the Develocity Access key.
|
||||
required: false
|
||||
|
||||
develocity-token-expiry:
|
||||
description: The Develocity short-lived access tokens expiry in hours. Default is 2 hours.
|
||||
required: false
|
||||
|
||||
develocity-injection-enabled:
|
||||
description: Enables Develocity injection.
|
||||
required: false
|
||||
|
||||
develocity-url:
|
||||
description: The URL for the Develocity server.
|
||||
required: false
|
||||
|
||||
develocity-allow-untrusted-server:
|
||||
description: Allow communication with an untrusted server; set to _true_ if your Develocity instance is using a self-signed.
|
||||
required: false
|
||||
|
||||
develocity-capture-file-fingerprints:
|
||||
description: Enables capturing the paths and content hashes of each individual input file.
|
||||
required: false
|
||||
|
||||
develocity-enforce-url:
|
||||
description: Enforce the configured Develocity URL over a URL configured in the project's build; set to _true_ to enforce publication of build scans to the configured Develocity URL.
|
||||
required: false
|
||||
|
||||
develocity-plugin-version:
|
||||
description: The version of the Develocity Gradle plugin to apply.
|
||||
required: false
|
||||
|
||||
develocity-ccud-plugin-version:
|
||||
description: The version of the Common Custom User Data Gradle plugin to apply, if any.
|
||||
required: false
|
||||
|
||||
gradle-plugin-repository-url:
|
||||
description: The URL of the repository to use when resolving the Develocity and CCUD plugins; the Gradle Plugin Portal is used by default.
|
||||
required: false
|
||||
|
||||
gradle-plugin-repository-username:
|
||||
description: The username for the repository URL to use when resolving the Develocity and CCUD.
|
||||
required: false
|
||||
|
||||
gradle-plugin-repository-password:
|
||||
description: The password for the repository URL to use when resolving the Develocity and CCUD plugins; Consider using secrets to pass the value to this variable.
|
||||
required: false
|
||||
|
||||
# Wrapper validation configuration
|
||||
validate-wrappers:
|
||||
description: |
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Configuration file for asdf version manager
|
||||
nodejs 20.10.0
|
||||
gradle 8.7
|
||||
gradle 8.8
|
||||
|
||||
28
sources/package-lock.json
generated
28
sources/package-lock.json
generated
@@ -3316,12 +3316,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -4736,9 +4736,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
@@ -11628,12 +11628,12 @@
|
||||
}
|
||||
},
|
||||
"braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
}
|
||||
},
|
||||
"browserslist": {
|
||||
@@ -12659,9 +12659,9 @@
|
||||
}
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import * as core from '@actions/core'
|
||||
import {BuildScanConfig} from './configuration'
|
||||
|
||||
export function setup(config: BuildScanConfig): void {
|
||||
maybeExportVariable('DEVELOCITY_INJECTION_INIT_SCRIPT_NAME', 'gradle-actions.inject-develocity.init.gradle')
|
||||
maybeExportVariable('DEVELOCITY_AUTO_INJECTION_CUSTOM_VALUE', 'gradle-actions')
|
||||
if (config.getBuildScanPublishEnabled()) {
|
||||
maybeExportVariable('DEVELOCITY_INJECTION_ENABLED', 'true')
|
||||
maybeExportVariable('DEVELOCITY_PLUGIN_VERSION', '3.17.2')
|
||||
maybeExportVariable('DEVELOCITY_CCUD_PLUGIN_VERSION', '2.0')
|
||||
maybeExportVariable('DEVELOCITY_TERMS_OF_USE_URL', config.getBuildScanTermsOfUseUrl())
|
||||
maybeExportVariable('DEVELOCITY_TERMS_OF_USE_AGREE', config.getBuildScanTermsOfUseAgree())
|
||||
}
|
||||
}
|
||||
|
||||
function maybeExportVariable(variableName: string, value: unknown): void {
|
||||
if (!process.env[variableName]) {
|
||||
core.exportVariable(variableName, value)
|
||||
}
|
||||
}
|
||||
@@ -188,6 +188,9 @@ export enum JobSummaryOption {
|
||||
}
|
||||
|
||||
export class BuildScanConfig {
|
||||
static DevelocityAccessKeyEnvVar = 'DEVELOCITY_ACCESS_KEY'
|
||||
static GradleEnterpriseAccessKeyEnvVar = 'GRADLE_ENTERPRISE_ACCESS_KEY'
|
||||
|
||||
getBuildScanPublishEnabled(): boolean {
|
||||
return getBooleanInput('build-scan-publish') && this.verifyTermsOfUseAgreement()
|
||||
}
|
||||
@@ -200,6 +203,59 @@ export class BuildScanConfig {
|
||||
return this.getTermsOfUseProp('build-scan-terms-of-use-agree', 'build-scan-terms-of-service-agree')
|
||||
}
|
||||
|
||||
getDevelocityAccessKey(): string {
|
||||
return (
|
||||
core.getInput('develocity-access-key') ||
|
||||
process.env[BuildScanConfig.DevelocityAccessKeyEnvVar] ||
|
||||
process.env[BuildScanConfig.GradleEnterpriseAccessKeyEnvVar] ||
|
||||
''
|
||||
)
|
||||
}
|
||||
|
||||
getDevelocityTokenExpiry(): string {
|
||||
return core.getInput('develocity-token-expiry')
|
||||
}
|
||||
|
||||
getDevelocityInjectionEnabled(): boolean | undefined {
|
||||
return getOptionalBooleanInput('develocity-injection-enabled')
|
||||
}
|
||||
|
||||
getDevelocityUrl(): string {
|
||||
return core.getInput('develocity-url')
|
||||
}
|
||||
|
||||
getDevelocityAllowUntrustedServer(): boolean | undefined {
|
||||
return getOptionalBooleanInput('develocity-allow-untrusted-server')
|
||||
}
|
||||
|
||||
getDevelocityCaptureFileFingerprints(): boolean | undefined {
|
||||
return getOptionalBooleanInput('develocity-capture-file-fingerprints')
|
||||
}
|
||||
|
||||
getDevelocityEnforceUrl(): boolean | undefined {
|
||||
return getOptionalBooleanInput('develocity-enforce-url')
|
||||
}
|
||||
|
||||
getDevelocityPluginVersion(): string {
|
||||
return core.getInput('develocity-plugin-version')
|
||||
}
|
||||
|
||||
getDevelocityCcudPluginVersion(): string {
|
||||
return core.getInput('develocity-ccud-plugin-version')
|
||||
}
|
||||
|
||||
getGradlePluginRepositoryUrl(): string {
|
||||
return core.getInput('gradle-plugin-repository-url')
|
||||
}
|
||||
|
||||
getGradlePluginRepositoryUsername(): string {
|
||||
return core.getInput('gradle-plugin-repository-username')
|
||||
}
|
||||
|
||||
getGradlePluginRepositoryPassword(): string {
|
||||
return core.getInput('gradle-plugin-repository-password')
|
||||
}
|
||||
|
||||
private verifyTermsOfUseAgreement(): boolean {
|
||||
if (
|
||||
(this.getBuildScanTermsOfUseUrl() !== 'https://gradle.com/terms-of-service' &&
|
||||
@@ -313,3 +369,11 @@ function getBooleanInput(paramName: string, paramDefault = false): boolean {
|
||||
}
|
||||
throw TypeError(`The value '${paramValue} is not valid for '${paramName}. Valid values are: [true, false]`)
|
||||
}
|
||||
|
||||
function getOptionalBooleanInput(paramName: string): boolean | undefined {
|
||||
const paramValue = core.getInput(paramName)
|
||||
if (paramValue === '') {
|
||||
return undefined
|
||||
}
|
||||
return getBooleanInput(paramName)
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ export async function setup(config: DependencyGraphConfig): Promise<void> {
|
||||
}
|
||||
// Download and submit early, for compatability with dependency review.
|
||||
if (option === DependencyGraphOption.DownloadAndSubmit) {
|
||||
maybeExportVariable('DEPENDENCY_GRAPH_REPORT_DIR', config.getReportDirectory())
|
||||
await downloadAndSubmitDependencyGraphs(config)
|
||||
return
|
||||
}
|
||||
@@ -124,17 +125,16 @@ async function submitDependencyGraphs(dependencyGraphFiles: string[]): Promise<v
|
||||
await submitDependencyGraphFile(dependencyGraphFile)
|
||||
} catch (error) {
|
||||
if (error instanceof RequestError) {
|
||||
throw new Error(translateErrorMessage(dependencyGraphFile, error))
|
||||
} else {
|
||||
throw error
|
||||
error.message = translateErrorMessage(dependencyGraphFile, error)
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function translateErrorMessage(jsonFile: string, error: RequestError): string {
|
||||
const relativeJsonFile = getRelativePathFromWorkspace(jsonFile)
|
||||
const mainWarning = `Dependency submission failed for ${relativeJsonFile}.\n${String(error)}`
|
||||
const mainWarning = `Dependency submission failed for ${relativeJsonFile}.\n${error.message}`
|
||||
if (error.message === 'Resource not accessible by integration') {
|
||||
return `${mainWarning}
|
||||
Please ensure that the 'contents: write' permission is available for the workflow job.
|
||||
|
||||
39
sources/src/develocity/build-scan.ts
Normal file
39
sources/src/develocity/build-scan.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import * as core from '@actions/core'
|
||||
import {BuildScanConfig} from '../configuration'
|
||||
import {setupToken} from './short-lived-token'
|
||||
|
||||
export async function setup(config: BuildScanConfig): Promise<void> {
|
||||
maybeExportVariable('DEVELOCITY_INJECTION_INIT_SCRIPT_NAME', 'gradle-actions.inject-develocity.init.gradle')
|
||||
maybeExportVariable('DEVELOCITY_AUTO_INJECTION_CUSTOM_VALUE', 'gradle-actions')
|
||||
if (config.getBuildScanPublishEnabled()) {
|
||||
maybeExportVariable('DEVELOCITY_INJECTION_ENABLED', 'true')
|
||||
maybeExportVariable('DEVELOCITY_PLUGIN_VERSION', '3.17.5')
|
||||
maybeExportVariable('DEVELOCITY_CCUD_PLUGIN_VERSION', '2.0')
|
||||
maybeExportVariable('DEVELOCITY_TERMS_OF_USE_URL', config.getBuildScanTermsOfUseUrl())
|
||||
maybeExportVariable('DEVELOCITY_TERMS_OF_USE_AGREE', config.getBuildScanTermsOfUseAgree())
|
||||
}
|
||||
|
||||
maybeExportVariableNotEmpty('DEVELOCITY_INJECTION_ENABLED', config.getDevelocityInjectionEnabled())
|
||||
maybeExportVariableNotEmpty('DEVELOCITY_URL', config.getDevelocityUrl())
|
||||
maybeExportVariableNotEmpty('DEVELOCITY_ALLOW_UNTRUSTED_SERVER', config.getDevelocityAllowUntrustedServer())
|
||||
maybeExportVariableNotEmpty('DEVELOCITY_CAPTURE_FILE_FINGERPRINTS', config.getDevelocityCaptureFileFingerprints())
|
||||
maybeExportVariableNotEmpty('DEVELOCITY_ENFORCE_URL', config.getDevelocityEnforceUrl())
|
||||
maybeExportVariableNotEmpty('DEVELOCITY_PLUGIN_VERSION', config.getDevelocityPluginVersion())
|
||||
maybeExportVariableNotEmpty('GRADLE_PLUGIN_REPOSITORY_URL', config.getGradlePluginRepositoryUrl())
|
||||
maybeExportVariableNotEmpty('GRADLE_PLUGIN_REPOSITORY_USERNAME', config.getGradlePluginRepositoryUsername())
|
||||
maybeExportVariableNotEmpty('GRADLE_PLUGIN_REPOSITORY_PASSWORD', config.getGradlePluginRepositoryPassword())
|
||||
|
||||
return setupToken(config.getDevelocityAccessKey(), config.getDevelocityTokenExpiry())
|
||||
}
|
||||
|
||||
function maybeExportVariable(variableName: string, value: unknown): void {
|
||||
if (!process.env[variableName]) {
|
||||
core.exportVariable(variableName, value)
|
||||
}
|
||||
}
|
||||
|
||||
function maybeExportVariableNotEmpty(variableName: string, value: unknown): void {
|
||||
if (value !== null && value !== undefined && value !== '') {
|
||||
maybeExportVariable(variableName, value)
|
||||
}
|
||||
}
|
||||
160
sources/src/develocity/short-lived-token.ts
Normal file
160
sources/src/develocity/short-lived-token.ts
Normal file
@@ -0,0 +1,160 @@
|
||||
import * as httpm from 'typed-rest-client/HttpClient'
|
||||
import * as core from '@actions/core'
|
||||
import {BuildScanConfig} from '../configuration'
|
||||
import {recordDeprecation} from '../deprecation-collector'
|
||||
|
||||
export async function setupToken(develocityAccessKey: string, develocityTokenExpiry: string): Promise<void> {
|
||||
if (develocityAccessKey) {
|
||||
try {
|
||||
core.debug('Fetching short-lived token...')
|
||||
const tokens = await getToken(develocityAccessKey, develocityTokenExpiry)
|
||||
if (tokens != null && !tokens.isEmpty()) {
|
||||
core.debug(`Got token(s), setting the access key env vars`)
|
||||
const token = tokens.raw()
|
||||
core.setSecret(token)
|
||||
exportAccessKeyEnvVars(token)
|
||||
} else {
|
||||
handleMissingAccessToken()
|
||||
}
|
||||
} catch (e) {
|
||||
handleMissingAccessToken()
|
||||
core.warning(`Failed to fetch short-lived token, reason: ${e}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function exportAccessKeyEnvVars(value: string): void {
|
||||
;[BuildScanConfig.DevelocityAccessKeyEnvVar, BuildScanConfig.GradleEnterpriseAccessKeyEnvVar].forEach(key =>
|
||||
core.exportVariable(key, value)
|
||||
)
|
||||
}
|
||||
|
||||
function handleMissingAccessToken(): void {
|
||||
core.warning(`Failed to fetch short-lived token for Develocity`)
|
||||
|
||||
if (process.env[BuildScanConfig.GradleEnterpriseAccessKeyEnvVar]) {
|
||||
// We do not clear the GRADLE_ENTERPRISE_ACCESS_KEY env var in v3, to let the users upgrade to DV 2024.1
|
||||
recordDeprecation(`The ${BuildScanConfig.GradleEnterpriseAccessKeyEnvVar} env var is deprecated`)
|
||||
}
|
||||
if (process.env[BuildScanConfig.DevelocityAccessKeyEnvVar]) {
|
||||
core.warning(`The ${BuildScanConfig.DevelocityAccessKeyEnvVar} env var should be mapped to a short-lived token`)
|
||||
}
|
||||
}
|
||||
|
||||
export async function getToken(accessKey: string, expiry: string): Promise<DevelocityAccessCredentials | null> {
|
||||
const empty: Promise<DevelocityAccessCredentials | null> = new Promise(r => r(null))
|
||||
const develocityAccessKey = DevelocityAccessCredentials.parse(accessKey)
|
||||
const shortLivedTokenClient = new ShortLivedTokenClient()
|
||||
|
||||
if (develocityAccessKey == null) {
|
||||
return empty
|
||||
}
|
||||
const tokens = new Array<HostnameAccessKey>()
|
||||
for (const k of develocityAccessKey.keys) {
|
||||
try {
|
||||
core.info(`Requesting short-lived Develocity access token for ${k.hostname}`)
|
||||
const token = await shortLivedTokenClient.fetchToken(`https://${k.hostname}`, k, expiry)
|
||||
tokens.push(token)
|
||||
} catch (e) {
|
||||
// Ignore failure to obtain token
|
||||
core.info(`Failed to obtain short-lived Develocity access token for ${k.hostname}: ${e}`)
|
||||
}
|
||||
}
|
||||
if (tokens.length > 0) {
|
||||
return DevelocityAccessCredentials.of(tokens)
|
||||
}
|
||||
return empty
|
||||
}
|
||||
|
||||
class ShortLivedTokenClient {
|
||||
httpc = new httpm.HttpClient('gradle/actions/setup-gradle')
|
||||
maxRetries = 3
|
||||
retryInterval = 1000
|
||||
|
||||
async fetchToken(serverUrl: string, accessKey: HostnameAccessKey, expiry: string): Promise<HostnameAccessKey> {
|
||||
const queryParams = expiry ? `?expiresInHours${expiry}` : ''
|
||||
const sanitizedServerUrl = !serverUrl.endsWith('/') ? `${serverUrl}/` : serverUrl
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${accessKey.key}`
|
||||
}
|
||||
|
||||
let attempts = 0
|
||||
while (attempts < this.maxRetries) {
|
||||
try {
|
||||
const requestUrl = `${sanitizedServerUrl}api/auth/token${queryParams}`
|
||||
core.debug(`Attempt ${attempts} to fetch short lived token at ${requestUrl}`)
|
||||
const response = await this.httpc.post(requestUrl, '', headers)
|
||||
if (response.message.statusCode === 200) {
|
||||
const text = await response.readBody()
|
||||
return new Promise<HostnameAccessKey>(resolve => resolve({hostname: accessKey.hostname, key: text}))
|
||||
}
|
||||
// This should be only 404
|
||||
attempts++
|
||||
if (attempts === this.maxRetries) {
|
||||
return new Promise((resolve, reject) =>
|
||||
reject(
|
||||
new Error(
|
||||
`Develocity short lived token request failed ${serverUrl} with status code ${response.message.statusCode}`
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
attempts++
|
||||
if (attempts === this.maxRetries) {
|
||||
return new Promise((resolve, reject) => reject(error))
|
||||
}
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, this.retryInterval))
|
||||
}
|
||||
return new Promise((resolve, reject) => reject(new Error('Illegal state')))
|
||||
}
|
||||
}
|
||||
|
||||
type HostnameAccessKey = {
|
||||
hostname: string
|
||||
key: string
|
||||
}
|
||||
|
||||
export class DevelocityAccessCredentials {
|
||||
static readonly accessKeyRegexp = /^([^;=\s]+=\w+)(;[^;=\s]+=\w+)*$/
|
||||
readonly keys: HostnameAccessKey[]
|
||||
|
||||
private constructor(allKeys: HostnameAccessKey[]) {
|
||||
this.keys = allKeys
|
||||
}
|
||||
|
||||
static of(allKeys: HostnameAccessKey[]): DevelocityAccessCredentials {
|
||||
return new DevelocityAccessCredentials(allKeys)
|
||||
}
|
||||
|
||||
private static readonly keyDelimiter = ';'
|
||||
private static readonly hostDelimiter = '='
|
||||
|
||||
static parse(rawKey: string): DevelocityAccessCredentials | null {
|
||||
if (!this.isValid(rawKey)) {
|
||||
return null
|
||||
}
|
||||
return new DevelocityAccessCredentials(
|
||||
rawKey.split(this.keyDelimiter).map(hostKey => {
|
||||
const pair = hostKey.split(this.hostDelimiter)
|
||||
return {hostname: pair[0], key: pair[1]}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
isEmpty(): boolean {
|
||||
return this.keys.length === 0
|
||||
}
|
||||
|
||||
raw(): string {
|
||||
return this.keys
|
||||
.map(k => `${k.hostname}${DevelocityAccessCredentials.hostDelimiter}${k.key}`)
|
||||
.join(DevelocityAccessCredentials.keyDelimiter)
|
||||
}
|
||||
|
||||
private static isValid(allKeys: string): boolean {
|
||||
return this.accessKeyRegexp.test(allKeys)
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,10 @@ export function handleMainActionError(error: unknown): void {
|
||||
}
|
||||
}
|
||||
} else if (error instanceof JobFailure) {
|
||||
core.setFailed(String(error)) // No stack trace for JobFailure: these are known errors
|
||||
core.setFailed(String(error))
|
||||
if (error.stack) {
|
||||
core.info(error.stack)
|
||||
}
|
||||
} else {
|
||||
core.setFailed(String(error))
|
||||
if (error instanceof Error && error.stack) {
|
||||
@@ -34,6 +37,9 @@ export function handleMainActionError(error: unknown): void {
|
||||
export function handlePostActionError(error: unknown): void {
|
||||
if (error instanceof JobFailure) {
|
||||
core.setFailed(String(error))
|
||||
if (error.stack) {
|
||||
core.info(error.stack)
|
||||
}
|
||||
} else {
|
||||
core.warning(`Unhandled error in Gradle post-action - job will continue: ${error}`)
|
||||
if (error instanceof Error && error.stack) {
|
||||
|
||||
@@ -78,7 +78,7 @@ Note that this permission is never available for a workflow triggered from a rep
|
||||
return mainWarning
|
||||
}
|
||||
|
||||
function renderSummaryTable(results: BuildResult[]): string {
|
||||
export function renderSummaryTable(results: BuildResult[]): string {
|
||||
return `${renderDeprecations()}\n${renderBuildResults(results)}`
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ function renderBuildResults(results: BuildResult[]): string {
|
||||
<th>Requested Tasks</th>
|
||||
<th>Gradle Version</th>
|
||||
<th>Build Outcome</th>
|
||||
<th>Build Scan®</th>
|
||||
<th>Build Scan®</th>
|
||||
</tr>${results.map(result => renderBuildResultRow(result)).join('')}
|
||||
</table>
|
||||
`
|
||||
@@ -134,23 +134,46 @@ function renderOutcome(result: BuildResult): string {
|
||||
return result.buildFailed ? ':x:' : ':white_check_mark:'
|
||||
}
|
||||
|
||||
function renderBuildScan(result: BuildResult): string {
|
||||
if (result.buildScanFailed) {
|
||||
return renderBuildScanBadge(
|
||||
'PUBLISH_FAILED',
|
||||
'orange',
|
||||
'https://docs.gradle.com/develocity/gradle-plugin/#troubleshooting'
|
||||
)
|
||||
}
|
||||
if (result.buildScanUri) {
|
||||
return renderBuildScanBadge('PUBLISHED', '06A0CE', result.buildScanUri)
|
||||
}
|
||||
return renderBuildScanBadge('NOT_PUBLISHED', 'lightgrey', 'https://scans.gradle.com')
|
||||
interface BadgeSpec {
|
||||
text: string
|
||||
alt: string
|
||||
color: string
|
||||
logo: boolean
|
||||
targetUrl: string
|
||||
}
|
||||
|
||||
function renderBuildScanBadge(outcomeText: string, outcomeColor: string, targetUrl: string): string {
|
||||
const badgeUrl = `https://img.shields.io/badge/Build%20Scan%C2%AE-${outcomeText}-${outcomeColor}?logo=Gradle`
|
||||
const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />`
|
||||
function renderBuildScan(result: BuildResult): string {
|
||||
if (result.buildScanFailed) {
|
||||
return renderBuildScanBadge({
|
||||
text: 'Publish failed',
|
||||
alt: 'Build Scan publish failed',
|
||||
color: 'orange',
|
||||
logo: false,
|
||||
targetUrl: 'https://docs.gradle.com/develocity/gradle-plugin/#troubleshooting'
|
||||
})
|
||||
}
|
||||
if (result.buildScanUri) {
|
||||
return renderBuildScanBadge({
|
||||
text: 'Build Scan®',
|
||||
alt: 'Build Scan published',
|
||||
color: '06A0CE',
|
||||
logo: true,
|
||||
targetUrl: result.buildScanUri
|
||||
})
|
||||
}
|
||||
return renderBuildScanBadge({
|
||||
text: 'Not published',
|
||||
alt: 'Build Scan not published',
|
||||
color: 'lightgrey',
|
||||
logo: false,
|
||||
targetUrl: 'https://scans.gradle.com'
|
||||
})
|
||||
}
|
||||
|
||||
function renderBuildScanBadge({text, alt, color, logo, targetUrl}: BadgeSpec): string {
|
||||
const encodedText = encodeURIComponent(text)
|
||||
const badgeUrl = `https://img.shields.io/badge/${encodedText}-${color}${logo ? '?logo=Gradle' : ''}`
|
||||
const badgeHtml = `<img src="${badgeUrl}" alt="${alt}" />`
|
||||
return `<a href="${targetUrl}" rel="nofollow" target="_blank">${badgeHtml}</a>`
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ if (gradleVersion < GradleVersion.version("5.2") ||
|
||||
if (getVariable('GITHUB_DEPENDENCY_GRAPH_CONTINUE_ON_FAILURE') != "true") {
|
||||
throw new GradleException("Dependency Graph is not supported for ${gradleVersion}. No dependency snapshot will be generated.")
|
||||
}
|
||||
println "::warning::Dependency Graph is not supported for ${gradleVersion}. No dependency snapshot will be generated."
|
||||
logger.warn("::warning::Dependency Graph is not supported for ${gradleVersion}. No dependency snapshot will be generated.")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ if (isTopLevelBuild) {
|
||||
def reportFile = getUniqueReportFile(getVariable('GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR'))
|
||||
|
||||
if (reportFile == null) {
|
||||
println "::warning::No dependency snapshot generated for step. Could not determine unique job correlator - specify GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR var for this step."
|
||||
logger.warn("::warning::No dependency snapshot generated for step. Could not determine unique job correlator - specify GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR var for this step.")
|
||||
return
|
||||
}
|
||||
|
||||
println "Generating dependency graph into '${reportFile}'"
|
||||
logger.lifecycle("Generating dependency graph into '${reportFile}'")
|
||||
}
|
||||
|
||||
apply from: 'gradle-actions.github-dependency-graph-gradle-plugin-apply.groovy'
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
/*
|
||||
* Initscript for injection of Develocity into Gradle builds.
|
||||
* Version: v1.0
|
||||
*/
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
|
||||
// note that there is no mechanism to share code between the initscript{} block and the main script, so some logic is duplicated
|
||||
|
||||
// conditionally apply the Develocity plugin to the classpath so it can be applied to the build further down in this script
|
||||
initscript {
|
||||
// NOTE: there is no mechanism to share code between the initscript{} block and the main script, so some logic is duplicated
|
||||
def isTopLevelBuild = !gradle.parent
|
||||
if (!isTopLevelBuild) {
|
||||
return
|
||||
}
|
||||
|
||||
def getInputParam = { String name ->
|
||||
def envVarName = name.toUpperCase().replace('.', '_').replace('-', '_')
|
||||
def ENV_VAR_PREFIX = ''
|
||||
def envVarName = ENV_VAR_PREFIX + name.toUpperCase().replace('.', '_').replace('-', '_')
|
||||
return System.getProperty(name) ?: System.getenv(envVarName)
|
||||
}
|
||||
|
||||
@@ -20,9 +24,9 @@ initscript {
|
||||
return
|
||||
}
|
||||
|
||||
// finish early if injection is disabled
|
||||
def gradleInjectionEnabled = getInputParam("develocity.injection-enabled")
|
||||
if (gradleInjectionEnabled != "true") {
|
||||
// Plugin loading is only required for Develocity injection. Abort early if not enabled.
|
||||
def develocityInjectionEnabled = Boolean.parseBoolean(getInputParam("develocity.injection-enabled"))
|
||||
if (!develocityInjectionEnabled) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -75,6 +79,37 @@ initscript {
|
||||
}
|
||||
}
|
||||
|
||||
static getInputParam(String name) {
|
||||
def ENV_VAR_PREFIX = ''
|
||||
def envVarName = ENV_VAR_PREFIX + name.toUpperCase().replace('.', '_').replace('-', '_')
|
||||
return System.getProperty(name) ?: System.getenv(envVarName)
|
||||
}
|
||||
|
||||
def isTopLevelBuild = !gradle.parent
|
||||
if (!isTopLevelBuild) {
|
||||
return
|
||||
}
|
||||
|
||||
def requestedInitScriptName = getInputParam('develocity.injection.init-script-name')
|
||||
def initScriptName = buildscript.sourceFile.name
|
||||
if (requestedInitScriptName != initScriptName) {
|
||||
logger.quiet("Ignoring init script '${initScriptName}' as requested name '${requestedInitScriptName}' does not match")
|
||||
return
|
||||
}
|
||||
|
||||
def develocityInjectionEnabled = Boolean.parseBoolean(getInputParam("develocity.injection-enabled"))
|
||||
if (develocityInjectionEnabled) {
|
||||
enableDevelocityInjection()
|
||||
}
|
||||
|
||||
// To enable build-scan capture, a `captureBuildScanLink(String)` method must be added to `BuildScanCollector`.
|
||||
def buildScanCollector = new BuildScanCollector()
|
||||
def buildScanCaptureEnabled = buildScanCollector.metaClass.respondsTo(buildScanCollector, 'captureBuildScanLink', String)
|
||||
if (buildScanCaptureEnabled) {
|
||||
enableBuildScanLinkCapture(buildScanCollector)
|
||||
}
|
||||
|
||||
void enableDevelocityInjection() {
|
||||
def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan'
|
||||
def BUILD_SCAN_PLUGIN_CLASS = 'com.gradle.scan.plugin.BuildScanPlugin'
|
||||
|
||||
@@ -88,29 +123,6 @@ def CI_AUTO_INJECTION_CUSTOM_VALUE_NAME = 'CI auto injection'
|
||||
def CCUD_PLUGIN_ID = 'com.gradle.common-custom-user-data-gradle-plugin'
|
||||
def CCUD_PLUGIN_CLASS = 'com.gradle.CommonCustomUserDataGradlePlugin'
|
||||
|
||||
def isTopLevelBuild = !gradle.parent
|
||||
if (!isTopLevelBuild) {
|
||||
return
|
||||
}
|
||||
|
||||
def getInputParam = { String name ->
|
||||
def envVarName = name.toUpperCase().replace('.', '_').replace('-', '_')
|
||||
return System.getProperty(name) ?: System.getenv(envVarName)
|
||||
}
|
||||
|
||||
def requestedInitScriptName = getInputParam('develocity.injection.init-script-name')
|
||||
def initScriptName = buildscript.sourceFile.name
|
||||
if (requestedInitScriptName != initScriptName) {
|
||||
logger.quiet("Ignoring init script '${initScriptName}' as requested name '${requestedInitScriptName}' does not match")
|
||||
return
|
||||
}
|
||||
|
||||
// finish early if injection is disabled
|
||||
def gradleInjectionEnabled = getInputParam("develocity.injection-enabled")
|
||||
if (gradleInjectionEnabled != "true") {
|
||||
return
|
||||
}
|
||||
|
||||
def develocityUrl = getInputParam('develocity.url')
|
||||
def develocityAllowUntrustedServer = Boolean.parseBoolean(getInputParam('develocity.allow-untrusted-server'))
|
||||
def develocityEnforceUrl = Boolean.parseBoolean(getInputParam('develocity.enforce-url'))
|
||||
@@ -139,7 +151,7 @@ if (ccudPluginVersion && isNotAtLeast(ccudPluginVersion, '1.7')) {
|
||||
return
|
||||
}
|
||||
|
||||
// register buildScanPublished listener and optionally apply the Develocity plugin
|
||||
// Conditionally apply and configure the Develocity plugin
|
||||
if (GradleVersion.current() < GradleVersion.version('6.0')) {
|
||||
rootProject {
|
||||
buildscript.configurations.getByName("classpath").incoming.afterResolve { ResolvableDependencies incoming ->
|
||||
@@ -308,6 +320,7 @@ if (GradleVersion.current() < GradleVersion.version('6.0')) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void applyPluginExternally(def pluginManager, String pluginClassName) {
|
||||
def externallyApplied = 'develocity.externally-applied'
|
||||
@@ -361,3 +374,41 @@ static boolean isAtLeast(String versionUnderTest, String referenceVersion) {
|
||||
static boolean isNotAtLeast(String versionUnderTest, String referenceVersion) {
|
||||
!isAtLeast(versionUnderTest, referenceVersion)
|
||||
}
|
||||
|
||||
void enableBuildScanLinkCapture(BuildScanCollector collector) {
|
||||
def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan'
|
||||
def DEVELOCITY_PLUGIN_ID = 'com.gradle.develocity'
|
||||
|
||||
// Conditionally apply and configure the Develocity plugin
|
||||
if (GradleVersion.current() < GradleVersion.version('6.0')) {
|
||||
rootProject {
|
||||
pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID) {
|
||||
// Only execute if develocity plugin isn't applied.
|
||||
if (gradle.rootProject.extensions.findByName("develocity")) return
|
||||
buildScanPublishedAction(buildScan, collector)
|
||||
}
|
||||
|
||||
pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) {
|
||||
buildScanPublishedAction(develocity.buildScan, collector)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gradle.settingsEvaluated { settings ->
|
||||
eachDevelocitySettingsExtension(settings) { ext ->
|
||||
buildScanPublishedAction(ext.buildScan, collector)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Action will only be called if a `BuildScanCollector.captureBuildScanLink` method is present.
|
||||
// Add `void captureBuildScanLink(String) {}` to the `BuildScanCollector` class to respond to buildScanPublished events
|
||||
static buildScanPublishedAction(def buildScanExtension, BuildScanCollector collector) {
|
||||
if (buildScanExtension.metaClass.respondsTo(buildScanExtension, 'buildScanPublished', Action)) {
|
||||
buildScanExtension.buildScanPublished { scan ->
|
||||
collector.captureBuildScanLink(scan.buildScanUri.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BuildScanCollector {}
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as path from 'path'
|
||||
import * as os from 'os'
|
||||
import * as caches from './caching/caches'
|
||||
import * as jobSummary from './job-summary'
|
||||
import * as buildScan from './build-scan'
|
||||
import * as buildScan from './develocity/build-scan'
|
||||
|
||||
import {loadBuildResults, markBuildResultsProcessed} from './build-results'
|
||||
import {CacheListener, generateCachingReport} from './caching/cache-reporting'
|
||||
@@ -41,7 +41,7 @@ export async function setup(cacheConfig: CacheConfig, buildScanConfig: BuildScan
|
||||
|
||||
core.saveState(CACHE_LISTENER, cacheListener.stringify())
|
||||
|
||||
buildScan.setup(buildScanConfig)
|
||||
await buildScan.setup(buildScanConfig)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
[
|
||||
{
|
||||
"version": "8.8",
|
||||
"checksum": "cb0da6751c2b753a16ac168bb354870ebb1e162e9083f116729cec9c781156b8"
|
||||
},
|
||||
{
|
||||
"version": "8.8-rc-2",
|
||||
"checksum": "cb0da6751c2b753a16ac168bb354870ebb1e162e9083f116729cec9c781156b8"
|
||||
},
|
||||
{
|
||||
"version": "8.8-rc-1",
|
||||
"checksum": "cb0da6751c2b753a16ac168bb354870ebb1e162e9083f116729cec9c781156b8"
|
||||
},
|
||||
{
|
||||
"version": "8.7",
|
||||
"checksum": "cb0da6751c2b753a16ac168bb354870ebb1e162e9083f116729cec9c781156b8"
|
||||
|
||||
@@ -20,7 +20,7 @@ dependencies {
|
||||
testImplementation ('io.ratpack:ratpack-groovy-test:1.9.0') {
|
||||
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
|
||||
}
|
||||
testImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.17.0'
|
||||
testImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.17.1'
|
||||
}
|
||||
|
||||
test {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id "com.gradle.develocity" version "3.17.2"
|
||||
id "com.gradle.develocity" version "3.17.5"
|
||||
id "com.gradle.common-custom-user-data-gradle-plugin" version "2.0.1"
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.nio.file.Files
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
||||
class BaseInitScriptTest extends Specification {
|
||||
static final String DEVELOCITY_PLUGIN_VERSION = '3.17.2'
|
||||
static final String DEVELOCITY_PLUGIN_VERSION = '3.17.5'
|
||||
static final String CCUD_PLUGIN_VERSION = '2.0.1'
|
||||
|
||||
static final TestGradleVersion GRADLE_3_X = new TestGradleVersion(GradleVersion.version('3.5.1'), 7, 9)
|
||||
|
||||
@@ -190,7 +190,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
|
||||
when:
|
||||
settingsFile.text = """
|
||||
plugins {
|
||||
id 'com.gradle.develocity' version '3.17.2' apply(false)
|
||||
id 'com.gradle.develocity' version '3.17.5' apply(false)
|
||||
}
|
||||
gradle.settingsEvaluated {
|
||||
apply plugin: 'com.gradle.develocity'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as exec from '@actions/exec'
|
||||
import * as core from '@actions/core'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import {CacheCleaner} from '../../src/caching/cache-cleaner'
|
||||
@@ -23,13 +24,13 @@ test('will cleanup unused dependency jars and build-cache entries', async () =>
|
||||
|
||||
expect(fs.existsSync(commonsMath31)).toBe(true)
|
||||
expect(fs.existsSync(commonsMath311)).toBe(true)
|
||||
expect(fs.readdirSync(buildCacheDir).length).toBe(6)
|
||||
expect(fs.readdirSync(buildCacheDir).length).toBe(4) // gc.properties, build-cache-1.lock, and 2 task entries
|
||||
|
||||
await cacheCleaner.forceCleanup()
|
||||
|
||||
expect(fs.existsSync(commonsMath31)).toBe(false)
|
||||
expect(fs.existsSync(commonsMath311)).toBe(true)
|
||||
expect(fs.readdirSync(buildCacheDir).length).toBe(5)
|
||||
expect(fs.readdirSync(buildCacheDir).length).toBe(3) // 1 task entry has been cleaned up
|
||||
})
|
||||
|
||||
test('will cleanup unused gradle versions', async () => {
|
||||
@@ -49,7 +50,7 @@ test('will cleanup unused gradle versions', async () => {
|
||||
|
||||
const gradle802 = path.resolve(gradleUserHome, "caches/8.0.2")
|
||||
const wrapper802 = path.resolve(gradleUserHome, "wrapper/dists/gradle-8.0.2-bin")
|
||||
const gradleCurrent = path.resolve(gradleUserHome, "caches/8.7")
|
||||
const gradleCurrent = path.resolve(gradleUserHome, "caches/8.8")
|
||||
|
||||
expect(fs.existsSync(gradle802)).toBe(true)
|
||||
expect(fs.existsSync(wrapper802)).toBe(true)
|
||||
|
||||
177
sources/test/jest/job-summary.test.ts
Normal file
177
sources/test/jest/job-summary.test.ts
Normal file
@@ -0,0 +1,177 @@
|
||||
import { BuildResult } from '../../src/build-results'
|
||||
import { renderSummaryTable } from '../../src/job-summary'
|
||||
import dedent from 'dedent'
|
||||
|
||||
|
||||
const successfulHelpBuild: BuildResult = {
|
||||
rootProjectName: 'root',
|
||||
rootProjectDir: '/',
|
||||
requestedTasks: 'help',
|
||||
gradleVersion: '8.0',
|
||||
gradleHomeDir: '/opt/gradle',
|
||||
buildFailed: false,
|
||||
buildScanUri: 'https://scans.gradle.com/s/abc123',
|
||||
buildScanFailed: false
|
||||
}
|
||||
|
||||
const failedHelpBuild: BuildResult = {
|
||||
...successfulHelpBuild,
|
||||
buildFailed: true
|
||||
}
|
||||
|
||||
const longArgsBuild: BuildResult = {
|
||||
...successfulHelpBuild,
|
||||
requestedTasks: 'check publishMyLongNamePluginPublicationToMavenCentral publishMyLongNamePluginPublicationToPluginPortal',
|
||||
}
|
||||
|
||||
const scanPublishDisabledBuild: BuildResult = {
|
||||
...successfulHelpBuild,
|
||||
buildScanUri: '',
|
||||
buildScanFailed: false,
|
||||
}
|
||||
|
||||
const scanPublishFailedBuild: BuildResult = {
|
||||
...successfulHelpBuild,
|
||||
buildScanUri: '',
|
||||
buildScanFailed: true,
|
||||
}
|
||||
|
||||
describe('renderSummaryTable', () => {
|
||||
describe('renders', () => {
|
||||
it('successful build', () => {
|
||||
const table = renderSummaryTable([successfulHelpBuild])
|
||||
expect(table.trim()).toBe(dedent`
|
||||
<table>
|
||||
<tr>
|
||||
<th>Gradle Root Project</th>
|
||||
<th>Requested Tasks</th>
|
||||
<th>Gradle Version</th>
|
||||
<th>Build Outcome</th>
|
||||
<th>Build Scan®</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root</td>
|
||||
<td>help</td>
|
||||
<td align='center'>8.0</td>
|
||||
<td align='center'>:white_check_mark:</td>
|
||||
<td><a href="https://scans.gradle.com/s/abc123" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
`);
|
||||
})
|
||||
it('failed build', () => {
|
||||
const table = renderSummaryTable([failedHelpBuild])
|
||||
expect(table.trim()).toBe(dedent`
|
||||
<table>
|
||||
<tr>
|
||||
<th>Gradle Root Project</th>
|
||||
<th>Requested Tasks</th>
|
||||
<th>Gradle Version</th>
|
||||
<th>Build Outcome</th>
|
||||
<th>Build Scan®</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root</td>
|
||||
<td>help</td>
|
||||
<td align='center'>8.0</td>
|
||||
<td align='center'>:x:</td>
|
||||
<td><a href="https://scans.gradle.com/s/abc123" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
`);
|
||||
})
|
||||
describe('when build scan', () => {
|
||||
it('publishing disabled', () => {
|
||||
const table = renderSummaryTable([scanPublishDisabledBuild])
|
||||
expect(table.trim()).toBe(dedent`
|
||||
<table>
|
||||
<tr>
|
||||
<th>Gradle Root Project</th>
|
||||
<th>Requested Tasks</th>
|
||||
<th>Gradle Version</th>
|
||||
<th>Build Outcome</th>
|
||||
<th>Build Scan®</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root</td>
|
||||
<td>help</td>
|
||||
<td align='center'>8.0</td>
|
||||
<td align='center'>:white_check_mark:</td>
|
||||
<td><a href="https://scans.gradle.com" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Not%20published-lightgrey" alt="Build Scan not published" /></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
`);
|
||||
})
|
||||
it('publishing failed', () => {
|
||||
const table = renderSummaryTable([scanPublishFailedBuild])
|
||||
expect(table.trim()).toBe(dedent`
|
||||
<table>
|
||||
<tr>
|
||||
<th>Gradle Root Project</th>
|
||||
<th>Requested Tasks</th>
|
||||
<th>Gradle Version</th>
|
||||
<th>Build Outcome</th>
|
||||
<th>Build Scan®</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root</td>
|
||||
<td>help</td>
|
||||
<td align='center'>8.0</td>
|
||||
<td align='center'>:white_check_mark:</td>
|
||||
<td><a href="https://docs.gradle.com/develocity/gradle-plugin/#troubleshooting" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Publish%20failed-orange" alt="Build Scan publish failed" /></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
`);
|
||||
})
|
||||
})
|
||||
it('multiple builds', () => {
|
||||
const table = renderSummaryTable([successfulHelpBuild, failedHelpBuild])
|
||||
expect(table.trim()).toBe(dedent`
|
||||
<table>
|
||||
<tr>
|
||||
<th>Gradle Root Project</th>
|
||||
<th>Requested Tasks</th>
|
||||
<th>Gradle Version</th>
|
||||
<th>Build Outcome</th>
|
||||
<th>Build Scan®</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root</td>
|
||||
<td>help</td>
|
||||
<td align='center'>8.0</td>
|
||||
<td align='center'>:white_check_mark:</td>
|
||||
<td><a href="https://scans.gradle.com/s/abc123" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root</td>
|
||||
<td>help</td>
|
||||
<td align='center'>8.0</td>
|
||||
<td align='center'>:x:</td>
|
||||
<td><a href="https://scans.gradle.com/s/abc123" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
`);
|
||||
})
|
||||
it('truncating long requested tasks', () => {
|
||||
const table = renderSummaryTable([longArgsBuild])
|
||||
expect(table.trim()).toBe(dedent`
|
||||
<table>
|
||||
<tr>
|
||||
<th>Gradle Root Project</th>
|
||||
<th>Requested Tasks</th>
|
||||
<th>Gradle Version</th>
|
||||
<th>Build Outcome</th>
|
||||
<th>Build Scan®</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root</td>
|
||||
<td><div title='check publishMyLongNamePluginPublicationToMavenCentral publishMyLongNamePluginPublicationToPluginPortal'>check publishMyLongNamePluginPublicationToMavenCentral publ…</div></td>
|
||||
<td align='center'>8.0</td>
|
||||
<td align='center'>:white_check_mark:</td>
|
||||
<td><a href="https://scans.gradle.com/s/abc123" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
`);
|
||||
})
|
||||
})
|
||||
})
|
||||
117
sources/test/jest/short-lived-token.test.ts
Normal file
117
sources/test/jest/short-lived-token.test.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import {DevelocityAccessCredentials, getToken} from "../../src/develocity/short-lived-token";
|
||||
import nock from "nock";
|
||||
|
||||
describe('short lived tokens', () => {
|
||||
it('parse valid access key should return an object', async () => {
|
||||
let develocityAccessCredentials = DevelocityAccessCredentials.parse('some-host.local=key1;host2=key2');
|
||||
|
||||
expect(develocityAccessCredentials).toStrictEqual(DevelocityAccessCredentials.of([
|
||||
{hostname: 'some-host.local', key: 'key1'},
|
||||
{hostname: 'host2', key: 'key2'}])
|
||||
)
|
||||
})
|
||||
|
||||
it('parse wrong access key should return null', async () => {
|
||||
let develocityAccessCredentials = DevelocityAccessCredentials.parse('random;foo');
|
||||
|
||||
expect(develocityAccessCredentials).toBeNull()
|
||||
})
|
||||
|
||||
it('parse empty access key should return null', async () => {
|
||||
let develocityAccessCredentials = DevelocityAccessCredentials.parse('');
|
||||
|
||||
expect(develocityAccessCredentials).toBeNull()
|
||||
})
|
||||
|
||||
it('access key as raw string', async () => {
|
||||
let develocityAccessCredentials = DevelocityAccessCredentials.parse('host1=key1;host2=key2');
|
||||
|
||||
expect(develocityAccessCredentials?.raw()).toBe('host1=key1;host2=key2')
|
||||
})
|
||||
|
||||
it('get short lived token fails when cannot connect', async () => {
|
||||
nock('http://localhost:3333')
|
||||
.post('/api/auth/token')
|
||||
.times(3)
|
||||
.replyWithError({
|
||||
message: 'connect ECONNREFUSED 127.0.0.1:3333',
|
||||
code: 'ECONNREFUSED'
|
||||
})
|
||||
await expect(getToken('localhost=key0', ''))
|
||||
.resolves
|
||||
.toBeNull()
|
||||
})
|
||||
|
||||
it('get short lived token is null when request fails', async () => {
|
||||
nock('http://dev:3333')
|
||||
.post('/api/auth/token')
|
||||
.times(3)
|
||||
.reply(500, 'Internal error')
|
||||
expect.assertions(1)
|
||||
await expect(getToken('dev=xyz', ''))
|
||||
.resolves
|
||||
.toBeNull()
|
||||
})
|
||||
|
||||
it('get short lived token returns null when access key is empty', async () => {
|
||||
expect.assertions(1)
|
||||
await expect(getToken('', ''))
|
||||
.resolves
|
||||
.toBeNull()
|
||||
})
|
||||
|
||||
it('get short lived token succeeds when single key is set', async () => {
|
||||
nock('https://dev')
|
||||
.post('/api/auth/token')
|
||||
.reply(200, 'token')
|
||||
expect.assertions(1)
|
||||
await expect(getToken('dev=key1', ''))
|
||||
.resolves
|
||||
.toEqual({"keys": [{"hostname": "dev", "key": "token"}]})
|
||||
})
|
||||
|
||||
it('get short lived token succeeds when multiple keys are set', async () => {
|
||||
nock('https://dev')
|
||||
.post('/api/auth/token')
|
||||
.reply(200, 'token1')
|
||||
nock('https://prod')
|
||||
.post('/api/auth/token')
|
||||
.reply(200, 'token2')
|
||||
expect.assertions(1)
|
||||
await expect(getToken('dev=key1;prod=key2', ''))
|
||||
.resolves
|
||||
.toEqual({"keys": [{"hostname": "dev", "key": "token1"}, {"hostname": "prod", "key": "token2"}]})
|
||||
})
|
||||
|
||||
it('get short lived token succeeds when multiple keys are set and one is failing', async () => {
|
||||
nock('https://dev')
|
||||
.post('/api/auth/token')
|
||||
.reply(200, 'token1')
|
||||
nock('https://bogus')
|
||||
.post('/api/auth/token')
|
||||
.times(3)
|
||||
.reply(500, 'Internal Error')
|
||||
nock('https://prod')
|
||||
.post('/api/auth/token')
|
||||
.reply(200, 'token2')
|
||||
expect.assertions(1)
|
||||
await expect(getToken('dev=key1;bogus=key0;prod=key2', ''))
|
||||
.resolves
|
||||
.toEqual({"keys": [{"hostname": "dev", "key": "token1"}, {"hostname": "prod", "key": "token2"}]})
|
||||
})
|
||||
|
||||
it('get short lived token is null when multiple keys are set and all are failing', async () => {
|
||||
nock('https://dev')
|
||||
.post('/api/auth/token')
|
||||
.times(3)
|
||||
.reply(500, 'Internal Error')
|
||||
nock('https://bogus')
|
||||
.post('/api/auth/token')
|
||||
.times(3)
|
||||
.reply(500, 'Internal Error')
|
||||
expect.assertions(1)
|
||||
await expect(getToken('dev=key1;bogus=key0', ''))
|
||||
.resolves
|
||||
.toBeNull()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user