mirror of
https://github.com/actions/setup-java.git
synced 2025-05-21 18:01:46 +00:00
Added support for GPG
This commit is contained in:
parent
5c87b70ffe
commit
798fdaeebd
44
README.md
44
README.md
@ -29,27 +29,27 @@ Examples of version specifications that the java-version parameter will accept:
|
|||||||
- A major Java version
|
- A major Java version
|
||||||
|
|
||||||
e.g. ```6, 7, 8, 9, 10, 11, 12, 13, ...```
|
e.g. ```6, 7, 8, 9, 10, 11, 12, 13, ...```
|
||||||
|
|
||||||
- A semver Java version specification
|
- A semver Java version specification
|
||||||
|
|
||||||
e.g. ```8.0.232, 7.0.181, 11.0.4```
|
e.g. ```8.0.232, 7.0.181, 11.0.4```
|
||||||
|
|
||||||
e.g. ```8.0.x, >11.0.3, >=13.0.1, <8.0.212```
|
e.g. ```8.0.x, >11.0.3, >=13.0.1, <8.0.212```
|
||||||
|
|
||||||
- An early access (EA) Java version
|
- An early access (EA) Java version
|
||||||
|
|
||||||
e.g. ```14-ea, 15-ea```
|
e.g. ```14-ea, 15-ea```
|
||||||
|
|
||||||
e.g. ```14.0.0-ea, 15.0.0-ea```
|
e.g. ```14.0.0-ea, 15.0.0-ea```
|
||||||
|
|
||||||
e.g. ```14.0.0-ea.28, 15.0.0-ea.2``` (syntax for specifying an EA build number)
|
e.g. ```14.0.0-ea.28, 15.0.0-ea.2``` (syntax for specifying an EA build number)
|
||||||
|
|
||||||
Note that, per semver rules, EA builds will be matched by explicit EA version specifications.
|
Note that, per semver rules, EA builds will be matched by explicit EA version specifications.
|
||||||
|
|
||||||
- 1.x syntax
|
- 1.x syntax
|
||||||
|
|
||||||
e.g. ```1.8``` (same as ```8```)
|
e.g. ```1.8``` (same as ```8```)
|
||||||
|
|
||||||
e.g. ```1.8.0.212``` (same as ```8.0.212```)
|
e.g. ```1.8.0.212``` (same as ```8.0.212```)
|
||||||
|
|
||||||
|
|
||||||
@ -113,12 +113,14 @@ jobs:
|
|||||||
server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml
|
server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml
|
||||||
server-username: MAVEN_USERNAME # env variable for username in deploy
|
server-username: MAVEN_USERNAME # env variable for username in deploy
|
||||||
server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy
|
server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy
|
||||||
|
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
|
||||||
|
|
||||||
- name: Publish to Apache Maven Central
|
- name: Publish to Apache Maven Central
|
||||||
run: mvn deploy
|
run: mvn deploy
|
||||||
env:
|
env:
|
||||||
MAVEN_USERNAME: maven_username123
|
MAVEN_USERNAME: maven_username123
|
||||||
MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
|
MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
|
||||||
|
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
|
||||||
```
|
```
|
||||||
|
|
||||||
The two `settings.xml` files created from the above example look like the following.
|
The two `settings.xml` files created from the above example look like the following.
|
||||||
@ -131,6 +133,16 @@ The two `settings.xml` files created from the above example look like the follow
|
|||||||
<username>${env.GITHUB_ACTOR}</username>
|
<username>${env.GITHUB_ACTOR}</username>
|
||||||
<password>${env.GITHUB_TOKEN}</password>
|
<password>${env.GITHUB_TOKEN}</password>
|
||||||
</server>
|
</server>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<gpg.passphrase>${env.GPG_PASSPHRASE}</gpg.passphrase>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
<profiles>
|
||||||
</servers>
|
</servers>
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -142,10 +154,20 @@ The two `settings.xml` files created from the above example look like the follow
|
|||||||
<username>${env.MAVEN_USERNAME}</username>
|
<username>${env.MAVEN_USERNAME}</username>
|
||||||
<password>${env.MAVEN_CENTRAL_TOKEN}</password>
|
<password>${env.MAVEN_CENTRAL_TOKEN}</password>
|
||||||
</server>
|
</server>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<gpg.passphrase>${env.MAVEN_GPG_PASSPHRASE}</gpg.passphrase>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
<profiles>
|
||||||
</servers>
|
</servers>
|
||||||
```
|
```
|
||||||
|
|
||||||
***NOTE: The `settings.xml` file is created in the Actions $HOME directory. If you have an existing `settings.xml` file at that location, it will be overwritten. See below for using the `settings-path` to change your `settings.xml` file location.***
|
***NOTE: The `settings.xml` file is created in the Actions $HOME directory. If you have an existing `settings.xml` file at that location, it will be overwritten. See below for using the `settings-path` to change your `settings.xml` file location.***
|
||||||
|
|
||||||
See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file.
|
See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file.
|
||||||
|
|
||||||
@ -172,7 +194,7 @@ jobs:
|
|||||||
PASSWORD: ${{ secrets.GITHUB_TOKEN }}
|
PASSWORD: ${{ secrets.GITHUB_TOKEN }}
|
||||||
```
|
```
|
||||||
|
|
||||||
***NOTE: The `USERNAME` and `PASSWORD` need to correspond to the credentials environment variables used in the publishing section of your `build.gradle`.***
|
***NOTE: The `USERNAME` and `PASSWORD` need to correspond to the credentials environment variables used in the publishing section of your `build.gradle`.***
|
||||||
|
|
||||||
See the help docs on [Publishing a Package with Gradle](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages#example-using-gradle-groovy-for-a-single-package-in-a-repository) for more information on the `build.gradle` configuration file.
|
See the help docs on [Publishing a Package with Gradle](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages#example-using-gradle-groovy-for-a-single-package-in-a-repository) for more information on the `build.gradle` configuration file.
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import io = require('@actions/io');
|
|||||||
import fs = require('fs');
|
import fs = require('fs');
|
||||||
import os = require('os');
|
import os = require('os');
|
||||||
import path = require('path');
|
import path = require('path');
|
||||||
|
import exec = require('@actions/exec');
|
||||||
|
|
||||||
// make the os.homedir() call be local to the tests
|
// make the os.homedir() call be local to the tests
|
||||||
jest.doMock('os', () => {
|
jest.doMock('os', () => {
|
||||||
@ -10,10 +11,19 @@ jest.doMock('os', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jest.mock('@actions/exec', () => {
|
||||||
|
return {
|
||||||
|
exec: jest.fn()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
import * as auth from '../src/auth';
|
import * as auth from '../src/auth';
|
||||||
|
|
||||||
|
const env = process.env;
|
||||||
const m2Dir = path.join(__dirname, auth.M2_DIR);
|
const m2Dir = path.join(__dirname, auth.M2_DIR);
|
||||||
const settingsFile = path.join(m2Dir, auth.SETTINGS_FILE);
|
const settingsFile = path.join(m2Dir, auth.SETTINGS_FILE);
|
||||||
|
const gpgDir = path.join(__dirname, auth.GPG_DIR);
|
||||||
|
const gpgFile = path.join(gpgDir, auth.GPG_FILE);
|
||||||
|
|
||||||
describe('auth tests', () => {
|
describe('auth tests', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@ -23,6 +33,7 @@ describe('auth tests', () => {
|
|||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
try {
|
try {
|
||||||
await io.rmRF(m2Dir);
|
await io.rmRF(m2Dir);
|
||||||
|
await io.rmRF(gpgDir);
|
||||||
} catch {
|
} catch {
|
||||||
console.log('Failed to remove test directories');
|
console.log('Failed to remove test directories');
|
||||||
}
|
}
|
||||||
@ -53,17 +64,25 @@ describe('auth tests', () => {
|
|||||||
await io.rmRF(altHome);
|
await io.rmRF(altHome);
|
||||||
}, 100000);
|
}, 100000);
|
||||||
|
|
||||||
it('creates settings.xml with username and password', async () => {
|
it('creates settings.xml with all data', async () => {
|
||||||
const id = 'packages';
|
const id = 'packages';
|
||||||
const username = 'UNAME';
|
const username = 'UNAME';
|
||||||
const password = 'TOKEN';
|
const password = 'TOKEN';
|
||||||
|
const gpgPrivateKey = 'PRIVATE';
|
||||||
|
const gpgPassphrase = 'GPG';
|
||||||
|
|
||||||
await auth.configAuthentication(id, username, password);
|
await auth.configAuthentication(
|
||||||
|
id,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
gpgPrivateKey,
|
||||||
|
gpgPassphrase
|
||||||
|
);
|
||||||
|
|
||||||
expect(fs.existsSync(m2Dir)).toBe(true);
|
expect(fs.existsSync(m2Dir)).toBe(true);
|
||||||
expect(fs.existsSync(settingsFile)).toBe(true);
|
expect(fs.existsSync(settingsFile)).toBe(true);
|
||||||
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
|
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
|
||||||
auth.generate(id, username, password)
|
auth.generate(id, username, password, gpgPassphrase)
|
||||||
);
|
);
|
||||||
}, 100000);
|
}, 100000);
|
||||||
|
|
||||||
@ -128,8 +147,9 @@ describe('auth tests', () => {
|
|||||||
const id = 'packages';
|
const id = 'packages';
|
||||||
const username = 'USER';
|
const username = 'USER';
|
||||||
const password = '&<>"\'\'"><&';
|
const password = '&<>"\'\'"><&';
|
||||||
|
const gpgPassphrase = 'PASSWORD';
|
||||||
|
|
||||||
expect(auth.generate(id, username, password)).toEqual(`
|
expect(auth.generate(id, username, password, gpgPassphrase)).toEqual(`
|
||||||
<settings>
|
<settings>
|
||||||
<servers>
|
<servers>
|
||||||
<server>
|
<server>
|
||||||
@ -138,7 +158,44 @@ describe('auth tests', () => {
|
|||||||
<password>\${env.&<>"''"><&}</password>
|
<password>\${env.&<>"''"><&}</password>
|
||||||
</server>
|
</server>
|
||||||
</servers>
|
</servers>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<gpg.passphrase>\${env.${gpgPassphrase}}</gpg.passphrase>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
<profiles>
|
||||||
</settings>
|
</settings>
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('imports gpg private key', async () => {
|
||||||
|
const id = 'packages';
|
||||||
|
const username = 'USERNAME';
|
||||||
|
const password = 'PASSWORD';
|
||||||
|
const gpgPrivateKey = 'KEY CONTENTS';
|
||||||
|
|
||||||
|
await auth.configAuthentication(id, username, password, gpgPrivateKey);
|
||||||
|
|
||||||
|
expect(exec.exec).toHaveBeenCalledWith(`gpg --import --batch ${gpgFile}`);
|
||||||
|
|
||||||
|
expect(fs.existsSync(gpgDir)).toBe(false);
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
|
it('does not import gpg private key when private key is not set', async () => {
|
||||||
|
const id = 'packages';
|
||||||
|
const username = 'USERNAME';
|
||||||
|
const password = 'PASSWORD';
|
||||||
|
|
||||||
|
await auth.configAuthentication(id, username, password);
|
||||||
|
|
||||||
|
expect(exec.exec).not.toHaveBeenCalledWith(
|
||||||
|
`gpg --import --batch ${gpgFile}`
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fs.existsSync(gpgDir)).toBe(false);
|
||||||
|
}, 100000);
|
||||||
});
|
});
|
||||||
|
@ -36,6 +36,14 @@ inputs:
|
|||||||
settings-path:
|
settings-path:
|
||||||
description: 'Path to where the settings.xml file will be written. Default is ~/.m2.'
|
description: 'Path to where the settings.xml file will be written. Default is ~/.m2.'
|
||||||
required: false
|
required: false
|
||||||
|
gpg-private-key:
|
||||||
|
description: 'Environment variable name for the GPG private key to import. Default is
|
||||||
|
$GPG_PRIVATE_KEY.'
|
||||||
|
required: false
|
||||||
|
gpg-passphrase:
|
||||||
|
description: 'Environment variable name for the GPG private key passphrase. Default is
|
||||||
|
$GPG_PASSPHRASE.'
|
||||||
|
required: false
|
||||||
runs:
|
runs:
|
||||||
using: 'node12'
|
using: 'node12'
|
||||||
main: 'dist/index.js'
|
main: 'dist/index.js'
|
||||||
|
BIN
dist/index.js
generated
vendored
BIN
dist/index.js
generated
vendored
Binary file not shown.
61
src/auth.ts
61
src/auth.ts
@ -3,32 +3,57 @@ import * as os from 'os';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as io from '@actions/io';
|
import * as io from '@actions/io';
|
||||||
|
import * as exec from '@actions/exec';
|
||||||
|
|
||||||
export const M2_DIR = '.m2';
|
export const M2_DIR = '.m2';
|
||||||
export const SETTINGS_FILE = 'settings.xml';
|
export const SETTINGS_FILE = 'settings.xml';
|
||||||
|
export const GPG_DIR = '.gpgtmp';
|
||||||
|
export const GPG_FILE = 'private.asc';
|
||||||
|
|
||||||
export const DEFAULT_ID = 'github';
|
export const DEFAULT_ID = 'github';
|
||||||
export const DEFAULT_USERNAME = 'GITHUB_ACTOR';
|
export const DEFAULT_USERNAME = 'GITHUB_ACTOR';
|
||||||
export const DEFAULT_PASSWORD = 'GITHUB_TOKEN';
|
export const DEFAULT_PASSWORD = 'GITHUB_TOKEN';
|
||||||
|
export const DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE';
|
||||||
|
export const DEFAULT_GPG_PRIVATE_KEY = '';
|
||||||
|
|
||||||
export async function configAuthentication(
|
export async function configAuthentication(
|
||||||
id = DEFAULT_ID,
|
id = DEFAULT_ID,
|
||||||
username = DEFAULT_USERNAME,
|
username = DEFAULT_USERNAME,
|
||||||
password = DEFAULT_PASSWORD
|
password = DEFAULT_PASSWORD,
|
||||||
|
gpgPrivateKey = DEFAULT_GPG_PRIVATE_KEY,
|
||||||
|
gpgPassphrase = DEFAULT_GPG_PASSPHRASE
|
||||||
) {
|
) {
|
||||||
console.log(
|
console.log(
|
||||||
`creating ${SETTINGS_FILE} with server-id: ${id};`,
|
`creating ${SETTINGS_FILE} with server-id: ${id};`,
|
||||||
`environment variables: username=\$${username} and password=\$${password}`
|
'environment variables:',
|
||||||
|
`username=\$${username},`,
|
||||||
|
`password=\$${password},`,
|
||||||
|
`and gpg-passphrase=\$${gpgPassphrase}`
|
||||||
);
|
);
|
||||||
// when an alternate m2 location is specified use only that location (no .m2 directory)
|
// when an alternate m2 location is specified use only that location (no .m2 directory)
|
||||||
// otherwise use the home/.m2/ path
|
// otherwise use the home/.m2/ path
|
||||||
const directory: string = path.join(
|
const settingsDirectory: string = path.join(
|
||||||
core.getInput('settings-path') || os.homedir(),
|
core.getInput('settings-path') || os.homedir(),
|
||||||
core.getInput('settings-path') ? '' : M2_DIR
|
core.getInput('settings-path') ? '' : M2_DIR
|
||||||
);
|
);
|
||||||
await io.mkdirP(directory);
|
await io.mkdirP(settingsDirectory);
|
||||||
core.debug(`created directory ${directory}`);
|
core.debug(`created directory ${settingsDirectory}`);
|
||||||
await write(directory, generate(id, username, password));
|
await write(
|
||||||
|
settingsDirectory,
|
||||||
|
SETTINGS_FILE,
|
||||||
|
generate(id, username, password, gpgPassphrase)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (gpgPrivateKey !== DEFAULT_GPG_PRIVATE_KEY) {
|
||||||
|
console.log('importing gpg key');
|
||||||
|
const gpgDirectory: string = path.join(os.homedir(), GPG_DIR);
|
||||||
|
await io.mkdirP(gpgDirectory);
|
||||||
|
core.debug(`created directory ${gpgDirectory}`);
|
||||||
|
await write(gpgDirectory, GPG_FILE, gpgPrivateKey);
|
||||||
|
await importGpgKey(gpgDirectory, GPG_FILE);
|
||||||
|
await io.rmRF(gpgDirectory);
|
||||||
|
core.debug(`removed directory ${gpgDirectory}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeXML(value: string) {
|
function escapeXML(value: string) {
|
||||||
@ -44,7 +69,8 @@ function escapeXML(value: string) {
|
|||||||
export function generate(
|
export function generate(
|
||||||
id = DEFAULT_ID,
|
id = DEFAULT_ID,
|
||||||
username = DEFAULT_USERNAME,
|
username = DEFAULT_USERNAME,
|
||||||
password = DEFAULT_PASSWORD
|
password = DEFAULT_PASSWORD,
|
||||||
|
gpgPassphrase = DEFAULT_GPG_PASSPHRASE
|
||||||
) {
|
) {
|
||||||
return `
|
return `
|
||||||
<settings>
|
<settings>
|
||||||
@ -55,20 +81,35 @@ export function generate(
|
|||||||
<password>\${env.${escapeXML(password)}}</password>
|
<password>\${env.${escapeXML(password)}}</password>
|
||||||
</server>
|
</server>
|
||||||
</servers>
|
</servers>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<gpg.passphrase>\${env.${escapeXML(gpgPassphrase)}}</gpg.passphrase>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
<profiles>
|
||||||
</settings>
|
</settings>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function write(directory: string, settings: string) {
|
async function write(directory: string, file: string, contents: string) {
|
||||||
const location = path.join(directory, SETTINGS_FILE);
|
const location = path.join(directory, file);
|
||||||
if (fs.existsSync(location)) {
|
if (fs.existsSync(location)) {
|
||||||
console.warn(`overwriting existing file ${location}`);
|
console.warn(`overwriting existing file ${location}`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`writing ${location}`);
|
console.log(`writing ${location}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs.writeFileSync(location, settings, {
|
return fs.writeFileSync(location, contents, {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
flag: 'w'
|
flag: 'w'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function importGpgKey(directory: string, file: string) {
|
||||||
|
const location = path.join(directory, file);
|
||||||
|
exec.exec(`gpg --import --batch ${location}`);
|
||||||
|
}
|
||||||
|
@ -23,8 +23,18 @@ async function run() {
|
|||||||
core.getInput('server-username', {required: false}) || undefined;
|
core.getInput('server-username', {required: false}) || undefined;
|
||||||
const password =
|
const password =
|
||||||
core.getInput('server-password', {required: false}) || undefined;
|
core.getInput('server-password', {required: false}) || undefined;
|
||||||
|
const gpgPassphrase =
|
||||||
|
core.getInput('gpg-passphrase', {required: false}) || undefined;
|
||||||
|
const gpgPrivateKey =
|
||||||
|
core.getInput('gpg-private-key', {required: false}) || undefined;
|
||||||
|
|
||||||
await auth.configAuthentication(id, username, password);
|
await auth.configAuthentication(
|
||||||
|
id,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
gpgPassphrase,
|
||||||
|
gpgPrivateKey
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user