mirror of
https://github.com/actions/setup-java.git
synced 2026-07-17 14:02:57 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 46f6294045 | |||
| e40a8e0642 | |||
| 6e2e32e729 | |||
| 38fa86f9e4 | |||
| ecd5f809c2 | |||
| 4a24efdcc9 | |||
| cc8cdedf67 | |||
| 4b0728bd0d | |||
| 7d485884af | |||
| c3568cc9d9 | |||
| 81c13a41f9 | |||
| 3c85b14378 | |||
| 80c368b720 |
@@ -1,102 +0,0 @@
|
||||
name: Validate cache with cache-dependency-path option
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- releases/*
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
gradle1-save:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run setup-java with the cache for gradle
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '17'
|
||||
cache: gradle
|
||||
cache-dependency-path: __tests__/cache/gradle1/*.gradle*
|
||||
- name: Create files to cache
|
||||
# Need to avoid using Gradle daemon to stabilize the save process on Windows
|
||||
# https://github.com/actions/cache/issues/454#issuecomment-840493935
|
||||
run: |
|
||||
gradle downloadDependencies --no-daemon -p __tests__/cache/gradle1
|
||||
if [ ! -d ~/.gradle/caches ]; then
|
||||
echo "::error::The ~/.gradle/caches directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
gradle1-restore:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
needs: gradle1-save
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run setup-java with the cache for gradle
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
cache: gradle
|
||||
cache-dependency-path: __tests__/cache/gradle1/*.gradle*
|
||||
- name: Confirm that ~/.gradle/caches directory has been made
|
||||
run: |
|
||||
if [ ! -d ~/.gradle/caches ]; then
|
||||
echo "::error::The ~/.gradle/caches directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
ls ~/.gradle/caches/
|
||||
gradle2-restore:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
needs: gradle1-save
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run setup-java with the cache for gradle
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
cache: gradle
|
||||
cache-dependency-path: __tests__/cache/gradle2/*.gradle*
|
||||
- name: Confirm that ~/.gradle/caches directory has not been made
|
||||
run: |
|
||||
if [ -d ~/.gradle/caches ]; then
|
||||
echo "::error::The ~/.gradle/caches directory exists unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
+255
-54
@@ -42,10 +42,7 @@ jobs:
|
||||
# https://github.com/actions/cache/issues/454#issuecomment-840493935
|
||||
run: |
|
||||
gradle downloadDependencies --no-daemon -p __tests__/cache/gradle1
|
||||
if [ ! -d ~/.gradle/caches ]; then
|
||||
echo "::error::The ~/.gradle/caches directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
bash __tests__/check-dir.sh "$HOME/.gradle/caches"
|
||||
gradle-restore:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
@@ -66,12 +63,7 @@ jobs:
|
||||
java-version: '11'
|
||||
cache: gradle
|
||||
- name: Confirm that ~/.gradle/caches directory has been made
|
||||
run: |
|
||||
if [ ! -d ~/.gradle/caches ]; then
|
||||
echo "::error::The ~/.gradle/caches directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
ls ~/.gradle/caches/
|
||||
run: bash __tests__/check-dir.sh "$HOME/.gradle/caches"
|
||||
maven-save:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
@@ -93,10 +85,7 @@ jobs:
|
||||
- name: Create files to cache
|
||||
run: |
|
||||
mvn verify -f __tests__/cache/maven/pom.xml
|
||||
if [ ! -d ~/.m2/repository ]; then
|
||||
echo "::error::The ~/.m2/repository directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
bash __tests__/check-dir.sh "$HOME/.m2/repository"
|
||||
maven-restore:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
@@ -117,12 +106,7 @@ jobs:
|
||||
java-version: '11'
|
||||
cache: maven
|
||||
- name: Confirm that ~/.m2/repository directory has been made
|
||||
run: |
|
||||
if [ ! -d ~/.m2/repository ]; then
|
||||
echo "::error::The ~/.m2/repository directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
ls ~/.m2/repository
|
||||
run: bash __tests__/check-dir.sh "$HOME/.m2/repository"
|
||||
sbt-save:
|
||||
runs-on: ${{ matrix.os }}
|
||||
defaults:
|
||||
@@ -155,25 +139,13 @@ jobs:
|
||||
|
||||
- name: Check files to cache on macos-latest
|
||||
if: matrix.os == 'macos-15-intel'
|
||||
run: |
|
||||
if [ ! -d ~/Library/Caches/Coursier ]; then
|
||||
echo "::error::The ~/Library/Caches/Coursier directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/Library/Caches/Coursier"
|
||||
- name: Check files to cache on windows-latest
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: |
|
||||
if [ ! -d ~/AppData/Local/Coursier/Cache ]; then
|
||||
echo "::error::The ~/AppData/Local/Coursier/Cache directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/AppData/Local/Coursier/Cache"
|
||||
- name: Check files to cache on ubuntu-latest
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: |
|
||||
if [ ! -d ~/.cache/coursier ]; then
|
||||
echo "::error::The ~/.cache/coursier directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/.cache/coursier"
|
||||
sbt-restore:
|
||||
runs-on: ${{ matrix.os }}
|
||||
defaults:
|
||||
@@ -200,25 +172,254 @@ jobs:
|
||||
|
||||
- name: Confirm that ~/Library/Caches/Coursier directory has been made
|
||||
if: matrix.os == 'macos-15-intel'
|
||||
run: |
|
||||
if [ ! -d ~/Library/Caches/Coursier ]; then
|
||||
echo "::error::The ~/Library/Caches/Coursier directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
ls ~/Library/Caches/Coursier
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/Library/Caches/Coursier"
|
||||
- name: Confirm that ~/AppData/Local/Coursier/Cache directory has been made
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: |
|
||||
if [ ! -d ~/AppData/Local/Coursier/Cache ]; then
|
||||
echo "::error::The ~/AppData/Local/Coursier/Cache directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
ls ~/AppData/Local/Coursier/Cache
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/AppData/Local/Coursier/Cache"
|
||||
- name: Confirm that ~/.cache/coursier directory has been made
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/.cache/coursier"
|
||||
gradle1-save:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run setup-java with the cache for gradle
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '17'
|
||||
cache: gradle
|
||||
cache-dependency-path: __tests__/cache/gradle1/*.gradle*
|
||||
- name: Create files to cache
|
||||
# Need to avoid using Gradle daemon to stabilize the save process on Windows
|
||||
# https://github.com/actions/cache/issues/454#issuecomment-840493935
|
||||
run: |
|
||||
if [ ! -d ~/.cache/coursier ]; then
|
||||
echo "::error::The ~/.cache/coursier directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
ls ~/.cache/coursier
|
||||
gradle downloadDependencies --no-daemon -p __tests__/cache/gradle1
|
||||
bash __tests__/check-dir.sh "$HOME/.gradle/caches"
|
||||
gradle1-restore:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
needs: gradle1-save
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run setup-java with the cache for gradle
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
cache: gradle
|
||||
cache-dependency-path: __tests__/cache/gradle1/*.gradle*
|
||||
- name: Confirm that ~/.gradle/caches directory has been made
|
||||
run: bash __tests__/check-dir.sh "$HOME/.gradle/caches"
|
||||
gradle2-restore:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
needs: gradle1-save
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run setup-java with the cache for gradle
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
cache: gradle
|
||||
cache-dependency-path: __tests__/cache/gradle2/*.gradle*
|
||||
- name: Confirm that ~/.gradle/caches directory has not been made
|
||||
run: bash __tests__/check-dir.sh "$HOME/.gradle/caches" absent
|
||||
maven1-save:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-15-intel, windows-latest, ubuntu-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run setup-java with the cache for maven
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
cache: maven
|
||||
cache-dependency-path: __tests__/cache/maven/pom.xml
|
||||
- name: Create files to cache
|
||||
run: |
|
||||
mvn verify -f __tests__/cache/maven/pom.xml
|
||||
bash __tests__/check-dir.sh "$HOME/.m2/repository"
|
||||
maven1-restore:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-15-intel, windows-latest, ubuntu-latest]
|
||||
needs: maven1-save
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run setup-java with the cache for maven
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
cache: maven
|
||||
cache-dependency-path: __tests__/cache/maven/pom.xml
|
||||
- name: Confirm that ~/.m2/repository directory has been made
|
||||
run: bash __tests__/check-dir.sh "$HOME/.m2/repository"
|
||||
maven2-restore:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-15-intel, windows-latest, ubuntu-latest]
|
||||
needs: maven1-save
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run setup-java with the cache for maven
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
cache: maven
|
||||
cache-dependency-path: __tests__/cache/maven2/pom.xml
|
||||
- name: Confirm that ~/.m2/repository directory has not been made
|
||||
run: bash __tests__/check-dir.sh "$HOME/.m2/repository" absent
|
||||
sbt1-save:
|
||||
runs-on: ${{ matrix.os }}
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
working-directory: __tests__/cache/sbt
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-15-intel, windows-latest, ubuntu-22.04]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run setup-java with the cache for sbt
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
cache: sbt
|
||||
cache-dependency-path: __tests__/cache/sbt/*.sbt
|
||||
- name: Setup SBT
|
||||
if: matrix.os == 'macos-15-intel'
|
||||
run: |
|
||||
echo ""Installing SBT...""
|
||||
brew install sbt
|
||||
- name: Create files to cache
|
||||
run: sbt update
|
||||
|
||||
- name: Check files to cache on macos-latest
|
||||
if: matrix.os == 'macos-15-intel'
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/Library/Caches/Coursier"
|
||||
- name: Check files to cache on windows-latest
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/AppData/Local/Coursier/Cache"
|
||||
- name: Check files to cache on ubuntu-latest
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/.cache/coursier"
|
||||
sbt1-restore:
|
||||
runs-on: ${{ matrix.os }}
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
working-directory: __tests__/cache/sbt
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-15-intel, windows-latest, ubuntu-22.04]
|
||||
needs: sbt1-save
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run setup-java with the cache for sbt
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
cache: sbt
|
||||
cache-dependency-path: __tests__/cache/sbt/*.sbt
|
||||
|
||||
- name: Confirm that ~/Library/Caches/Coursier directory has been made
|
||||
if: matrix.os == 'macos-15-intel'
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/Library/Caches/Coursier"
|
||||
- name: Confirm that ~/AppData/Local/Coursier/Cache directory has been made
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/AppData/Local/Coursier/Cache"
|
||||
- name: Confirm that ~/.cache/coursier directory has been made
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/.cache/coursier"
|
||||
sbt2-restore:
|
||||
runs-on: ${{ matrix.os }}
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
working-directory: __tests__/cache/sbt2
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-15-intel, windows-latest, ubuntu-22.04]
|
||||
needs: sbt1-save
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run setup-java with the cache for sbt
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
cache: sbt
|
||||
cache-dependency-path: __tests__/cache/sbt2/*.sbt
|
||||
|
||||
- name: Confirm that ~/Library/Caches/Coursier directory has not been made
|
||||
if: matrix.os == 'macos-15-intel'
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/Library/Caches/Coursier" absent
|
||||
- name: Confirm that ~/AppData/Local/Coursier/Cache directory has not been made
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/AppData/Local/Coursier/Cache" absent
|
||||
- name: Confirm that ~/.cache/coursier directory has not been made
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: bash "$GITHUB_WORKSPACE/__tests__/check-dir.sh" "$HOME/.cache/coursier" absent
|
||||
|
||||
@@ -46,13 +46,25 @@ jobs:
|
||||
$xmlPath = Join-Path $HOME ".m2" "settings.xml"
|
||||
Get-Content $xmlPath | ForEach-Object { Write-Host $_ }
|
||||
|
||||
[xml]$xml = Get-Content $xmlPath
|
||||
$servers = $xml.settings.servers.server
|
||||
if (($servers[0].id -ne 'maven') -or ($servers[0].username -ne '${env.MAVEN_USERNAME}') -or ($servers[0].password -ne '${env.MAVEN_CENTRAL_TOKEN}')) {
|
||||
throw "Generated XML file is incorrect"
|
||||
}
|
||||
$content = [System.IO.File]::ReadAllText($xmlPath)
|
||||
$expected = @(
|
||||
'<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"'
|
||||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
|
||||
' xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">'
|
||||
' <interactiveMode>false</interactiveMode>'
|
||||
' <servers>'
|
||||
' <server>'
|
||||
' <id>maven</id>'
|
||||
' <username>${env.MAVEN_USERNAME}</username>'
|
||||
' <password>${env.MAVEN_CENTRAL_TOKEN}</password>'
|
||||
' </server>'
|
||||
' </servers>'
|
||||
'</settings>'
|
||||
) -join "`n"
|
||||
|
||||
if (($servers[1].id -ne 'gpg.passphrase') -or ($servers[1].passphrase -ne '${env.MAVEN_GPG_PASSPHRASE}')) {
|
||||
if ($content -ne $expected) {
|
||||
Write-Host "Expected settings.xml:"
|
||||
$expected -split "`n" | ForEach-Object { Write-Host $_ }
|
||||
throw "Generated XML file is incorrect"
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,8 @@ jobs:
|
||||
os: ubuntu-latest
|
||||
version: '24-ea'
|
||||
steps:
|
||||
- name: Checkout
|
||||
- &checkout_step
|
||||
name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
@@ -127,10 +128,7 @@ jobs:
|
||||
distribution: ['temurin', 'sapmachine']
|
||||
version: ['21', '17']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- *checkout_step
|
||||
- name: Install bash
|
||||
run: apk add --no-cache bash
|
||||
- name: setup-java
|
||||
@@ -153,7 +151,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
os: &default_os [macos-latest, windows-latest, ubuntu-latest]
|
||||
distribution: ['temurin', 'zulu', 'liberica']
|
||||
version:
|
||||
- '11.0'
|
||||
@@ -182,10 +180,7 @@ jobs:
|
||||
os: ubuntu-latest
|
||||
version: '17.0.7'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- *checkout_step
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
@@ -207,7 +202,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
os: *default_os
|
||||
distribution:
|
||||
[
|
||||
'temurin',
|
||||
@@ -221,10 +216,7 @@ jobs:
|
||||
- distribution: dragonwell
|
||||
os: macos-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- *checkout_step
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
@@ -247,7 +239,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
os: *default_os
|
||||
distribution:
|
||||
[
|
||||
'temurin',
|
||||
@@ -261,10 +253,7 @@ jobs:
|
||||
- distribution: dragonwell
|
||||
os: macos-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- *checkout_step
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
@@ -294,26 +283,37 @@ jobs:
|
||||
run: bash __tests__/verify-java.sh "17" "$JAVA_PATH"
|
||||
shell: bash
|
||||
|
||||
setup-java-ea-versions-zulu:
|
||||
name: zulu ${{ matrix.version }} (jdk-${{ contains(matrix.os, 'macos') && !contains(matrix.os, 'intel') && 'arm64' || 'x64' }}) - ${{ matrix.os }}
|
||||
setup-java-ea-versions:
|
||||
name: ${{ matrix.distribution }} ${{ matrix.version }} (jdk-${{ contains(matrix.os, 'macos') && !contains(matrix.os, 'intel') && 'arm64' || 'x64' }}) - ${{ matrix.os }}
|
||||
needs: setup-java-major-minor-versions
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-15-intel, windows-latest, ubuntu-latest]
|
||||
version: ['17-ea', '15.0.0-ea.14']
|
||||
include:
|
||||
- {os: macos-15-intel, version: '17-ea', distribution: zulu}
|
||||
- {os: windows-latest, version: '17-ea', distribution: zulu}
|
||||
- {os: ubuntu-latest, version: '17-ea', distribution: zulu}
|
||||
- {os: macos-15-intel, version: '15.0.0-ea.14', distribution: zulu}
|
||||
- {os: windows-latest, version: '15.0.0-ea.14', distribution: zulu}
|
||||
- {os: ubuntu-latest, version: '15.0.0-ea.14', distribution: zulu}
|
||||
- {os: macos-latest, version: '17-ea', distribution: temurin}
|
||||
- {os: windows-latest, version: '17-ea', distribution: temurin}
|
||||
- {os: ubuntu-latest, version: '17-ea', distribution: temurin}
|
||||
- {os: macos-latest, version: '17-ea', distribution: sapmachine}
|
||||
- {os: windows-latest, version: '17-ea', distribution: sapmachine}
|
||||
- {os: ubuntu-latest, version: '17-ea', distribution: sapmachine}
|
||||
- {os: macos-latest, version: '21-ea', distribution: sapmachine}
|
||||
- {os: windows-latest, version: '21-ea', distribution: sapmachine}
|
||||
- {os: ubuntu-latest, version: '21-ea', distribution: sapmachine}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- *checkout_step
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
java-version: ${{ matrix.version }}
|
||||
distribution: zulu
|
||||
distribution: ${{ matrix.distribution }}
|
||||
- name: Verify Java
|
||||
env:
|
||||
JAVA_VERSION: ${{ matrix.version }}
|
||||
@@ -321,53 +321,24 @@ jobs:
|
||||
run: bash __tests__/verify-java.sh "$JAVA_VERSION" "$JAVA_PATH"
|
||||
shell: bash
|
||||
|
||||
setup-java-ea-versions-temurin:
|
||||
name: temurin ${{ matrix.version }} (jdk-${{ contains(matrix.os, 'macos') && !contains(matrix.os, 'intel') && 'arm64' || 'x64' }}) - ${{ matrix.os }}
|
||||
setup-java-signature-verification:
|
||||
name: ${{ matrix.distribution }} ${{ matrix.version }} signature verification - ${{ matrix.os }}
|
||||
needs: setup-java-major-minor-versions
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
version: ['17-ea']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
java-version: ${{ matrix.version }}
|
||||
distribution: temurin
|
||||
- name: Verify Java
|
||||
env:
|
||||
JAVA_VERSION: ${{ matrix.version }}
|
||||
JAVA_PATH: ${{ steps.setup-java.outputs.path }}
|
||||
run: bash __tests__/verify-java.sh "$JAVA_VERSION" "$JAVA_PATH"
|
||||
shell: bash
|
||||
|
||||
setup-java-temurin-signature-verification:
|
||||
name: temurin ${{ matrix.version }} signature verification - ${{ matrix.os }}
|
||||
needs: setup-java-major-minor-versions
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
os: *default_os
|
||||
version: ['21', '17']
|
||||
distribution: [temurin, microsoft]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- *checkout_step
|
||||
- name: setup-java with signature verification
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
java-version: ${{ matrix.version }}
|
||||
distribution: temurin
|
||||
distribution: ${{ matrix.distribution }}
|
||||
verify-signature: true
|
||||
- name: Verify Java
|
||||
env:
|
||||
@@ -376,61 +347,6 @@ jobs:
|
||||
run: bash __tests__/verify-java.sh "$JAVA_VERSION" "$JAVA_PATH"
|
||||
shell: bash
|
||||
|
||||
setup-java-microsoft-signature-verification:
|
||||
name: microsoft ${{ matrix.version }} signature verification - ${{ matrix.os }}
|
||||
needs: setup-java-major-minor-versions
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
version: ['21', '17']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: setup-java with signature verification
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
java-version: ${{ matrix.version }}
|
||||
distribution: microsoft
|
||||
verify-signature: true
|
||||
- name: Verify Java
|
||||
env:
|
||||
JAVA_VERSION: ${{ matrix.version }}
|
||||
JAVA_PATH: ${{ steps.setup-java.outputs.path }}
|
||||
run: bash __tests__/verify-java.sh "$JAVA_VERSION" "$JAVA_PATH"
|
||||
shell: bash
|
||||
|
||||
setup-java-ea-versions-sapmachine:
|
||||
name: sapmachine ${{ matrix.version }} (jdk-${{ contains(matrix.os, 'macos') && !contains(matrix.os, 'intel') && 'arm64' || 'x64' }}) - ${{ matrix.os }}
|
||||
needs: setup-java-major-minor-versions
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
version: ['17-ea', '21-ea']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
java-version: ${{ matrix.version }}
|
||||
distribution: sapmachine
|
||||
- name: Verify Java
|
||||
env:
|
||||
JAVA_VERSION: ${{ matrix.version }}
|
||||
JAVA_PATH: ${{ steps.setup-java.outputs.path }}
|
||||
run: bash __tests__/verify-java.sh "$JAVA_VERSION" "$JAVA_PATH"
|
||||
shell: bash
|
||||
|
||||
setup-java-custom-package-type:
|
||||
name: ${{ matrix.distribution }} ${{ matrix.version }} (${{ matrix.java-package }}-x64) - ${{ matrix.os }}
|
||||
needs: setup-java-major-minor-versions
|
||||
@@ -510,10 +426,7 @@ jobs:
|
||||
os: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- *checkout_step
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
@@ -543,10 +456,7 @@ jobs:
|
||||
distribution: ['liberica', 'zulu', 'corretto']
|
||||
version: ['11']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- *checkout_step
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
@@ -567,14 +477,11 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
os: *default_os
|
||||
distribution: ['temurin', 'microsoft', 'corretto']
|
||||
java-version-file: ['.java-version', '.tool-versions']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- *checkout_step
|
||||
- name: Create .java-version file
|
||||
shell: bash
|
||||
run: echo "17" > .java-version
|
||||
@@ -600,14 +507,11 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
os: *default_os
|
||||
distribution: ['temurin', 'zulu', 'liberica', 'microsoft', 'corretto']
|
||||
java-version-file: ['.java-version', '.tool-versions']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- *checkout_step
|
||||
- name: Create .java-version file
|
||||
shell: bash
|
||||
run: echo "11" > .java-version
|
||||
@@ -632,14 +536,11 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
os: *default_os
|
||||
distribution: ['adopt', 'adopt-openj9', 'zulu']
|
||||
java-version-file: ['.java-version', '.tool-versions']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- *checkout_step
|
||||
- name: Create .java-version file
|
||||
shell: bash
|
||||
run: echo "17.0.10" > .java-version
|
||||
@@ -664,14 +565,11 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
os: *default_os
|
||||
distribution: ['adopt', 'zulu', 'liberica']
|
||||
java-version-file: ['.java-version', '.tool-versions', '.sdkmanrc']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- *checkout_step
|
||||
- name: Create .java-version file
|
||||
shell: bash
|
||||
run: echo "openjdk64-17.0.10" > .java-version
|
||||
@@ -700,10 +598,9 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
os: *default_os
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
- *checkout_step
|
||||
- name: Setup Java 17 as default
|
||||
uses: ./
|
||||
id: setup-java-17
|
||||
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@actions/cache"
|
||||
version: 6.1.0
|
||||
version: 6.2.0
|
||||
type: npm
|
||||
summary: Actions cache lib
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/cache
|
||||
|
||||
@@ -20,8 +20,17 @@ This action allows you to work with Java and Scala projects.
|
||||
|
||||
## What's new in V6
|
||||
|
||||
> [!NOTE]
|
||||
> V6 is still in development (`main` branch) and is not yet recommended for production workflows.
|
||||
|
||||
- **Migrated to ESM** to enable support for the latest `@actions/*` package versions. This is an internal implementation change only. No changes are required to your workflow configuration, and the action's behavior is unchanged. Existing workflows continue to work as before.
|
||||
|
||||
## Breaking changes in V6
|
||||
|
||||
- **The GPG passphrase is now passed to the Maven GPG Plugin through an environment variable (`gpg.passphraseEnvName`) instead of the deprecated `gpg.passphrase` server in `settings.xml`.** The `gpg-passphrase` input and its default (`GPG_PASSPHRASE`) are unchanged, so if you already set that environment variable in your build step your workflow keeps working. However, this now requires `maven-gpg-plugin` **3.2.0 or newer**; older versions do not honor `gpg.passphraseEnvName` and, because the `gpg.passphrase` server is no longer written, will not pick up the passphrase. Upgrade the plugin to 3.2.0+.
|
||||
|
||||
See [GPG](docs/advanced-usage.md#gpg) for details.
|
||||
|
||||
## Breaking changes in V5
|
||||
|
||||
- Upgraded action from node20 to node24
|
||||
@@ -31,73 +40,79 @@ For more details, see the full release notes on the [releases page](https://git
|
||||
|
||||
## Usage
|
||||
|
||||
- `java-version`: The Java version that is going to be set up. Takes a whole or [semver](#supported-version-syntax) Java version. If not specified, the action will expect `java-version-file` input to be specified.
|
||||
- `java-version`: The Java version that is going to be set up. Takes a whole or [semver](#supported-version-syntax) Java version. If not specified, the action will expect `java-version-file` input to be specified.
|
||||
|
||||
- `java-version-file`: The path to a file containing java version. Supported file types are `.java-version`, `.tool-versions`, and `.sdkmanrc`. See more details in [about .java-version-file](docs/advanced-usage.md#Java-version-file).
|
||||
- `java-version-file`: The path to a file containing java version. Supported file types are `.java-version`, `.tool-versions`, and `.sdkmanrc`. See more details in [about .java-version-file](docs/advanced-usage.md#Java-version-file).
|
||||
|
||||
- `distribution`: Java [distribution](#supported-distributions). Required unless `java-version-file` points to `.sdkmanrc` with a recognized distribution suffix (for example `java=21.0.5-tem`).
|
||||
- `distribution`: Java [distribution](#supported-distributions). Required unless `java-version-file` points to `.sdkmanrc` with a recognized distribution suffix (for example `java=21.0.5-tem`).
|
||||
|
||||
- `java-package`: The packaging variant of the chosen distribution. Possible values: `jdk`, `jre`, `jdk+fx`, `jre+fx`. For Azul Zulu, `jdk+crac` and `jre+crac` are also supported. Default value: `jdk`.
|
||||
- `java-package`: The packaging variant of the chosen distribution. Possible values: `jdk`, `jre`, `jdk+fx`, `jre+fx`. For Azul Zulu, `jdk+crac` and `jre+crac` are also supported. Default value: `jdk`.
|
||||
|
||||
- `architecture`: The target architecture of the package. Possible values: `x86`, `x64`, `armv7`, `aarch64`, `ppc64le`. Default value: Derived from the runner machine.
|
||||
- `architecture`: The target architecture of the package. Possible values: `x86`, `x64`, `armv7`, `aarch64`, `ppc64le`. Default value: Derived from the runner machine.
|
||||
|
||||
- `jdk-file`: If a use-case requires a custom distribution setup-java uses the compressed JDK from the location pointed by this input and will take care of the installation and caching on the VM. Note: `distribution` must be set to 'jdkfile' (case-sensitive; all lowercase) when using this option. (The camelCase `jdkFile` input is still accepted as a deprecated alias and may be removed in a future release.)
|
||||
- `jdk-file`: If a use-case requires a custom distribution setup-java uses the compressed JDK from the location pointed by this input and will take care of the installation and caching on the VM. Note: `distribution` must be set to 'jdkfile' (case-sensitive; all lowercase) when using this option. (The camelCase `jdkFile` input is still accepted as a deprecated alias and may be removed in a future release.)
|
||||
|
||||
- `check-latest`: Setting this option makes the action to check for the latest available version for the version spec.
|
||||
- `check-latest`: Setting this option makes the action to check for the latest available version for the version spec.
|
||||
|
||||
- `set-default`: Set to `false` to install a JDK without making it the default. When `false`, `JAVA_HOME` and `PATH` are not updated, but `JAVA_HOME_<major>_<arch>` is still set so the JDK remains discoverable. Default value: `true`. See [Installing JDK without setting as default](docs/advanced-usage.md#Installing-JDK-without-setting-as-default) for more details.
|
||||
- `set-default`: Set to `false` to install a JDK without making it the default. When `false`, `JAVA_HOME` and `PATH` are not updated, but `JAVA_HOME_<major>_<arch>` is still set so the JDK remains discoverable. Default value: `true`. See [Installing JDK without setting as default](docs/advanced-usage.md#Installing-JDK-without-setting-as-default) for more details.
|
||||
|
||||
- `verify-signature`: Verifies downloaded Java package signatures when supported by the selected distribution. Currently supported for `temurin` and `microsoft`. If set to `true` for unsupported distributions, the action fails.
|
||||
- `problem-matcher`: Set to `false` to disable Java problem matcher annotations (compiler diagnostics and uncaught exceptions). Default value: `true`. See [Java problem matcher](docs/advanced-usage.md#java-problem-matcher-compiler-annotations) for details and annotation limits.
|
||||
|
||||
- `verify-signature-public-key`: ASCII-armored GPG public key used to verify the downloaded package signature. Overrides the default bundled key for the selected distribution.
|
||||
- `verify-signature`: Verifies downloaded Java package signatures when supported by the selected distribution. Currently supported for `temurin` and `microsoft`. If set to `true` for unsupported distributions, the action fails.
|
||||
|
||||
- `cache`: Quick [setup caching](#caching-packages-dependencies) for the dependencies managed through one of the predefined package managers. It can be one of "maven", "gradle" or "sbt".
|
||||
- `verify-signature-public-key`: ASCII-armored GPG public key used to verify the downloaded package signature. Overrides the default bundled key for the selected distribution.
|
||||
|
||||
- `cache-dependency-path`: The path to a dependency file: pom.xml, build.gradle, build.sbt, etc. This option can be used with the `cache` option. If this option is omitted, the action searches for the dependency file in the entire repository. This option supports wildcards and a list of file names for caching multiple dependencies.
|
||||
- `token`: The token used to authenticate when fetching version manifests hosted on GitHub.com. Defaults to `${{ github.token }}` when running on GitHub.com; defaults to an empty string on GitHub Enterprise Server. On GHES, provide a GitHub.com personal access token if manifest requests are rate-limited. See [Using Microsoft distribution on GHES](docs/advanced-usage.md#using-microsoft-distribution-on-ghes) for more details.
|
||||
|
||||
- `cache`: Quick [setup caching](#caching-packages-dependencies) for the dependencies managed through one of the predefined package managers. It can be one of "maven", "gradle" or "sbt".
|
||||
|
||||
- `cache-dependency-path`: The path to a dependency file: pom.xml, build.gradle, build.sbt, etc. This option can be used with the `cache` option. If this option is omitted, the action searches for the dependency file in the entire repository. This option supports wildcards and a list of file names for caching multiple dependencies.
|
||||
|
||||
#### Maven options
|
||||
The action has a bunch of inputs to generate maven's [settings.xml](https://maven.apache.org/settings.html) on the fly and pass the values to Apache Maven GPG Plugin as well as Apache Maven Toolchains. See [advanced usage](docs/advanced-usage.md) for more.
|
||||
|
||||
- `overwrite-settings`: By default action overwrites the settings.xml. In order to skip generation of file if it exists, set this to `false`.
|
||||
- `overwrite-settings`: By default action overwrites the settings.xml. In order to skip generation of file if it exists, set this to `false`.
|
||||
|
||||
- `server-id`: ID of the distributionManagement repository in the pom.xml file. Default is `github`.
|
||||
- `server-id`: ID of the distributionManagement repository in the pom.xml file. Default is `github`.
|
||||
|
||||
- `server-username`: Environment variable name for the username for authentication to the Apache Maven repository. Default is GITHUB_ACTOR.
|
||||
- `server-username`: Environment variable name for the username for authentication to the Apache Maven repository. Default is GITHUB\_ACTOR.
|
||||
|
||||
- `server-password`: Environment variable name for password or token for authentication to the Apache Maven repository. Default is GITHUB_TOKEN.
|
||||
- `server-password`: Environment variable name for password or token for authentication to the Apache Maven repository. Default is GITHUB\_TOKEN.
|
||||
|
||||
- `settings-path`: Maven related setting to point to the directory where the settings.xml file will be written. Default is ~/.m2.
|
||||
- `settings-path`: Maven related setting to point to the directory where the settings.xml file will be written. Default is \~/.m2.
|
||||
|
||||
- `gpg-private-key`: GPG private key to import. Default is empty string.
|
||||
- `gpg-private-key`: GPG private key to import. Default is empty string.
|
||||
|
||||
- `gpg-passphrase`: Environment variable name for the GPG private key passphrase. Default is GPG_PASSPHRASE.
|
||||
- `gpg-passphrase`: Environment variable name for the GPG private key passphrase. Default is GPG\_PASSPHRASE.
|
||||
|
||||
- `mvn-toolchain-id`: Name of Maven Toolchain ID if the default name of `${distribution}_${java-version}` is not wanted.
|
||||
- `mvn-toolchain-id`: Name of Maven Toolchain ID if the default name of `${distribution}_${java-version}` is not wanted.
|
||||
|
||||
- `mvn-toolchain-vendor`: Name of Maven Toolchain Vendor if the default name of `${distribution}` is not wanted.
|
||||
- `mvn-toolchain-vendor`: Name of Maven Toolchain Vendor if the default name of `${distribution}` is not wanted.
|
||||
|
||||
- `show-download-progress`: Set to `true` to keep Maven artifact download and transfer progress in build logs. Default value: `false`. By default, the action adds `-ntp` (`--no-transfer-progress`) to `MAVEN_ARGS`. This input has no effect on non-Maven builds. See [Maven transfer progress](docs/advanced-usage.md#maven-transfer-progress-download-logs) for more details.
|
||||
|
||||
### Basic Configuration
|
||||
|
||||
#### Eclipse Temurin
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin' # See 'Supported distributions' for available options
|
||||
java-version: '25'
|
||||
- run: java --version
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/setup-java@v6
|
||||
with:
|
||||
distribution: 'temurin' # See 'Supported distributions' for available options
|
||||
java-version: '25'
|
||||
- run: java --version
|
||||
```
|
||||
|
||||
#### Azul Zulu OpenJDK
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'zulu' # See 'Supported distributions' for available options
|
||||
java-version: '25'
|
||||
- run: java --version
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/setup-java@v6
|
||||
with:
|
||||
distribution: 'zulu' # See 'Supported distributions' for available options
|
||||
java-version: '25'
|
||||
- run: java --version
|
||||
```
|
||||
|
||||
#### Supported version syntax
|
||||
@@ -163,24 +178,26 @@ The workflow output `cache-primary-key` exposes the primary cache key computed b
|
||||
|
||||
The cache input is optional, and caching is turned off by default.
|
||||
|
||||
**Maven Wrapper:** when `cache: 'maven'` is enabled, the action also caches and restores the Maven Wrapper distribution downloaded to `~/.m2/wrapper/dists` (in addition to the local repository), so wrapper-based (`./mvnw`) builds don't re-download the wrapper on every run. This is keyed on `**/.mvn/wrapper/maven-wrapper.properties` as shown above.
|
||||
**Maven Wrapper:** when `cache: 'maven'` is enabled, the action also caches and restores the Maven Wrapper distribution downloaded to `~/.m2/wrapper/dists` (in addition to the local repository), so wrapper-based (`./mvnw`) builds don't re-download the Maven distribution. The wrapper distribution is stored in a **separate** cache entry keyed only on `**/.mvn/wrapper/maven-wrapper.properties`, so it stays cached across the frequent `pom.xml` changes that rotate the main dependency cache key.
|
||||
|
||||
#### Caching gradle dependencies
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'gradle'
|
||||
cache-dependency-path: | # optional
|
||||
sub-project/*.gradle*
|
||||
sub-project/**/gradle-wrapper.properties
|
||||
- run: ./gradlew build --no-daemon
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/setup-java@v6
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'gradle'
|
||||
cache-dependency-path: | # optional
|
||||
sub-project/*.gradle*
|
||||
sub-project/**/gradle-wrapper.properties
|
||||
- run: ./gradlew build --no-daemon
|
||||
```
|
||||
Using the `cache: gradle` provides a simple and effective way to cache Gradle dependencies with minimal configuration.
|
||||
|
||||
**Gradle Wrapper:** when `cache: 'gradle'` is enabled, the action also caches and restores the Gradle Wrapper distribution downloaded to `~/.gradle/wrapper` (in addition to the Gradle caches), so wrapper-based (`./gradlew`) builds don't re-download the Gradle distribution. The wrapper distribution is stored in a **separate** cache entry keyed only on `**/gradle-wrapper.properties`, so it stays cached across the frequent `*.gradle*` changes that rotate the main dependency cache key.
|
||||
|
||||
For projects that require more advanced `Gradle` caching features, such as caching build outputs, support for Gradle configuration cache, encrypted cache storage, fine-grained cache control (including options to enable or disable the cache, set it to read-only or write-only, perform automated cleanup, and define custom cache rules), or optimized performance for complex CI workflows, consider using [`gradle/actions/setup-gradle`](https://github.com/gradle/actions/tree/main/setup-gradle).
|
||||
|
||||
For setup details and a comprehensive overview of all available features, visit the [setup-gradle documentation](https://github.com/gradle/actions/blob/main/docs/setup-gradle.md).
|
||||
@@ -188,15 +205,15 @@ For setup details and a comprehensive overview of all available features, visit
|
||||
#### Caching maven dependencies
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'maven'
|
||||
cache-dependency-path: 'sub-project/pom.xml' # optional
|
||||
- name: Build with Maven
|
||||
run: mvn -B package --file pom.xml
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/setup-java@v6
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'maven'
|
||||
cache-dependency-path: 'sub-project/pom.xml' # optional
|
||||
- name: Build with Maven
|
||||
run: mvn package --file pom.xml
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
@@ -209,17 +226,17 @@ steps:
|
||||
#### Caching sbt dependencies
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'sbt'
|
||||
cache-dependency-path: | # optional
|
||||
sub-project/build.sbt
|
||||
sub-project/project/build.properties
|
||||
- name: Build with SBT
|
||||
run: sbt package
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/setup-java@v6
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'sbt'
|
||||
cache-dependency-path: | # optional
|
||||
sub-project/build.sbt
|
||||
sub-project/project/build.properties
|
||||
- name: Build with SBT
|
||||
run: sbt package
|
||||
```
|
||||
|
||||
#### Cache segment restore timeout
|
||||
@@ -229,13 +246,13 @@ Usually, cache gets downloaded in multiple segments of fixed sizes. Sometimes, a
|
||||
env:
|
||||
SEGMENT_DOWNLOAD_TIMEOUT_MINS: '5'
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'gradle'
|
||||
- run: ./gradlew build --no-daemon
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/setup-java@v6
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'gradle'
|
||||
- run: ./gradlew build --no-daemon
|
||||
```
|
||||
|
||||
### Check latest
|
||||
@@ -249,13 +266,13 @@ For Java distributions that are not cached on Hosted images, `check-latest` alwa
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
check-latest: true
|
||||
- run: java --version
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/setup-java@v6
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
check-latest: true
|
||||
- run: java --version
|
||||
```
|
||||
|
||||
### Testing against different Java versions
|
||||
@@ -268,9 +285,9 @@ jobs:
|
||||
java: [ '8', '11', '17', '21', '25' ]
|
||||
name: Java ${{ matrix.Java }} sample
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
- name: Setup java
|
||||
uses: actions/setup-java@v5
|
||||
uses: actions/setup-java@v6
|
||||
with:
|
||||
distribution: '<distribution>'
|
||||
java-version: ${{ matrix.java }}
|
||||
@@ -279,11 +296,11 @@ jobs:
|
||||
|
||||
### Install multiple JDKs
|
||||
|
||||
All configured Java versions are added to the PATH. The last one added to the PATH (i.e., the last JDK set up by this action) will be used as the default and available globally. Other Java versions can be accessed through environment variables such as 'JAVA_HOME_{{ MAJOR_VERSION }}_{{ ARCHITECTURE }}'. To use a specific Java version, set the JAVA_HOME environment variable accordingly and prepend its bin directory to the PATH to ensure it takes priority during execution.
|
||||
All configured Java versions are added to the PATH. The last one added to the PATH (i.e., the last JDK set up by this action) will be used as the default and available globally. Other Java versions can be accessed through environment variables such as 'JAVA\_HOME\_{{ MAJOR\_VERSION }}\_{{ ARCHITECTURE }}'. To use a specific Java version, set the JAVA\_HOME environment variable accordingly and prepend its bin directory to the PATH to ensure it takes priority during execution.
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/setup-java@v5
|
||||
steps:
|
||||
- uses: actions/setup-java@v6
|
||||
with:
|
||||
distribution: '<distribution>'
|
||||
java-version: |
|
||||
@@ -298,39 +315,31 @@ In the example above multiple JDKs are installed for the same job. The result af
|
||||
### Advanced Configuration
|
||||
|
||||
- [Selecting a Java distribution](docs/advanced-usage.md#Selecting-a-Java-distribution)
|
||||
- [Eclipse Temurin](docs/advanced-usage.md#Eclipse-Temurin)
|
||||
- [Adopt](docs/advanced-usage.md#Adopt)
|
||||
- [Zulu](docs/advanced-usage.md#Zulu)
|
||||
- [Liberica](docs/advanced-usage.md#Liberica)
|
||||
- [Liberica Native Image Kit](docs/advanced-usage.md#Liberica-Native-Image-Kit)
|
||||
- [Microsoft](docs/advanced-usage.md#Microsoft)
|
||||
- [Amazon Corretto](docs/advanced-usage.md#Amazon-Corretto)
|
||||
- [Oracle](docs/advanced-usage.md#Oracle)
|
||||
- [Alibaba Dragonwell](docs/advanced-usage.md#Alibaba-Dragonwell)
|
||||
- [SapMachine](docs/advanced-usage.md#SapMachine)
|
||||
- [GraalVM](docs/advanced-usage.md#GraalVM)
|
||||
- [JetBrains](docs/advanced-usage.md#JetBrains)
|
||||
- [Tencent Kona](docs/advanced-usage.md#Tencent-Kona)
|
||||
- [Eclipse Temurin](docs/advanced-usage.md#Eclipse-Temurin)
|
||||
- [Adopt](docs/advanced-usage.md#Adopt)
|
||||
- [Zulu](docs/advanced-usage.md#Zulu)
|
||||
- [Liberica](docs/advanced-usage.md#Liberica)
|
||||
- [Liberica Native Image Kit](docs/advanced-usage.md#Liberica-Native-Image-Kit)
|
||||
- [Microsoft](docs/advanced-usage.md#Microsoft)
|
||||
- [Amazon Corretto](docs/advanced-usage.md#Amazon-Corretto)
|
||||
- [Oracle](docs/advanced-usage.md#Oracle)
|
||||
- [Alibaba Dragonwell](docs/advanced-usage.md#Alibaba-Dragonwell)
|
||||
- [SapMachine](docs/advanced-usage.md#SapMachine)
|
||||
- [GraalVM](docs/advanced-usage.md#GraalVM)
|
||||
- [JetBrains](docs/advanced-usage.md#JetBrains)
|
||||
- [Tencent Kona](docs/advanced-usage.md#Tencent-Kona)
|
||||
- [Installing custom Java package type](docs/advanced-usage.md#Installing-custom-Java-package-type)
|
||||
- [Installing custom Java architecture](docs/advanced-usage.md#Installing-custom-Java-architecture)
|
||||
- [Installing custom Java distribution from local file](docs/advanced-usage.md#Installing-Java-from-local-file)
|
||||
- [Testing against different Java distributions](docs/advanced-usage.md#Testing-against-different-Java-distributions)
|
||||
- [Testing against different platforms](docs/advanced-usage.md#Testing-against-different-platforms)
|
||||
- [Publishing using Apache Maven](docs/advanced-usage.md#Publishing-using-Apache-Maven)
|
||||
- [Maven transfer progress (download logs)](docs/advanced-usage.md#maven-transfer-progress-download-logs)
|
||||
- [Publishing using Gradle](docs/advanced-usage.md#Publishing-using-Gradle)
|
||||
- [Hosted Tool Cache](docs/advanced-usage.md#Hosted-Tool-Cache)
|
||||
- [Modifying Maven Toolchains](docs/advanced-usage.md#Modifying-Maven-Toolchains)
|
||||
- [Java Version File](docs/advanced-usage.md#Java-version-file)
|
||||
|
||||
## V2 vs V1
|
||||
|
||||
Examples in this README use `actions/setup-java@v5`, but the main migration note from V1 still applies to all later major versions (`v2`, `v3`, `v4`, and `v5`):
|
||||
|
||||
- Starting with V2, the action supports custom distributions. V1 supports only Azul Zulu OpenJDK.
|
||||
- Starting with V2, you must specify distribution along with the version. V1 defaults to Azul Zulu OpenJDK, so only version input is required. Follow [the migration guide](docs/switching-to-v2.md) to switch from V1 to V2.
|
||||
|
||||
For information about the latest releases, recent updates, and newly supported distributions, please refer to the `setup-java` [Releases](https://github.com/actions/setup-java/releases).
|
||||
|
||||
## Recommended permissions
|
||||
|
||||
When using the `setup-java` action in your GitHub Actions workflow, it is recommended to set the following permissions to ensure proper functionality:
|
||||
|
||||
+33
-2
@@ -228,9 +228,40 @@ describe('auth tests', () => {
|
||||
<username>\${env.${username}}</username>
|
||||
<password>\${env.&<>"''"><&}</password>
|
||||
</server>
|
||||
</servers>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>setup-java-gpg</id>
|
||||
<properties>
|
||||
<gpg.passphraseEnvName>${gpgPassphrase}</gpg.passphraseEnvName>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
<activeProfiles>
|
||||
<activeProfile>setup-java-gpg</activeProfile>
|
||||
</activeProfiles>
|
||||
</settings>`;
|
||||
|
||||
expect(auth.generate(id, username, password, gpgPassphrase)).toEqual(
|
||||
expectedSettings
|
||||
);
|
||||
});
|
||||
|
||||
it('does not add a gpg profile when the passphrase env var is the maven-gpg-plugin default', () => {
|
||||
const id = 'packages';
|
||||
const username = 'USER';
|
||||
const password = '&<>"\'\'"><&';
|
||||
const gpgPassphrase = 'MAVEN_GPG_PASSPHRASE';
|
||||
|
||||
const expectedSettings = `<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||
<interactiveMode>false</interactiveMode>
|
||||
<servers>
|
||||
<server>
|
||||
<id>gpg.passphrase</id>
|
||||
<passphrase>\${env.${gpgPassphrase}}</passphrase>
|
||||
<id>${id}</id>
|
||||
<username>\${env.${username}}</username>
|
||||
<password>\${env.&<>"''"><&}</password>
|
||||
</server>
|
||||
</servers>
|
||||
</settings>`;
|
||||
|
||||
+196
-12
@@ -166,10 +166,7 @@ describe('dependency cache', () => {
|
||||
|
||||
await restore('maven', '');
|
||||
expect(spyCacheRestore).toHaveBeenCalledWith(
|
||||
[
|
||||
join(os.homedir(), '.m2', 'repository'),
|
||||
join(os.homedir(), '.m2', 'wrapper', 'dists')
|
||||
],
|
||||
[join(os.homedir(), '.m2', 'repository')],
|
||||
expect.any(String)
|
||||
);
|
||||
expect(spyGlobHashFiles).toHaveBeenCalledWith(
|
||||
@@ -196,10 +193,7 @@ describe('dependency cache', () => {
|
||||
|
||||
await restore('maven', '');
|
||||
expect(spyCacheRestore).toHaveBeenCalledWith(
|
||||
[
|
||||
join(os.homedir(), '.m2', 'repository'),
|
||||
join(os.homedir(), '.m2', 'wrapper', 'dists')
|
||||
],
|
||||
[join(os.homedir(), '.m2', 'repository')],
|
||||
expect.any(String)
|
||||
);
|
||||
expect(spyGlobHashFiles).toHaveBeenCalledWith(
|
||||
@@ -214,10 +208,7 @@ describe('dependency cache', () => {
|
||||
|
||||
await restore('maven', '');
|
||||
expect(spyCacheRestore).toHaveBeenCalledWith(
|
||||
[
|
||||
join(os.homedir(), '.m2', 'repository'),
|
||||
join(os.homedir(), '.m2', 'wrapper', 'dists')
|
||||
],
|
||||
[join(os.homedir(), '.m2', 'repository')],
|
||||
expect.any(String)
|
||||
);
|
||||
expect(spyGlobHashFiles).toHaveBeenCalledWith(
|
||||
@@ -226,6 +217,47 @@ describe('dependency cache', () => {
|
||||
expect(spyWarning).not.toHaveBeenCalled();
|
||||
expect(spyInfo).toHaveBeenCalledWith('maven cache is not found');
|
||||
});
|
||||
it('restores the maven wrapper distribution cache independently of the main cache', async () => {
|
||||
createDirectory(join(workspace, '.mvn'));
|
||||
createDirectory(join(workspace, '.mvn', 'wrapper'));
|
||||
createFile(
|
||||
join(workspace, '.mvn', 'wrapper', 'maven-wrapper.properties')
|
||||
);
|
||||
|
||||
await restore('maven', '');
|
||||
// Main dependency cache no longer carries the wrapper dists path.
|
||||
expect(spyCacheRestore).toHaveBeenCalledWith(
|
||||
[join(os.homedir(), '.m2', 'repository')],
|
||||
expect.any(String)
|
||||
);
|
||||
expect(spyCacheRestore).toHaveBeenCalledWith(
|
||||
[join(os.homedir(), '.m2', 'wrapper', 'dists')],
|
||||
expect.stringContaining('maven-wrapper')
|
||||
);
|
||||
expect(spyGlobHashFiles).toHaveBeenCalledWith(
|
||||
'**/.mvn/wrapper/maven-wrapper.properties'
|
||||
);
|
||||
});
|
||||
it('skips the maven wrapper cache when no wrapper properties exist', async () => {
|
||||
createFile(join(workspace, 'pom.xml'));
|
||||
spyGlobHashFiles.mockImplementation((pattern: string) =>
|
||||
Promise.resolve(
|
||||
pattern === '**/.mvn/wrapper/maven-wrapper.properties'
|
||||
? ''
|
||||
: 'hash-stub'
|
||||
)
|
||||
);
|
||||
|
||||
await restore('maven', '');
|
||||
// Only the main dependency cache is restored; the wrapper cache path is
|
||||
// never touched because the project does not use mvnw.
|
||||
expect(spyCacheRestore).toHaveBeenCalledTimes(1);
|
||||
expect(spyCacheRestore).toHaveBeenCalledWith(
|
||||
[join(os.homedir(), '.m2', 'repository')],
|
||||
expect.any(String)
|
||||
);
|
||||
expect(spyWarning).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
describe('for gradle', () => {
|
||||
it('throws error if no build.gradle found', async () => {
|
||||
@@ -282,6 +314,43 @@ describe('dependency cache', () => {
|
||||
expect(spyWarning).not.toHaveBeenCalled();
|
||||
expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found');
|
||||
});
|
||||
it('restores the gradle wrapper distribution cache independently of the main cache', async () => {
|
||||
createFile(join(workspace, 'build.gradle'));
|
||||
|
||||
await restore('gradle', '');
|
||||
// Main dependency cache no longer carries the wrapper path.
|
||||
expect(spyCacheRestore).toHaveBeenCalledWith(
|
||||
[join(os.homedir(), '.gradle', 'caches')],
|
||||
expect.any(String)
|
||||
);
|
||||
// Wrapper distribution is restored on its own, keyed only on the
|
||||
// wrapper properties file.
|
||||
expect(spyCacheRestore).toHaveBeenCalledWith(
|
||||
[join(os.homedir(), '.gradle', 'wrapper')],
|
||||
expect.stringContaining('setup-java-')
|
||||
);
|
||||
expect(spyGlobHashFiles).toHaveBeenCalledWith(
|
||||
'**/gradle-wrapper.properties'
|
||||
);
|
||||
});
|
||||
it('skips the gradle wrapper cache when no wrapper properties exist', async () => {
|
||||
createFile(join(workspace, 'build.gradle'));
|
||||
spyGlobHashFiles.mockImplementation((pattern: string) =>
|
||||
Promise.resolve(
|
||||
pattern === '**/gradle-wrapper.properties' ? '' : 'hash-stub'
|
||||
)
|
||||
);
|
||||
|
||||
await restore('gradle', '');
|
||||
// Only the main dependency cache is restored; the wrapper cache path is
|
||||
// never touched because the project does not use the gradle wrapper.
|
||||
expect(spyCacheRestore).toHaveBeenCalledTimes(1);
|
||||
expect(spyCacheRestore).toHaveBeenCalledWith(
|
||||
[join(os.homedir(), '.gradle', 'caches')],
|
||||
expect.any(String)
|
||||
);
|
||||
expect(spyWarning).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
describe('for sbt', () => {
|
||||
it('throws error if no build.sbt found', async () => {
|
||||
@@ -457,6 +526,77 @@ describe('dependency cache', () => {
|
||||
expect.stringMatching(/^Cache saved with the key:.*/)
|
||||
);
|
||||
});
|
||||
it('saves the maven wrapper distribution cache under its own key', async () => {
|
||||
createFile(join(workspace, 'pom.xml'));
|
||||
(core.getState as jest.Mock<any>).mockImplementation((name: any) => {
|
||||
switch (name) {
|
||||
case 'cache-primary-key':
|
||||
return 'setup-java-cache-primary-key';
|
||||
case 'cache-matched-key':
|
||||
return 'setup-java-cache-matched-key';
|
||||
case 'cache-primary-key-maven-wrapper':
|
||||
return 'setup-java-maven-wrapper-key';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
await save('maven');
|
||||
expect(spyCacheSave).toHaveBeenCalledWith(
|
||||
[join(os.homedir(), '.m2', 'wrapper', 'dists')],
|
||||
'setup-java-maven-wrapper-key'
|
||||
);
|
||||
expect(spyWarning).not.toHaveBeenCalled();
|
||||
});
|
||||
it('does not save the maven wrapper cache on an exact wrapper hit', async () => {
|
||||
createFile(join(workspace, 'pom.xml'));
|
||||
(core.getState as jest.Mock<any>).mockImplementation((name: any) => {
|
||||
switch (name) {
|
||||
case 'cache-primary-key':
|
||||
return 'setup-java-cache-primary-key';
|
||||
case 'cache-matched-key':
|
||||
return 'setup-java-cache-matched-key';
|
||||
case 'cache-primary-key-maven-wrapper':
|
||||
case 'cache-matched-key-maven-wrapper':
|
||||
return 'setup-java-maven-wrapper-key';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
await save('maven');
|
||||
expect(spyCacheSave).not.toHaveBeenCalledWith(
|
||||
[join(os.homedir(), '.m2', 'wrapper', 'dists')],
|
||||
expect.any(String)
|
||||
);
|
||||
});
|
||||
it('does not fail the post step when the wrapper distribution path is missing', async () => {
|
||||
createFile(join(workspace, 'pom.xml'));
|
||||
(core.getState as jest.Mock<any>).mockImplementation((name: any) => {
|
||||
switch (name) {
|
||||
case 'cache-primary-key':
|
||||
return 'setup-java-cache-primary-key';
|
||||
case 'cache-matched-key':
|
||||
return 'setup-java-cache-matched-key';
|
||||
case 'cache-primary-key-maven-wrapper':
|
||||
return 'setup-java-maven-wrapper-key';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
});
|
||||
spyCacheSave.mockImplementation((paths: string[]) =>
|
||||
paths.includes(join(os.homedir(), '.m2', 'wrapper', 'dists'))
|
||||
? Promise.reject(
|
||||
new cache.ValidationError(
|
||||
'Path Validation Error: Path(s) specified in the action for caching do(es) not exist'
|
||||
)
|
||||
)
|
||||
: Promise.resolve(0)
|
||||
);
|
||||
|
||||
await expect(save('maven')).resolves.toBeUndefined();
|
||||
expect(spyWarning).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
describe('for gradle', () => {
|
||||
it('uploads cache even if no build.gradle found', async () => {
|
||||
@@ -509,6 +649,50 @@ describe('dependency cache', () => {
|
||||
expect.stringMatching(/^Cache saved with the key:.*/)
|
||||
);
|
||||
});
|
||||
it('saves the gradle wrapper distribution cache under its own key', async () => {
|
||||
createFile(join(workspace, 'build.gradle'));
|
||||
(core.getState as jest.Mock<any>).mockImplementation((name: any) => {
|
||||
switch (name) {
|
||||
case 'cache-primary-key':
|
||||
return 'setup-java-cache-primary-key';
|
||||
case 'cache-matched-key':
|
||||
return 'setup-java-cache-matched-key';
|
||||
case 'cache-primary-key-gradle-wrapper':
|
||||
return 'setup-java-gradle-wrapper-key';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
await save('gradle');
|
||||
expect(spyCacheSave).toHaveBeenCalledWith(
|
||||
[join(os.homedir(), '.gradle', 'wrapper')],
|
||||
'setup-java-gradle-wrapper-key'
|
||||
);
|
||||
expect(spyWarning).not.toHaveBeenCalled();
|
||||
});
|
||||
it('does not save the gradle wrapper cache on an exact wrapper hit', async () => {
|
||||
createFile(join(workspace, 'build.gradle'));
|
||||
(core.getState as jest.Mock<any>).mockImplementation((name: any) => {
|
||||
switch (name) {
|
||||
case 'cache-primary-key':
|
||||
return 'setup-java-cache-primary-key';
|
||||
case 'cache-matched-key':
|
||||
return 'setup-java-cache-matched-key';
|
||||
case 'cache-primary-key-gradle-wrapper':
|
||||
case 'cache-matched-key-gradle-wrapper':
|
||||
return 'setup-java-gradle-wrapper-key';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
await save('gradle');
|
||||
expect(spyCacheSave).not.toHaveBeenCalledWith(
|
||||
[join(os.homedir(), '.gradle', 'wrapper')],
|
||||
expect.any(String)
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('for sbt', () => {
|
||||
it('uploads cache even if no build.sbt found', async () => {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>io.github.actions</groupId>
|
||||
<artifactId>setup-java-maven2-example</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1 @@
|
||||
target/
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
ThisBuild / scalaVersion := "2.12.15"
|
||||
|
||||
libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "2.1.1"
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
# Assert whether a directory exists, for use in the e2e cache workflows.
|
||||
#
|
||||
# Usage: check-dir.sh <dir> [present|absent]
|
||||
#
|
||||
# present (default): fail if <dir> does NOT exist, otherwise list its contents.
|
||||
# absent: fail if <dir> DOES exist.
|
||||
#
|
||||
# Call with already-expanded paths (e.g. "$HOME/.gradle/caches") to avoid
|
||||
# tilde-expansion pitfalls.
|
||||
set -eu
|
||||
|
||||
if [ "$#" -lt 1 ]; then
|
||||
echo "Usage: check-dir.sh <dir> [present|absent]" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
dir=$1
|
||||
mode=${2:-present}
|
||||
|
||||
case "$mode" in
|
||||
present)
|
||||
if [ ! -d "$dir" ]; then
|
||||
echo "::error::The $dir directory does not exist unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
ls "$dir"
|
||||
;;
|
||||
absent)
|
||||
if [ -d "$dir" ]; then
|
||||
echo "::error::The $dir directory exists unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "::error::Unknown mode '$mode' (expected 'present' or 'absent')"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,44 @@
|
||||
import {afterEach, beforeEach, describe, expect, it, jest} from '@jest/globals';
|
||||
|
||||
const mockGetInput = jest.fn<(...args: any[]) => any>();
|
||||
const mockInfo = jest.fn<(...args: any[]) => any>();
|
||||
const mockDebug = jest.fn<(...args: any[]) => any>();
|
||||
|
||||
jest.unstable_mockModule('@actions/core', () => ({
|
||||
getInput: mockGetInput,
|
||||
info: mockInfo,
|
||||
debug: mockDebug,
|
||||
warning: jest.fn(),
|
||||
setSecret: jest.fn()
|
||||
}));
|
||||
|
||||
const {configureProblemMatcher} = await import('../src/problem-matcher.js');
|
||||
const {INPUT_PROBLEM_MATCHER} = await import('../src/constants.js');
|
||||
|
||||
describe('configureProblemMatcher', () => {
|
||||
let inputs: Record<string, string>;
|
||||
|
||||
beforeEach(() => {
|
||||
inputs = {};
|
||||
mockGetInput.mockImplementation((name: string) => inputs[name] ?? '');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('registers the Java problem matcher by default', () => {
|
||||
configureProblemMatcher('/matchers/java.json');
|
||||
|
||||
expect(mockInfo).toHaveBeenCalledWith('##[add-matcher]/matchers/java.json');
|
||||
});
|
||||
|
||||
it('does not register the Java problem matcher when disabled', () => {
|
||||
inputs[INPUT_PROBLEM_MATCHER] = 'false';
|
||||
|
||||
configureProblemMatcher('/matchers/java.json');
|
||||
|
||||
expect(mockInfo).not.toHaveBeenCalled();
|
||||
expect(mockDebug).toHaveBeenCalledWith('Java problem matcher is disabled');
|
||||
});
|
||||
});
|
||||
@@ -94,6 +94,10 @@ inputs:
|
||||
description: 'Whether Maven should print artifact download/transfer progress to the build log. When "false" (default) the action sets "-ntp" (--no-transfer-progress) in MAVEN_ARGS to produce cleaner logs. Set to "true" to keep the progress output. Has no effect on non-Maven builds.'
|
||||
required: false
|
||||
default: false
|
||||
problem-matcher:
|
||||
description: 'Whether to register the Java problem matcher (compiler errors/warnings and uncaught exceptions). Set to "false" to disable annotations.'
|
||||
required: false
|
||||
default: true
|
||||
outputs:
|
||||
distribution:
|
||||
description: 'Distribution of Java that has been installed'
|
||||
|
||||
Vendored
+242
-38
@@ -39023,7 +39023,7 @@ module.exports = { version: packageJson.version }
|
||||
/***/ 4012:
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"6.1.0","description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","type":"module","main":"lib/cache.js","types":"lib/cache.d.ts","exports":{".":{"types":"./lib/cache.d.ts","import":"./lib/cache.js"}},"directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^3.0.1","@actions/exec":"^3.0.0","@actions/glob":"^0.6.1","@actions/http-client":"^4.0.1","@actions/io":"^3.0.2","@azure/core-rest-pipeline":"^1.23.0","@azure/storage-blob":"^12.31.0","@protobuf-ts/runtime-rpc":"^2.11.1","semver":"^7.7.4"},"devDependencies":{"@protobuf-ts/plugin":"^2.11.1","@types/node":"^25.6.0","@types/semver":"^7.7.1","typescript":"^5.9.3"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
|
||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"6.2.0","description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","type":"module","main":"lib/cache.js","types":"lib/cache.d.ts","exports":{".":{"types":"./lib/cache.d.ts","import":"./lib/cache.js"}},"directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^3.0.1","@actions/exec":"^3.0.0","@actions/glob":"^0.6.1","@actions/http-client":"^4.0.1","@actions/io":"^3.0.2","@azure/core-rest-pipeline":"^1.23.0","@azure/storage-blob":"^12.31.0","@protobuf-ts/runtime-rpc":"^2.11.1","semver":"^7.7.4"},"devDependencies":{"@protobuf-ts/plugin":"^2.11.1","@types/node":"^25.6.0","@types/semver":"^7.7.1","typescript":"^5.9.3"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
|
||||
|
||||
/***/ })
|
||||
|
||||
@@ -44068,6 +44068,10 @@ const SystemTarPathOnWindows = `${process.env['SYSTEMDRIVE']}\\Windows\\System32
|
||||
const TarFilename = 'cache.tar';
|
||||
const ManifestFilename = 'manifest.txt';
|
||||
const CacheFileSizeLimit = 10 * Math.pow(1024, 3); // 10GiB per repository
|
||||
// Prefix the cache backend embeds in a read-denial message (v2 twirp
|
||||
// GetCacheEntryDownloadURL error or the GHES v1 `_apis/artifactcache` 403 body).
|
||||
// Shared so cache.ts and cacheHttpClient.ts match the same contract value.
|
||||
const constants_CacheReadDeniedMessagePrefix = 'cache read denied:';
|
||||
//# sourceMappingURL=constants.js.map
|
||||
;// CONCATENATED MODULE: ./node_modules/@actions/cache/lib/internal/cacheUtils.js
|
||||
var cacheUtils_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
@@ -93948,6 +93952,24 @@ function config_getCacheServiceVersion() {
|
||||
return 'v1';
|
||||
return process.env['ACTIONS_CACHE_SERVICE_V2'] ? 'v2' : 'v1';
|
||||
}
|
||||
// The cache-mode lattice: readable = {read, write}, writable = {write,
|
||||
// write-only}, none = neither.
|
||||
const KNOWN_CACHE_MODES = ['none', 'read', 'write', 'write-only'];
|
||||
// The effective cache-mode exported by the runner, or '' when not set.
|
||||
function config_getCacheMode() {
|
||||
return (process.env['ACTIONS_CACHE_MODE'] || '').trim().toLowerCase();
|
||||
}
|
||||
// Unset or unrecognized modes are permissive so behavior matches today.
|
||||
function config_isCacheReadable(mode) {
|
||||
if (!KNOWN_CACHE_MODES.includes(mode))
|
||||
return true;
|
||||
return mode === 'read' || mode === 'write';
|
||||
}
|
||||
function isCacheWritable(mode) {
|
||||
if (!KNOWN_CACHE_MODES.includes(mode))
|
||||
return true;
|
||||
return mode === 'write' || mode === 'write-only';
|
||||
}
|
||||
function getCacheServiceURL() {
|
||||
const version = config_getCacheServiceVersion();
|
||||
// Based on the version of the cache service, we will determine which
|
||||
@@ -93997,6 +94019,7 @@ var cacheHttpClient_awaiter = (undefined && undefined.__awaiter) || function (th
|
||||
|
||||
|
||||
|
||||
|
||||
function getCacheApiUrl(resource) {
|
||||
const baseUrl = getCacheServiceURL();
|
||||
if (!baseUrl) {
|
||||
@@ -94024,6 +94047,7 @@ function createHttpClient() {
|
||||
}
|
||||
function getCacheEntry(keys, paths, options) {
|
||||
return cacheHttpClient_awaiter(this, void 0, void 0, function* () {
|
||||
var _a;
|
||||
const httpClient = createHttpClient();
|
||||
const version = utils.getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod, options === null || options === void 0 ? void 0 : options.enableCrossOsArchive);
|
||||
const resource = `cache?keys=${encodeURIComponent(keys.join(','))}&version=${version}`;
|
||||
@@ -94037,6 +94061,12 @@ function getCacheEntry(keys, paths, options) {
|
||||
return null;
|
||||
}
|
||||
if (!isSuccessStatusCode(response.statusCode)) {
|
||||
// Only surface the receiver's body for a `cache read denied:` policy denial
|
||||
// so callers can dispatch on it; keep the generic message otherwise.
|
||||
const errorMessage = (_a = response.error) === null || _a === void 0 ? void 0 : _a.message;
|
||||
if (errorMessage === null || errorMessage === void 0 ? void 0 : errorMessage.includes(CacheReadDeniedMessagePrefix)) {
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
throw new Error(`Cache service responded with ${response.statusCode}`);
|
||||
}
|
||||
const cacheResult = response.result;
|
||||
@@ -95297,6 +95327,7 @@ var cache_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _ar
|
||||
|
||||
|
||||
|
||||
|
||||
class ValidationError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
@@ -95312,19 +95343,20 @@ class ReserveCacheError extends Error {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Stable prefix the receiver writes into the cache reservation response when
|
||||
* the issuer downgraded the cache token to read-only (for example, because
|
||||
* Stable prefix the cache service writes into the cache reservation response
|
||||
* when the issuer downgraded the cache token to read-only (for example, because
|
||||
* the run was triggered by an untrusted event). saveCacheV1 / saveCacheV2
|
||||
* dispatch on this prefix to re-classify the failure as a
|
||||
* CacheWriteDeniedError so consumers (and the outer catch arm) can
|
||||
* distinguish a policy denial from other reservation failures.
|
||||
* dispatch on this prefix to re-classify the failure as a CacheWriteDeniedError
|
||||
* so consumers and tests can distinguish a policy denial from other reservation
|
||||
* failures. Internally it is logged as a non-fatal warning like other
|
||||
* best-effort save failures.
|
||||
*/
|
||||
const CACHE_WRITE_DENIED_PREFIX = 'cache write denied:';
|
||||
/**
|
||||
* Raised when the cache backend refuses to reserve a writable cache entry
|
||||
* because the JWT issued for this run was scoped read-only (for example, the
|
||||
* run was triggered by an event the repository administrator classified as
|
||||
* untrusted). The receiver-supplied detail message always begins with
|
||||
* untrusted). The service-supplied detail message always begins with
|
||||
* `cache write denied:` (the full error message includes additional context
|
||||
* like the cache key).
|
||||
*
|
||||
@@ -95340,6 +95372,19 @@ class CacheWriteDeniedError extends ReserveCacheError {
|
||||
Object.setPrototypeOf(this, CacheWriteDeniedError.prototype);
|
||||
}
|
||||
}
|
||||
// Re-exported from constants so consumers keep referencing it here; the shared
|
||||
// value also drives detection in cacheHttpClient without duplicating the string.
|
||||
const CACHE_READ_DENIED_PREFIX = (/* unused pure expression or super */ null && (CacheReadDeniedMessagePrefix));
|
||||
// Raised when the cache backend denies a download URL because the run's token
|
||||
// has no readable cache scopes. Caching is best-effort, so restoreCache logs a
|
||||
// warning and reports a cache miss rather than rethrowing this.
|
||||
class CacheReadDeniedError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = 'CacheReadDeniedError';
|
||||
Object.setPrototypeOf(this, CacheReadDeniedError.prototype);
|
||||
}
|
||||
}
|
||||
class FinalizeCacheError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
@@ -95394,6 +95439,12 @@ function restoreCache(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
const cacheServiceVersion = getCacheServiceVersion();
|
||||
core.debug(`Cache service version: ${cacheServiceVersion}`);
|
||||
checkPaths(paths);
|
||||
const cacheMode = getCacheMode();
|
||||
if (!isCacheReadable(cacheMode)) {
|
||||
core.info(`Cache restore skipped: the effective cache-mode '${cacheMode}' does not permit reads.`);
|
||||
core.debug(`Skipped restore for paths [${paths.join(', ')}] with primary key '${primaryKey}'.`);
|
||||
return undefined;
|
||||
}
|
||||
switch (cacheServiceVersion) {
|
||||
case 'v2':
|
||||
return yield restoreCacheV2(paths, primaryKey, restoreKeys, options, enableCrossOsArchive);
|
||||
@@ -95415,6 +95466,7 @@ function restoreCache(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
*/
|
||||
function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
return cache_awaiter(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) {
|
||||
var _a;
|
||||
restoreKeys = restoreKeys || [];
|
||||
const keys = [primaryKey, ...restoreKeys];
|
||||
core.debug('Resolved Keys:');
|
||||
@@ -95429,10 +95481,26 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
let archivePath = '';
|
||||
try {
|
||||
// path are needed to compute version
|
||||
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
|
||||
compressionMethod,
|
||||
enableCrossOsArchive
|
||||
});
|
||||
let cacheEntry;
|
||||
try {
|
||||
cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
|
||||
compressionMethod,
|
||||
enableCrossOsArchive
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
// The v1 artifact cache service returns HTTP 403 with a
|
||||
// `cache read denied:` body when the run's token has no readable cache
|
||||
// scopes. getCacheEntry lives in a dependency-free internal module and
|
||||
// cannot import CacheReadDeniedError without a circular dependency, so it
|
||||
// only surfaces the raw denial message; we classify it into the typed
|
||||
// error here so the outer catch and consumers can dispatch on it.
|
||||
const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
|
||||
if (errorMessage.includes(CACHE_READ_DENIED_PREFIX)) {
|
||||
throw new CacheReadDeniedError(errorMessage);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
|
||||
// Cache not found
|
||||
return undefined;
|
||||
@@ -95461,7 +95529,9 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
}
|
||||
else {
|
||||
// warn on cache restore failure and continue build
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A read denied by policy (CacheReadDeniedError) is not an HttpClientError
|
||||
// so it falls here and is warned, treated as a cache miss.
|
||||
if (typedError instanceof HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
@@ -95496,6 +95566,7 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
*/
|
||||
function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
return cache_awaiter(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) {
|
||||
var _a;
|
||||
// Override UploadOptions to force the use of Azure
|
||||
options = Object.assign(Object.assign({}, options), { useAzureSdk: true });
|
||||
restoreKeys = restoreKeys || [];
|
||||
@@ -95517,7 +95588,20 @@ function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
restoreKeys,
|
||||
version: utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive)
|
||||
};
|
||||
const response = yield twirpClient.GetCacheEntryDownloadURL(request);
|
||||
let response;
|
||||
try {
|
||||
response = yield twirpClient.GetCacheEntryDownloadURL(request);
|
||||
}
|
||||
catch (error) {
|
||||
// The receiver returns twirp PermissionDenied (403) when the run's token
|
||||
// has no readable cache scopes. The client wraps that 403, so the stable
|
||||
// prefix is embedded in the message rather than leading it.
|
||||
const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
|
||||
if (errorMessage.includes(CACHE_READ_DENIED_PREFIX)) {
|
||||
throw new CacheReadDeniedError(errorMessage);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (!response.ok) {
|
||||
core.debug(`Cache not found for version ${request.version} of keys: ${keys.join(', ')}`);
|
||||
return undefined;
|
||||
@@ -95552,8 +95636,10 @@ function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
throw error;
|
||||
}
|
||||
else {
|
||||
// Supress all non-validation cache related errors because caching should be optional
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Suppress all non-validation cache related errors because caching should be optional
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A read denied by policy (CacheReadDeniedError) is not an HttpClientError
|
||||
// so it falls here and is warned, treated as a cache miss.
|
||||
if (typedError instanceof HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
@@ -95592,6 +95678,12 @@ function cache_saveCache(paths_1, key_1, options_1) {
|
||||
core_debug(`Cache service version: ${cacheServiceVersion}`);
|
||||
checkPaths(paths);
|
||||
checkKey(key);
|
||||
const cacheMode = config_getCacheMode();
|
||||
if (!isCacheWritable(cacheMode)) {
|
||||
info(`Cache save skipped: the effective cache-mode '${cacheMode}' does not permit writes.`);
|
||||
core_debug(`Skipped save for paths [${paths.join(', ')}] with key '${key}'.`);
|
||||
return -1;
|
||||
}
|
||||
switch (cacheServiceVersion) {
|
||||
case 'v2':
|
||||
return yield saveCacheV2(paths, key, options, enableCrossOsArchive);
|
||||
@@ -95669,17 +95761,14 @@ function saveCacheV1(paths_1, key_1, options_1) {
|
||||
if (typedError.name === ValidationError.name) {
|
||||
throw error;
|
||||
}
|
||||
else if (typedError.name === CacheWriteDeniedError.name) {
|
||||
// Cache write was denied by policy (read-only token). Surface to the
|
||||
// customer at warning level so it is visible in the workflow log
|
||||
// without failing the run.
|
||||
warning(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else if (typedError.name === ReserveCacheError.name) {
|
||||
info(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else {
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A write denied by policy (CacheWriteDeniedError) is not an
|
||||
// HttpClientError and its name does not match the ReserveCacheError arm,
|
||||
// so it falls here and is warned without failing the run.
|
||||
if (typedError instanceof lib_HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
@@ -95790,12 +95879,6 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
||||
if (typedError.name === ValidationError.name) {
|
||||
throw error;
|
||||
}
|
||||
else if (typedError.name === CacheWriteDeniedError.name) {
|
||||
// Cache write was denied by policy (read-only token). Surface to the
|
||||
// customer at warning level so it is visible in the workflow log
|
||||
// without failing the run.
|
||||
warning(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else if (typedError.name === ReserveCacheError.name) {
|
||||
info(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
@@ -95803,7 +95886,10 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
||||
warning(typedError.message);
|
||||
}
|
||||
else {
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A write denied by policy (CacheWriteDeniedError) is not an
|
||||
// HttpClientError and its name does not match the ReserveCacheError arm,
|
||||
// so it falls here and is warned without failing the run.
|
||||
if (typedError instanceof lib_HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
@@ -95838,6 +95924,7 @@ const INPUT_JDK_FILE = 'jdk-file';
|
||||
const INPUT_JDK_FILE_DEPRECATED = 'jdkFile';
|
||||
const INPUT_CHECK_LATEST = 'check-latest';
|
||||
const INPUT_SET_DEFAULT = 'set-default';
|
||||
const INPUT_PROBLEM_MATCHER = 'problem-matcher';
|
||||
const INPUT_VERIFY_SIGNATURE = 'verify-signature';
|
||||
const INPUT_VERIFY_SIGNATURE_PUBLIC_KEY = 'verify-signature-public-key';
|
||||
const INPUT_SERVER_ID = 'server-id';
|
||||
@@ -95849,6 +95936,12 @@ const INPUT_GPG_PRIVATE_KEY = 'gpg-private-key';
|
||||
const INPUT_GPG_PASSPHRASE = 'gpg-passphrase';
|
||||
const INPUT_DEFAULT_GPG_PRIVATE_KEY = (/* unused pure expression or super */ null && (undefined));
|
||||
const INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE';
|
||||
// The default name of the environment variable the maven-gpg-plugin reads the
|
||||
// passphrase from (property `gpg.passphraseEnvName`). When the configured
|
||||
// passphrase env var name matches this, no extra configuration is required.
|
||||
const MAVEN_GPG_PASSPHRASE_DEFAULT_ENV = 'MAVEN_GPG_PASSPHRASE';
|
||||
// Id of the settings.xml profile used to set `gpg.passphraseEnvName`.
|
||||
const GPG_PASSPHRASE_PROFILE_ID = 'setup-java-gpg';
|
||||
const INPUT_CACHE = 'cache';
|
||||
const INPUT_CACHE_DEPENDENCY_PATH = 'cache-dependency-path';
|
||||
const INPUT_JOB_STATUS = 'job-status';
|
||||
@@ -99666,23 +99759,28 @@ const CACHE_KEY_PREFIX = 'setup-java';
|
||||
const supportedPackageManager = [
|
||||
{
|
||||
id: 'maven',
|
||||
path: [
|
||||
(0,external_path_.join)(external_os_default().homedir(), '.m2', 'repository'),
|
||||
(0,external_path_.join)(external_os_default().homedir(), '.m2', 'wrapper', 'dists')
|
||||
],
|
||||
path: [(0,external_path_.join)(external_os_default().homedir(), '.m2', 'repository')],
|
||||
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---maven
|
||||
pattern: [
|
||||
'**/pom.xml',
|
||||
'**/.mvn/wrapper/maven-wrapper.properties',
|
||||
'**/.mvn/extensions.xml'
|
||||
],
|
||||
// The Maven wrapper distribution only depends on the wrapper properties,
|
||||
// which change very rarely, so it is cached separately from the local
|
||||
// repository. This keeps it available across the frequent pom.xml changes
|
||||
// that rotate the main cache key. See issue #1095.
|
||||
additionalCaches: [
|
||||
{
|
||||
name: 'maven-wrapper',
|
||||
path: [(0,external_path_.join)(external_os_default().homedir(), '.m2', 'wrapper', 'dists')],
|
||||
pattern: ['**/.mvn/wrapper/maven-wrapper.properties']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'gradle',
|
||||
path: [
|
||||
(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'caches'),
|
||||
(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'wrapper')
|
||||
],
|
||||
path: [(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'caches')],
|
||||
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle
|
||||
pattern: [
|
||||
'**/*.gradle*',
|
||||
@@ -99691,6 +99789,17 @@ const supportedPackageManager = [
|
||||
'buildSrc/**/Dependencies.kt',
|
||||
'gradle/*.versions.toml',
|
||||
'**/versions.properties'
|
||||
],
|
||||
// The Gradle wrapper distribution only depends on the wrapper properties,
|
||||
// which change very rarely, so it is cached separately from the Gradle
|
||||
// caches. This keeps it available across the frequent *.gradle* changes
|
||||
// that rotate the main cache key. See issue #269.
|
||||
additionalCaches: [
|
||||
{
|
||||
name: 'gradle-wrapper',
|
||||
path: [(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'wrapper')],
|
||||
pattern: ['**/gradle-wrapper.properties']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -99726,6 +99835,19 @@ function findPackageManager(id) {
|
||||
}
|
||||
return packageManager;
|
||||
}
|
||||
/**
|
||||
* State keys used to carry an additional cache's restore-time information over
|
||||
* to the post (save) action, scoped by the additional cache name.
|
||||
*/
|
||||
function additionalCachePrimaryKeyState(name) {
|
||||
return `${STATE_CACHE_PRIMARY_KEY}-${name}`;
|
||||
}
|
||||
function additionalCacheMatchedKeyState(name) {
|
||||
return `${CACHE_MATCHED_KEY}-${name}`;
|
||||
}
|
||||
function buildCacheKey(id, fileHash) {
|
||||
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-${id}-${fileHash}`;
|
||||
}
|
||||
/**
|
||||
* A function that generates a cache key to use.
|
||||
* Format of the generated key will be "${{ platform }}-${{ id }}-${{ fileHash }}"".
|
||||
@@ -99739,7 +99861,19 @@ async function computeCacheKey(packageManager, cacheDependencyPath) {
|
||||
if (!fileHash) {
|
||||
throw new Error(`No file in ${process.cwd()} matched to [${pattern}], make sure you have checked out the target repository`);
|
||||
}
|
||||
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-${packageManager.id}-${fileHash}`;
|
||||
return buildCacheKey(packageManager.id, fileHash);
|
||||
}
|
||||
/**
|
||||
* Computes the cache key for an additional cache. Unlike {@link computeCacheKey}
|
||||
* this returns undefined (instead of throwing) when no file matches the pattern,
|
||||
* because additional caches are optional features that many projects do not use.
|
||||
*/
|
||||
async function computeAdditionalCacheKey(additionalCache) {
|
||||
const fileHash = await glob.hashFiles(additionalCache.pattern.join('\n'));
|
||||
if (!fileHash) {
|
||||
return undefined;
|
||||
}
|
||||
return buildCacheKey(additionalCache.name, fileHash);
|
||||
}
|
||||
/**
|
||||
* Restore the dependency cache
|
||||
@@ -99763,6 +99897,29 @@ async function restore(id, cacheDependencyPath) {
|
||||
core.setOutput('cache-hit', false);
|
||||
core.info(`${packageManager.id} cache is not found`);
|
||||
}
|
||||
for (const additionalCache of packageManager.additionalCaches ?? []) {
|
||||
await restoreAdditionalCache(additionalCache);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Restore an additional cache (e.g. a build-tool wrapper distribution) that is
|
||||
* keyed independently of the main dependency cache so that it survives changes
|
||||
* to volatile dependency files. Skips silently when the project does not use
|
||||
* the corresponding feature.
|
||||
*/
|
||||
async function restoreAdditionalCache(additionalCache) {
|
||||
const primaryKey = await computeAdditionalCacheKey(additionalCache);
|
||||
if (!primaryKey) {
|
||||
core.debug(`No file matched [${additionalCache.pattern}] for the ${additionalCache.name} cache, skipping.`);
|
||||
return;
|
||||
}
|
||||
core.debug(`${additionalCache.name} primary key is ${primaryKey}`);
|
||||
core.saveState(additionalCachePrimaryKeyState(additionalCache.name), primaryKey);
|
||||
const matchedKey = await cache.restoreCache(additionalCache.path, primaryKey);
|
||||
if (matchedKey) {
|
||||
core.saveState(additionalCacheMatchedKeyState(additionalCache.name), matchedKey);
|
||||
core.info(`${additionalCache.name} cache restored from key: ${matchedKey}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Save the dependency cache
|
||||
@@ -99773,6 +99930,9 @@ async function save(id) {
|
||||
const matchedKey = getState(CACHE_MATCHED_KEY);
|
||||
// Inputs are re-evaluated before the post action, so we want the original key used for restore
|
||||
const primaryKey = getState(STATE_CACHE_PRIMARY_KEY);
|
||||
for (const additionalCache of packageManager.additionalCaches ?? []) {
|
||||
await saveAdditionalCache(packageManager, additionalCache);
|
||||
}
|
||||
if (!primaryKey) {
|
||||
warning('Error retrieving key from state.');
|
||||
return;
|
||||
@@ -99807,6 +99967,50 @@ async function save(id) {
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Save an additional cache under its own key. Skips when no key was recorded at
|
||||
* restore time (feature unused) or when the exact key was already restored.
|
||||
*/
|
||||
async function saveAdditionalCache(packageManager, additionalCache) {
|
||||
const primaryKey = getState(additionalCachePrimaryKeyState(additionalCache.name));
|
||||
const matchedKey = getState(additionalCacheMatchedKeyState(additionalCache.name));
|
||||
if (!primaryKey) {
|
||||
// The feature is not used by this project, nothing to save.
|
||||
core_debug(`No primary key for the ${additionalCache.name} cache, not saving cache.`);
|
||||
return;
|
||||
}
|
||||
else if (matchedKey === primaryKey) {
|
||||
info(`Cache hit occurred on the ${additionalCache.name} primary key ${primaryKey}, not saving cache.`);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const cacheId = await cache_saveCache(additionalCache.path, primaryKey);
|
||||
if (cacheId === -1) {
|
||||
core_debug(`${additionalCache.name} cache was not saved for the key: ${primaryKey}`);
|
||||
return;
|
||||
}
|
||||
info(`${additionalCache.name} cache saved with the key: ${primaryKey}`);
|
||||
}
|
||||
catch (error) {
|
||||
const err = error;
|
||||
if (err.name === ValidationError.name) {
|
||||
// The cache paths did not resolve, e.g. the wrapper distribution was
|
||||
// never downloaded because a system build tool was used or the download
|
||||
// failed. Optional wrapper caches must not fail the post step, so skip.
|
||||
core_debug(`${additionalCache.name} cache paths do not exist, not saving cache: ${err.message}`);
|
||||
return;
|
||||
}
|
||||
if (err.name === ReserveCacheError.name) {
|
||||
info(err.message);
|
||||
}
|
||||
else {
|
||||
if (isProbablyGradleDaemonProblem(packageManager, err)) {
|
||||
warning('Failed to save Gradle cache on Windows. If tar.exe reported "Permission denied", try to run Gradle with `--no-daemon` option. Refer to https://github.com/actions/cache/issues/454 for details.');
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param packageManager the specified package manager by user
|
||||
* @param error the error thrown by the saveCache
|
||||
|
||||
Vendored
+275
-44
@@ -70021,7 +70021,7 @@ module.exports = { version: packageJson.version }
|
||||
/***/ 4012:
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"6.1.0","description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","type":"module","main":"lib/cache.js","types":"lib/cache.d.ts","exports":{".":{"types":"./lib/cache.d.ts","import":"./lib/cache.js"}},"directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^3.0.1","@actions/exec":"^3.0.0","@actions/glob":"^0.6.1","@actions/http-client":"^4.0.1","@actions/io":"^3.0.2","@azure/core-rest-pipeline":"^1.23.0","@azure/storage-blob":"^12.31.0","@protobuf-ts/runtime-rpc":"^2.11.1","semver":"^7.7.4"},"devDependencies":{"@protobuf-ts/plugin":"^2.11.1","@types/node":"^25.6.0","@types/semver":"^7.7.1","typescript":"^5.9.3"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
|
||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"6.2.0","description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","type":"module","main":"lib/cache.js","types":"lib/cache.d.ts","exports":{".":{"types":"./lib/cache.d.ts","import":"./lib/cache.js"}},"directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^3.0.1","@actions/exec":"^3.0.0","@actions/glob":"^0.6.1","@actions/http-client":"^4.0.1","@actions/io":"^3.0.2","@azure/core-rest-pipeline":"^1.23.0","@azure/storage-blob":"^12.31.0","@protobuf-ts/runtime-rpc":"^2.11.1","semver":"^7.7.4"},"devDependencies":{"@protobuf-ts/plugin":"^2.11.1","@types/node":"^25.6.0","@types/semver":"^7.7.1","typescript":"^5.9.3"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
|
||||
|
||||
/***/ })
|
||||
|
||||
@@ -73283,6 +73283,7 @@ const INPUT_JDK_FILE = 'jdk-file';
|
||||
const INPUT_JDK_FILE_DEPRECATED = 'jdkFile';
|
||||
const INPUT_CHECK_LATEST = 'check-latest';
|
||||
const INPUT_SET_DEFAULT = 'set-default';
|
||||
const INPUT_PROBLEM_MATCHER = 'problem-matcher';
|
||||
const INPUT_VERIFY_SIGNATURE = 'verify-signature';
|
||||
const INPUT_VERIFY_SIGNATURE_PUBLIC_KEY = 'verify-signature-public-key';
|
||||
const INPUT_SERVER_ID = 'server-id';
|
||||
@@ -73294,6 +73295,12 @@ const INPUT_GPG_PRIVATE_KEY = 'gpg-private-key';
|
||||
const INPUT_GPG_PASSPHRASE = 'gpg-passphrase';
|
||||
const INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined;
|
||||
const INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE';
|
||||
// The default name of the environment variable the maven-gpg-plugin reads the
|
||||
// passphrase from (property `gpg.passphraseEnvName`). When the configured
|
||||
// passphrase env var name matches this, no extra configuration is required.
|
||||
const MAVEN_GPG_PASSPHRASE_DEFAULT_ENV = 'MAVEN_GPG_PASSPHRASE';
|
||||
// Id of the settings.xml profile used to set `gpg.passphraseEnvName`.
|
||||
const GPG_PASSPHRASE_PROFILE_ID = 'setup-java-gpg';
|
||||
const INPUT_CACHE = 'cache';
|
||||
const INPUT_CACHE_DEPENDENCY_PATH = 'cache-dependency-path';
|
||||
const constants_INPUT_JOB_STATUS = 'job-status';
|
||||
@@ -75095,6 +75102,10 @@ const SystemTarPathOnWindows = `${process.env['SYSTEMDRIVE']}\\Windows\\System32
|
||||
const TarFilename = 'cache.tar';
|
||||
const constants_ManifestFilename = 'manifest.txt';
|
||||
const CacheFileSizeLimit = 10 * Math.pow(1024, 3); // 10GiB per repository
|
||||
// Prefix the cache backend embeds in a read-denial message (v2 twirp
|
||||
// GetCacheEntryDownloadURL error or the GHES v1 `_apis/artifactcache` 403 body).
|
||||
// Shared so cache.ts and cacheHttpClient.ts match the same contract value.
|
||||
const CacheReadDeniedMessagePrefix = 'cache read denied:';
|
||||
//# sourceMappingURL=constants.js.map
|
||||
;// CONCATENATED MODULE: ./node_modules/@actions/cache/lib/internal/cacheUtils.js
|
||||
var cacheUtils_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
@@ -124976,6 +124987,24 @@ function config_getCacheServiceVersion() {
|
||||
return 'v1';
|
||||
return process.env['ACTIONS_CACHE_SERVICE_V2'] ? 'v2' : 'v1';
|
||||
}
|
||||
// The cache-mode lattice: readable = {read, write}, writable = {write,
|
||||
// write-only}, none = neither.
|
||||
const KNOWN_CACHE_MODES = ['none', 'read', 'write', 'write-only'];
|
||||
// The effective cache-mode exported by the runner, or '' when not set.
|
||||
function config_getCacheMode() {
|
||||
return (process.env['ACTIONS_CACHE_MODE'] || '').trim().toLowerCase();
|
||||
}
|
||||
// Unset or unrecognized modes are permissive so behavior matches today.
|
||||
function isCacheReadable(mode) {
|
||||
if (!KNOWN_CACHE_MODES.includes(mode))
|
||||
return true;
|
||||
return mode === 'read' || mode === 'write';
|
||||
}
|
||||
function config_isCacheWritable(mode) {
|
||||
if (!KNOWN_CACHE_MODES.includes(mode))
|
||||
return true;
|
||||
return mode === 'write' || mode === 'write-only';
|
||||
}
|
||||
function getCacheServiceURL() {
|
||||
const version = config_getCacheServiceVersion();
|
||||
// Based on the version of the cache service, we will determine which
|
||||
@@ -125025,6 +125054,7 @@ var cacheHttpClient_awaiter = (undefined && undefined.__awaiter) || function (th
|
||||
|
||||
|
||||
|
||||
|
||||
function getCacheApiUrl(resource) {
|
||||
const baseUrl = getCacheServiceURL();
|
||||
if (!baseUrl) {
|
||||
@@ -125052,6 +125082,7 @@ function createHttpClient() {
|
||||
}
|
||||
function getCacheEntry(keys, paths, options) {
|
||||
return cacheHttpClient_awaiter(this, void 0, void 0, function* () {
|
||||
var _a;
|
||||
const httpClient = createHttpClient();
|
||||
const version = getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod, options === null || options === void 0 ? void 0 : options.enableCrossOsArchive);
|
||||
const resource = `cache?keys=${encodeURIComponent(keys.join(','))}&version=${version}`;
|
||||
@@ -125065,6 +125096,12 @@ function getCacheEntry(keys, paths, options) {
|
||||
return null;
|
||||
}
|
||||
if (!requestUtils_isSuccessStatusCode(response.statusCode)) {
|
||||
// Only surface the receiver's body for a `cache read denied:` policy denial
|
||||
// so callers can dispatch on it; keep the generic message otherwise.
|
||||
const errorMessage = (_a = response.error) === null || _a === void 0 ? void 0 : _a.message;
|
||||
if (errorMessage === null || errorMessage === void 0 ? void 0 : errorMessage.includes(CacheReadDeniedMessagePrefix)) {
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
throw new Error(`Cache service responded with ${response.statusCode}`);
|
||||
}
|
||||
const cacheResult = response.result;
|
||||
@@ -126326,6 +126363,7 @@ var cache_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _ar
|
||||
|
||||
|
||||
|
||||
|
||||
class ValidationError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
@@ -126341,19 +126379,20 @@ class ReserveCacheError extends Error {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Stable prefix the receiver writes into the cache reservation response when
|
||||
* the issuer downgraded the cache token to read-only (for example, because
|
||||
* Stable prefix the cache service writes into the cache reservation response
|
||||
* when the issuer downgraded the cache token to read-only (for example, because
|
||||
* the run was triggered by an untrusted event). saveCacheV1 / saveCacheV2
|
||||
* dispatch on this prefix to re-classify the failure as a
|
||||
* CacheWriteDeniedError so consumers (and the outer catch arm) can
|
||||
* distinguish a policy denial from other reservation failures.
|
||||
* dispatch on this prefix to re-classify the failure as a CacheWriteDeniedError
|
||||
* so consumers and tests can distinguish a policy denial from other reservation
|
||||
* failures. Internally it is logged as a non-fatal warning like other
|
||||
* best-effort save failures.
|
||||
*/
|
||||
const CACHE_WRITE_DENIED_PREFIX = 'cache write denied:';
|
||||
/**
|
||||
* Raised when the cache backend refuses to reserve a writable cache entry
|
||||
* because the JWT issued for this run was scoped read-only (for example, the
|
||||
* run was triggered by an event the repository administrator classified as
|
||||
* untrusted). The receiver-supplied detail message always begins with
|
||||
* untrusted). The service-supplied detail message always begins with
|
||||
* `cache write denied:` (the full error message includes additional context
|
||||
* like the cache key).
|
||||
*
|
||||
@@ -126369,6 +126408,19 @@ class CacheWriteDeniedError extends ReserveCacheError {
|
||||
Object.setPrototypeOf(this, CacheWriteDeniedError.prototype);
|
||||
}
|
||||
}
|
||||
// Re-exported from constants so consumers keep referencing it here; the shared
|
||||
// value also drives detection in cacheHttpClient without duplicating the string.
|
||||
const CACHE_READ_DENIED_PREFIX = CacheReadDeniedMessagePrefix;
|
||||
// Raised when the cache backend denies a download URL because the run's token
|
||||
// has no readable cache scopes. Caching is best-effort, so restoreCache logs a
|
||||
// warning and reports a cache miss rather than rethrowing this.
|
||||
class CacheReadDeniedError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = 'CacheReadDeniedError';
|
||||
Object.setPrototypeOf(this, CacheReadDeniedError.prototype);
|
||||
}
|
||||
}
|
||||
class FinalizeCacheError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
@@ -126423,6 +126475,12 @@ function restoreCache(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
const cacheServiceVersion = config_getCacheServiceVersion();
|
||||
core_debug(`Cache service version: ${cacheServiceVersion}`);
|
||||
checkPaths(paths);
|
||||
const cacheMode = config_getCacheMode();
|
||||
if (!isCacheReadable(cacheMode)) {
|
||||
info(`Cache restore skipped: the effective cache-mode '${cacheMode}' does not permit reads.`);
|
||||
core_debug(`Skipped restore for paths [${paths.join(', ')}] with primary key '${primaryKey}'.`);
|
||||
return undefined;
|
||||
}
|
||||
switch (cacheServiceVersion) {
|
||||
case 'v2':
|
||||
return yield restoreCacheV2(paths, primaryKey, restoreKeys, options, enableCrossOsArchive);
|
||||
@@ -126444,6 +126502,7 @@ function restoreCache(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
*/
|
||||
function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
return cache_awaiter(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) {
|
||||
var _a;
|
||||
restoreKeys = restoreKeys || [];
|
||||
const keys = [primaryKey, ...restoreKeys];
|
||||
core_debug('Resolved Keys:');
|
||||
@@ -126458,10 +126517,26 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
let archivePath = '';
|
||||
try {
|
||||
// path are needed to compute version
|
||||
const cacheEntry = yield getCacheEntry(keys, paths, {
|
||||
compressionMethod,
|
||||
enableCrossOsArchive
|
||||
});
|
||||
let cacheEntry;
|
||||
try {
|
||||
cacheEntry = yield getCacheEntry(keys, paths, {
|
||||
compressionMethod,
|
||||
enableCrossOsArchive
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
// The v1 artifact cache service returns HTTP 403 with a
|
||||
// `cache read denied:` body when the run's token has no readable cache
|
||||
// scopes. getCacheEntry lives in a dependency-free internal module and
|
||||
// cannot import CacheReadDeniedError without a circular dependency, so it
|
||||
// only surfaces the raw denial message; we classify it into the typed
|
||||
// error here so the outer catch and consumers can dispatch on it.
|
||||
const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
|
||||
if (errorMessage.includes(CACHE_READ_DENIED_PREFIX)) {
|
||||
throw new CacheReadDeniedError(errorMessage);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
|
||||
// Cache not found
|
||||
return undefined;
|
||||
@@ -126490,7 +126565,9 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
}
|
||||
else {
|
||||
// warn on cache restore failure and continue build
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A read denied by policy (CacheReadDeniedError) is not an HttpClientError
|
||||
// so it falls here and is warned, treated as a cache miss.
|
||||
if (typedError instanceof lib_HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
@@ -126525,6 +126602,7 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
*/
|
||||
function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
return cache_awaiter(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) {
|
||||
var _a;
|
||||
// Override UploadOptions to force the use of Azure
|
||||
options = Object.assign(Object.assign({}, options), { useAzureSdk: true });
|
||||
restoreKeys = restoreKeys || [];
|
||||
@@ -126546,7 +126624,20 @@ function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
restoreKeys,
|
||||
version: getCacheVersion(paths, compressionMethod, enableCrossOsArchive)
|
||||
};
|
||||
const response = yield twirpClient.GetCacheEntryDownloadURL(request);
|
||||
let response;
|
||||
try {
|
||||
response = yield twirpClient.GetCacheEntryDownloadURL(request);
|
||||
}
|
||||
catch (error) {
|
||||
// The receiver returns twirp PermissionDenied (403) when the run's token
|
||||
// has no readable cache scopes. The client wraps that 403, so the stable
|
||||
// prefix is embedded in the message rather than leading it.
|
||||
const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
|
||||
if (errorMessage.includes(CACHE_READ_DENIED_PREFIX)) {
|
||||
throw new CacheReadDeniedError(errorMessage);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (!response.ok) {
|
||||
core_debug(`Cache not found for version ${request.version} of keys: ${keys.join(', ')}`);
|
||||
return undefined;
|
||||
@@ -126581,8 +126672,10 @@ function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) {
|
||||
throw error;
|
||||
}
|
||||
else {
|
||||
// Supress all non-validation cache related errors because caching should be optional
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Suppress all non-validation cache related errors because caching should be optional
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A read denied by policy (CacheReadDeniedError) is not an HttpClientError
|
||||
// so it falls here and is warned, treated as a cache miss.
|
||||
if (typedError instanceof lib_HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
@@ -126621,6 +126714,12 @@ function cache_saveCache(paths_1, key_1, options_1) {
|
||||
core.debug(`Cache service version: ${cacheServiceVersion}`);
|
||||
checkPaths(paths);
|
||||
checkKey(key);
|
||||
const cacheMode = getCacheMode();
|
||||
if (!isCacheWritable(cacheMode)) {
|
||||
core.info(`Cache save skipped: the effective cache-mode '${cacheMode}' does not permit writes.`);
|
||||
core.debug(`Skipped save for paths [${paths.join(', ')}] with key '${key}'.`);
|
||||
return -1;
|
||||
}
|
||||
switch (cacheServiceVersion) {
|
||||
case 'v2':
|
||||
return yield saveCacheV2(paths, key, options, enableCrossOsArchive);
|
||||
@@ -126698,17 +126797,14 @@ function saveCacheV1(paths_1, key_1, options_1) {
|
||||
if (typedError.name === ValidationError.name) {
|
||||
throw error;
|
||||
}
|
||||
else if (typedError.name === CacheWriteDeniedError.name) {
|
||||
// Cache write was denied by policy (read-only token). Surface to the
|
||||
// customer at warning level so it is visible in the workflow log
|
||||
// without failing the run.
|
||||
core.warning(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else if (typedError.name === ReserveCacheError.name) {
|
||||
core.info(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else {
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A write denied by policy (CacheWriteDeniedError) is not an
|
||||
// HttpClientError and its name does not match the ReserveCacheError arm,
|
||||
// so it falls here and is warned without failing the run.
|
||||
if (typedError instanceof HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
@@ -126819,12 +126915,6 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
||||
if (typedError.name === ValidationError.name) {
|
||||
throw error;
|
||||
}
|
||||
else if (typedError.name === CacheWriteDeniedError.name) {
|
||||
// Cache write was denied by policy (read-only token). Surface to the
|
||||
// customer at warning level so it is visible in the workflow log
|
||||
// without failing the run.
|
||||
core.warning(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else if (typedError.name === ReserveCacheError.name) {
|
||||
core.info(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
@@ -126832,7 +126922,10 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
||||
core.warning(typedError.message);
|
||||
}
|
||||
else {
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
// Log server errors (5xx) as errors, all other errors as warnings.
|
||||
// A write denied by policy (CacheWriteDeniedError) is not an
|
||||
// HttpClientError and its name does not match the ReserveCacheError arm,
|
||||
// so it falls here and is warned without failing the run.
|
||||
if (typedError instanceof HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500) {
|
||||
@@ -127311,12 +127404,25 @@ function generate(id, username, password, gpgPassphrase) {
|
||||
}
|
||||
}
|
||||
};
|
||||
if (gpgPassphrase) {
|
||||
const gpgServer = {
|
||||
id: 'gpg.passphrase',
|
||||
passphrase: `\${env.${gpgPassphrase}}`
|
||||
// The maven-gpg-plugin reads the passphrase from the environment variable
|
||||
// named by the `gpg.passphraseEnvName` property (default MAVEN_GPG_PASSPHRASE).
|
||||
// Only configure it when the requested env var name differs from that default;
|
||||
// otherwise the plugin already reads the right variable and no extra settings
|
||||
// are needed. Writing `gpg.passphrase` to settings.xml is deprecated and fails
|
||||
// when the plugin's `bestPractices` mode is enabled.
|
||||
if (gpgPassphrase &&
|
||||
gpgPassphrase !== MAVEN_GPG_PASSPHRASE_DEFAULT_ENV) {
|
||||
xmlObj.settings.profiles = {
|
||||
profile: {
|
||||
id: GPG_PASSPHRASE_PROFILE_ID,
|
||||
properties: {
|
||||
'gpg.passphraseEnvName': gpgPassphrase
|
||||
}
|
||||
}
|
||||
};
|
||||
xmlObj.settings.activeProfiles = {
|
||||
activeProfile: GPG_PASSPHRASE_PROFILE_ID
|
||||
};
|
||||
xmlObj.settings.servers.server.push(gpgServer);
|
||||
}
|
||||
return (0,lib/* create */.vt)(xmlObj).end({
|
||||
headless: true,
|
||||
@@ -130887,23 +130993,28 @@ const CACHE_KEY_PREFIX = 'setup-java';
|
||||
const supportedPackageManager = [
|
||||
{
|
||||
id: 'maven',
|
||||
path: [
|
||||
(0,external_path_.join)(external_os_default().homedir(), '.m2', 'repository'),
|
||||
(0,external_path_.join)(external_os_default().homedir(), '.m2', 'wrapper', 'dists')
|
||||
],
|
||||
path: [(0,external_path_.join)(external_os_default().homedir(), '.m2', 'repository')],
|
||||
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---maven
|
||||
pattern: [
|
||||
'**/pom.xml',
|
||||
'**/.mvn/wrapper/maven-wrapper.properties',
|
||||
'**/.mvn/extensions.xml'
|
||||
],
|
||||
// The Maven wrapper distribution only depends on the wrapper properties,
|
||||
// which change very rarely, so it is cached separately from the local
|
||||
// repository. This keeps it available across the frequent pom.xml changes
|
||||
// that rotate the main cache key. See issue #1095.
|
||||
additionalCaches: [
|
||||
{
|
||||
name: 'maven-wrapper',
|
||||
path: [(0,external_path_.join)(external_os_default().homedir(), '.m2', 'wrapper', 'dists')],
|
||||
pattern: ['**/.mvn/wrapper/maven-wrapper.properties']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'gradle',
|
||||
path: [
|
||||
(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'caches'),
|
||||
(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'wrapper')
|
||||
],
|
||||
path: [(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'caches')],
|
||||
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle
|
||||
pattern: [
|
||||
'**/*.gradle*',
|
||||
@@ -130912,6 +131023,17 @@ const supportedPackageManager = [
|
||||
'buildSrc/**/Dependencies.kt',
|
||||
'gradle/*.versions.toml',
|
||||
'**/versions.properties'
|
||||
],
|
||||
// The Gradle wrapper distribution only depends on the wrapper properties,
|
||||
// which change very rarely, so it is cached separately from the Gradle
|
||||
// caches. This keeps it available across the frequent *.gradle* changes
|
||||
// that rotate the main cache key. See issue #269.
|
||||
additionalCaches: [
|
||||
{
|
||||
name: 'gradle-wrapper',
|
||||
path: [(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'wrapper')],
|
||||
pattern: ['**/gradle-wrapper.properties']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -130947,6 +131069,19 @@ function findPackageManager(id) {
|
||||
}
|
||||
return packageManager;
|
||||
}
|
||||
/**
|
||||
* State keys used to carry an additional cache's restore-time information over
|
||||
* to the post (save) action, scoped by the additional cache name.
|
||||
*/
|
||||
function additionalCachePrimaryKeyState(name) {
|
||||
return `${STATE_CACHE_PRIMARY_KEY}-${name}`;
|
||||
}
|
||||
function additionalCacheMatchedKeyState(name) {
|
||||
return `${CACHE_MATCHED_KEY}-${name}`;
|
||||
}
|
||||
function buildCacheKey(id, fileHash) {
|
||||
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-${id}-${fileHash}`;
|
||||
}
|
||||
/**
|
||||
* A function that generates a cache key to use.
|
||||
* Format of the generated key will be "${{ platform }}-${{ id }}-${{ fileHash }}"".
|
||||
@@ -130960,7 +131095,19 @@ async function computeCacheKey(packageManager, cacheDependencyPath) {
|
||||
if (!fileHash) {
|
||||
throw new Error(`No file in ${process.cwd()} matched to [${pattern}], make sure you have checked out the target repository`);
|
||||
}
|
||||
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-${packageManager.id}-${fileHash}`;
|
||||
return buildCacheKey(packageManager.id, fileHash);
|
||||
}
|
||||
/**
|
||||
* Computes the cache key for an additional cache. Unlike {@link computeCacheKey}
|
||||
* this returns undefined (instead of throwing) when no file matches the pattern,
|
||||
* because additional caches are optional features that many projects do not use.
|
||||
*/
|
||||
async function computeAdditionalCacheKey(additionalCache) {
|
||||
const fileHash = await lib_glob_hashFiles(additionalCache.pattern.join('\n'));
|
||||
if (!fileHash) {
|
||||
return undefined;
|
||||
}
|
||||
return buildCacheKey(additionalCache.name, fileHash);
|
||||
}
|
||||
/**
|
||||
* Restore the dependency cache
|
||||
@@ -130984,6 +131131,29 @@ async function restore(id, cacheDependencyPath) {
|
||||
setOutput('cache-hit', false);
|
||||
info(`${packageManager.id} cache is not found`);
|
||||
}
|
||||
for (const additionalCache of packageManager.additionalCaches ?? []) {
|
||||
await restoreAdditionalCache(additionalCache);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Restore an additional cache (e.g. a build-tool wrapper distribution) that is
|
||||
* keyed independently of the main dependency cache so that it survives changes
|
||||
* to volatile dependency files. Skips silently when the project does not use
|
||||
* the corresponding feature.
|
||||
*/
|
||||
async function restoreAdditionalCache(additionalCache) {
|
||||
const primaryKey = await computeAdditionalCacheKey(additionalCache);
|
||||
if (!primaryKey) {
|
||||
core_debug(`No file matched [${additionalCache.pattern}] for the ${additionalCache.name} cache, skipping.`);
|
||||
return;
|
||||
}
|
||||
core_debug(`${additionalCache.name} primary key is ${primaryKey}`);
|
||||
saveState(additionalCachePrimaryKeyState(additionalCache.name), primaryKey);
|
||||
const matchedKey = await restoreCache(additionalCache.path, primaryKey);
|
||||
if (matchedKey) {
|
||||
saveState(additionalCacheMatchedKeyState(additionalCache.name), matchedKey);
|
||||
info(`${additionalCache.name} cache restored from key: ${matchedKey}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Save the dependency cache
|
||||
@@ -130994,6 +131164,9 @@ async function save(id) {
|
||||
const matchedKey = core.getState(CACHE_MATCHED_KEY);
|
||||
// Inputs are re-evaluated before the post action, so we want the original key used for restore
|
||||
const primaryKey = core.getState(STATE_CACHE_PRIMARY_KEY);
|
||||
for (const additionalCache of packageManager.additionalCaches ?? []) {
|
||||
await saveAdditionalCache(packageManager, additionalCache);
|
||||
}
|
||||
if (!primaryKey) {
|
||||
core.warning('Error retrieving key from state.');
|
||||
return;
|
||||
@@ -131028,6 +131201,50 @@ async function save(id) {
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Save an additional cache under its own key. Skips when no key was recorded at
|
||||
* restore time (feature unused) or when the exact key was already restored.
|
||||
*/
|
||||
async function saveAdditionalCache(packageManager, additionalCache) {
|
||||
const primaryKey = core.getState(additionalCachePrimaryKeyState(additionalCache.name));
|
||||
const matchedKey = core.getState(additionalCacheMatchedKeyState(additionalCache.name));
|
||||
if (!primaryKey) {
|
||||
// The feature is not used by this project, nothing to save.
|
||||
core.debug(`No primary key for the ${additionalCache.name} cache, not saving cache.`);
|
||||
return;
|
||||
}
|
||||
else if (matchedKey === primaryKey) {
|
||||
core.info(`Cache hit occurred on the ${additionalCache.name} primary key ${primaryKey}, not saving cache.`);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const cacheId = await cache.saveCache(additionalCache.path, primaryKey);
|
||||
if (cacheId === -1) {
|
||||
core.debug(`${additionalCache.name} cache was not saved for the key: ${primaryKey}`);
|
||||
return;
|
||||
}
|
||||
core.info(`${additionalCache.name} cache saved with the key: ${primaryKey}`);
|
||||
}
|
||||
catch (error) {
|
||||
const err = error;
|
||||
if (err.name === cache.ValidationError.name) {
|
||||
// The cache paths did not resolve, e.g. the wrapper distribution was
|
||||
// never downloaded because a system build tool was used or the download
|
||||
// failed. Optional wrapper caches must not fail the post step, so skip.
|
||||
core.debug(`${additionalCache.name} cache paths do not exist, not saving cache: ${err.message}`);
|
||||
return;
|
||||
}
|
||||
if (err.name === cache.ReserveCacheError.name) {
|
||||
core.info(err.message);
|
||||
}
|
||||
else {
|
||||
if (isProbablyGradleDaemonProblem(packageManager, err)) {
|
||||
core.warning('Failed to save Gradle cache on Windows. If tar.exe reported "Permission denied", try to run Gradle with `--no-daemon` option. Refer to https://github.com/actions/cache/issues/454 for details.');
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param packageManager the specified package manager by user
|
||||
* @param error the error thrown by the saveCache
|
||||
@@ -133772,6 +133989,19 @@ function configureMavenArgs() {
|
||||
`Set '${INPUT_SHOW_DOWNLOAD_PROGRESS}: true' to keep the download progress output.`);
|
||||
}
|
||||
|
||||
;// CONCATENATED MODULE: ./src/problem-matcher.ts
|
||||
|
||||
|
||||
|
||||
function configureProblemMatcher(matcherPath) {
|
||||
const problemMatcherEnabled = util_getBooleanInput(INPUT_PROBLEM_MATCHER, true);
|
||||
if (!problemMatcherEnabled) {
|
||||
core_debug('Java problem matcher is disabled');
|
||||
return;
|
||||
}
|
||||
info(`##[add-matcher]${matcherPath}`);
|
||||
}
|
||||
|
||||
;// CONCATENATED MODULE: ./src/setup-java.ts
|
||||
|
||||
|
||||
@@ -133784,6 +134014,7 @@ function configureMavenArgs() {
|
||||
|
||||
|
||||
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const versions = getMultilineInput(INPUT_JAVA_VERSION);
|
||||
@@ -133857,7 +134088,7 @@ async function run() {
|
||||
}
|
||||
endGroup();
|
||||
const matchersPath = external_path_.join(external_path_.dirname((0,external_url_.fileURLToPath)(import.meta.url)), '..', '..', '.github');
|
||||
info(`##[add-matcher]${external_path_.join(matchersPath, 'java.json')}`);
|
||||
configureProblemMatcher(external_path_.join(matchersPath, 'java.json'));
|
||||
await configureAuthentication();
|
||||
configureMavenArgs();
|
||||
if (cache && isCacheFeatureAvailable()) {
|
||||
|
||||
+394
-354
File diff suppressed because it is too large
Load Diff
+16
-16
@@ -4,13 +4,13 @@ The major breaking change in V2 is the new mandatory `distribution` input. This
|
||||
Use the `zulu` keyword if you would like to continue using the same distribution as in V1.
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: '11'
|
||||
java-package: jdk # optional (jdk or jre) - defaults to jdk
|
||||
- run: java -cp java HelloWorldApp
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: '11'
|
||||
java-package: jdk # optional (jdk or jre) - defaults to jdk
|
||||
- run: java -cp java HelloWorldApp
|
||||
```
|
||||
|
||||
**General recommendation** — configure CI with the same distribution that is used on your local dev machine.
|
||||
@@ -19,15 +19,15 @@ steps:
|
||||
Since the `distribution` input is required in V2, you should specify it using `jdkfile` to continue installing Java from a local file on the runner
|
||||
```yaml
|
||||
steps:
|
||||
- run: |
|
||||
download_url="https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.10_9.tar.gz"
|
||||
wget -O $RUNNER_TEMP/java_package.tar.gz $download_url
|
||||
- uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'jdkfile'
|
||||
jdkFile: ${{ runner.temp }}/java_package.tar.gz
|
||||
java-version: '11.0.0'
|
||||
architecture: x64
|
||||
- run: |
|
||||
download_url="https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.10_9.tar.gz"
|
||||
wget -O $RUNNER_TEMP/java_package.tar.gz $download_url
|
||||
- uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'jdkfile'
|
||||
jdkFile: ${{ runner.temp }}/java_package.tar.gz
|
||||
java-version: '11.0.0'
|
||||
architecture: x64
|
||||
```
|
||||
|
||||
## Dropping legacy Java version syntax 1.x
|
||||
|
||||
Generated
+4
-34
@@ -9,7 +9,7 @@
|
||||
"version": "6.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^6.1.0",
|
||||
"@actions/cache": "^6.2.0",
|
||||
"@actions/core": "^3.0.1",
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/glob": "^0.7.0",
|
||||
@@ -44,9 +44,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/cache": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-6.1.0.tgz",
|
||||
"integrity": "sha512-LVqybSbzhBp2uAETOQ3HnVjXA4AcjavgMH+LCr+cjgO+PZfciv/1QAgoW+esXBaAhvDid+vXeV70GGJpAh4V5Q==",
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-6.2.0.tgz",
|
||||
"integrity": "sha512-Nv0xWRmbxfDbAn/70flO/F6tj2Nv4XTYMAsQHiDFSojCDfso/Zni+fRKa14ToI9hnmOW/rQcY1WYb6wsM7Pgwg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^3.0.1",
|
||||
@@ -2365,9 +2365,6 @@
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2382,9 +2379,6 @@
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2399,9 +2393,6 @@
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2416,9 +2407,6 @@
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2433,9 +2421,6 @@
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2450,9 +2435,6 @@
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2467,9 +2449,6 @@
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2484,9 +2463,6 @@
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2501,9 +2477,6 @@
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2518,9 +2491,6 @@
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@
|
||||
"author": "GitHub",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^6.1.0",
|
||||
"@actions/cache": "^6.2.0",
|
||||
"@actions/core": "^3.0.1",
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/glob": "^0.7.0",
|
||||
|
||||
+20
-5
@@ -93,12 +93,27 @@ export function generate(
|
||||
}
|
||||
};
|
||||
|
||||
if (gpgPassphrase) {
|
||||
const gpgServer = {
|
||||
id: 'gpg.passphrase',
|
||||
passphrase: `\${env.${gpgPassphrase}}`
|
||||
// The maven-gpg-plugin reads the passphrase from the environment variable
|
||||
// named by the `gpg.passphraseEnvName` property (default MAVEN_GPG_PASSPHRASE).
|
||||
// Only configure it when the requested env var name differs from that default;
|
||||
// otherwise the plugin already reads the right variable and no extra settings
|
||||
// are needed. Writing `gpg.passphrase` to settings.xml is deprecated and fails
|
||||
// when the plugin's `bestPractices` mode is enabled.
|
||||
if (
|
||||
gpgPassphrase &&
|
||||
gpgPassphrase !== constants.MAVEN_GPG_PASSPHRASE_DEFAULT_ENV
|
||||
) {
|
||||
xmlObj.settings.profiles = {
|
||||
profile: {
|
||||
id: constants.GPG_PASSPHRASE_PROFILE_ID,
|
||||
properties: {
|
||||
'gpg.passphraseEnvName': gpgPassphrase
|
||||
}
|
||||
}
|
||||
};
|
||||
xmlObj.settings.activeProfiles = {
|
||||
activeProfile: constants.GPG_PASSPHRASE_PROFILE_ID
|
||||
};
|
||||
xmlObj.settings.servers.server.push(gpgServer);
|
||||
}
|
||||
|
||||
return xmlCreate(xmlObj).end({
|
||||
|
||||
+185
-9
@@ -12,6 +12,30 @@ const STATE_CACHE_PRIMARY_KEY = 'cache-primary-key';
|
||||
const CACHE_MATCHED_KEY = 'cache-matched-key';
|
||||
const CACHE_KEY_PREFIX = 'setup-java';
|
||||
|
||||
/**
|
||||
* An additional cache entry that is restored and saved independently of the
|
||||
* main dependency cache. Used for build-tool wrapper distributions that rarely
|
||||
* change (e.g. the Maven wrapper distribution) so that they are not evicted
|
||||
* every time a volatile dependency file such as pom.xml changes. See
|
||||
* https://github.com/actions/setup-java/issues/1095.
|
||||
*/
|
||||
interface AdditionalCache {
|
||||
/**
|
||||
* Short identifier for the cache, used to build its cache key and to scope
|
||||
* the state keys that carry information from restore to save.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Paths that make up this cache entry.
|
||||
*/
|
||||
path: string[];
|
||||
/**
|
||||
* Glob patterns whose hash forms the cache key. If no file matches, the
|
||||
* cache is skipped silently (the project simply does not use this feature).
|
||||
*/
|
||||
pattern: string[];
|
||||
}
|
||||
|
||||
interface PackageManager {
|
||||
id: 'maven' | 'gradle' | 'sbt';
|
||||
/**
|
||||
@@ -19,27 +43,36 @@ interface PackageManager {
|
||||
*/
|
||||
path: string[];
|
||||
pattern: string[];
|
||||
/**
|
||||
* Additional caches keyed independently of the main dependency cache.
|
||||
*/
|
||||
additionalCaches?: AdditionalCache[];
|
||||
}
|
||||
const supportedPackageManager: PackageManager[] = [
|
||||
{
|
||||
id: 'maven',
|
||||
path: [
|
||||
join(os.homedir(), '.m2', 'repository'),
|
||||
join(os.homedir(), '.m2', 'wrapper', 'dists')
|
||||
],
|
||||
path: [join(os.homedir(), '.m2', 'repository')],
|
||||
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---maven
|
||||
pattern: [
|
||||
'**/pom.xml',
|
||||
'**/.mvn/wrapper/maven-wrapper.properties',
|
||||
'**/.mvn/extensions.xml'
|
||||
],
|
||||
// The Maven wrapper distribution only depends on the wrapper properties,
|
||||
// which change very rarely, so it is cached separately from the local
|
||||
// repository. This keeps it available across the frequent pom.xml changes
|
||||
// that rotate the main cache key. See issue #1095.
|
||||
additionalCaches: [
|
||||
{
|
||||
name: 'maven-wrapper',
|
||||
path: [join(os.homedir(), '.m2', 'wrapper', 'dists')],
|
||||
pattern: ['**/.mvn/wrapper/maven-wrapper.properties']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'gradle',
|
||||
path: [
|
||||
join(os.homedir(), '.gradle', 'caches'),
|
||||
join(os.homedir(), '.gradle', 'wrapper')
|
||||
],
|
||||
path: [join(os.homedir(), '.gradle', 'caches')],
|
||||
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle
|
||||
pattern: [
|
||||
'**/*.gradle*',
|
||||
@@ -48,6 +81,17 @@ const supportedPackageManager: PackageManager[] = [
|
||||
'buildSrc/**/Dependencies.kt',
|
||||
'gradle/*.versions.toml',
|
||||
'**/versions.properties'
|
||||
],
|
||||
// The Gradle wrapper distribution only depends on the wrapper properties,
|
||||
// which change very rarely, so it is cached separately from the Gradle
|
||||
// caches. This keeps it available across the frequent *.gradle* changes
|
||||
// that rotate the main cache key. See issue #269.
|
||||
additionalCaches: [
|
||||
{
|
||||
name: 'gradle-wrapper',
|
||||
path: [join(os.homedir(), '.gradle', 'wrapper')],
|
||||
pattern: ['**/gradle-wrapper.properties']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -87,6 +131,21 @@ function findPackageManager(id: string): PackageManager {
|
||||
return packageManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* State keys used to carry an additional cache's restore-time information over
|
||||
* to the post (save) action, scoped by the additional cache name.
|
||||
*/
|
||||
function additionalCachePrimaryKeyState(name: string): string {
|
||||
return `${STATE_CACHE_PRIMARY_KEY}-${name}`;
|
||||
}
|
||||
function additionalCacheMatchedKeyState(name: string): string {
|
||||
return `${CACHE_MATCHED_KEY}-${name}`;
|
||||
}
|
||||
|
||||
function buildCacheKey(id: string, fileHash: string): string {
|
||||
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-${id}-${fileHash}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that generates a cache key to use.
|
||||
* Format of the generated key will be "${{ platform }}-${{ id }}-${{ fileHash }}"".
|
||||
@@ -105,7 +164,22 @@ async function computeCacheKey(
|
||||
`No file in ${process.cwd()} matched to [${pattern}], make sure you have checked out the target repository`
|
||||
);
|
||||
}
|
||||
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-${packageManager.id}-${fileHash}`;
|
||||
return buildCacheKey(packageManager.id, fileHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the cache key for an additional cache. Unlike {@link computeCacheKey}
|
||||
* this returns undefined (instead of throwing) when no file matches the pattern,
|
||||
* because additional caches are optional features that many projects do not use.
|
||||
*/
|
||||
async function computeAdditionalCacheKey(
|
||||
additionalCache: AdditionalCache
|
||||
): Promise<string | undefined> {
|
||||
const fileHash = await glob.hashFiles(additionalCache.pattern.join('\n'));
|
||||
if (!fileHash) {
|
||||
return undefined;
|
||||
}
|
||||
return buildCacheKey(additionalCache.name, fileHash);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,6 +204,40 @@ export async function restore(id: string, cacheDependencyPath: string) {
|
||||
core.setOutput('cache-hit', false);
|
||||
core.info(`${packageManager.id} cache is not found`);
|
||||
}
|
||||
|
||||
for (const additionalCache of packageManager.additionalCaches ?? []) {
|
||||
await restoreAdditionalCache(additionalCache);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore an additional cache (e.g. a build-tool wrapper distribution) that is
|
||||
* keyed independently of the main dependency cache so that it survives changes
|
||||
* to volatile dependency files. Skips silently when the project does not use
|
||||
* the corresponding feature.
|
||||
*/
|
||||
async function restoreAdditionalCache(additionalCache: AdditionalCache) {
|
||||
const primaryKey = await computeAdditionalCacheKey(additionalCache);
|
||||
if (!primaryKey) {
|
||||
core.debug(
|
||||
`No file matched [${additionalCache.pattern}] for the ${additionalCache.name} cache, skipping.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
core.debug(`${additionalCache.name} primary key is ${primaryKey}`);
|
||||
core.saveState(
|
||||
additionalCachePrimaryKeyState(additionalCache.name),
|
||||
primaryKey
|
||||
);
|
||||
|
||||
const matchedKey = await cache.restoreCache(additionalCache.path, primaryKey);
|
||||
if (matchedKey) {
|
||||
core.saveState(
|
||||
additionalCacheMatchedKeyState(additionalCache.name),
|
||||
matchedKey
|
||||
);
|
||||
core.info(`${additionalCache.name} cache restored from key: ${matchedKey}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,6 +251,10 @@ export async function save(id: string) {
|
||||
// Inputs are re-evaluated before the post action, so we want the original key used for restore
|
||||
const primaryKey = core.getState(STATE_CACHE_PRIMARY_KEY);
|
||||
|
||||
for (const additionalCache of packageManager.additionalCaches ?? []) {
|
||||
await saveAdditionalCache(packageManager, additionalCache);
|
||||
}
|
||||
|
||||
if (!primaryKey) {
|
||||
core.warning('Error retrieving key from state.');
|
||||
return;
|
||||
@@ -180,6 +292,70 @@ export async function save(id: string) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an additional cache under its own key. Skips when no key was recorded at
|
||||
* restore time (feature unused) or when the exact key was already restored.
|
||||
*/
|
||||
async function saveAdditionalCache(
|
||||
packageManager: PackageManager,
|
||||
additionalCache: AdditionalCache
|
||||
) {
|
||||
const primaryKey = core.getState(
|
||||
additionalCachePrimaryKeyState(additionalCache.name)
|
||||
);
|
||||
const matchedKey = core.getState(
|
||||
additionalCacheMatchedKeyState(additionalCache.name)
|
||||
);
|
||||
|
||||
if (!primaryKey) {
|
||||
// The feature is not used by this project, nothing to save.
|
||||
core.debug(
|
||||
`No primary key for the ${additionalCache.name} cache, not saving cache.`
|
||||
);
|
||||
return;
|
||||
} else if (matchedKey === primaryKey) {
|
||||
core.info(
|
||||
`Cache hit occurred on the ${additionalCache.name} primary key ${primaryKey}, not saving cache.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const cacheId = await cache.saveCache(additionalCache.path, primaryKey);
|
||||
if (cacheId === -1) {
|
||||
core.debug(
|
||||
`${additionalCache.name} cache was not saved for the key: ${primaryKey}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
core.info(
|
||||
`${additionalCache.name} cache saved with the key: ${primaryKey}`
|
||||
);
|
||||
} catch (error) {
|
||||
const err = error as Error;
|
||||
|
||||
if (err.name === cache.ValidationError.name) {
|
||||
// The cache paths did not resolve, e.g. the wrapper distribution was
|
||||
// never downloaded because a system build tool was used or the download
|
||||
// failed. Optional wrapper caches must not fail the post step, so skip.
|
||||
core.debug(
|
||||
`${additionalCache.name} cache paths do not exist, not saving cache: ${err.message}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (err.name === cache.ReserveCacheError.name) {
|
||||
core.info(err.message);
|
||||
} else {
|
||||
if (isProbablyGradleDaemonProblem(packageManager, err)) {
|
||||
core.warning(
|
||||
'Failed to save Gradle cache on Windows. If tar.exe reported "Permission denied", try to run Gradle with `--no-daemon` option. Refer to https://github.com/actions/cache/issues/454 for details.'
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param packageManager the specified package manager by user
|
||||
* @param error the error thrown by the saveCache
|
||||
|
||||
@@ -8,6 +8,7 @@ export const INPUT_JDK_FILE = 'jdk-file';
|
||||
export const INPUT_JDK_FILE_DEPRECATED = 'jdkFile';
|
||||
export const INPUT_CHECK_LATEST = 'check-latest';
|
||||
export const INPUT_SET_DEFAULT = 'set-default';
|
||||
export const INPUT_PROBLEM_MATCHER = 'problem-matcher';
|
||||
export const INPUT_VERIFY_SIGNATURE = 'verify-signature';
|
||||
export const INPUT_VERIFY_SIGNATURE_PUBLIC_KEY = 'verify-signature-public-key';
|
||||
export const INPUT_SERVER_ID = 'server-id';
|
||||
@@ -21,6 +22,14 @@ export const INPUT_GPG_PASSPHRASE = 'gpg-passphrase';
|
||||
export const INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined;
|
||||
export const INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE';
|
||||
|
||||
// The default name of the environment variable the maven-gpg-plugin reads the
|
||||
// passphrase from (property `gpg.passphraseEnvName`). When the configured
|
||||
// passphrase env var name matches this, no extra configuration is required.
|
||||
export const MAVEN_GPG_PASSPHRASE_DEFAULT_ENV = 'MAVEN_GPG_PASSPHRASE';
|
||||
|
||||
// Id of the settings.xml profile used to set `gpg.passphraseEnvName`.
|
||||
export const GPG_PASSPHRASE_PROFILE_ID = 'setup-java-gpg';
|
||||
|
||||
export const INPUT_CACHE = 'cache';
|
||||
export const INPUT_CACHE_DEPENDENCY_PATH = 'cache-dependency-path';
|
||||
export const INPUT_JOB_STATUS = 'job-status';
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
import * as core from '@actions/core';
|
||||
import {INPUT_PROBLEM_MATCHER} from './constants.js';
|
||||
import {getBooleanInput} from './util.js';
|
||||
|
||||
export function configureProblemMatcher(matcherPath: string): void {
|
||||
const problemMatcherEnabled = getBooleanInput(INPUT_PROBLEM_MATCHER, true);
|
||||
|
||||
if (!problemMatcherEnabled) {
|
||||
core.debug('Java problem matcher is disabled');
|
||||
return;
|
||||
}
|
||||
|
||||
core.info(`##[add-matcher]${matcherPath}`);
|
||||
}
|
||||
+2
-1
@@ -14,6 +14,7 @@ import {fileURLToPath} from 'url';
|
||||
import {getJavaDistribution} from './distributions/distribution-factory.js';
|
||||
import {JavaInstallerOptions} from './distributions/base-models.js';
|
||||
import {configureMavenArgs} from './maven-args.js';
|
||||
import {configureProblemMatcher} from './problem-matcher.js';
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
@@ -120,7 +121,7 @@ async function run() {
|
||||
'..',
|
||||
'.github'
|
||||
);
|
||||
core.info(`##[add-matcher]${path.join(matchersPath, 'java.json')}`);
|
||||
configureProblemMatcher(path.join(matchersPath, 'java.json'));
|
||||
|
||||
await auth.configureAuthentication();
|
||||
configureMavenArgs();
|
||||
|
||||
Reference in New Issue
Block a user