Merge branch 'main' into bugfix/architecture

This commit is contained in:
Austin Shalit 2020-08-17 20:17:03 -07:00
commit 2a54549d2e
No known key found for this signature in database
GPG key ID: 4B1567D6898D8368
23 changed files with 37995 additions and 163 deletions

View file

@ -1,12 +0,0 @@
name: Lint YAML
on: [pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Lint action.yml
uses: ibiqlik/action-yamllint@master
with:
file_or_dir: action.yml
config_file: yaml-lint-config.yml

View file

@ -35,15 +35,16 @@ jobs:
if: runner.os == 'windows' if: runner.os == 'windows'
run: move "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old" run: move "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old"
- name: Setup Java 13 - name: Setup Java 13
id: setup-java
uses: ./ uses: ./
with: with:
java-version: 13.0.2 java-version: 13.0.2
- name: Verify Java 13 - name: Verify Java 13
if: runner.os != 'windows' if: runner.os != 'windows'
run: __tests__/verify-java.sh 13.0.2 run: __tests__/verify-java.sh 13.0.2 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}"
- name: Verify Java 13 (Windows) - name: Verify Java 13 (Windows)
if: runner.os == 'windows' if: runner.os == 'windows'
run: __tests__/verify-java.ps1 13.0.2 run: __tests__/verify-java.ps1 13.0.2 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}"
test-proxy: test-proxy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -62,11 +63,12 @@ jobs:
- name: Clear tool cache - name: Clear tool cache
run: rm -rf $RUNNER_TOOL_CACHE/* run: rm -rf $RUNNER_TOOL_CACHE/*
- name: Setup Java 13 - name: Setup Java 13
id: setup-java
uses: ./ uses: ./
with: with:
java-version: 13.0.2 java-version: 13.0.2
- name: Verify Java 13 - name: Verify Java 13
run: __tests__/verify-java.sh 13.0.2 run: __tests__/verify-java.sh 13.0.2 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}"
test-bypass-proxy: test-bypass-proxy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -78,8 +80,9 @@ jobs:
- name: Clear tool cache - name: Clear tool cache
run: rm -rf $RUNNER_TOOL_CACHE/* run: rm -rf $RUNNER_TOOL_CACHE/*
- name: Setup Java 13 - name: Setup Java 13
id: setup-java
uses: ./ uses: ./
with: with:
java-version: 13.0.2 java-version: 13.0.2
- name: Verify Java 13 - name: Verify Java 13
run: __tests__/verify-java.sh 13.0.2 run: __tests__/verify-java.sh 13.0.2 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}"

View file

@ -113,40 +113,61 @@ 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
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase
- 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.
`settings.xml` file created for the first deploy to GitHub Packages `settings.xml` file created for the first deploy to GitHub Packages
```xml ```xml
<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">
<servers> <servers>
<server> <server>
<id>github</id> <id>github</id>
<username>${env.GITHUB_ACTOR}</username> <username>${env.GITHUB_ACTOR}</username>
<password>${env.GITHUB_TOKEN}</password> <password>${env.GITHUB_TOKEN}</password>
</server> </server>
<server>
<id>gpg.passphrase</id>
<passphrase>${env.GPG_PASSPHRASE}</passphrase>
</server>
</servers> </servers>
</settings>
``` ```
`settings.xml` file created for the second deploy to Apache Maven Central `settings.xml` file created for the second deploy to Apache Maven Central
```xml ```xml
<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">
<servers> <servers>
<server> <server>
<id>maven</id> <id>maven</id>
<username>${env.MAVEN_USERNAME}</username> <username>${env.MAVEN_USERNAME}</username>
<password>${env.MAVEN_CENTRAL_TOKEN}</password> <password>${env.MAVEN_CENTRAL_TOKEN}</password>
</server> </server>
<server>
<id>gpg.passphrase</id>
<passphrase>${env.MAVEN_GPG_PASSPHRASE}</passphrase>
</server>
</servers> </servers>
</settings>
``` ```
***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.***
If `gpg-private-key` input is provided, the private key will be written to a file in the runner's temp directory, the private key file will be imported into the GPG keychain, and then the file will be promptly removed before proceeding with the rest of the setup process. A cleanup step will remove the imported private key from the GPG keychain after the job completes regardless of the job status. This ensures that the private key is no longer accessible on self-hosted runners and cannot "leak" between jobs (hosted runners are always clean instances).
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.
## Publishing using Gradle ## Publishing using Gradle

View file

@ -53,7 +53,7 @@ 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 minimal configuration', async () => {
const id = 'packages'; const id = 'packages';
const username = 'UNAME'; const username = 'UNAME';
const password = 'TOKEN'; const password = 'TOKEN';
@ -67,6 +67,21 @@ describe('auth tests', () => {
); );
}, 100000); }, 100000);
it('creates settings.xml with additional configuration', async () => {
const id = 'packages';
const username = 'UNAME';
const password = 'TOKEN';
const gpgPassphrase = 'GPG';
await auth.configAuthentication(id, username, password, gpgPassphrase);
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)
);
}, 100000);
it('overwrites existing settings.xml files', async () => { it('overwrites existing settings.xml files', async () => {
const id = 'packages'; const id = 'packages';
const username = 'USERNAME'; const username = 'USERNAME';
@ -86,59 +101,50 @@ describe('auth tests', () => {
); );
}, 100000); }, 100000);
it('does not create settings.xml without required parameters', async () => { it('generates valid settings.xml with minimal configuration', () => {
await auth.configAuthentication('FOO');
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
auth.generate('FOO', auth.DEFAULT_USERNAME, auth.DEFAULT_PASSWORD)
);
await auth.configAuthentication(undefined, 'BAR', undefined);
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
auth.generate(auth.DEFAULT_ID, 'BAR', auth.DEFAULT_PASSWORD)
);
await auth.configAuthentication(undefined, undefined, 'BAZ');
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
auth.generate(auth.DEFAULT_ID, auth.DEFAULT_USERNAME, 'BAZ')
);
await auth.configAuthentication();
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
auth.generate(
auth.DEFAULT_ID,
auth.DEFAULT_USERNAME,
auth.DEFAULT_PASSWORD
)
);
}, 100000);
it('escapes invalid XML inputs', () => {
const id = 'packages'; const id = 'packages';
const username = 'USER'; const username = 'USER';
const password = '&<>"\'\'"><&'; const password = '&<>"\'\'"><&';
expect(auth.generate(id, username, password)).toEqual(` const expectedSettings = `<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
<settings> 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">
<servers> <servers>
<server> <server>
<id>${id}</id> <id>${id}</id>
<username>\${env.${username}}</username> <username>\${env.${username}}</username>
<password>\${env.&amp;&lt;&gt;&quot;&apos;&apos;&quot;&gt;&lt;&amp;}</password> <password>\${env.&amp;&lt;&gt;"''"&gt;&lt;&amp;}</password>
</server> </server>
</servers> </servers>
</settings> </settings>`;
`);
expect(auth.generate(id, username, password)).toEqual(expectedSettings);
});
it('generates valid settings.xml with additional configuration', () => {
const id = 'packages';
const username = 'USER';
const password = '&<>"\'\'"><&';
const gpgPassphrase = '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">
<servers>
<server>
<id>${id}</id>
<username>\${env.${username}}</username>
<password>\${env.&amp;&lt;&gt;"''"&gt;&lt;&amp;}</password>
</server>
<server>
<id>gpg.passphrase</id>
<passphrase>\${env.${gpgPassphrase}}</passphrase>
</server>
</servers>
</settings>`;
expect(auth.generate(id, username, password, gpgPassphrase)).toEqual(
expectedSettings
);
}); });
}); });

56
__tests__/gpg.test.ts Normal file
View file

@ -0,0 +1,56 @@
import path = require('path');
import io = require('@actions/io');
import exec = require('@actions/exec');
jest.mock('@actions/exec', () => {
return {
exec: jest.fn()
};
});
const tempDir = path.join(__dirname, 'runner', 'temp');
process.env['RUNNER_TEMP'] = tempDir;
import gpg = require('../src/gpg');
describe('gpg tests', () => {
beforeEach(async () => {
await io.mkdirP(tempDir);
});
afterAll(async () => {
try {
await io.rmRF(tempDir);
} catch {
console.log('Failed to remove test directories');
}
});
describe('importKey', () => {
it('attempts to import private key and returns null key id on failure', async () => {
const privateKey = 'KEY CONTENTS';
const keyId = await gpg.importKey(privateKey);
expect(keyId).toBeNull();
expect(exec.exec).toHaveBeenCalledWith(
'gpg',
expect.anything(),
expect.anything()
);
});
});
describe('deleteKey', () => {
it('deletes private key', async () => {
const keyId = 'asdfhjkl';
await gpg.deleteKey(keyId);
expect(exec.exec).toHaveBeenCalledWith(
'gpg',
expect.anything(),
expect.anything()
);
});
});
});

61
__tests__/util.test.ts Normal file
View file

@ -0,0 +1,61 @@
import path = require('path');
const env = process.env;
describe('util tests', () => {
beforeEach(() => {
const tempEnv = Object.assign({}, env);
delete tempEnv.RUNNER_TEMP;
delete tempEnv.USERPROFILE;
process.env = tempEnv;
Object.defineProperty(process, 'platform', {value: 'linux'});
});
describe('getTempDir', () => {
it('gets temp dir using env', () => {
process.env['RUNNER_TEMP'] = 'defaulttmp';
const util = require('../src/util');
const tempDir = util.getTempDir();
expect(tempDir).toEqual(process.env['RUNNER_TEMP']);
});
it('gets temp dir for windows using userprofile', () => {
Object.defineProperty(process, 'platform', {value: 'win32'});
process.env['USERPROFILE'] = 'winusertmp';
const util = require('../src/util');
const tempDir = util.getTempDir();
expect(tempDir).toEqual(
path.join(process.env['USERPROFILE'], 'actions', 'temp')
);
});
it('gets temp dir for windows using c drive', () => {
Object.defineProperty(process, 'platform', {value: 'win32'});
const util = require('../src/util');
const tempDir = util.getTempDir();
expect(tempDir).toEqual(path.join('C:\\', 'actions', 'temp'));
});
it('gets temp dir for mac', () => {
Object.defineProperty(process, 'platform', {value: 'darwin'});
const util = require('../src/util');
const tempDir = util.getTempDir();
expect(tempDir).toEqual(path.join('/Users', 'actions', 'temp'));
});
it('gets temp dir for linux', () => {
const util = require('../src/util');
const tempDir = util.getTempDir();
expect(tempDir).toEqual(path.join('/home', 'actions', 'temp'));
});
});
});

View file

@ -9,3 +9,23 @@ if (!$java_version.Contains($args[0]))
{ {
throw "Unexpected version" throw "Unexpected version"
} }
if ($args.Count -lt 2 -or !$args[1])
{
throw "Must supply java path argument"
}
if ($args[1] -ne $Env:JAVA_HOME)
{
throw "Unexpected path"
}
if ($args.Count -lt 3 -or !$args[2])
{
throw "Must supply java version argument"
}
if ($args[0] -ne $args[2])
{
throw "Unexpected version"
}

View file

@ -1,13 +1,33 @@
#!/bin/sh #!/bin/sh
if [ -z "$1" ]; then if [ -z "$1" ]; then
echo "Must supply java version argument" echo "::error::Must supply java version argument"
exit 1 exit 1
fi fi
java_version="$(java -version 2>&1)" java_version="$(java -version 2>&1)"
echo "Found java version: $java_version" echo "Found java version: $java_version"
if [ -z "$(echo $java_version | grep --fixed-strings $1)" ]; then if [ -z "$(echo $java_version | grep --fixed-strings $1)" ]; then
echo "Unexpected version" echo "::error::Unexpected version"
exit 1
fi
if [ -z "$2" ]; then
echo "::error::Must supply java path argument"
exit 1
fi
if [ "$2" != "$JAVA_HOME" ]; then
echo "::error::Unexpected path"
exit 1
fi
if [ -z "$3" ]; then
echo "::error::Must supply java version argument"
exit 1
fi
if [ "$1" != "$3" ]; then
echo "::error::Unexpected version"
exit 1 exit 1
fi fi

View file

@ -25,17 +25,33 @@ inputs:
description: 'ID of the distributionManagement repository in the pom.xml description: 'ID of the distributionManagement repository in the pom.xml
file. Default is `github`' file. Default is `github`'
required: false required: false
default: 'github'
server-username: server-username:
description: 'Environment variable name for the username for authentication description: 'Environment variable name for the username for authentication
to the Apache Maven repository. Default is $GITHUB_ACTOR' to the Apache Maven repository. Default is $GITHUB_ACTOR'
required: false required: false
default: 'GITHUB_ACTOR'
server-password: server-password:
description: 'Environment variable name for password or token for description: 'Environment variable name for password or token for
authentication to the Apache Maven repository. Default is $GITHUB_TOKEN' authentication to the Apache Maven repository. Default is $GITHUB_TOKEN'
required: false required: false
default: 'GITHUB_TOKEN'
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: 'GPG private key to import. Default is empty string.'
required: false
gpg-passphrase:
description: 'Environment variable name for the GPG private key passphrase. Default is
$GPG_PASSPHRASE.'
required: false
outputs:
path:
description: 'Path to where the java environment has been installed (same as $JAVA_HOME)'
version:
description: 'Actual version of the java environment that has been installed'
runs: runs:
using: 'node12' using: 'node12'
main: 'dist/index.js' main: 'dist/setup/index.js'
post: 'dist/cleanup/index.js'

1707
dist/cleanup/index.js vendored Normal file

File diff suppressed because it is too large Load diff

53
dist/cleanup/licenses.txt vendored Normal file
View file

@ -0,0 +1,53 @@
@actions/core
MIT
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@actions/exec
MIT
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@actions/io
MIT
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

35363
dist/setup/index.js vendored Normal file

File diff suppressed because it is too large Load diff

289
dist/setup/licenses.txt vendored Normal file
View file

@ -0,0 +1,289 @@
@actions/core
MIT
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@actions/exec
MIT
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@actions/http-client
MIT
Actions Http Client for Node.js
Copyright (c) GitHub, Inc.
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@actions/io
MIT
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@actions/tool-cache
MIT
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@oozcitak/dom
MIT
MIT License
Copyright (c) 2019 Ozgur Ozcitak
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@oozcitak/infra
MIT
MIT License
Copyright (c) 2019 Ozgur Ozcitak
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@oozcitak/url
MIT
MIT License
Copyright (c) 2019 Ozgur Ozcitak
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@oozcitak/util
MIT
MIT License
Copyright (c) 2019 Ozgur Ozcitak
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
semver
ISC
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
tunnel
MIT
The MIT License (MIT)
Copyright (c) 2012 Koichi Kobayashi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
uuid
MIT
The MIT License (MIT)
Copyright (c) 2010-2016 Robert Kieffer and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
xmlbuilder2
MIT
MIT License
Copyright (c) 2019 Ozgur Ozcitak
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

90
package-lock.json generated
View file

@ -18,9 +18,9 @@
} }
}, },
"@actions/http-client": { "@actions/http-client": {
"version": "1.0.6", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.6.tgz", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz",
"integrity": "sha512-LGmio4w98UyGX33b/W6V6Nx/sQHRXZ859YlMkn36wPsXPB82u8xTVlA/Dq2DXrm6lEq9RVmisRJa1c+HETAIJA==", "integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==",
"requires": { "requires": {
"tunnel": "0.0.6" "tunnel": "0.0.6"
} }
@ -430,6 +430,74 @@
"@types/yargs": "^13.0.0" "@types/yargs": "^13.0.0"
} }
}, },
"@oozcitak/dom": {
"version": "1.15.5",
"resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.5.tgz",
"integrity": "sha512-L6v3Mwb0TaYBYgeYlIeBaHnc+2ZEaDSbFiRm5KmqZQSoBlbPlf+l6aIH/sD5GUf2MYwULw00LT7+dOnEuAEC0A==",
"requires": {
"@oozcitak/infra": "1.0.5",
"@oozcitak/url": "1.0.0",
"@oozcitak/util": "8.0.0"
},
"dependencies": {
"@oozcitak/util": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.0.0.tgz",
"integrity": "sha512-+9Hq6yuoq/3TRV/n/xcpydGBq2qN2/DEDMqNTG7rm95K6ZE2/YY/sPyx62+1n8QsE9O26e5M1URlXsk+AnN9Jw=="
}
}
},
"@oozcitak/infra": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.5.tgz",
"integrity": "sha512-o+zZH7M6l5e3FaAWy3ojaPIVN5eusaYPrKm6MZQt0DKNdgXa2wDYExjpP0t/zx+GoQgQKzLu7cfD8rHCLt8JrQ==",
"requires": {
"@oozcitak/util": "8.0.0"
},
"dependencies": {
"@oozcitak/util": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.0.0.tgz",
"integrity": "sha512-+9Hq6yuoq/3TRV/n/xcpydGBq2qN2/DEDMqNTG7rm95K6ZE2/YY/sPyx62+1n8QsE9O26e5M1URlXsk+AnN9Jw=="
}
}
},
"@oozcitak/url": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-1.0.0.tgz",
"integrity": "sha512-LGrMeSxeLzsdaitxq3ZmBRVOrlRRQIgNNci6L0VRnOKlJFuRIkNm4B+BObXPCJA6JT5bEJtrrwjn30jueHJYZQ==",
"requires": {
"@oozcitak/infra": "1.0.3",
"@oozcitak/util": "1.0.2"
},
"dependencies": {
"@oozcitak/infra": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.3.tgz",
"integrity": "sha512-9O2wxXGnRzy76O1XUxESxDGsXT5kzETJPvYbreO4mv6bqe1+YSuux2cZTagjJ/T4UfEwFJz5ixanOqB0QgYAag==",
"requires": {
"@oozcitak/util": "1.0.1"
},
"dependencies": {
"@oozcitak/util": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-1.0.1.tgz",
"integrity": "sha512-dFwFqcKrQnJ2SapOmRD1nQWEZUtbtIy9Y6TyJquzsalWNJsKIPxmTI0KG6Ypyl8j7v89L2wixH9fQDNrF78hKg=="
}
}
},
"@oozcitak/util": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-1.0.2.tgz",
"integrity": "sha512-4n8B1cWlJleSOSba5gxsMcN4tO8KkkcvXhNWW+ADqvq9Xj+Lrl9uCa90GRpjekqQJyt84aUX015DG81LFpZYXA=="
}
}
},
"@oozcitak/util": {
"version": "8.3.3",
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.3.tgz",
"integrity": "sha512-Ufpab7G5PfnEhQyy5kDg9C8ltWJjsVT1P/IYqacjstaqydG4Q21HAT2HUZQYBrC/a1ZLKCz87pfydlDvv8y97w=="
},
"@types/babel__core": { "@types/babel__core": {
"version": "7.1.3", "version": "7.1.3",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz",
@ -3308,9 +3376,9 @@
} }
}, },
"lodash": { "lodash": {
"version": "4.17.15", "version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"dev": true "dev": true
}, },
"lodash.memoize": { "lodash.memoize": {
@ -4955,6 +5023,16 @@
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
"dev": true "dev": true
}, },
"xmlbuilder2": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-2.1.2.tgz",
"integrity": "sha512-PI710tmtVlQ5VmwzbRTuhmVhKnj9pM8Si+iOZCV2g2SNo3gCrpzR2Ka9wNzZtqfD+mnP+xkrqoNy0sjKZqP4Dg==",
"requires": {
"@oozcitak/dom": "1.15.5",
"@oozcitak/infra": "1.0.5",
"@oozcitak/util": "8.3.3"
}
},
"y18n": { "y18n": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",

View file

@ -5,11 +5,11 @@
"description": "setup java action", "description": "setup java action",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
"build": "ncc build src/setup-java.ts", "build": "ncc build -o dist/setup src/setup-java.ts && ncc build -o dist/cleanup src/cleanup-java.ts",
"format": "prettier --write **/*.ts", "format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.ts", "format-check": "prettier --check **/*.ts",
"prerelease": "npm run-script build", "prerelease": "npm run-script build",
"release": "git add -f dist/index.js", "release": "git add -f dist/setup/index.js dist/cleanup/index.js",
"test": "jest" "test": "jest"
}, },
"repository": { "repository": {
@ -26,10 +26,11 @@
"dependencies": { "dependencies": {
"@actions/core": "^1.0.0", "@actions/core": "^1.0.0",
"@actions/exec": "^1.0.0", "@actions/exec": "^1.0.0",
"@actions/http-client": "^1.0.6", "@actions/http-client": "^1.0.8",
"@actions/io": "^1.0.0", "@actions/io": "^1.0.0",
"@actions/tool-cache": "^1.3.1", "@actions/tool-cache": "^1.3.1",
"semver": "^6.1.1" "semver": "^6.1.1",
"xmlbuilder2": "^2.1.2"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^24.0.13", "@types/jest": "^24.0.13",

View file

@ -3,60 +3,73 @@ 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 {create as xmlCreate} from 'xmlbuilder2';
import * as constants from './constants';
export const M2_DIR = '.m2'; export const M2_DIR = '.m2';
export const SETTINGS_FILE = 'settings.xml'; export const SETTINGS_FILE = 'settings.xml';
export const DEFAULT_ID = 'github';
export const DEFAULT_USERNAME = 'GITHUB_ACTOR';
export const DEFAULT_PASSWORD = 'GITHUB_TOKEN';
export async function configAuthentication( export async function configAuthentication(
id = DEFAULT_ID, id: string,
username = DEFAULT_USERNAME, username: string,
password = DEFAULT_PASSWORD password: string,
gpgPassphrase: string | undefined = undefined
) { ) {
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 ? '$' + gpgPassphrase : null}`
); );
// 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(constants.INPUT_SETTINGS_PATH) || os.homedir(),
core.getInput('settings-path') ? '' : M2_DIR core.getInput(constants.INPUT_SETTINGS_PATH) ? '' : M2_DIR
);
await io.mkdirP(settingsDirectory);
core.debug(`created directory ${settingsDirectory}`);
await write(
settingsDirectory,
generate(id, username, password, gpgPassphrase)
); );
await io.mkdirP(directory);
core.debug(`created directory ${directory}`);
await write(directory, generate(id, username, password));
}
function escapeXML(value: string) {
return value
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&apos;');
} }
// only exported for testing purposes // only exported for testing purposes
export function generate( export function generate(
id = DEFAULT_ID, id: string,
username = DEFAULT_USERNAME, username: string,
password = DEFAULT_PASSWORD password: string,
gpgPassphrase: string | undefined = undefined
) { ) {
return ` const xmlObj: {[key: string]: any} = {
<settings> settings: {
<servers> '@xmlns': 'http://maven.apache.org/SETTINGS/1.0.0',
<server> '@xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
<id>${escapeXML(id)}</id> '@xsi:schemaLocation':
<username>\${env.${escapeXML(username)}}</username> 'http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd',
<password>\${env.${escapeXML(password)}}</password> servers: {
</server> server: [
</servers> {
</settings> id: id,
`; username: `\${env.${username}}`,
password: `\${env.${password}}`
}
]
}
}
};
if (gpgPassphrase) {
const gpgServer = {
id: 'gpg.passphrase',
passphrase: `\${env.${gpgPassphrase}}`
};
xmlObj.settings.servers.server.push(gpgServer);
}
return xmlCreate(xmlObj).end({headless: true, prettyPrint: true, width: 80});
} }
async function write(directory: string, settings: string) { async function write(directory: string, settings: string) {

19
src/cleanup-java.ts Normal file
View file

@ -0,0 +1,19 @@
import * as core from '@actions/core';
import * as gpg from './gpg';
import * as constants from './constants';
async function run() {
if (core.getInput(constants.INPUT_GPG_PRIVATE_KEY, {required: false})) {
core.info('removing private key from keychain');
try {
const keyFingerprint = core.getState(
constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT
);
await gpg.deleteKey(keyFingerprint);
} catch (error) {
core.setFailed('failed to remove private key');
}
}
}
run();

16
src/constants.ts Normal file
View file

@ -0,0 +1,16 @@
export const INPUT_VERSION = 'version';
export const INPUT_JAVA_VERSION = 'java-version';
export const INPUT_ARCHITECTURE = 'architecture';
export const INPUT_JAVA_PACKAGE = 'java-package';
export const INPUT_JDK_FILE = 'jdkFile';
export const INPUT_SERVER_ID = 'server-id';
export const INPUT_SERVER_USERNAME = 'server-username';
export const INPUT_SERVER_PASSWORD = 'server-password';
export const INPUT_SETTINGS_PATH = 'settings-path';
export const INPUT_GPG_PRIVATE_KEY = 'gpg-private-key';
export const INPUT_GPG_PASSPHRASE = 'gpg-passphrase';
export const INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined;
export const INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE';
export const STATE_GPG_PRIVATE_KEY_FINGERPRINT = 'gpg-private-key-fingerprint';

58
src/gpg.ts Normal file
View file

@ -0,0 +1,58 @@
import * as fs from 'fs';
import * as path from 'path';
import * as io from '@actions/io';
import * as exec from '@actions/exec';
import * as util from './util';
import {ExecOptions} from '@actions/exec/lib/interfaces';
export const PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc');
const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/;
export async function importKey(privateKey: string) {
fs.writeFileSync(PRIVATE_KEY_FILE, privateKey, {
encoding: 'utf-8',
flag: 'w'
});
let output = '';
const options: ExecOptions = {
silent: true,
listeners: {
stdout: (data: Buffer) => {
output += data.toString();
}
}
};
await exec.exec(
'gpg',
[
'--batch',
'--import-options',
'import-show',
'--import',
PRIVATE_KEY_FILE
],
options
);
await io.rmRF(PRIVATE_KEY_FILE);
const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX);
return match && match[0];
}
export async function deleteKey(keyFingerprint: string) {
await exec.exec(
'gpg',
['--batch', '--yes', '--delete-secret-keys', keyFingerprint],
{silent: true}
);
await exec.exec(
'gpg',
['--batch', '--yes', '--delete-keys', keyFingerprint],
{silent: true}
);
}

View file

@ -1,5 +1,3 @@
let tempDirectory = process.env['RUNNER_TEMP'] || '';
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'; import * as exec from '@actions/exec';
@ -8,23 +6,10 @@ import * as tc from '@actions/tool-cache';
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as semver from 'semver'; import * as semver from 'semver';
import * as util from './util';
const IS_WINDOWS = process.platform === 'win32'; const tempDirectory = util.getTempDir();
const IS_WINDOWS = util.isWindows();
if (!tempDirectory) {
let baseLocation;
if (IS_WINDOWS) {
// On windows use the USERPROFILE env variable
baseLocation = process.env['USERPROFILE'] || 'C:\\';
} else {
if (process.platform === 'darwin') {
baseLocation = '/Users';
} else {
baseLocation = '/home';
}
}
tempDirectory = path.join(baseLocation, 'actions', 'temp');
}
export async function getJava( export async function getJava(
version: string, version: string,
@ -87,9 +72,17 @@ export async function getJava(
} }
let extendedJavaHome = 'JAVA_HOME_' + version + '_' + arch; let extendedJavaHome = 'JAVA_HOME_' + version + '_' + arch;
core.exportVariable(extendedJavaHome, toolPath); //TODO: remove for v2
// For portability reasons environment variables should only consist of
// uppercase letters, digits, and the underscore. Therefore we convert
// the extendedJavaHome variable to upper case and replace '.' symbols and
// any other non-alphanumeric characters with an underscore.
extendedJavaHome = extendedJavaHome.toUpperCase().replace(/[^0-9A-Z_]/g, '_');
core.exportVariable('JAVA_HOME', toolPath); core.exportVariable('JAVA_HOME', toolPath);
core.exportVariable(extendedJavaHome, toolPath); core.exportVariable(extendedJavaHome, toolPath);
core.addPath(path.join(toolPath, 'bin')); core.addPath(path.join(toolPath, 'bin'));
core.setOutput('path', toolPath);
core.setOutput('version', version);
} }
function getCacheVersionString(version: string) { function getCacheVersionString(version: string) {

View file

@ -1,30 +1,55 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as installer from './installer'; import * as installer from './installer';
import * as auth from './auth'; import * as auth from './auth';
import * as gpg from './gpg';
import * as constants from './constants';
import * as path from 'path'; import * as path from 'path';
async function run() { async function run() {
try { try {
let version = core.getInput('version'); let version = core.getInput(constants.INPUT_VERSION);
if (!version) { if (!version) {
version = core.getInput('java-version', {required: true}); version = core.getInput(constants.INPUT_JAVA_VERSION, {required: true});
} }
const arch = core.getInput('architecture', {required: true}); const arch = core.getInput(constants.INPUT_ARCHITECTURE, {required: true});
const javaPackage = core.getInput('java-package', {required: true}); const javaPackage = core.getInput(constants.INPUT_JAVA_PACKAGE, {
const jdkFile = core.getInput('jdkFile', {required: false}) || ''; required: true
});
const jdkFile = core.getInput(constants.INPUT_JDK_FILE, {required: false});
await installer.getJava(version, arch, jdkFile, javaPackage); await installer.getJava(version, arch, jdkFile, javaPackage);
const matchersPath = path.join(__dirname, '..', '.github'); const matchersPath = path.join(__dirname, '..', '..', '.github');
console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); core.info(`##[add-matcher]${path.join(matchersPath, 'java.json')}`);
const id = core.getInput('server-id', {required: false}) || undefined; const id = core.getInput(constants.INPUT_SERVER_ID, {required: false});
const username = const username = core.getInput(constants.INPUT_SERVER_USERNAME, {
core.getInput('server-username', {required: false}) || undefined; required: false
const password = });
core.getInput('server-password', {required: false}) || undefined; const password = core.getInput(constants.INPUT_SERVER_PASSWORD, {
required: false
});
const gpgPrivateKey =
core.getInput(constants.INPUT_GPG_PRIVATE_KEY, {required: false}) ||
constants.INPUT_DEFAULT_GPG_PRIVATE_KEY;
const gpgPassphrase =
core.getInput(constants.INPUT_GPG_PASSPHRASE, {required: false}) ||
(gpgPrivateKey ? constants.INPUT_DEFAULT_GPG_PASSPHRASE : undefined);
await auth.configAuthentication(id, username, password); if (gpgPrivateKey) {
core.setSecret(gpgPrivateKey);
}
await auth.configAuthentication(id, username, password, gpgPassphrase);
if (gpgPrivateKey) {
core.info('importing private key');
const keyFingerprint = (await gpg.importKey(gpgPrivateKey)) || '';
core.saveState(
constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT,
keyFingerprint
);
}
} catch (error) { } catch (error) {
core.setFailed(error.message); core.setFailed(error.message);
} }

26
src/util.ts Normal file
View file

@ -0,0 +1,26 @@
import * as path from 'path';
export function getTempDir() {
let tempDirectory = process.env.RUNNER_TEMP;
if (tempDirectory === undefined) {
let baseLocation;
if (isWindows()) {
// On windows use the USERPROFILE env variable
baseLocation = process.env['USERPROFILE']
? process.env['USERPROFILE']
: 'C:\\';
} else {
if (process.platform === 'darwin') {
baseLocation = '/Users';
} else {
baseLocation = '/home';
}
}
tempDirectory = path.join(baseLocation, 'actions', 'temp');
}
return tempDirectory;
}
export function isWindows() {
return process.platform === 'win32';
}