Fix alpine failures by switching default back to only warn on verification failures. To prevent build failures due to missing GPG or rotated vendor keys. (#1262)

Also allow multiple GPG keys to be provided.

Co-authored-by: John <1615532+johnoliver@users.noreply.github.com>
This commit is contained in:
Bruno Borges
2026-09-03 13:27:24 -04:00
committed by GitHub
parent 4889c4aff5
commit 0781fc6af3
27 changed files with 575 additions and 136 deletions
+1 -1
View File
@@ -65,7 +65,7 @@ class LocalDistribution extends _base_installer_js__WEBPACK_IMPORTED_MODULE_3__/
architecture: this.architecture,
version: this.version,
source,
verification: getJdkVerificationIdentity(false),
verification: getJdkVerificationIdentity(false, false),
path: this.getJdkCachePath(this.version)
};
}
+31 -10
View File
@@ -42,6 +42,8 @@ Fa133tP85xzJEq1XeXm8WeLFo2wV
=rHCS
-----END PGP PUBLIC KEY BLOCK-----`;
// EXTERNAL MODULE: ./src/constants.ts
var constants = __webpack_require__(7242);
// EXTERNAL MODULE: ./node_modules/@actions/core/lib/core.js + 7 modules
var core = __webpack_require__(3838);
// EXTERNAL MODULE: ./node_modules/@actions/tool-cache/lib/tool-cache.js + 2 modules
@@ -62,6 +64,7 @@ var external_path_default = /*#__PURE__*/__webpack_require__.n(external_path_);
class MicrosoftDistributions extends base_installer/* JavaBase */.O {
constructor(installerOptions) {
super('Microsoft', installerOptions);
@@ -70,15 +73,23 @@ class MicrosoftDistributions extends base_installer/* JavaBase */.O {
core/* info */.pq(`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`);
let javaArchivePath = await this.downloadAndVerify(javaRelease);
if (this.verifySignature) {
if (!javaRelease.signatureUrl) {
throw new Error(`Input 'verify-signature' is enabled, but no signature URL was found for Microsoft Build of OpenJDK version ${javaRelease.version}.`);
}
core/* info */.pq(`Verifying Java package signature...`);
try {
await gpg/* verifyPackageSignature */.Yi(javaArchivePath, javaRelease.signatureUrl, this.verifySignaturePublicKey ?? MICROSOFT_PUBLIC_KEY);
if (!javaRelease.signatureUrl) {
throw new Error(`Input 'verify-signature' is enabled, but no signature URL was found for Microsoft Build of OpenJDK version ${javaRelease.version}.`);
}
core/* info */.pq(`Verifying Java package signature...`);
try {
await gpg/* verifyPackageSignature */.Yi(javaArchivePath, javaRelease.signatureUrl, this.verifySignaturePublicKey ?? MICROSOFT_PUBLIC_KEY);
}
catch (error) {
throw new Error(`Failed to verify signature for Microsoft Build of OpenJDK version ${javaRelease.version}. Signature URL: ${javaRelease.signatureUrl}. Error: ${error.message} ${constants/* SIGNATURE_VERIFICATION_FAILURE_HELP */.kQ}`, { cause: error });
}
}
catch (error) {
throw new Error(`Failed to verify signature for Microsoft Build of OpenJDK version ${javaRelease.version}. Signature URL: ${javaRelease.signatureUrl}. Error: ${error.message}`, { cause: error });
if (this.verifySignatureExplicitlyRequested) {
throw error;
}
core/* warning */.$e(error instanceof Error ? error.message : `Unknown error: ${error}`);
}
}
core/* info */.pq(`Extracting Java archive...`);
@@ -167,7 +178,8 @@ class MicrosoftDistributions extends base_installer/* JavaBase */.O {
/* harmony export */ Fh: () => (/* binding */ importKey),
/* harmony export */ Yi: () => (/* binding */ verifyPackageSignature),
/* harmony export */ mS: () => (/* binding */ removeGpgHome),
/* harmony export */ nY: () => (/* binding */ toGpgPath)
/* harmony export */ nY: () => (/* binding */ toGpgPath),
/* harmony export */ o6: () => (/* binding */ isGpgAvailable)
/* harmony export */ });
/* unused harmony export GPG_HOME_PREFIX */
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9896);
@@ -189,6 +201,9 @@ class MicrosoftDistributions extends base_installer/* JavaBase */.O {
const GPG_HOME_PREFIX = 'setup-java-gpg-';
const VERIFY_GPG_HOME_PREFIX = 'verify-signature-gpg-home-';
async function isGpgAvailable() {
return Boolean(await _actions_io__WEBPACK_IMPORTED_MODULE_3__/* .which */ .K7('gpg', false));
}
// Convert a Windows path (D:\a\_temp\...) to a POSIX path (/d/a/_temp/...).
// The Git-bundled GPG on Windows (MSYS2-based) uses POSIX path conventions
// internally. Passing Windows paths with backslashes can cause fatal GPG errors
@@ -272,15 +287,21 @@ async function verifyPackageSignature(archivePath, signatureUrl, publicKeyConten
throw new Error(`Failed to create temporary GPG home directory for signature verification: ${error.message}`, { cause: error });
}
try {
const publicKeyFile = path__WEBPACK_IMPORTED_MODULE_1__.join(gpgHome, 'public-key.asc');
fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync(publicKeyFile, publicKeyContent, { encoding: 'utf-8' });
const publicKeys = Array.isArray(publicKeyContent)
? publicKeyContent
: [publicKeyContent];
const publicKeyFiles = publicKeys.map((publicKey, index) => {
const publicKeyFile = path__WEBPACK_IMPORTED_MODULE_1__.join(gpgHome, `public-key-${index}.asc`);
fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync(publicKeyFile, publicKey, { encoding: 'utf-8' });
return toGpgPath(publicKeyFile);
});
const options = { silent: true };
await _actions_exec__WEBPACK_IMPORTED_MODULE_4__/* .exec */ .m('gpg', [
'--homedir',
toGpgPath(gpgHome),
'--batch',
'--import',
toGpgPath(publicKeyFile)
...publicKeyFiles
], options);
await _actions_exec__WEBPACK_IMPORTED_MODULE_4__/* .exec */ .m('gpg', [
'--homedir',
+4 -1
View File
@@ -226,6 +226,7 @@ class JavaBase {
floatingVersionVerified = false;
setDefault;
verifySignature;
verifySignatureExplicitlyRequested;
verifySignaturePublicKey;
constructor(distribution, installerOptions) {
this.distribution = distribution;
@@ -246,6 +247,8 @@ class JavaBase {
: true;
this.verifySignature =
installerOptions.verifySignature ?? this.supportsSignatureVerification();
this.verifySignatureExplicitlyRequested =
installerOptions.verifySignature === true;
this.verifySignaturePublicKey = installerOptions.verifySignaturePublicKey;
}
async downloadAndVerify(javaRelease) {
@@ -481,7 +484,7 @@ class JavaBase {
architecture: this.architecture,
version: javaRelease.version,
source: this.getJdkReleaseIdentity(javaRelease),
verification: getJdkVerificationIdentity(this.verifySignature, this.verifySignaturePublicKey),
verification: getJdkVerificationIdentity(this.verifySignature, this.verifySignatureExplicitlyRequested, this.verifySignaturePublicKey),
path: this.getJdkCachePath(javaRelease.version)
};
}
+37 -10
View File
@@ -159,15 +159,32 @@ class TemurinDistribution extends base_installer/* JavaBase */.O {
async downloadPackage(release) {
const archivePath = await this.downloadAndVerify(release);
if (this.verifySignature) {
if (!release.signatureUrl) {
throw new Error(`Input 'verify-signature' is enabled, but no signature URL was found for Temurin version ${release.version}.`);
}
core/* info */.pq(`Verifying Java package signature...`);
try {
await gpg/* verifyPackageSignature */.Yi(archivePath, release.signatureUrl, this.verifySignaturePublicKey ?? ADOPTIUM_PUBLIC_KEY);
if (!(await gpg/* isGpgAvailable */.o6())) {
throw new Error("Input 'verify-signature' is enabled, but gpg is not available.");
}
if (!release.signatureUrl) {
throw new Error(`Input 'verify-signature' is enabled, but no signature URL was found for Temurin version ${release.version}.`);
}
core/* info */.pq(`Verifying Java package signature...`);
try {
await gpg/* verifyPackageSignature */.Yi(archivePath, release.signatureUrl, this.verifySignaturePublicKey ?? ADOPTIUM_PUBLIC_KEY);
}
catch (error) {
const verificationError = new Error(`Failed to verify signature for Temurin version ${release.version} from ${release.signatureUrl}: ${error.message} ${constants/* SIGNATURE_VERIFICATION_FAILURE_HELP */.kQ}`, { cause: error });
if (this.verifySignatureExplicitlyRequested) {
throw verificationError;
}
else {
core/* warning */.$e(verificationError.message);
}
}
}
catch (error) {
throw new Error(`Failed to verify signature for Temurin version ${release.version} from ${release.signatureUrl}: ${error.message}`, { cause: error });
if (this.verifySignatureExplicitlyRequested) {
throw error;
}
core/* warning */.$e(error instanceof Error ? error.message : `Unknown error: ${error}`);
}
}
return archivePath;
@@ -273,7 +290,8 @@ class TemurinDistribution extends base_installer/* JavaBase */.O {
/* harmony export */ Fh: () => (/* binding */ importKey),
/* harmony export */ Yi: () => (/* binding */ verifyPackageSignature),
/* harmony export */ mS: () => (/* binding */ removeGpgHome),
/* harmony export */ nY: () => (/* binding */ toGpgPath)
/* harmony export */ nY: () => (/* binding */ toGpgPath),
/* harmony export */ o6: () => (/* binding */ isGpgAvailable)
/* harmony export */ });
/* unused harmony export GPG_HOME_PREFIX */
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9896);
@@ -295,6 +313,9 @@ class TemurinDistribution extends base_installer/* JavaBase */.O {
const GPG_HOME_PREFIX = 'setup-java-gpg-';
const VERIFY_GPG_HOME_PREFIX = 'verify-signature-gpg-home-';
async function isGpgAvailable() {
return Boolean(await _actions_io__WEBPACK_IMPORTED_MODULE_3__/* .which */ .K7('gpg', false));
}
// Convert a Windows path (D:\a\_temp\...) to a POSIX path (/d/a/_temp/...).
// The Git-bundled GPG on Windows (MSYS2-based) uses POSIX path conventions
// internally. Passing Windows paths with backslashes can cause fatal GPG errors
@@ -378,15 +399,21 @@ async function verifyPackageSignature(archivePath, signatureUrl, publicKeyConten
throw new Error(`Failed to create temporary GPG home directory for signature verification: ${error.message}`, { cause: error });
}
try {
const publicKeyFile = path__WEBPACK_IMPORTED_MODULE_1__.join(gpgHome, 'public-key.asc');
fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync(publicKeyFile, publicKeyContent, { encoding: 'utf-8' });
const publicKeys = Array.isArray(publicKeyContent)
? publicKeyContent
: [publicKeyContent];
const publicKeyFiles = publicKeys.map((publicKey, index) => {
const publicKeyFile = path__WEBPACK_IMPORTED_MODULE_1__.join(gpgHome, `public-key-${index}.asc`);
fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync(publicKeyFile, publicKey, { encoding: 'utf-8' });
return toGpgPath(publicKeyFile);
});
const options = { silent: true };
await _actions_exec__WEBPACK_IMPORTED_MODULE_4__/* .exec */ .m('gpg', [
'--homedir',
toGpgPath(gpgHome),
'--batch',
'--import',
toGpgPath(publicKeyFile)
...publicKeyFiles
], options);
await _actions_exec__WEBPACK_IMPORTED_MODULE_4__/* .exec */ .m('gpg', [
'--homedir',
+15 -6
View File
@@ -127,16 +127,25 @@ function getInstallationIdentity(jdkPath, architecture) {
return undefined;
}
}
function getJdkVerificationIdentity(verifySignature, publicKey) {
function getJdkVerificationIdentity(verifySignature, enforceSignatureVerification, publicKey) {
if (!verifySignature) {
return 'unverified';
return 'disabled';
}
const verificationPolicy = enforceSignatureVerification
? 'enforced'
: 'check-and-warn';
if (!publicKey) {
return 'verified:bundled';
return `${verificationPolicy}:bundled`;
}
const normalizedKey = publicKey.replace(/\r\n?/g, '\n').trim();
const fingerprint = (0,crypto__WEBPACK_IMPORTED_MODULE_0__.createHash)('sha256').update(normalizedKey).digest('hex');
return `verified:custom:sha256:${fingerprint}`;
const publicKeys = Array.isArray(publicKey) ? publicKey : [publicKey];
const normalizedKeys = publicKeys.map(key => key.replace(/\r\n?/g, '\n').trim());
const fingerprintSource = Array.isArray(publicKey)
? normalizedKeys.map(key => `${Buffer.byteLength(key)}:${key}`).join('')
: normalizedKeys[0];
const fingerprint = (0,crypto__WEBPACK_IMPORTED_MODULE_0__.createHash)('sha256')
.update(fingerprintSource)
.digest('hex');
return `${verificationPolicy}:custom:sha256:${fingerprint}`;
}
async function saveJdkCaches() {
const state = _actions_core__WEBPACK_IMPORTED_MODULE_4__/* .getState */ .Gu(STATE_JDK_CACHES);
+14 -4
View File
@@ -265,7 +265,8 @@ async function write(directory, settings, overwriteSettings) {
/* harmony export */ Fh: () => (/* binding */ importKey),
/* harmony export */ Yi: () => (/* binding */ verifyPackageSignature),
/* harmony export */ mS: () => (/* binding */ removeGpgHome),
/* harmony export */ nY: () => (/* binding */ toGpgPath)
/* harmony export */ nY: () => (/* binding */ toGpgPath),
/* harmony export */ o6: () => (/* binding */ isGpgAvailable)
/* harmony export */ });
/* unused harmony export GPG_HOME_PREFIX */
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9896);
@@ -287,6 +288,9 @@ async function write(directory, settings, overwriteSettings) {
const GPG_HOME_PREFIX = 'setup-java-gpg-';
const VERIFY_GPG_HOME_PREFIX = 'verify-signature-gpg-home-';
async function isGpgAvailable() {
return Boolean(await _actions_io__WEBPACK_IMPORTED_MODULE_3__/* .which */ .K7('gpg', false));
}
// Convert a Windows path (D:\a\_temp\...) to a POSIX path (/d/a/_temp/...).
// The Git-bundled GPG on Windows (MSYS2-based) uses POSIX path conventions
// internally. Passing Windows paths with backslashes can cause fatal GPG errors
@@ -370,15 +374,21 @@ async function verifyPackageSignature(archivePath, signatureUrl, publicKeyConten
throw new Error(`Failed to create temporary GPG home directory for signature verification: ${error.message}`, { cause: error });
}
try {
const publicKeyFile = path__WEBPACK_IMPORTED_MODULE_1__.join(gpgHome, 'public-key.asc');
fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync(publicKeyFile, publicKeyContent, { encoding: 'utf-8' });
const publicKeys = Array.isArray(publicKeyContent)
? publicKeyContent
: [publicKeyContent];
const publicKeyFiles = publicKeys.map((publicKey, index) => {
const publicKeyFile = path__WEBPACK_IMPORTED_MODULE_1__.join(gpgHome, `public-key-${index}.asc`);
fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync(publicKeyFile, publicKey, { encoding: 'utf-8' });
return toGpgPath(publicKeyFile);
});
const options = { silent: true };
await _actions_exec__WEBPACK_IMPORTED_MODULE_4__/* .exec */ .m('gpg', [
'--homedir',
toGpgPath(gpgHome),
'--batch',
'--import',
toGpgPath(publicKeyFile)
...publicKeyFiles
], options);
await _actions_exec__WEBPACK_IMPORTED_MODULE_4__/* .exec */ .m('gpg', [
'--homedir',
+4 -1
View File
@@ -30801,6 +30801,7 @@ module.exports = {
/* harmony export */ jv: () => (/* binding */ MAVEN_CENTRAL_REPOSITORY_URL),
/* harmony export */ kM: () => (/* binding */ INPUT_JDK_FILE),
/* harmony export */ kN: () => (/* binding */ MAVEN_NO_TRANSFER_PROGRESS_LONG_FLAG),
/* harmony export */ kQ: () => (/* binding */ SIGNATURE_VERIFICATION_FAILURE_HELP),
/* harmony export */ ko: () => (/* binding */ MAVEN_GPG_PASSPHRASE_DEFAULT_ENV),
/* harmony export */ m7: () => (/* binding */ INPUT_MVN_TOOLCHAIN_VENDOR),
/* harmony export */ nr: () => (/* binding */ INPUT_MVN_TOOLCHAIN_ID),
@@ -30821,7 +30822,7 @@ module.exports = {
/* harmony export */ xg: () => (/* binding */ MAVEN_CENTRAL_REPOSITORY_ID),
/* harmony export */ xp: () => (/* binding */ INPUT_DEFAULT_SERVER_PASSWORD)
/* harmony export */ });
/* unused harmony exports INPUT_CACHE_READ_ONLY, INPUT_JOB_STATUS */
/* unused harmony exports SIGNATURE_VERIFICATION_DOCUMENTATION_URL, INPUT_CACHE_READ_ONLY, INPUT_JOB_STATUS */
const MACOS_JAVA_CONTENT_POSTFIX = 'Contents/Home';
const INPUT_JAVA_VERSION = 'java-version';
const INPUT_JAVA_VERSION_FILE = 'java-version-file';
@@ -30836,6 +30837,8 @@ 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 SIGNATURE_VERIFICATION_DOCUMENTATION_URL = 'https://github.com/actions/setup-java#download-integrity-and-signatures';
const SIGNATURE_VERIFICATION_FAILURE_HELP = `If this is a legitimate vendor signing-key rotation, see ${SIGNATURE_VERIFICATION_DOCUMENTATION_URL} for instructions to configure the updated public key or temporarily disable signature verification.`;
const INPUT_MVN_SERVER_CREDENTIALS = 'mvn-server-credentials';
const INPUT_MVN_REPOSITORIES = 'mvn-repositories';
const INPUT_MVN_REPOSITORIES_INCLUDE_CENTRAL = 'mvn-repositories-include-central';