mirror of
https://github.com/actions/setup-java.git
synced 2026-08-18 11:42:51 +00:00
Add multiple Maven server credentials (#1239)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot App
parent
fb4abd7a70
commit
a42a52cfb5
@@ -170,6 +170,7 @@ steps:
|
||||
| `server-id` | Maven repository ID used in generated `settings.xml`. | `github` |
|
||||
| `server-username-env-var` | Environment variable name for Maven repository username. | `GITHUB_ACTOR` |
|
||||
| `server-password-env-var` | Environment variable name for Maven repository password or token. | `GITHUB_TOKEN` |
|
||||
| `mvn-server-credentials` | Multiline Maven server credentials in the format `server-id:USERNAME_ENV:PASSWORD_ENV`. Replaces the single server configured by the three inputs above when set. | |
|
||||
| `settings-path` | Directory where `settings.xml` is written. | `~/.m2` |
|
||||
| `overwrite-settings` | Overwrite an existing `settings.xml`. | `true` |
|
||||
| `gpg-private-key` | GPG private key to import into an isolated temporary keyring. | |
|
||||
|
||||
+167
-28
@@ -26,7 +26,7 @@ jest.unstable_mockModule('@actions/core', () => ({
|
||||
setOutput: jest.fn(),
|
||||
getInput: jest.fn(),
|
||||
getBooleanInput: jest.fn(),
|
||||
getMultilineInput: jest.fn(),
|
||||
getMultilineInput: jest.fn(() => []),
|
||||
addPath: jest.fn(),
|
||||
exportVariable: jest.fn(),
|
||||
saveState: jest.fn(),
|
||||
@@ -57,6 +57,9 @@ const {M2_DIR, MVN_SETTINGS_FILE, STATE_GPG_HOME} =
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const m2Dir = path.join(__dirname, M2_DIR);
|
||||
const settingsFile = path.join(m2Dir, MVN_SETTINGS_FILE);
|
||||
const credentials = (id: string, username: string, password: string) => [
|
||||
{id, usernameEnvVar: username, passwordEnvVar: password}
|
||||
];
|
||||
|
||||
describe('auth tests', () => {
|
||||
let spyOSHomedir: any;
|
||||
@@ -73,6 +76,9 @@ describe('auth tests', () => {
|
||||
|
||||
afterEach(() => {
|
||||
(core.getInput as jest.Mock).mockReset();
|
||||
(core.getMultilineInput as jest.Mock).mockReset();
|
||||
(core.getMultilineInput as jest.Mock).mockReturnValue([]);
|
||||
(core.warning as jest.Mock).mockReset();
|
||||
(core.exportVariable as jest.Mock).mockReset();
|
||||
(gpg.importKey as jest.Mock).mockReset();
|
||||
(gpg.removeGpgHome as jest.Mock).mockReset();
|
||||
@@ -100,9 +106,7 @@ describe('auth tests', () => {
|
||||
await io.rmRF(altHome); // ensure it doesn't already exist
|
||||
|
||||
await auth.createAuthenticationSettings(
|
||||
id,
|
||||
username,
|
||||
password,
|
||||
credentials(id, username, password),
|
||||
altHome,
|
||||
true
|
||||
);
|
||||
@@ -113,7 +117,7 @@ describe('auth tests', () => {
|
||||
expect(fs.existsSync(altHome)).toBe(true);
|
||||
expect(fs.existsSync(altSettingsFile)).toBe(true);
|
||||
expect(fs.readFileSync(altSettingsFile, 'utf-8')).toEqual(
|
||||
auth.generate(id, username, password)
|
||||
auth.generate(credentials(id, username, password))
|
||||
);
|
||||
|
||||
await io.rmRF(altHome);
|
||||
@@ -125,9 +129,7 @@ describe('auth tests', () => {
|
||||
const password = 'TOKEN';
|
||||
|
||||
await auth.createAuthenticationSettings(
|
||||
id,
|
||||
username,
|
||||
password,
|
||||
credentials(id, username, password),
|
||||
m2Dir,
|
||||
true
|
||||
);
|
||||
@@ -135,7 +137,7 @@ describe('auth tests', () => {
|
||||
expect(fs.existsSync(m2Dir)).toBe(true);
|
||||
expect(fs.existsSync(settingsFile)).toBe(true);
|
||||
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
|
||||
auth.generate(id, username, password)
|
||||
auth.generate(credentials(id, username, password))
|
||||
);
|
||||
}, 100000);
|
||||
|
||||
@@ -146,9 +148,7 @@ describe('auth tests', () => {
|
||||
const gpgPassphrase = 'GPG';
|
||||
|
||||
await auth.createAuthenticationSettings(
|
||||
id,
|
||||
username,
|
||||
password,
|
||||
credentials(id, username, password),
|
||||
m2Dir,
|
||||
true,
|
||||
gpgPassphrase
|
||||
@@ -157,7 +157,7 @@ describe('auth tests', () => {
|
||||
expect(fs.existsSync(m2Dir)).toBe(true);
|
||||
expect(fs.existsSync(settingsFile)).toBe(true);
|
||||
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
|
||||
auth.generate(id, username, password, gpgPassphrase)
|
||||
auth.generate(credentials(id, username, password), gpgPassphrase)
|
||||
);
|
||||
}, 100000);
|
||||
|
||||
@@ -218,9 +218,7 @@ describe('auth tests', () => {
|
||||
expect(fs.existsSync(settingsFile)).toBe(true);
|
||||
|
||||
await auth.createAuthenticationSettings(
|
||||
id,
|
||||
username,
|
||||
password,
|
||||
credentials(id, username, password),
|
||||
m2Dir,
|
||||
true
|
||||
);
|
||||
@@ -228,7 +226,7 @@ describe('auth tests', () => {
|
||||
expect(fs.existsSync(m2Dir)).toBe(true);
|
||||
expect(fs.existsSync(settingsFile)).toBe(true);
|
||||
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
|
||||
auth.generate(id, username, password)
|
||||
auth.generate(credentials(id, username, password))
|
||||
);
|
||||
}, 100000);
|
||||
|
||||
@@ -243,9 +241,7 @@ describe('auth tests', () => {
|
||||
expect(fs.existsSync(settingsFile)).toBe(true);
|
||||
|
||||
await auth.createAuthenticationSettings(
|
||||
id,
|
||||
username,
|
||||
password,
|
||||
credentials(id, username, password),
|
||||
m2Dir,
|
||||
false
|
||||
);
|
||||
@@ -273,7 +269,9 @@ describe('auth tests', () => {
|
||||
</servers>
|
||||
</settings>`;
|
||||
|
||||
expect(auth.generate(id, username, password)).toEqual(expectedSettings);
|
||||
expect(auth.generate(credentials(id, username, password))).toEqual(
|
||||
expectedSettings
|
||||
);
|
||||
});
|
||||
|
||||
it('generates valid settings.xml with additional configuration', () => {
|
||||
@@ -306,9 +304,9 @@ describe('auth tests', () => {
|
||||
</activeProfiles>
|
||||
</settings>`;
|
||||
|
||||
expect(auth.generate(id, username, password, gpgPassphrase)).toEqual(
|
||||
expectedSettings
|
||||
);
|
||||
expect(
|
||||
auth.generate(credentials(id, username, password), gpgPassphrase)
|
||||
).toEqual(expectedSettings);
|
||||
});
|
||||
|
||||
it('does not add a gpg profile when the passphrase env var is the maven-gpg-plugin default', () => {
|
||||
@@ -330,9 +328,9 @@ describe('auth tests', () => {
|
||||
</servers>
|
||||
</settings>`;
|
||||
|
||||
expect(auth.generate(id, username, password, gpgPassphrase)).toEqual(
|
||||
expectedSettings
|
||||
);
|
||||
expect(
|
||||
auth.generate(credentials(id, username, password), gpgPassphrase)
|
||||
).toEqual(expectedSettings);
|
||||
});
|
||||
|
||||
it('escapes settings.xml values while preserving parsed semantics', () => {
|
||||
@@ -341,7 +339,10 @@ describe('auth tests', () => {
|
||||
const password = `TOKEN&<>"'é`;
|
||||
const gpgPassphrase = `GPG&<>"'é`;
|
||||
|
||||
const xml = auth.generate(id, username, password, gpgPassphrase);
|
||||
const xml = auth.generate(
|
||||
credentials(id, username, password),
|
||||
gpgPassphrase
|
||||
);
|
||||
const parsed = parseXmlObject(xml) as any;
|
||||
|
||||
expect(parsed.settings.interactiveMode).toBe('false');
|
||||
@@ -352,6 +353,144 @@ describe('auth tests', () => {
|
||||
expect(parsed.settings.activeProfiles.activeProfile).toBe('setup-java-gpg');
|
||||
});
|
||||
|
||||
it('generates ordered settings.xml entries for multiple servers', () => {
|
||||
const servers = [
|
||||
{
|
||||
id: 'releases',
|
||||
usernameEnvVar: 'RELEASES_USERNAME',
|
||||
passwordEnvVar: 'RELEASES_PASSWORD'
|
||||
},
|
||||
{
|
||||
id: 'snapshots',
|
||||
usernameEnvVar: 'SNAPSHOTS_USERNAME',
|
||||
passwordEnvVar: 'SNAPSHOTS_PASSWORD'
|
||||
}
|
||||
];
|
||||
|
||||
const parsed = parseXmlObject(auth.generate(servers)) as any;
|
||||
|
||||
expect(parsed.settings.servers.server).toEqual([
|
||||
{
|
||||
id: 'releases',
|
||||
username: '${env.RELEASES_USERNAME}',
|
||||
password: '${env.RELEASES_PASSWORD}'
|
||||
},
|
||||
{
|
||||
id: 'snapshots',
|
||||
username: '${env.SNAPSHOTS_USERNAME}',
|
||||
password: '${env.SNAPSHOTS_PASSWORD}'
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it('parses and trims multiline Maven server credentials', () => {
|
||||
expect(
|
||||
auth.parseMavenServerCredentials([
|
||||
'',
|
||||
' releases : RELEASES_USERNAME : RELEASES_PASSWORD ',
|
||||
'snapshots:SNAPSHOTS_USERNAME:SNAPSHOTS_PASSWORD'
|
||||
])
|
||||
).toEqual([
|
||||
{
|
||||
id: 'releases',
|
||||
usernameEnvVar: 'RELEASES_USERNAME',
|
||||
passwordEnvVar: 'RELEASES_PASSWORD'
|
||||
},
|
||||
{
|
||||
id: 'snapshots',
|
||||
usernameEnvVar: 'SNAPSHOTS_USERNAME',
|
||||
passwordEnvVar: 'SNAPSHOTS_PASSWORD'
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
entries: ['releases:RELEASES_USERNAME'],
|
||||
error:
|
||||
'Invalid mvn-server-credentials entry at line 1. Expected format: server-id:USERNAME_ENV:PASSWORD_ENV'
|
||||
},
|
||||
{
|
||||
entries: ['', 'releases:RELEASES_USERNAME:RELEASES_PASSWORD:EXTRA'],
|
||||
error:
|
||||
'Invalid mvn-server-credentials entry at line 2. Expected format: server-id:USERNAME_ENV:PASSWORD_ENV'
|
||||
},
|
||||
{
|
||||
entries: ['releases::RELEASES_PASSWORD'],
|
||||
error:
|
||||
'Invalid mvn-server-credentials entry at line 1. server-id, username environment variable, and password environment variable are required'
|
||||
}
|
||||
])(
|
||||
'rejects malformed Maven server credentials: $entries',
|
||||
({entries, error}) => {
|
||||
expect(() => auth.parseMavenServerCredentials(entries)).toThrow(error);
|
||||
}
|
||||
);
|
||||
|
||||
it('rejects duplicate Maven server ids', () => {
|
||||
expect(() =>
|
||||
auth.parseMavenServerCredentials([
|
||||
'releases:RELEASES_USERNAME:RELEASES_PASSWORD',
|
||||
'releases:OTHER_USERNAME:OTHER_PASSWORD'
|
||||
])
|
||||
).toThrow("Duplicate server-id 'releases' in mvn-server-credentials input");
|
||||
});
|
||||
|
||||
it('uses multiline Maven server credentials instead of single-server inputs', () => {
|
||||
(core.getMultilineInput as jest.Mock).mockReturnValue([
|
||||
'releases:RELEASES_USERNAME:RELEASES_PASSWORD',
|
||||
'snapshots:SNAPSHOTS_USERNAME:SNAPSHOTS_PASSWORD'
|
||||
]);
|
||||
|
||||
expect(auth.getMavenServerSettings()).toEqual([
|
||||
{
|
||||
id: 'releases',
|
||||
usernameEnvVar: 'RELEASES_USERNAME',
|
||||
passwordEnvVar: 'RELEASES_PASSWORD'
|
||||
},
|
||||
{
|
||||
id: 'snapshots',
|
||||
usernameEnvVar: 'SNAPSHOTS_USERNAME',
|
||||
passwordEnvVar: 'SNAPSHOTS_PASSWORD'
|
||||
}
|
||||
]);
|
||||
expect(core.getInput).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('uses the existing single-server inputs when multiline credentials are absent', () => {
|
||||
(core.getInput as jest.Mock).mockImplementation((name: string) =>
|
||||
name === 'server-id' ? 'github' : ''
|
||||
);
|
||||
|
||||
expect(auth.getMavenServerSettings()).toEqual([
|
||||
{
|
||||
id: 'github',
|
||||
usernameEnvVar: 'GITHUB_ACTOR',
|
||||
passwordEnvVar: 'GITHUB_TOKEN'
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it('preserves deprecated single-server aliases as fallback inputs', () => {
|
||||
(core.getInput as jest.Mock).mockImplementation((name: string) => {
|
||||
const inputs: Record<string, string> = {
|
||||
'server-id': 'legacy',
|
||||
'server-username': 'LEGACY_USERNAME',
|
||||
'server-password': 'LEGACY_PASSWORD'
|
||||
};
|
||||
return inputs[name] ?? '';
|
||||
});
|
||||
|
||||
expect(auth.getMavenServerSettings()).toEqual([
|
||||
{
|
||||
id: 'legacy',
|
||||
usernameEnvVar: 'LEGACY_USERNAME',
|
||||
passwordEnvVar: 'LEGACY_PASSWORD'
|
||||
}
|
||||
]);
|
||||
expect(core.warning).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
function xmlElementText(xml: string, tagName: string): string {
|
||||
const match = new RegExp(`<${tagName}>([\\s\\S]*?)</${tagName}>`).exec(xml);
|
||||
expect(match).not.toBeNull();
|
||||
|
||||
@@ -64,6 +64,9 @@ inputs:
|
||||
server-password:
|
||||
description: 'Deprecated alias for server-password-env-var'
|
||||
required: false
|
||||
mvn-server-credentials:
|
||||
description: 'Multiline list of Maven server credentials in the format `server-id:USERNAME_ENV:PASSWORD_ENV`. When set, replaces the single server configured by server-id, server-username-env-var, and server-password-env-var.'
|
||||
required: false
|
||||
settings-path:
|
||||
description: 'Path to where the settings.xml file will be written. Default is ~/.m2.'
|
||||
required: false
|
||||
|
||||
Vendored
+2
-1
@@ -30774,7 +30774,7 @@ module.exports = {
|
||||
/* harmony export */ gk: () => (/* binding */ INPUT_CACHE),
|
||||
/* harmony export */ wG: () => (/* binding */ INPUT_JOB_STATUS)
|
||||
/* harmony export */ });
|
||||
/* unused harmony exports MACOS_JAVA_CONTENT_POSTFIX, INPUT_JAVA_VERSION, INPUT_JAVA_VERSION_FILE, INPUT_ARCHITECTURE, INPUT_JAVA_PACKAGE, INPUT_DISTRIBUTION, INPUT_JDK_FILE, INPUT_JDK_FILE_DEPRECATED, INPUT_CHECK_LATEST, INPUT_FORCE_DOWNLOAD, INPUT_SET_DEFAULT, INPUT_PROBLEM_MATCHER, INPUT_VERIFY_SIGNATURE, INPUT_VERIFY_SIGNATURE_PUBLIC_KEY, INPUT_SERVER_ID, INPUT_SERVER_USERNAME_ENV_VAR, INPUT_SERVER_PASSWORD_ENV_VAR, INPUT_SERVER_USERNAME_DEPRECATED, INPUT_SERVER_PASSWORD_DEPRECATED, INPUT_SETTINGS_PATH, INPUT_OVERWRITE_SETTINGS, INPUT_GPG_PRIVATE_KEY, INPUT_GPG_PASSPHRASE_ENV_VAR, INPUT_GPG_PASSPHRASE_DEPRECATED, INPUT_DEFAULT_SERVER_USERNAME, INPUT_DEFAULT_SERVER_PASSWORD, INPUT_DEFAULT_GPG_PRIVATE_KEY, INPUT_DEFAULT_GPG_PASSPHRASE, MAVEN_GPG_PASSPHRASE_DEFAULT_ENV, GPG_PASSPHRASE_PROFILE_ID, INPUT_CACHE_DEPENDENCY_PATH, INPUT_CACHE_PATH, M2_DIR, MVN_SETTINGS_FILE, MVN_TOOLCHAINS_FILE, INPUT_MVN_TOOLCHAIN_ID, INPUT_MVN_TOOLCHAIN_VENDOR, INPUT_SHOW_DOWNLOAD_PROGRESS, MAVEN_ARGS_ENV, MAVEN_NO_TRANSFER_PROGRESS_FLAG, MAVEN_NO_TRANSFER_PROGRESS_LONG_FLAG, DISTRIBUTIONS_ONLY_MAJOR_VERSION */
|
||||
/* unused harmony exports MACOS_JAVA_CONTENT_POSTFIX, INPUT_JAVA_VERSION, INPUT_JAVA_VERSION_FILE, INPUT_ARCHITECTURE, INPUT_JAVA_PACKAGE, INPUT_DISTRIBUTION, INPUT_JDK_FILE, INPUT_JDK_FILE_DEPRECATED, INPUT_CHECK_LATEST, INPUT_FORCE_DOWNLOAD, INPUT_SET_DEFAULT, INPUT_PROBLEM_MATCHER, INPUT_VERIFY_SIGNATURE, INPUT_VERIFY_SIGNATURE_PUBLIC_KEY, INPUT_MVN_SERVER_CREDENTIALS, INPUT_SERVER_ID, INPUT_SERVER_USERNAME_ENV_VAR, INPUT_SERVER_PASSWORD_ENV_VAR, INPUT_SERVER_USERNAME_DEPRECATED, INPUT_SERVER_PASSWORD_DEPRECATED, INPUT_SETTINGS_PATH, INPUT_OVERWRITE_SETTINGS, INPUT_GPG_PRIVATE_KEY, INPUT_GPG_PASSPHRASE_ENV_VAR, INPUT_GPG_PASSPHRASE_DEPRECATED, INPUT_DEFAULT_SERVER_USERNAME, INPUT_DEFAULT_SERVER_PASSWORD, INPUT_DEFAULT_GPG_PRIVATE_KEY, INPUT_DEFAULT_GPG_PASSPHRASE, MAVEN_GPG_PASSPHRASE_DEFAULT_ENV, GPG_PASSPHRASE_PROFILE_ID, INPUT_CACHE_DEPENDENCY_PATH, INPUT_CACHE_PATH, M2_DIR, MVN_SETTINGS_FILE, MVN_TOOLCHAINS_FILE, INPUT_MVN_TOOLCHAIN_ID, INPUT_MVN_TOOLCHAIN_VENDOR, INPUT_SHOW_DOWNLOAD_PROGRESS, MAVEN_ARGS_ENV, MAVEN_NO_TRANSFER_PROGRESS_FLAG, MAVEN_NO_TRANSFER_PROGRESS_LONG_FLAG, DISTRIBUTIONS_ONLY_MAJOR_VERSION */
|
||||
const MACOS_JAVA_CONTENT_POSTFIX = 'Contents/Home';
|
||||
const INPUT_JAVA_VERSION = 'java-version';
|
||||
const INPUT_JAVA_VERSION_FILE = 'java-version-file';
|
||||
@@ -30789,6 +30789,7 @@ 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_MVN_SERVER_CREDENTIALS = 'mvn-server-credentials';
|
||||
const INPUT_SERVER_ID = 'server-id';
|
||||
const INPUT_SERVER_USERNAME_ENV_VAR = 'server-username-env-var';
|
||||
const INPUT_SERVER_PASSWORD_ENV_VAR = 'server-password-env-var';
|
||||
|
||||
Vendored
+52
-16
@@ -10,7 +10,9 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ configureAuthentication: () => (/* binding */ configureAuthentication),
|
||||
/* harmony export */ createAuthenticationSettings: () => (/* binding */ createAuthenticationSettings),
|
||||
/* harmony export */ generate: () => (/* binding */ generate),
|
||||
/* harmony export */ getInputWithDeprecatedAlias: () => (/* binding */ getInputWithDeprecatedAlias)
|
||||
/* harmony export */ getInputWithDeprecatedAlias: () => (/* binding */ getInputWithDeprecatedAlias),
|
||||
/* harmony export */ getMavenServerSettings: () => (/* binding */ getMavenServerSettings),
|
||||
/* harmony export */ parseMavenServerCredentials: () => (/* binding */ parseMavenServerCredentials)
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6928);
|
||||
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__);
|
||||
@@ -34,9 +36,7 @@ __webpack_require__.r(__webpack_exports__);
|
||||
|
||||
|
||||
async function configureAuthentication() {
|
||||
const id = _actions_core__WEBPACK_IMPORTED_MODULE_1__/* .getInput */ .V4(_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_SERVER_ID */ .fd);
|
||||
const usernameEnvVar = getInputWithDeprecatedAlias(_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_SERVER_USERNAME_ENV_VAR */ .sc, _constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_SERVER_USERNAME_DEPRECATED */ .sp, _constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_DEFAULT_SERVER_USERNAME */ .Wj);
|
||||
const passwordEnvVar = getInputWithDeprecatedAlias(_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_SERVER_PASSWORD_ENV_VAR */ .r4, _constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_SERVER_PASSWORD_DEPRECATED */ .Vt, _constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_DEFAULT_SERVER_PASSWORD */ .xp);
|
||||
const servers = getMavenServerSettings();
|
||||
const settingsDirectory = _actions_core__WEBPACK_IMPORTED_MODULE_1__/* .getInput */ .V4(_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_SETTINGS_PATH */ .Xh) ||
|
||||
path__WEBPACK_IMPORTED_MODULE_0__.join(os__WEBPACK_IMPORTED_MODULE_4__.homedir(), _constants_js__WEBPACK_IMPORTED_MODULE_7__/* .M2_DIR */ .iT);
|
||||
const overwriteSettings = (0,_util_js__WEBPACK_IMPORTED_MODULE_6__/* .getBooleanInput */ .Vt)(_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_OVERWRITE_SETTINGS */ .TS, true);
|
||||
@@ -46,7 +46,7 @@ async function configureAuthentication() {
|
||||
if (gpgPrivateKey) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_1__/* .setSecret */ .Pq(gpgPrivateKey);
|
||||
}
|
||||
await createAuthenticationSettings(id, usernameEnvVar, passwordEnvVar, settingsDirectory, overwriteSettings, gpgPassphraseEnvVar);
|
||||
await createAuthenticationSettings(servers, settingsDirectory, overwriteSettings, gpgPassphraseEnvVar);
|
||||
if (gpgPrivateKey) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_1__/* .info */ .pq('Importing private gpg key');
|
||||
const gpgHome = await _gpg_js__WEBPACK_IMPORTED_MODULE_5__/* .importKey */ .Fh(gpgPrivateKey);
|
||||
@@ -68,15 +68,53 @@ function getInputWithDeprecatedAlias(inputName, deprecatedInputName, defaultValu
|
||||
}
|
||||
return value || deprecatedValue || defaultValue || '';
|
||||
}
|
||||
async function createAuthenticationSettings(id, usernameEnvVar, passwordEnvVar, settingsDirectory, overwriteSettings, gpgPassphraseEnvVar = undefined) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_1__/* .info */ .pq(`Creating ${_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .MVN_SETTINGS_FILE */ .vO} with server-id: ${id}`);
|
||||
// only exported for testing purposes
|
||||
function getMavenServerSettings() {
|
||||
const entries = _actions_core__WEBPACK_IMPORTED_MODULE_1__/* .getMultilineInput */ .q3(_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_MVN_SERVER_CREDENTIALS */ .MM);
|
||||
if (entries.some(entry => entry.trim())) {
|
||||
return parseMavenServerCredentials(entries);
|
||||
}
|
||||
return [
|
||||
{
|
||||
id: _actions_core__WEBPACK_IMPORTED_MODULE_1__/* .getInput */ .V4(_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_SERVER_ID */ .fd),
|
||||
usernameEnvVar: getInputWithDeprecatedAlias(_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_SERVER_USERNAME_ENV_VAR */ .sc, _constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_SERVER_USERNAME_DEPRECATED */ .sp, _constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_DEFAULT_SERVER_USERNAME */ .Wj),
|
||||
passwordEnvVar: getInputWithDeprecatedAlias(_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_SERVER_PASSWORD_ENV_VAR */ .r4, _constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_SERVER_PASSWORD_DEPRECATED */ .Vt, _constants_js__WEBPACK_IMPORTED_MODULE_7__/* .INPUT_DEFAULT_SERVER_PASSWORD */ .xp)
|
||||
}
|
||||
];
|
||||
}
|
||||
// only exported for testing purposes
|
||||
function parseMavenServerCredentials(entries) {
|
||||
const servers = [];
|
||||
const serverIds = new Set();
|
||||
entries.forEach((entry, index) => {
|
||||
if (!entry.trim()) {
|
||||
return;
|
||||
}
|
||||
const fields = entry.split(':');
|
||||
if (fields.length !== 3) {
|
||||
throw new Error(`Invalid mvn-server-credentials entry at line ${index + 1}. Expected format: server-id:USERNAME_ENV:PASSWORD_ENV`);
|
||||
}
|
||||
const [id, usernameEnvVar, passwordEnvVar] = fields.map(field => field.trim());
|
||||
if (!id || !usernameEnvVar || !passwordEnvVar) {
|
||||
throw new Error(`Invalid mvn-server-credentials entry at line ${index + 1}. server-id, username environment variable, and password environment variable are required`);
|
||||
}
|
||||
if (serverIds.has(id)) {
|
||||
throw new Error(`Duplicate server-id '${id}' in mvn-server-credentials input`);
|
||||
}
|
||||
serverIds.add(id);
|
||||
servers.push({ id, usernameEnvVar, passwordEnvVar });
|
||||
});
|
||||
return servers;
|
||||
}
|
||||
async function createAuthenticationSettings(servers, settingsDirectory, overwriteSettings, gpgPassphraseEnvVar = undefined) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_1__/* .info */ .pq(`Creating ${_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .MVN_SETTINGS_FILE */ .vO} with server-id: ${servers.map(server => server.id).join(', ')}`);
|
||||
// when an alternate m2 location is specified use only that location (no .m2 directory)
|
||||
// otherwise use the home/.m2/ path
|
||||
await _actions_io__WEBPACK_IMPORTED_MODULE_2__/* .mkdirP */ .U$(settingsDirectory);
|
||||
await write(settingsDirectory, generate(id, usernameEnvVar, passwordEnvVar, gpgPassphraseEnvVar), overwriteSettings);
|
||||
await write(settingsDirectory, generate(servers, gpgPassphraseEnvVar), overwriteSettings);
|
||||
}
|
||||
// only exported for testing purposes
|
||||
function generate(id, usernameEnvVar, passwordEnvVar, gpgPassphraseEnvVar) {
|
||||
function generate(servers, gpgPassphraseEnvVar) {
|
||||
// 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;
|
||||
@@ -90,14 +128,12 @@ function generate(id, usernameEnvVar, passwordEnvVar, gpgPassphraseEnvVar) {
|
||||
' 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>${(0,_xml_js__WEBPACK_IMPORTED_MODULE_8__/* .escapeXmlText */ .I)(id)}</id>`,
|
||||
` <username>${(0,_xml_js__WEBPACK_IMPORTED_MODULE_8__/* .escapeXmlText */ .I)(`\${env.${usernameEnvVar}}`)}</username>`,
|
||||
` <password>${(0,_xml_js__WEBPACK_IMPORTED_MODULE_8__/* .escapeXmlText */ .I)(`\${env.${passwordEnvVar}}`)}</password>`,
|
||||
' </server>',
|
||||
' </servers>'
|
||||
' <servers>'
|
||||
];
|
||||
for (const server of servers) {
|
||||
lines.push(' <server>', ` <id>${(0,_xml_js__WEBPACK_IMPORTED_MODULE_8__/* .escapeXmlText */ .I)(server.id)}</id>`, ` <username>${(0,_xml_js__WEBPACK_IMPORTED_MODULE_8__/* .escapeXmlText */ .I)(`\${env.${server.usernameEnvVar}}`)}</username>`, ` <password>${(0,_xml_js__WEBPACK_IMPORTED_MODULE_8__/* .escapeXmlText */ .I)(`\${env.${server.passwordEnvVar}}`)}</password>`, ' </server>');
|
||||
}
|
||||
lines.push(' </servers>');
|
||||
if (includeGpgPassphraseProfile) {
|
||||
lines.push(' <profiles>', ' <profile>', ` <id>${_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .GPG_PASSPHRASE_PROFILE_ID */ .K$}</id>`, ' <properties>', ` <gpg.passphraseEnvName>${(0,_xml_js__WEBPACK_IMPORTED_MODULE_8__/* .escapeXmlText */ .I)(gpgPassphraseEnvVar)}</gpg.passphraseEnvName>`, ' </properties>', ' </profile>', ' </profiles>', ' <activeProfiles>', ` <activeProfile>${_constants_js__WEBPACK_IMPORTED_MODULE_7__/* .GPG_PASSPHRASE_PROFILE_ID */ .K$}</activeProfile>`, ' </activeProfiles>');
|
||||
}
|
||||
|
||||
Vendored
+2
@@ -30775,6 +30775,7 @@ module.exports = {
|
||||
/* harmony export */ I9: () => (/* binding */ INPUT_FORCE_DOWNLOAD),
|
||||
/* harmony export */ K$: () => (/* binding */ GPG_PASSPHRASE_PROFILE_ID),
|
||||
/* harmony export */ LS: () => (/* binding */ INPUT_ARCHITECTURE),
|
||||
/* harmony export */ MM: () => (/* binding */ INPUT_MVN_SERVER_CREDENTIALS),
|
||||
/* harmony export */ OD: () => (/* binding */ INPUT_DEFAULT_GPG_PRIVATE_KEY),
|
||||
/* harmony export */ PG: () => (/* binding */ MACOS_JAVA_CONTENT_POSTFIX),
|
||||
/* harmony export */ QM: () => (/* binding */ INPUT_JAVA_VERSION),
|
||||
@@ -30829,6 +30830,7 @@ 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_MVN_SERVER_CREDENTIALS = 'mvn-server-credentials';
|
||||
const INPUT_SERVER_ID = 'server-id';
|
||||
const INPUT_SERVER_USERNAME_ENV_VAR = 'server-username-env-var';
|
||||
const INPUT_SERVER_PASSWORD_ENV_VAR = 'server-password-env-var';
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
- [Testing against different Java distributions](#Testing-against-different-Java-distributions)
|
||||
- [Testing against different platforms](#Testing-against-different-platforms)
|
||||
- [Publishing using Apache Maven](#Publishing-using-Apache-Maven)
|
||||
- [Publishing to multiple Maven servers](#publishing-to-multiple-maven-servers)
|
||||
- [Apache Maven with a settings path](#apache-maven-with-a-settings-path)
|
||||
- [Maven transfer progress (download logs)](#Maven-transfer-progress-download-logs)
|
||||
- [Java problem matcher (compiler annotations)](#java-problem-matcher-compiler-annotations)
|
||||
@@ -863,6 +864,49 @@ The two `settings.xml` files created from the above example look like the follow
|
||||
|
||||
If you don't want to overwrite the `settings.xml` file, you can set `overwrite-settings: false`
|
||||
|
||||
### Publishing to multiple Maven servers
|
||||
|
||||
Use `mvn-server-credentials` to add more than one credential entry to the generated `settings.xml`. Each line has the format `server-id:USERNAME_ENV:PASSWORD_ENV`. The username and password fields are environment variable names, not credential values.
|
||||
|
||||
When this input is set, it replaces the single server configured by `server-id`, `server-username-env-var`, and `server-password-env-var`.
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- name: Set up release and snapshot repositories
|
||||
uses: actions/setup-java@v6
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '21'
|
||||
mvn-server-credentials: |
|
||||
releases:RELEASES_USERNAME:RELEASES_PASSWORD
|
||||
snapshots:SNAPSHOTS_USERNAME:SNAPSHOTS_PASSWORD
|
||||
- name: Publish with Maven
|
||||
run: mvn deploy
|
||||
env:
|
||||
RELEASES_USERNAME: ${{ secrets.RELEASES_USERNAME }}
|
||||
RELEASES_PASSWORD: ${{ secrets.RELEASES_PASSWORD }}
|
||||
SNAPSHOTS_USERNAME: ${{ secrets.SNAPSHOTS_USERNAME }}
|
||||
SNAPSHOTS_PASSWORD: ${{ secrets.SNAPSHOTS_PASSWORD }}
|
||||
```
|
||||
|
||||
This configuration produces the following server entries:
|
||||
|
||||
```xml
|
||||
<servers>
|
||||
<server>
|
||||
<id>releases</id>
|
||||
<username>${env.RELEASES_USERNAME}</username>
|
||||
<password>${env.RELEASES_PASSWORD}</password>
|
||||
</server>
|
||||
<server>
|
||||
<id>snapshots</id>
|
||||
<username>${env.SNAPSHOTS_USERNAME}</username>
|
||||
<password>${env.SNAPSHOTS_PASSWORD}</password>
|
||||
</server>
|
||||
</servers>
|
||||
```
|
||||
|
||||
### GPG
|
||||
|
||||
The example above uses the [Maven GPG Plugin](https://maven.apache.org/plugins/maven-gpg-plugin/)'s Bouncy Castle signer (`-Dgpg.signer=bc`, available since `maven-gpg-plugin` 3.2.0). It is a pure-Java signer that reads the key directly from the `MAVEN_GPG_KEY` environment variable, so it does **not** require the `gpg` executable, importing the key into a GPG keychain, or the `--pinentry-mode loopback` workaround in your `pom.xml`. The key must be an ASCII-armored secret key (transferable secret key format).
|
||||
|
||||
+93
-29
@@ -9,18 +9,14 @@ import * as gpg from './gpg.js';
|
||||
import {getBooleanInput} from './util.js';
|
||||
import {escapeXmlText} from './xml.js';
|
||||
|
||||
export interface MavenServerCredentials {
|
||||
id: string;
|
||||
usernameEnvVar: string;
|
||||
passwordEnvVar: string;
|
||||
}
|
||||
|
||||
export async function configureAuthentication() {
|
||||
const id = core.getInput(constants.INPUT_SERVER_ID);
|
||||
const usernameEnvVar = getInputWithDeprecatedAlias(
|
||||
constants.INPUT_SERVER_USERNAME_ENV_VAR,
|
||||
constants.INPUT_SERVER_USERNAME_DEPRECATED,
|
||||
constants.INPUT_DEFAULT_SERVER_USERNAME
|
||||
);
|
||||
const passwordEnvVar = getInputWithDeprecatedAlias(
|
||||
constants.INPUT_SERVER_PASSWORD_ENV_VAR,
|
||||
constants.INPUT_SERVER_PASSWORD_DEPRECATED,
|
||||
constants.INPUT_DEFAULT_SERVER_PASSWORD
|
||||
);
|
||||
const servers = getMavenServerSettings();
|
||||
const settingsDirectory =
|
||||
core.getInput(constants.INPUT_SETTINGS_PATH) ||
|
||||
path.join(os.homedir(), constants.M2_DIR);
|
||||
@@ -42,9 +38,7 @@ export async function configureAuthentication() {
|
||||
}
|
||||
|
||||
await createAuthenticationSettings(
|
||||
id,
|
||||
usernameEnvVar,
|
||||
passwordEnvVar,
|
||||
servers,
|
||||
settingsDirectory,
|
||||
overwriteSettings,
|
||||
gpgPassphraseEnvVar
|
||||
@@ -80,30 +74,95 @@ export function getInputWithDeprecatedAlias(
|
||||
return value || deprecatedValue || defaultValue || '';
|
||||
}
|
||||
|
||||
// only exported for testing purposes
|
||||
export function getMavenServerSettings(): MavenServerCredentials[] {
|
||||
const entries = core.getMultilineInput(
|
||||
constants.INPUT_MVN_SERVER_CREDENTIALS
|
||||
);
|
||||
|
||||
if (entries.some(entry => entry.trim())) {
|
||||
return parseMavenServerCredentials(entries);
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
id: core.getInput(constants.INPUT_SERVER_ID),
|
||||
usernameEnvVar: getInputWithDeprecatedAlias(
|
||||
constants.INPUT_SERVER_USERNAME_ENV_VAR,
|
||||
constants.INPUT_SERVER_USERNAME_DEPRECATED,
|
||||
constants.INPUT_DEFAULT_SERVER_USERNAME
|
||||
),
|
||||
passwordEnvVar: getInputWithDeprecatedAlias(
|
||||
constants.INPUT_SERVER_PASSWORD_ENV_VAR,
|
||||
constants.INPUT_SERVER_PASSWORD_DEPRECATED,
|
||||
constants.INPUT_DEFAULT_SERVER_PASSWORD
|
||||
)
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
// only exported for testing purposes
|
||||
export function parseMavenServerCredentials(
|
||||
entries: string[]
|
||||
): MavenServerCredentials[] {
|
||||
const servers: MavenServerCredentials[] = [];
|
||||
const serverIds = new Set<string>();
|
||||
|
||||
entries.forEach((entry, index) => {
|
||||
if (!entry.trim()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fields = entry.split(':');
|
||||
if (fields.length !== 3) {
|
||||
throw new Error(
|
||||
`Invalid mvn-server-credentials entry at line ${index + 1}. Expected format: server-id:USERNAME_ENV:PASSWORD_ENV`
|
||||
);
|
||||
}
|
||||
|
||||
const [id, usernameEnvVar, passwordEnvVar] = fields.map(field =>
|
||||
field.trim()
|
||||
);
|
||||
if (!id || !usernameEnvVar || !passwordEnvVar) {
|
||||
throw new Error(
|
||||
`Invalid mvn-server-credentials entry at line ${index + 1}. server-id, username environment variable, and password environment variable are required`
|
||||
);
|
||||
}
|
||||
if (serverIds.has(id)) {
|
||||
throw new Error(
|
||||
`Duplicate server-id '${id}' in mvn-server-credentials input`
|
||||
);
|
||||
}
|
||||
|
||||
serverIds.add(id);
|
||||
servers.push({id, usernameEnvVar, passwordEnvVar});
|
||||
});
|
||||
|
||||
return servers;
|
||||
}
|
||||
|
||||
export async function createAuthenticationSettings(
|
||||
id: string,
|
||||
usernameEnvVar: string,
|
||||
passwordEnvVar: string,
|
||||
servers: MavenServerCredentials[],
|
||||
settingsDirectory: string,
|
||||
overwriteSettings: boolean,
|
||||
gpgPassphraseEnvVar: string | undefined = undefined
|
||||
) {
|
||||
core.info(`Creating ${constants.MVN_SETTINGS_FILE} with server-id: ${id}`);
|
||||
core.info(
|
||||
`Creating ${constants.MVN_SETTINGS_FILE} with server-id: ${servers.map(server => server.id).join(', ')}`
|
||||
);
|
||||
// when an alternate m2 location is specified use only that location (no .m2 directory)
|
||||
// otherwise use the home/.m2/ path
|
||||
await io.mkdirP(settingsDirectory);
|
||||
await write(
|
||||
settingsDirectory,
|
||||
generate(id, usernameEnvVar, passwordEnvVar, gpgPassphraseEnvVar),
|
||||
generate(servers, gpgPassphraseEnvVar),
|
||||
overwriteSettings
|
||||
);
|
||||
}
|
||||
|
||||
// only exported for testing purposes
|
||||
export function generate(
|
||||
id: string,
|
||||
usernameEnvVar: string,
|
||||
passwordEnvVar: string,
|
||||
servers: MavenServerCredentials[],
|
||||
gpgPassphraseEnvVar?: string | undefined
|
||||
) {
|
||||
// The maven-gpg-plugin reads the passphrase from the environment variable
|
||||
@@ -121,15 +180,20 @@ export function generate(
|
||||
' 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>${escapeXmlText(id)}</id>`,
|
||||
` <username>${escapeXmlText(`\${env.${usernameEnvVar}}`)}</username>`,
|
||||
` <password>${escapeXmlText(`\${env.${passwordEnvVar}}`)}</password>`,
|
||||
' </server>',
|
||||
' </servers>'
|
||||
' <servers>'
|
||||
];
|
||||
|
||||
for (const server of servers) {
|
||||
lines.push(
|
||||
' <server>',
|
||||
` <id>${escapeXmlText(server.id)}</id>`,
|
||||
` <username>${escapeXmlText(`\${env.${server.usernameEnvVar}}`)}</username>`,
|
||||
` <password>${escapeXmlText(`\${env.${server.passwordEnvVar}}`)}</password>`,
|
||||
' </server>'
|
||||
);
|
||||
}
|
||||
lines.push(' </servers>');
|
||||
|
||||
if (includeGpgPassphraseProfile) {
|
||||
lines.push(
|
||||
' <profiles>',
|
||||
|
||||
@@ -12,6 +12,7 @@ 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_MVN_SERVER_CREDENTIALS = 'mvn-server-credentials';
|
||||
export const INPUT_SERVER_ID = 'server-id';
|
||||
export const INPUT_SERVER_USERNAME_ENV_VAR = 'server-username-env-var';
|
||||
export const INPUT_SERVER_PASSWORD_ENV_VAR = 'server-password-env-var';
|
||||
|
||||
Reference in New Issue
Block a user