Added support for GPG
This commit is contained in:
		
							parent
							
								
									5c87b70ffe
								
							
						
					
					
						commit
						d94db22179
					
				
							
								
								
									
										19
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								README.md
									
									
									
									
									
								
							| @ -113,36 +113,55 @@ 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.*** | ||||||
|  | |||||||
| @ -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.&<>"''"><&}</password> |       <password>\${env.&<>"''"><&}</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.&<>"''"><&}</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
									
								
							
							
						
						
									
										56
									
								
								__tests__/gpg.test.ts
									
									
									
									
									
										Normal 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); | ||||||
|  |   }, 300000); | ||||||
|  | 
 | ||||||
|  |   afterAll(async () => { | ||||||
|  |     try { | ||||||
|  |       await io.rmRF(tempDir); | ||||||
|  |     } catch { | ||||||
|  |       console.log('Failed to remove test directories'); | ||||||
|  |     } | ||||||
|  |   }, 100000); | ||||||
|  | 
 | ||||||
|  |   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
									
								
							
							
						
						
									
										61
									
								
								__tests__/util.test.ts
									
									
									
									
									
										Normal 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')); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
							
								
								
									
										10
									
								
								action.yml
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								action.yml
									
									
									
									
									
								
							| @ -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: '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 | ||||||
| runs: | runs: | ||||||
|   using: 'node12' |   using: 'node12' | ||||||
|   main: 'dist/index.js' |   main: 'dist/setup/index.js' | ||||||
|  |   post: 'dist/cleanup/index.js' | ||||||
|  | |||||||
							
								
								
									
										1682
									
								
								dist/cleanup/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1682
									
								
								dist/cleanup/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,1682 @@ | |||||||
|  | module.exports = | ||||||
|  | /******/ (function(modules, runtime) { // webpackBootstrap
 | ||||||
|  | /******/ 	"use strict"; | ||||||
|  | /******/ 	// The module cache
 | ||||||
|  | /******/ 	var installedModules = {}; | ||||||
|  | /******/ | ||||||
|  | /******/ 	// The require function
 | ||||||
|  | /******/ 	function __webpack_require__(moduleId) { | ||||||
|  | /******/ | ||||||
|  | /******/ 		// Check if module is in cache
 | ||||||
|  | /******/ 		if(installedModules[moduleId]) { | ||||||
|  | /******/ 			return installedModules[moduleId].exports; | ||||||
|  | /******/ 		} | ||||||
|  | /******/ 		// Create a new module (and put it into the cache)
 | ||||||
|  | /******/ 		var module = installedModules[moduleId] = { | ||||||
|  | /******/ 			i: moduleId, | ||||||
|  | /******/ 			l: false, | ||||||
|  | /******/ 			exports: {} | ||||||
|  | /******/ 		}; | ||||||
|  | /******/ | ||||||
|  | /******/ 		// Execute the module function
 | ||||||
|  | /******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | ||||||
|  | /******/ | ||||||
|  | /******/ 		// Flag the module as loaded
 | ||||||
|  | /******/ 		module.l = true; | ||||||
|  | /******/ | ||||||
|  | /******/ 		// Return the exports of the module
 | ||||||
|  | /******/ 		return module.exports; | ||||||
|  | /******/ 	} | ||||||
|  | /******/ | ||||||
|  | /******/ | ||||||
|  | /******/ 	__webpack_require__.ab = __dirname + "/"; | ||||||
|  | /******/ | ||||||
|  | /******/ 	// the startup function
 | ||||||
|  | /******/ 	function startup() { | ||||||
|  | /******/ 		// Load entry module and return exports
 | ||||||
|  | /******/ 		return __webpack_require__(219); | ||||||
|  | /******/ 	}; | ||||||
|  | /******/ | ||||||
|  | /******/ 	// run startup
 | ||||||
|  | /******/ 	return startup(); | ||||||
|  | /******/ }) | ||||||
|  | /************************************************************************/ | ||||||
|  | /******/ ({ | ||||||
|  | 
 | ||||||
|  | /***/ 1: | ||||||
|  | /***/ (function(__unusedmodule, exports, __webpack_require__) { | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||||||
|  |     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||||||
|  |     return new (P || (P = Promise))(function (resolve, reject) { | ||||||
|  |         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||||||
|  |         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||||||
|  |         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||||||
|  |         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||||||
|  |     }); | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | const childProcess = __webpack_require__(129); | ||||||
|  | const path = __webpack_require__(622); | ||||||
|  | const util_1 = __webpack_require__(669); | ||||||
|  | const ioUtil = __webpack_require__(672); | ||||||
|  | const exec = util_1.promisify(childProcess.exec); | ||||||
|  | /** | ||||||
|  |  * Copies a file or folder. | ||||||
|  |  * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
 | ||||||
|  |  * | ||||||
|  |  * @param     source    source path | ||||||
|  |  * @param     dest      destination path | ||||||
|  |  * @param     options   optional. See CopyOptions. | ||||||
|  |  */ | ||||||
|  | function cp(source, dest, options = {}) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         const { force, recursive } = readCopyOptions(options); | ||||||
|  |         const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null; | ||||||
|  |         // Dest is an existing file, but not forcing
 | ||||||
|  |         if (destStat && destStat.isFile() && !force) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         // If dest is an existing directory, should copy inside.
 | ||||||
|  |         const newDest = destStat && destStat.isDirectory() | ||||||
|  |             ? path.join(dest, path.basename(source)) | ||||||
|  |             : dest; | ||||||
|  |         if (!(yield ioUtil.exists(source))) { | ||||||
|  |             throw new Error(`no such file or directory: ${source}`); | ||||||
|  |         } | ||||||
|  |         const sourceStat = yield ioUtil.stat(source); | ||||||
|  |         if (sourceStat.isDirectory()) { | ||||||
|  |             if (!recursive) { | ||||||
|  |                 throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`); | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 yield cpDirRecursive(source, newDest, 0, force); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             if (path.relative(source, newDest) === '') { | ||||||
|  |                 // a file cannot be copied to itself
 | ||||||
|  |                 throw new Error(`'${newDest}' and '${source}' are the same file`); | ||||||
|  |             } | ||||||
|  |             yield copyFile(source, newDest, force); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.cp = cp; | ||||||
|  | /** | ||||||
|  |  * Moves a path. | ||||||
|  |  * | ||||||
|  |  * @param     source    source path | ||||||
|  |  * @param     dest      destination path | ||||||
|  |  * @param     options   optional. See MoveOptions. | ||||||
|  |  */ | ||||||
|  | function mv(source, dest, options = {}) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         if (yield ioUtil.exists(dest)) { | ||||||
|  |             let destExists = true; | ||||||
|  |             if (yield ioUtil.isDirectory(dest)) { | ||||||
|  |                 // If dest is directory copy src into dest
 | ||||||
|  |                 dest = path.join(dest, path.basename(source)); | ||||||
|  |                 destExists = yield ioUtil.exists(dest); | ||||||
|  |             } | ||||||
|  |             if (destExists) { | ||||||
|  |                 if (options.force == null || options.force) { | ||||||
|  |                     yield rmRF(dest); | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|  |                     throw new Error('Destination already exists'); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         yield mkdirP(path.dirname(dest)); | ||||||
|  |         yield ioUtil.rename(source, dest); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.mv = mv; | ||||||
|  | /** | ||||||
|  |  * Remove a path recursively with force | ||||||
|  |  * | ||||||
|  |  * @param inputPath path to remove | ||||||
|  |  */ | ||||||
|  | function rmRF(inputPath) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         if (ioUtil.IS_WINDOWS) { | ||||||
|  |             // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
 | ||||||
|  |             // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
 | ||||||
|  |             try { | ||||||
|  |                 if (yield ioUtil.isDirectory(inputPath, true)) { | ||||||
|  |                     yield exec(`rd /s /q "${inputPath}"`); | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|  |                     yield exec(`del /f /a "${inputPath}"`); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             catch (err) { | ||||||
|  |                 // if you try to delete a file that doesn't exist, desired result is achieved
 | ||||||
|  |                 // other errors are valid
 | ||||||
|  |                 if (err.code !== 'ENOENT') | ||||||
|  |                     throw err; | ||||||
|  |             } | ||||||
|  |             // Shelling out fails to remove a symlink folder with missing source, this unlink catches that
 | ||||||
|  |             try { | ||||||
|  |                 yield ioUtil.unlink(inputPath); | ||||||
|  |             } | ||||||
|  |             catch (err) { | ||||||
|  |                 // if you try to delete a file that doesn't exist, desired result is achieved
 | ||||||
|  |                 // other errors are valid
 | ||||||
|  |                 if (err.code !== 'ENOENT') | ||||||
|  |                     throw err; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             let isDir = false; | ||||||
|  |             try { | ||||||
|  |                 isDir = yield ioUtil.isDirectory(inputPath); | ||||||
|  |             } | ||||||
|  |             catch (err) { | ||||||
|  |                 // if you try to delete a file that doesn't exist, desired result is achieved
 | ||||||
|  |                 // other errors are valid
 | ||||||
|  |                 if (err.code !== 'ENOENT') | ||||||
|  |                     throw err; | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             if (isDir) { | ||||||
|  |                 yield exec(`rm -rf "${inputPath}"`); | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 yield ioUtil.unlink(inputPath); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.rmRF = rmRF; | ||||||
|  | /** | ||||||
|  |  * Make a directory.  Creates the full path with folders in between | ||||||
|  |  * Will throw if it fails | ||||||
|  |  * | ||||||
|  |  * @param   fsPath        path to create | ||||||
|  |  * @returns Promise<void> | ||||||
|  |  */ | ||||||
|  | function mkdirP(fsPath) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         yield ioUtil.mkdirP(fsPath); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.mkdirP = mkdirP; | ||||||
|  | /** | ||||||
|  |  * Returns path of a tool had the tool actually been invoked.  Resolves via paths. | ||||||
|  |  * If you check and the tool does not exist, it will throw. | ||||||
|  |  * | ||||||
|  |  * @param     tool              name of the tool | ||||||
|  |  * @param     check             whether to check if tool exists | ||||||
|  |  * @returns   Promise<string>   path to tool | ||||||
|  |  */ | ||||||
|  | function which(tool, check) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         if (!tool) { | ||||||
|  |             throw new Error("parameter 'tool' is required"); | ||||||
|  |         } | ||||||
|  |         // recursive when check=true
 | ||||||
|  |         if (check) { | ||||||
|  |             const result = yield which(tool, false); | ||||||
|  |             if (!result) { | ||||||
|  |                 if (ioUtil.IS_WINDOWS) { | ||||||
|  |                     throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`); | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|  |                     throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         try { | ||||||
|  |             // build the list of extensions to try
 | ||||||
|  |             const extensions = []; | ||||||
|  |             if (ioUtil.IS_WINDOWS && process.env.PATHEXT) { | ||||||
|  |                 for (const extension of process.env.PATHEXT.split(path.delimiter)) { | ||||||
|  |                     if (extension) { | ||||||
|  |                         extensions.push(extension); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             // if it's rooted, return it if exists. otherwise return empty.
 | ||||||
|  |             if (ioUtil.isRooted(tool)) { | ||||||
|  |                 const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions); | ||||||
|  |                 if (filePath) { | ||||||
|  |                     return filePath; | ||||||
|  |                 } | ||||||
|  |                 return ''; | ||||||
|  |             } | ||||||
|  |             // if any path separators, return empty
 | ||||||
|  |             if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) { | ||||||
|  |                 return ''; | ||||||
|  |             } | ||||||
|  |             // build the list of directories
 | ||||||
|  |             //
 | ||||||
|  |             // Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
 | ||||||
|  |             // it feels like we should not do this. Checking the current directory seems like more of a use
 | ||||||
|  |             // case of a shell, and the which() function exposed by the toolkit should strive for consistency
 | ||||||
|  |             // across platforms.
 | ||||||
|  |             const directories = []; | ||||||
|  |             if (process.env.PATH) { | ||||||
|  |                 for (const p of process.env.PATH.split(path.delimiter)) { | ||||||
|  |                     if (p) { | ||||||
|  |                         directories.push(p); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             // return the first match
 | ||||||
|  |             for (const directory of directories) { | ||||||
|  |                 const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions); | ||||||
|  |                 if (filePath) { | ||||||
|  |                     return filePath; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return ''; | ||||||
|  |         } | ||||||
|  |         catch (err) { | ||||||
|  |             throw new Error(`which failed with message ${err.message}`); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.which = which; | ||||||
|  | function readCopyOptions(options) { | ||||||
|  |     const force = options.force == null ? true : options.force; | ||||||
|  |     const recursive = Boolean(options.recursive); | ||||||
|  |     return { force, recursive }; | ||||||
|  | } | ||||||
|  | function cpDirRecursive(sourceDir, destDir, currentDepth, force) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         // Ensure there is not a run away recursive copy
 | ||||||
|  |         if (currentDepth >= 255) | ||||||
|  |             return; | ||||||
|  |         currentDepth++; | ||||||
|  |         yield mkdirP(destDir); | ||||||
|  |         const files = yield ioUtil.readdir(sourceDir); | ||||||
|  |         for (const fileName of files) { | ||||||
|  |             const srcFile = `${sourceDir}/${fileName}`; | ||||||
|  |             const destFile = `${destDir}/${fileName}`; | ||||||
|  |             const srcFileStat = yield ioUtil.lstat(srcFile); | ||||||
|  |             if (srcFileStat.isDirectory()) { | ||||||
|  |                 // Recurse
 | ||||||
|  |                 yield cpDirRecursive(srcFile, destFile, currentDepth, force); | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 yield copyFile(srcFile, destFile, force); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         // Change the mode for the newly created directory
 | ||||||
|  |         yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | // Buffered file copy
 | ||||||
|  | function copyFile(srcFile, destFile, force) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) { | ||||||
|  |             // unlink/re-link it
 | ||||||
|  |             try { | ||||||
|  |                 yield ioUtil.lstat(destFile); | ||||||
|  |                 yield ioUtil.unlink(destFile); | ||||||
|  |             } | ||||||
|  |             catch (e) { | ||||||
|  |                 // Try to override file permission
 | ||||||
|  |                 if (e.code === 'EPERM') { | ||||||
|  |                     yield ioUtil.chmod(destFile, '0666'); | ||||||
|  |                     yield ioUtil.unlink(destFile); | ||||||
|  |                 } | ||||||
|  |                 // other errors = it doesn't exist, no work to do
 | ||||||
|  |             } | ||||||
|  |             // Copy over symlink
 | ||||||
|  |             const symlinkFull = yield ioUtil.readlink(srcFile); | ||||||
|  |             yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null); | ||||||
|  |         } | ||||||
|  |         else if (!(yield ioUtil.exists(destFile)) || force) { | ||||||
|  |             yield ioUtil.copyFile(srcFile, destFile); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | //# sourceMappingURL=io.js.map
 | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 9: | ||||||
|  | /***/ (function(__unusedmodule, exports, __webpack_require__) { | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||||||
|  |     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||||||
|  |     return new (P || (P = Promise))(function (resolve, reject) { | ||||||
|  |         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||||||
|  |         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||||||
|  |         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||||||
|  |         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||||||
|  |     }); | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | const os = __webpack_require__(87); | ||||||
|  | const events = __webpack_require__(614); | ||||||
|  | const child = __webpack_require__(129); | ||||||
|  | const path = __webpack_require__(622); | ||||||
|  | const io = __webpack_require__(1); | ||||||
|  | const ioUtil = __webpack_require__(672); | ||||||
|  | /* eslint-disable @typescript-eslint/unbound-method */ | ||||||
|  | const IS_WINDOWS = process.platform === 'win32'; | ||||||
|  | /* | ||||||
|  |  * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way. | ||||||
|  |  */ | ||||||
|  | class ToolRunner extends events.EventEmitter { | ||||||
|  |     constructor(toolPath, args, options) { | ||||||
|  |         super(); | ||||||
|  |         if (!toolPath) { | ||||||
|  |             throw new Error("Parameter 'toolPath' cannot be null or empty."); | ||||||
|  |         } | ||||||
|  |         this.toolPath = toolPath; | ||||||
|  |         this.args = args || []; | ||||||
|  |         this.options = options || {}; | ||||||
|  |     } | ||||||
|  |     _debug(message) { | ||||||
|  |         if (this.options.listeners && this.options.listeners.debug) { | ||||||
|  |             this.options.listeners.debug(message); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     _getCommandString(options, noPrefix) { | ||||||
|  |         const toolPath = this._getSpawnFileName(); | ||||||
|  |         const args = this._getSpawnArgs(options); | ||||||
|  |         let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
 | ||||||
|  |         if (IS_WINDOWS) { | ||||||
|  |             // Windows + cmd file
 | ||||||
|  |             if (this._isCmdFile()) { | ||||||
|  |                 cmd += toolPath; | ||||||
|  |                 for (const a of args) { | ||||||
|  |                     cmd += ` ${a}`; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             // Windows + verbatim
 | ||||||
|  |             else if (options.windowsVerbatimArguments) { | ||||||
|  |                 cmd += `"${toolPath}"`; | ||||||
|  |                 for (const a of args) { | ||||||
|  |                     cmd += ` ${a}`; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             // Windows (regular)
 | ||||||
|  |             else { | ||||||
|  |                 cmd += this._windowsQuoteCmdArg(toolPath); | ||||||
|  |                 for (const a of args) { | ||||||
|  |                     cmd += ` ${this._windowsQuoteCmdArg(a)}`; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             // OSX/Linux - this can likely be improved with some form of quoting.
 | ||||||
|  |             // creating processes on Unix is fundamentally different than Windows.
 | ||||||
|  |             // on Unix, execvp() takes an arg array.
 | ||||||
|  |             cmd += toolPath; | ||||||
|  |             for (const a of args) { | ||||||
|  |                 cmd += ` ${a}`; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return cmd; | ||||||
|  |     } | ||||||
|  |     _processLineBuffer(data, strBuffer, onLine) { | ||||||
|  |         try { | ||||||
|  |             let s = strBuffer + data.toString(); | ||||||
|  |             let n = s.indexOf(os.EOL); | ||||||
|  |             while (n > -1) { | ||||||
|  |                 const line = s.substring(0, n); | ||||||
|  |                 onLine(line); | ||||||
|  |                 // the rest of the string ...
 | ||||||
|  |                 s = s.substring(n + os.EOL.length); | ||||||
|  |                 n = s.indexOf(os.EOL); | ||||||
|  |             } | ||||||
|  |             strBuffer = s; | ||||||
|  |         } | ||||||
|  |         catch (err) { | ||||||
|  |             // streaming lines to console is best effort.  Don't fail a build.
 | ||||||
|  |             this._debug(`error processing line. Failed with error ${err}`); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     _getSpawnFileName() { | ||||||
|  |         if (IS_WINDOWS) { | ||||||
|  |             if (this._isCmdFile()) { | ||||||
|  |                 return process.env['COMSPEC'] || 'cmd.exe'; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return this.toolPath; | ||||||
|  |     } | ||||||
|  |     _getSpawnArgs(options) { | ||||||
|  |         if (IS_WINDOWS) { | ||||||
|  |             if (this._isCmdFile()) { | ||||||
|  |                 let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`; | ||||||
|  |                 for (const a of this.args) { | ||||||
|  |                     argline += ' '; | ||||||
|  |                     argline += options.windowsVerbatimArguments | ||||||
|  |                         ? a | ||||||
|  |                         : this._windowsQuoteCmdArg(a); | ||||||
|  |                 } | ||||||
|  |                 argline += '"'; | ||||||
|  |                 return [argline]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return this.args; | ||||||
|  |     } | ||||||
|  |     _endsWith(str, end) { | ||||||
|  |         return str.endsWith(end); | ||||||
|  |     } | ||||||
|  |     _isCmdFile() { | ||||||
|  |         const upperToolPath = this.toolPath.toUpperCase(); | ||||||
|  |         return (this._endsWith(upperToolPath, '.CMD') || | ||||||
|  |             this._endsWith(upperToolPath, '.BAT')); | ||||||
|  |     } | ||||||
|  |     _windowsQuoteCmdArg(arg) { | ||||||
|  |         // for .exe, apply the normal quoting rules that libuv applies
 | ||||||
|  |         if (!this._isCmdFile()) { | ||||||
|  |             return this._uvQuoteCmdArg(arg); | ||||||
|  |         } | ||||||
|  |         // otherwise apply quoting rules specific to the cmd.exe command line parser.
 | ||||||
|  |         // the libuv rules are generic and are not designed specifically for cmd.exe
 | ||||||
|  |         // command line parser.
 | ||||||
|  |         //
 | ||||||
|  |         // for a detailed description of the cmd.exe command line parser, refer to
 | ||||||
|  |         // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912
 | ||||||
|  |         // need quotes for empty arg
 | ||||||
|  |         if (!arg) { | ||||||
|  |             return '""'; | ||||||
|  |         } | ||||||
|  |         // determine whether the arg needs to be quoted
 | ||||||
|  |         const cmdSpecialChars = [ | ||||||
|  |             ' ', | ||||||
|  |             '\t', | ||||||
|  |             '&', | ||||||
|  |             '(', | ||||||
|  |             ')', | ||||||
|  |             '[', | ||||||
|  |             ']', | ||||||
|  |             '{', | ||||||
|  |             '}', | ||||||
|  |             '^', | ||||||
|  |             '=', | ||||||
|  |             ';', | ||||||
|  |             '!', | ||||||
|  |             "'", | ||||||
|  |             '+', | ||||||
|  |             ',', | ||||||
|  |             '`', | ||||||
|  |             '~', | ||||||
|  |             '|', | ||||||
|  |             '<', | ||||||
|  |             '>', | ||||||
|  |             '"' | ||||||
|  |         ]; | ||||||
|  |         let needsQuotes = false; | ||||||
|  |         for (const char of arg) { | ||||||
|  |             if (cmdSpecialChars.some(x => x === char)) { | ||||||
|  |                 needsQuotes = true; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         // short-circuit if quotes not needed
 | ||||||
|  |         if (!needsQuotes) { | ||||||
|  |             return arg; | ||||||
|  |         } | ||||||
|  |         // the following quoting rules are very similar to the rules that by libuv applies.
 | ||||||
|  |         //
 | ||||||
|  |         // 1) wrap the string in quotes
 | ||||||
|  |         //
 | ||||||
|  |         // 2) double-up quotes - i.e. " => ""
 | ||||||
|  |         //
 | ||||||
|  |         //    this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately
 | ||||||
|  |         //    doesn't work well with a cmd.exe command line.
 | ||||||
|  |         //
 | ||||||
|  |         //    note, replacing " with "" also works well if the arg is passed to a downstream .NET console app.
 | ||||||
|  |         //    for example, the command line:
 | ||||||
|  |         //          foo.exe "myarg:""my val"""
 | ||||||
|  |         //    is parsed by a .NET console app into an arg array:
 | ||||||
|  |         //          [ "myarg:\"my val\"" ]
 | ||||||
|  |         //    which is the same end result when applying libuv quoting rules. although the actual
 | ||||||
|  |         //    command line from libuv quoting rules would look like:
 | ||||||
|  |         //          foo.exe "myarg:\"my val\""
 | ||||||
|  |         //
 | ||||||
|  |         // 3) double-up slashes that precede a quote,
 | ||||||
|  |         //    e.g.  hello \world    => "hello \world"
 | ||||||
|  |         //          hello\"world    => "hello\\""world"
 | ||||||
|  |         //          hello\\"world   => "hello\\\\""world"
 | ||||||
|  |         //          hello world\    => "hello world\\"
 | ||||||
|  |         //
 | ||||||
|  |         //    technically this is not required for a cmd.exe command line, or the batch argument parser.
 | ||||||
|  |         //    the reasons for including this as a .cmd quoting rule are:
 | ||||||
|  |         //
 | ||||||
|  |         //    a) this is optimized for the scenario where the argument is passed from the .cmd file to an
 | ||||||
|  |         //       external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.
 | ||||||
|  |         //
 | ||||||
|  |         //    b) it's what we've been doing previously (by deferring to node default behavior) and we
 | ||||||
|  |         //       haven't heard any complaints about that aspect.
 | ||||||
|  |         //
 | ||||||
|  |         // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be
 | ||||||
|  |         // escaped when used on the command line directly - even though within a .cmd file % can be escaped
 | ||||||
|  |         // by using %%.
 | ||||||
|  |         //
 | ||||||
|  |         // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts
 | ||||||
|  |         // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.
 | ||||||
|  |         //
 | ||||||
|  |         // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would
 | ||||||
|  |         // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the
 | ||||||
|  |         // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args
 | ||||||
|  |         // to an external program.
 | ||||||
|  |         //
 | ||||||
|  |         // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.
 | ||||||
|  |         // % can be escaped within a .cmd file.
 | ||||||
|  |         let reverse = '"'; | ||||||
|  |         let quoteHit = true; | ||||||
|  |         for (let i = arg.length; i > 0; i--) { | ||||||
|  |             // walk the string in reverse
 | ||||||
|  |             reverse += arg[i - 1]; | ||||||
|  |             if (quoteHit && arg[i - 1] === '\\') { | ||||||
|  |                 reverse += '\\'; // double the slash
 | ||||||
|  |             } | ||||||
|  |             else if (arg[i - 1] === '"') { | ||||||
|  |                 quoteHit = true; | ||||||
|  |                 reverse += '"'; // double the quote
 | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 quoteHit = false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         reverse += '"'; | ||||||
|  |         return reverse | ||||||
|  |             .split('') | ||||||
|  |             .reverse() | ||||||
|  |             .join(''); | ||||||
|  |     } | ||||||
|  |     _uvQuoteCmdArg(arg) { | ||||||
|  |         // Tool runner wraps child_process.spawn() and needs to apply the same quoting as
 | ||||||
|  |         // Node in certain cases where the undocumented spawn option windowsVerbatimArguments
 | ||||||
|  |         // is used.
 | ||||||
|  |         //
 | ||||||
|  |         // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,
 | ||||||
|  |         // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),
 | ||||||
|  |         // pasting copyright notice from Node within this function:
 | ||||||
|  |         //
 | ||||||
|  |         //      Copyright Joyent, Inc. and other Node contributors. All rights reserved.
 | ||||||
|  |         //
 | ||||||
|  |         //      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.
 | ||||||
|  |         if (!arg) { | ||||||
|  |             // Need double quotation for empty argument
 | ||||||
|  |             return '""'; | ||||||
|  |         } | ||||||
|  |         if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) { | ||||||
|  |             // No quotation needed
 | ||||||
|  |             return arg; | ||||||
|  |         } | ||||||
|  |         if (!arg.includes('"') && !arg.includes('\\')) { | ||||||
|  |             // No embedded double quotes or backslashes, so I can just wrap
 | ||||||
|  |             // quote marks around the whole thing.
 | ||||||
|  |             return `"${arg}"`; | ||||||
|  |         } | ||||||
|  |         // Expected input/output:
 | ||||||
|  |         //   input : hello"world
 | ||||||
|  |         //   output: "hello\"world"
 | ||||||
|  |         //   input : hello""world
 | ||||||
|  |         //   output: "hello\"\"world"
 | ||||||
|  |         //   input : hello\world
 | ||||||
|  |         //   output: hello\world
 | ||||||
|  |         //   input : hello\\world
 | ||||||
|  |         //   output: hello\\world
 | ||||||
|  |         //   input : hello\"world
 | ||||||
|  |         //   output: "hello\\\"world"
 | ||||||
|  |         //   input : hello\\"world
 | ||||||
|  |         //   output: "hello\\\\\"world"
 | ||||||
|  |         //   input : hello world\
 | ||||||
|  |         //   output: "hello world\\" - note the comment in libuv actually reads "hello world\"
 | ||||||
|  |         //                             but it appears the comment is wrong, it should be "hello world\\"
 | ||||||
|  |         let reverse = '"'; | ||||||
|  |         let quoteHit = true; | ||||||
|  |         for (let i = arg.length; i > 0; i--) { | ||||||
|  |             // walk the string in reverse
 | ||||||
|  |             reverse += arg[i - 1]; | ||||||
|  |             if (quoteHit && arg[i - 1] === '\\') { | ||||||
|  |                 reverse += '\\'; | ||||||
|  |             } | ||||||
|  |             else if (arg[i - 1] === '"') { | ||||||
|  |                 quoteHit = true; | ||||||
|  |                 reverse += '\\'; | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 quoteHit = false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         reverse += '"'; | ||||||
|  |         return reverse | ||||||
|  |             .split('') | ||||||
|  |             .reverse() | ||||||
|  |             .join(''); | ||||||
|  |     } | ||||||
|  |     _cloneExecOptions(options) { | ||||||
|  |         options = options || {}; | ||||||
|  |         const result = { | ||||||
|  |             cwd: options.cwd || process.cwd(), | ||||||
|  |             env: options.env || process.env, | ||||||
|  |             silent: options.silent || false, | ||||||
|  |             windowsVerbatimArguments: options.windowsVerbatimArguments || false, | ||||||
|  |             failOnStdErr: options.failOnStdErr || false, | ||||||
|  |             ignoreReturnCode: options.ignoreReturnCode || false, | ||||||
|  |             delay: options.delay || 10000 | ||||||
|  |         }; | ||||||
|  |         result.outStream = options.outStream || process.stdout; | ||||||
|  |         result.errStream = options.errStream || process.stderr; | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |     _getSpawnOptions(options, toolPath) { | ||||||
|  |         options = options || {}; | ||||||
|  |         const result = {}; | ||||||
|  |         result.cwd = options.cwd; | ||||||
|  |         result.env = options.env; | ||||||
|  |         result['windowsVerbatimArguments'] = | ||||||
|  |             options.windowsVerbatimArguments || this._isCmdFile(); | ||||||
|  |         if (options.windowsVerbatimArguments) { | ||||||
|  |             result.argv0 = `"${toolPath}"`; | ||||||
|  |         } | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |     /** | ||||||
|  |      * Exec a tool. | ||||||
|  |      * Output will be streamed to the live console. | ||||||
|  |      * Returns promise with return code | ||||||
|  |      * | ||||||
|  |      * @param     tool     path to tool to exec | ||||||
|  |      * @param     options  optional exec options.  See ExecOptions | ||||||
|  |      * @returns   number | ||||||
|  |      */ | ||||||
|  |     exec() { | ||||||
|  |         return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |             // root the tool path if it is unrooted and contains relative pathing
 | ||||||
|  |             if (!ioUtil.isRooted(this.toolPath) && | ||||||
|  |                 (this.toolPath.includes('/') || | ||||||
|  |                     (IS_WINDOWS && this.toolPath.includes('\\')))) { | ||||||
|  |                 // prefer options.cwd if it is specified, however options.cwd may also need to be rooted
 | ||||||
|  |                 this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath); | ||||||
|  |             } | ||||||
|  |             // if the tool is only a file name, then resolve it from the PATH
 | ||||||
|  |             // otherwise verify it exists (add extension on Windows if necessary)
 | ||||||
|  |             this.toolPath = yield io.which(this.toolPath, true); | ||||||
|  |             return new Promise((resolve, reject) => { | ||||||
|  |                 this._debug(`exec tool: ${this.toolPath}`); | ||||||
|  |                 this._debug('arguments:'); | ||||||
|  |                 for (const arg of this.args) { | ||||||
|  |                     this._debug(`   ${arg}`); | ||||||
|  |                 } | ||||||
|  |                 const optionsNonNull = this._cloneExecOptions(this.options); | ||||||
|  |                 if (!optionsNonNull.silent && optionsNonNull.outStream) { | ||||||
|  |                     optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL); | ||||||
|  |                 } | ||||||
|  |                 const state = new ExecState(optionsNonNull, this.toolPath); | ||||||
|  |                 state.on('debug', (message) => { | ||||||
|  |                     this._debug(message); | ||||||
|  |                 }); | ||||||
|  |                 const fileName = this._getSpawnFileName(); | ||||||
|  |                 const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName)); | ||||||
|  |                 const stdbuffer = ''; | ||||||
|  |                 if (cp.stdout) { | ||||||
|  |                     cp.stdout.on('data', (data) => { | ||||||
|  |                         if (this.options.listeners && this.options.listeners.stdout) { | ||||||
|  |                             this.options.listeners.stdout(data); | ||||||
|  |                         } | ||||||
|  |                         if (!optionsNonNull.silent && optionsNonNull.outStream) { | ||||||
|  |                             optionsNonNull.outStream.write(data); | ||||||
|  |                         } | ||||||
|  |                         this._processLineBuffer(data, stdbuffer, (line) => { | ||||||
|  |                             if (this.options.listeners && this.options.listeners.stdline) { | ||||||
|  |                                 this.options.listeners.stdline(line); | ||||||
|  |                             } | ||||||
|  |                         }); | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |                 const errbuffer = ''; | ||||||
|  |                 if (cp.stderr) { | ||||||
|  |                     cp.stderr.on('data', (data) => { | ||||||
|  |                         state.processStderr = true; | ||||||
|  |                         if (this.options.listeners && this.options.listeners.stderr) { | ||||||
|  |                             this.options.listeners.stderr(data); | ||||||
|  |                         } | ||||||
|  |                         if (!optionsNonNull.silent && | ||||||
|  |                             optionsNonNull.errStream && | ||||||
|  |                             optionsNonNull.outStream) { | ||||||
|  |                             const s = optionsNonNull.failOnStdErr | ||||||
|  |                                 ? optionsNonNull.errStream | ||||||
|  |                                 : optionsNonNull.outStream; | ||||||
|  |                             s.write(data); | ||||||
|  |                         } | ||||||
|  |                         this._processLineBuffer(data, errbuffer, (line) => { | ||||||
|  |                             if (this.options.listeners && this.options.listeners.errline) { | ||||||
|  |                                 this.options.listeners.errline(line); | ||||||
|  |                             } | ||||||
|  |                         }); | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |                 cp.on('error', (err) => { | ||||||
|  |                     state.processError = err.message; | ||||||
|  |                     state.processExited = true; | ||||||
|  |                     state.processClosed = true; | ||||||
|  |                     state.CheckComplete(); | ||||||
|  |                 }); | ||||||
|  |                 cp.on('exit', (code) => { | ||||||
|  |                     state.processExitCode = code; | ||||||
|  |                     state.processExited = true; | ||||||
|  |                     this._debug(`Exit code ${code} received from tool '${this.toolPath}'`); | ||||||
|  |                     state.CheckComplete(); | ||||||
|  |                 }); | ||||||
|  |                 cp.on('close', (code) => { | ||||||
|  |                     state.processExitCode = code; | ||||||
|  |                     state.processExited = true; | ||||||
|  |                     state.processClosed = true; | ||||||
|  |                     this._debug(`STDIO streams have closed for tool '${this.toolPath}'`); | ||||||
|  |                     state.CheckComplete(); | ||||||
|  |                 }); | ||||||
|  |                 state.on('done', (error, exitCode) => { | ||||||
|  |                     if (stdbuffer.length > 0) { | ||||||
|  |                         this.emit('stdline', stdbuffer); | ||||||
|  |                     } | ||||||
|  |                     if (errbuffer.length > 0) { | ||||||
|  |                         this.emit('errline', errbuffer); | ||||||
|  |                     } | ||||||
|  |                     cp.removeAllListeners(); | ||||||
|  |                     if (error) { | ||||||
|  |                         reject(error); | ||||||
|  |                     } | ||||||
|  |                     else { | ||||||
|  |                         resolve(exitCode); | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | exports.ToolRunner = ToolRunner; | ||||||
|  | /** | ||||||
|  |  * Convert an arg string to an array of args. Handles escaping | ||||||
|  |  * | ||||||
|  |  * @param    argString   string of arguments | ||||||
|  |  * @returns  string[]    array of arguments | ||||||
|  |  */ | ||||||
|  | function argStringToArray(argString) { | ||||||
|  |     const args = []; | ||||||
|  |     let inQuotes = false; | ||||||
|  |     let escaped = false; | ||||||
|  |     let arg = ''; | ||||||
|  |     function append(c) { | ||||||
|  |         // we only escape double quotes.
 | ||||||
|  |         if (escaped && c !== '"') { | ||||||
|  |             arg += '\\'; | ||||||
|  |         } | ||||||
|  |         arg += c; | ||||||
|  |         escaped = false; | ||||||
|  |     } | ||||||
|  |     for (let i = 0; i < argString.length; i++) { | ||||||
|  |         const c = argString.charAt(i); | ||||||
|  |         if (c === '"') { | ||||||
|  |             if (!escaped) { | ||||||
|  |                 inQuotes = !inQuotes; | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 append(c); | ||||||
|  |             } | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         if (c === '\\' && escaped) { | ||||||
|  |             append(c); | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         if (c === '\\' && inQuotes) { | ||||||
|  |             escaped = true; | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         if (c === ' ' && !inQuotes) { | ||||||
|  |             if (arg.length > 0) { | ||||||
|  |                 args.push(arg); | ||||||
|  |                 arg = ''; | ||||||
|  |             } | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         append(c); | ||||||
|  |     } | ||||||
|  |     if (arg.length > 0) { | ||||||
|  |         args.push(arg.trim()); | ||||||
|  |     } | ||||||
|  |     return args; | ||||||
|  | } | ||||||
|  | exports.argStringToArray = argStringToArray; | ||||||
|  | class ExecState extends events.EventEmitter { | ||||||
|  |     constructor(options, toolPath) { | ||||||
|  |         super(); | ||||||
|  |         this.processClosed = false; // tracks whether the process has exited and stdio is closed
 | ||||||
|  |         this.processError = ''; | ||||||
|  |         this.processExitCode = 0; | ||||||
|  |         this.processExited = false; // tracks whether the process has exited
 | ||||||
|  |         this.processStderr = false; // tracks whether stderr was written to
 | ||||||
|  |         this.delay = 10000; // 10 seconds
 | ||||||
|  |         this.done = false; | ||||||
|  |         this.timeout = null; | ||||||
|  |         if (!toolPath) { | ||||||
|  |             throw new Error('toolPath must not be empty'); | ||||||
|  |         } | ||||||
|  |         this.options = options; | ||||||
|  |         this.toolPath = toolPath; | ||||||
|  |         if (options.delay) { | ||||||
|  |             this.delay = options.delay; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     CheckComplete() { | ||||||
|  |         if (this.done) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         if (this.processClosed) { | ||||||
|  |             this._setResult(); | ||||||
|  |         } | ||||||
|  |         else if (this.processExited) { | ||||||
|  |             this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     _debug(message) { | ||||||
|  |         this.emit('debug', message); | ||||||
|  |     } | ||||||
|  |     _setResult() { | ||||||
|  |         // determine whether there is an error
 | ||||||
|  |         let error; | ||||||
|  |         if (this.processExited) { | ||||||
|  |             if (this.processError) { | ||||||
|  |                 error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`); | ||||||
|  |             } | ||||||
|  |             else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) { | ||||||
|  |                 error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`); | ||||||
|  |             } | ||||||
|  |             else if (this.processStderr && this.options.failOnStdErr) { | ||||||
|  |                 error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         // clear the timeout
 | ||||||
|  |         if (this.timeout) { | ||||||
|  |             clearTimeout(this.timeout); | ||||||
|  |             this.timeout = null; | ||||||
|  |         } | ||||||
|  |         this.done = true; | ||||||
|  |         this.emit('done', error, this.processExitCode); | ||||||
|  |     } | ||||||
|  |     static HandleTimeout(state) { | ||||||
|  |         if (state.done) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         if (!state.processClosed && state.processExited) { | ||||||
|  |             const message = `The STDIO streams did not close within ${state.delay / | ||||||
|  |                 1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;
 | ||||||
|  |             state._debug(message); | ||||||
|  |         } | ||||||
|  |         state._setResult(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | //# sourceMappingURL=toolrunner.js.map
 | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 87: | ||||||
|  | /***/ (function(module) { | ||||||
|  | 
 | ||||||
|  | module.exports = require("os"); | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 129: | ||||||
|  | /***/ (function(module) { | ||||||
|  | 
 | ||||||
|  | module.exports = require("child_process"); | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 219: | ||||||
|  | /***/ (function(__unusedmodule, exports, __webpack_require__) { | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||||||
|  |     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||||||
|  |     return new (P || (P = Promise))(function (resolve, reject) { | ||||||
|  |         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||||||
|  |         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||||||
|  |         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||||||
|  |         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||||||
|  |     }); | ||||||
|  | }; | ||||||
|  | var __importStar = (this && this.__importStar) || function (mod) { | ||||||
|  |     if (mod && mod.__esModule) return mod; | ||||||
|  |     var result = {}; | ||||||
|  |     if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||||||
|  |     result["default"] = mod; | ||||||
|  |     return result; | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | const core = __importStar(__webpack_require__(470)); | ||||||
|  | const gpg = __importStar(__webpack_require__(884)); | ||||||
|  | function run() { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         if (core.getInput('gpg-private-key', { required: false })) { | ||||||
|  |             console.log('removing private key from keychain'); | ||||||
|  |             try { | ||||||
|  |                 const keyFingerprint = core.getState('gpg-private-key-fingerprint'); | ||||||
|  |                 yield gpg.deleteKey(keyFingerprint); | ||||||
|  |             } | ||||||
|  |             catch (error) { | ||||||
|  |                 core.setFailed(error.message); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | run(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 322: | ||||||
|  | /***/ (function(__unusedmodule, exports, __webpack_require__) { | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | var __importStar = (this && this.__importStar) || function (mod) { | ||||||
|  |     if (mod && mod.__esModule) return mod; | ||||||
|  |     var result = {}; | ||||||
|  |     if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||||||
|  |     result["default"] = mod; | ||||||
|  |     return result; | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | const path = __importStar(__webpack_require__(622)); | ||||||
|  | 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; | ||||||
|  | } | ||||||
|  | exports.getTempDir = getTempDir; | ||||||
|  | function isWindows() { | ||||||
|  |     return process.platform === 'win32'; | ||||||
|  | } | ||||||
|  | exports.isWindows = isWindows; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 357: | ||||||
|  | /***/ (function(module) { | ||||||
|  | 
 | ||||||
|  | module.exports = require("assert"); | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 431: | ||||||
|  | /***/ (function(__unusedmodule, exports, __webpack_require__) { | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | var __importStar = (this && this.__importStar) || function (mod) { | ||||||
|  |     if (mod && mod.__esModule) return mod; | ||||||
|  |     var result = {}; | ||||||
|  |     if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||||||
|  |     result["default"] = mod; | ||||||
|  |     return result; | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | const os = __importStar(__webpack_require__(87)); | ||||||
|  | /** | ||||||
|  |  * Commands | ||||||
|  |  * | ||||||
|  |  * Command Format: | ||||||
|  |  *   ::name key=value,key=value::message | ||||||
|  |  * | ||||||
|  |  * Examples: | ||||||
|  |  *   ::warning::This is the message | ||||||
|  |  *   ::set-env name=MY_VAR::some value | ||||||
|  |  */ | ||||||
|  | function issueCommand(command, properties, message) { | ||||||
|  |     const cmd = new Command(command, properties, message); | ||||||
|  |     process.stdout.write(cmd.toString() + os.EOL); | ||||||
|  | } | ||||||
|  | exports.issueCommand = issueCommand; | ||||||
|  | function issue(name, message = '') { | ||||||
|  |     issueCommand(name, {}, message); | ||||||
|  | } | ||||||
|  | exports.issue = issue; | ||||||
|  | const CMD_STRING = '::'; | ||||||
|  | class Command { | ||||||
|  |     constructor(command, properties, message) { | ||||||
|  |         if (!command) { | ||||||
|  |             command = 'missing.command'; | ||||||
|  |         } | ||||||
|  |         this.command = command; | ||||||
|  |         this.properties = properties; | ||||||
|  |         this.message = message; | ||||||
|  |     } | ||||||
|  |     toString() { | ||||||
|  |         let cmdStr = CMD_STRING + this.command; | ||||||
|  |         if (this.properties && Object.keys(this.properties).length > 0) { | ||||||
|  |             cmdStr += ' '; | ||||||
|  |             let first = true; | ||||||
|  |             for (const key in this.properties) { | ||||||
|  |                 if (this.properties.hasOwnProperty(key)) { | ||||||
|  |                     const val = this.properties[key]; | ||||||
|  |                     if (val) { | ||||||
|  |                         if (first) { | ||||||
|  |                             first = false; | ||||||
|  |                         } | ||||||
|  |                         else { | ||||||
|  |                             cmdStr += ','; | ||||||
|  |                         } | ||||||
|  |                         cmdStr += `${key}=${escapeProperty(val)}`; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         cmdStr += `${CMD_STRING}${escapeData(this.message)}`; | ||||||
|  |         return cmdStr; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | function escapeData(s) { | ||||||
|  |     return (s || '') | ||||||
|  |         .replace(/%/g, '%25') | ||||||
|  |         .replace(/\r/g, '%0D') | ||||||
|  |         .replace(/\n/g, '%0A'); | ||||||
|  | } | ||||||
|  | function escapeProperty(s) { | ||||||
|  |     return (s || '') | ||||||
|  |         .replace(/%/g, '%25') | ||||||
|  |         .replace(/\r/g, '%0D') | ||||||
|  |         .replace(/\n/g, '%0A') | ||||||
|  |         .replace(/:/g, '%3A') | ||||||
|  |         .replace(/,/g, '%2C'); | ||||||
|  | } | ||||||
|  | //# sourceMappingURL=command.js.map
 | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 470: | ||||||
|  | /***/ (function(__unusedmodule, exports, __webpack_require__) { | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||||||
|  |     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||||||
|  |     return new (P || (P = Promise))(function (resolve, reject) { | ||||||
|  |         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||||||
|  |         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||||||
|  |         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||||||
|  |         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||||||
|  |     }); | ||||||
|  | }; | ||||||
|  | var __importStar = (this && this.__importStar) || function (mod) { | ||||||
|  |     if (mod && mod.__esModule) return mod; | ||||||
|  |     var result = {}; | ||||||
|  |     if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||||||
|  |     result["default"] = mod; | ||||||
|  |     return result; | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | const command_1 = __webpack_require__(431); | ||||||
|  | const os = __importStar(__webpack_require__(87)); | ||||||
|  | const path = __importStar(__webpack_require__(622)); | ||||||
|  | /** | ||||||
|  |  * The code to exit an action | ||||||
|  |  */ | ||||||
|  | var ExitCode; | ||||||
|  | (function (ExitCode) { | ||||||
|  |     /** | ||||||
|  |      * A code indicating that the action was successful | ||||||
|  |      */ | ||||||
|  |     ExitCode[ExitCode["Success"] = 0] = "Success"; | ||||||
|  |     /** | ||||||
|  |      * A code indicating that the action was a failure | ||||||
|  |      */ | ||||||
|  |     ExitCode[ExitCode["Failure"] = 1] = "Failure"; | ||||||
|  | })(ExitCode = exports.ExitCode || (exports.ExitCode = {})); | ||||||
|  | //-----------------------------------------------------------------------
 | ||||||
|  | // Variables
 | ||||||
|  | //-----------------------------------------------------------------------
 | ||||||
|  | /** | ||||||
|  |  * Sets env variable for this action and future actions in the job | ||||||
|  |  * @param name the name of the variable to set | ||||||
|  |  * @param val the value of the variable | ||||||
|  |  */ | ||||||
|  | function exportVariable(name, val) { | ||||||
|  |     process.env[name] = val; | ||||||
|  |     command_1.issueCommand('set-env', { name }, val); | ||||||
|  | } | ||||||
|  | exports.exportVariable = exportVariable; | ||||||
|  | /** | ||||||
|  |  * Registers a secret which will get masked from logs | ||||||
|  |  * @param secret value of the secret | ||||||
|  |  */ | ||||||
|  | function setSecret(secret) { | ||||||
|  |     command_1.issueCommand('add-mask', {}, secret); | ||||||
|  | } | ||||||
|  | exports.setSecret = setSecret; | ||||||
|  | /** | ||||||
|  |  * Prepends inputPath to the PATH (for this action and future actions) | ||||||
|  |  * @param inputPath | ||||||
|  |  */ | ||||||
|  | function addPath(inputPath) { | ||||||
|  |     command_1.issueCommand('add-path', {}, inputPath); | ||||||
|  |     process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; | ||||||
|  | } | ||||||
|  | exports.addPath = addPath; | ||||||
|  | /** | ||||||
|  |  * Gets the value of an input.  The value is also trimmed. | ||||||
|  |  * | ||||||
|  |  * @param     name     name of the input to get | ||||||
|  |  * @param     options  optional. See InputOptions. | ||||||
|  |  * @returns   string | ||||||
|  |  */ | ||||||
|  | function getInput(name, options) { | ||||||
|  |     const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; | ||||||
|  |     if (options && options.required && !val) { | ||||||
|  |         throw new Error(`Input required and not supplied: ${name}`); | ||||||
|  |     } | ||||||
|  |     return val.trim(); | ||||||
|  | } | ||||||
|  | exports.getInput = getInput; | ||||||
|  | /** | ||||||
|  |  * Sets the value of an output. | ||||||
|  |  * | ||||||
|  |  * @param     name     name of the output to set | ||||||
|  |  * @param     value    value to store | ||||||
|  |  */ | ||||||
|  | function setOutput(name, value) { | ||||||
|  |     command_1.issueCommand('set-output', { name }, value); | ||||||
|  | } | ||||||
|  | exports.setOutput = setOutput; | ||||||
|  | //-----------------------------------------------------------------------
 | ||||||
|  | // Results
 | ||||||
|  | //-----------------------------------------------------------------------
 | ||||||
|  | /** | ||||||
|  |  * Sets the action status to failed. | ||||||
|  |  * When the action exits it will be with an exit code of 1 | ||||||
|  |  * @param message add error issue message | ||||||
|  |  */ | ||||||
|  | function setFailed(message) { | ||||||
|  |     process.exitCode = ExitCode.Failure; | ||||||
|  |     error(message); | ||||||
|  | } | ||||||
|  | exports.setFailed = setFailed; | ||||||
|  | //-----------------------------------------------------------------------
 | ||||||
|  | // Logging Commands
 | ||||||
|  | //-----------------------------------------------------------------------
 | ||||||
|  | /** | ||||||
|  |  * Writes debug message to user log | ||||||
|  |  * @param message debug message | ||||||
|  |  */ | ||||||
|  | function debug(message) { | ||||||
|  |     command_1.issueCommand('debug', {}, message); | ||||||
|  | } | ||||||
|  | exports.debug = debug; | ||||||
|  | /** | ||||||
|  |  * Adds an error issue | ||||||
|  |  * @param message error issue message | ||||||
|  |  */ | ||||||
|  | function error(message) { | ||||||
|  |     command_1.issue('error', message); | ||||||
|  | } | ||||||
|  | exports.error = error; | ||||||
|  | /** | ||||||
|  |  * Adds an warning issue | ||||||
|  |  * @param message warning issue message | ||||||
|  |  */ | ||||||
|  | function warning(message) { | ||||||
|  |     command_1.issue('warning', message); | ||||||
|  | } | ||||||
|  | exports.warning = warning; | ||||||
|  | /** | ||||||
|  |  * Writes info to log with console.log. | ||||||
|  |  * @param message info message | ||||||
|  |  */ | ||||||
|  | function info(message) { | ||||||
|  |     process.stdout.write(message + os.EOL); | ||||||
|  | } | ||||||
|  | exports.info = info; | ||||||
|  | /** | ||||||
|  |  * Begin an output group. | ||||||
|  |  * | ||||||
|  |  * Output until the next `groupEnd` will be foldable in this group | ||||||
|  |  * | ||||||
|  |  * @param name The name of the output group | ||||||
|  |  */ | ||||||
|  | function startGroup(name) { | ||||||
|  |     command_1.issue('group', name); | ||||||
|  | } | ||||||
|  | exports.startGroup = startGroup; | ||||||
|  | /** | ||||||
|  |  * End an output group. | ||||||
|  |  */ | ||||||
|  | function endGroup() { | ||||||
|  |     command_1.issue('endgroup'); | ||||||
|  | } | ||||||
|  | exports.endGroup = endGroup; | ||||||
|  | /** | ||||||
|  |  * Wrap an asynchronous function call in a group. | ||||||
|  |  * | ||||||
|  |  * Returns the same type as the function itself. | ||||||
|  |  * | ||||||
|  |  * @param name The name of the group | ||||||
|  |  * @param fn The function to wrap in the group | ||||||
|  |  */ | ||||||
|  | function group(name, fn) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         startGroup(name); | ||||||
|  |         let result; | ||||||
|  |         try { | ||||||
|  |             result = yield fn(); | ||||||
|  |         } | ||||||
|  |         finally { | ||||||
|  |             endGroup(); | ||||||
|  |         } | ||||||
|  |         return result; | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.group = group; | ||||||
|  | //-----------------------------------------------------------------------
 | ||||||
|  | // Wrapper action state
 | ||||||
|  | //-----------------------------------------------------------------------
 | ||||||
|  | /** | ||||||
|  |  * Saves state for current action, the state can only be retrieved by this action's post job execution. | ||||||
|  |  * | ||||||
|  |  * @param     name     name of the state to store | ||||||
|  |  * @param     value    value to store | ||||||
|  |  */ | ||||||
|  | function saveState(name, value) { | ||||||
|  |     command_1.issueCommand('save-state', { name }, value); | ||||||
|  | } | ||||||
|  | exports.saveState = saveState; | ||||||
|  | /** | ||||||
|  |  * Gets the value of an state set by this action's main execution. | ||||||
|  |  * | ||||||
|  |  * @param     name     name of the state to get | ||||||
|  |  * @returns   string | ||||||
|  |  */ | ||||||
|  | function getState(name) { | ||||||
|  |     return process.env[`STATE_${name}`] || ''; | ||||||
|  | } | ||||||
|  | exports.getState = getState; | ||||||
|  | //# sourceMappingURL=core.js.map
 | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 614: | ||||||
|  | /***/ (function(module) { | ||||||
|  | 
 | ||||||
|  | module.exports = require("events"); | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 622: | ||||||
|  | /***/ (function(module) { | ||||||
|  | 
 | ||||||
|  | module.exports = require("path"); | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 669: | ||||||
|  | /***/ (function(module) { | ||||||
|  | 
 | ||||||
|  | module.exports = require("util"); | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 672: | ||||||
|  | /***/ (function(__unusedmodule, exports, __webpack_require__) { | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||||||
|  |     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||||||
|  |     return new (P || (P = Promise))(function (resolve, reject) { | ||||||
|  |         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||||||
|  |         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||||||
|  |         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||||||
|  |         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||||||
|  |     }); | ||||||
|  | }; | ||||||
|  | var _a; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | const assert_1 = __webpack_require__(357); | ||||||
|  | const fs = __webpack_require__(747); | ||||||
|  | const path = __webpack_require__(622); | ||||||
|  | _a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink; | ||||||
|  | exports.IS_WINDOWS = process.platform === 'win32'; | ||||||
|  | function exists(fsPath) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         try { | ||||||
|  |             yield exports.stat(fsPath); | ||||||
|  |         } | ||||||
|  |         catch (err) { | ||||||
|  |             if (err.code === 'ENOENT') { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |             throw err; | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.exists = exists; | ||||||
|  | function isDirectory(fsPath, useStat = false) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath); | ||||||
|  |         return stats.isDirectory(); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.isDirectory = isDirectory; | ||||||
|  | /** | ||||||
|  |  * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like: | ||||||
|  |  * \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases). | ||||||
|  |  */ | ||||||
|  | function isRooted(p) { | ||||||
|  |     p = normalizeSeparators(p); | ||||||
|  |     if (!p) { | ||||||
|  |         throw new Error('isRooted() parameter "p" cannot be empty'); | ||||||
|  |     } | ||||||
|  |     if (exports.IS_WINDOWS) { | ||||||
|  |         return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
 | ||||||
|  |         ); // e.g. C: or C:\hello
 | ||||||
|  |     } | ||||||
|  |     return p.startsWith('/'); | ||||||
|  | } | ||||||
|  | exports.isRooted = isRooted; | ||||||
|  | /** | ||||||
|  |  * Recursively create a directory at `fsPath`. | ||||||
|  |  * | ||||||
|  |  * This implementation is optimistic, meaning it attempts to create the full | ||||||
|  |  * path first, and backs up the path stack from there. | ||||||
|  |  * | ||||||
|  |  * @param fsPath The path to create | ||||||
|  |  * @param maxDepth The maximum recursion depth | ||||||
|  |  * @param depth The current recursion depth | ||||||
|  |  */ | ||||||
|  | function mkdirP(fsPath, maxDepth = 1000, depth = 1) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         assert_1.ok(fsPath, 'a path argument must be provided'); | ||||||
|  |         fsPath = path.resolve(fsPath); | ||||||
|  |         if (depth >= maxDepth) | ||||||
|  |             return exports.mkdir(fsPath); | ||||||
|  |         try { | ||||||
|  |             yield exports.mkdir(fsPath); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         catch (err) { | ||||||
|  |             switch (err.code) { | ||||||
|  |                 case 'ENOENT': { | ||||||
|  |                     yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1); | ||||||
|  |                     yield exports.mkdir(fsPath); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |                 default: { | ||||||
|  |                     let stats; | ||||||
|  |                     try { | ||||||
|  |                         stats = yield exports.stat(fsPath); | ||||||
|  |                     } | ||||||
|  |                     catch (err2) { | ||||||
|  |                         throw err; | ||||||
|  |                     } | ||||||
|  |                     if (!stats.isDirectory()) | ||||||
|  |                         throw err; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.mkdirP = mkdirP; | ||||||
|  | /** | ||||||
|  |  * Best effort attempt to determine whether a file exists and is executable. | ||||||
|  |  * @param filePath    file path to check | ||||||
|  |  * @param extensions  additional file extensions to try | ||||||
|  |  * @return if file exists and is executable, returns the file path. otherwise empty string. | ||||||
|  |  */ | ||||||
|  | function tryGetExecutablePath(filePath, extensions) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         let stats = undefined; | ||||||
|  |         try { | ||||||
|  |             // test file exists
 | ||||||
|  |             stats = yield exports.stat(filePath); | ||||||
|  |         } | ||||||
|  |         catch (err) { | ||||||
|  |             if (err.code !== 'ENOENT') { | ||||||
|  |                 // eslint-disable-next-line no-console
 | ||||||
|  |                 console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         if (stats && stats.isFile()) { | ||||||
|  |             if (exports.IS_WINDOWS) { | ||||||
|  |                 // on Windows, test for valid extension
 | ||||||
|  |                 const upperExt = path.extname(filePath).toUpperCase(); | ||||||
|  |                 if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) { | ||||||
|  |                     return filePath; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 if (isUnixExecutable(stats)) { | ||||||
|  |                     return filePath; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         // try each extension
 | ||||||
|  |         const originalFilePath = filePath; | ||||||
|  |         for (const extension of extensions) { | ||||||
|  |             filePath = originalFilePath + extension; | ||||||
|  |             stats = undefined; | ||||||
|  |             try { | ||||||
|  |                 stats = yield exports.stat(filePath); | ||||||
|  |             } | ||||||
|  |             catch (err) { | ||||||
|  |                 if (err.code !== 'ENOENT') { | ||||||
|  |                     // eslint-disable-next-line no-console
 | ||||||
|  |                     console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             if (stats && stats.isFile()) { | ||||||
|  |                 if (exports.IS_WINDOWS) { | ||||||
|  |                     // preserve the case of the actual file (since an extension was appended)
 | ||||||
|  |                     try { | ||||||
|  |                         const directory = path.dirname(filePath); | ||||||
|  |                         const upperName = path.basename(filePath).toUpperCase(); | ||||||
|  |                         for (const actualName of yield exports.readdir(directory)) { | ||||||
|  |                             if (upperName === actualName.toUpperCase()) { | ||||||
|  |                                 filePath = path.join(directory, actualName); | ||||||
|  |                                 break; | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     catch (err) { | ||||||
|  |                         // eslint-disable-next-line no-console
 | ||||||
|  |                         console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`); | ||||||
|  |                     } | ||||||
|  |                     return filePath; | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|  |                     if (isUnixExecutable(stats)) { | ||||||
|  |                         return filePath; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return ''; | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.tryGetExecutablePath = tryGetExecutablePath; | ||||||
|  | function normalizeSeparators(p) { | ||||||
|  |     p = p || ''; | ||||||
|  |     if (exports.IS_WINDOWS) { | ||||||
|  |         // convert slashes on Windows
 | ||||||
|  |         p = p.replace(/\//g, '\\'); | ||||||
|  |         // remove redundant slashes
 | ||||||
|  |         return p.replace(/\\\\+/g, '\\'); | ||||||
|  |     } | ||||||
|  |     // remove redundant slashes
 | ||||||
|  |     return p.replace(/\/\/+/g, '/'); | ||||||
|  | } | ||||||
|  | // on Mac/Linux, test the execute bit
 | ||||||
|  | //     R   W  X  R  W X R W X
 | ||||||
|  | //   256 128 64 32 16 8 4 2 1
 | ||||||
|  | function isUnixExecutable(stats) { | ||||||
|  |     return ((stats.mode & 1) > 0 || | ||||||
|  |         ((stats.mode & 8) > 0 && stats.gid === process.getgid()) || | ||||||
|  |         ((stats.mode & 64) > 0 && stats.uid === process.getuid())); | ||||||
|  | } | ||||||
|  | //# sourceMappingURL=io-util.js.map
 | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 747: | ||||||
|  | /***/ (function(module) { | ||||||
|  | 
 | ||||||
|  | module.exports = require("fs"); | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 884: | ||||||
|  | /***/ (function(__unusedmodule, exports, __webpack_require__) { | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||||||
|  |     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||||||
|  |     return new (P || (P = Promise))(function (resolve, reject) { | ||||||
|  |         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||||||
|  |         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||||||
|  |         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||||||
|  |         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||||||
|  |     }); | ||||||
|  | }; | ||||||
|  | var __importStar = (this && this.__importStar) || function (mod) { | ||||||
|  |     if (mod && mod.__esModule) return mod; | ||||||
|  |     var result = {}; | ||||||
|  |     if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||||||
|  |     result["default"] = mod; | ||||||
|  |     return result; | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | const fs = __importStar(__webpack_require__(747)); | ||||||
|  | const path = __importStar(__webpack_require__(622)); | ||||||
|  | const io = __importStar(__webpack_require__(1)); | ||||||
|  | const exec = __importStar(__webpack_require__(986)); | ||||||
|  | const util = __importStar(__webpack_require__(322)); | ||||||
|  | exports.PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc'); | ||||||
|  | const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/; | ||||||
|  | function importKey(privateKey) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         fs.writeFileSync(exports.PRIVATE_KEY_FILE, privateKey, { | ||||||
|  |             encoding: 'utf-8', | ||||||
|  |             flag: 'w' | ||||||
|  |         }); | ||||||
|  |         let output = ''; | ||||||
|  |         const options = { | ||||||
|  |             silent: true, | ||||||
|  |             listeners: { | ||||||
|  |                 stdout: (data) => { | ||||||
|  |                     output += data.toString(); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |         yield exec.exec('gpg', [ | ||||||
|  |             '--batch', | ||||||
|  |             '--import-options', | ||||||
|  |             'import-show', | ||||||
|  |             '--import', | ||||||
|  |             exports.PRIVATE_KEY_FILE | ||||||
|  |         ], options); | ||||||
|  |         yield io.rmRF(exports.PRIVATE_KEY_FILE); | ||||||
|  |         const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX); | ||||||
|  |         return match && match[0]; | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.importKey = importKey; | ||||||
|  | function deleteKey(keyFingerprint) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         yield exec.exec('gpg', ['--batch', '--yes', '--delete-secret-keys', keyFingerprint], { silent: true }); | ||||||
|  |         yield exec.exec('gpg', ['--batch', '--yes', '--delete-keys', keyFingerprint], { silent: true }); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.deleteKey = deleteKey; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /***/ }), | ||||||
|  | 
 | ||||||
|  | /***/ 986: | ||||||
|  | /***/ (function(__unusedmodule, exports, __webpack_require__) { | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||||||
|  |     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||||||
|  |     return new (P || (P = Promise))(function (resolve, reject) { | ||||||
|  |         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||||||
|  |         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||||||
|  |         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||||||
|  |         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||||||
|  |     }); | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | const tr = __webpack_require__(9); | ||||||
|  | /** | ||||||
|  |  * Exec a command. | ||||||
|  |  * Output will be streamed to the live console. | ||||||
|  |  * Returns promise with return code | ||||||
|  |  * | ||||||
|  |  * @param     commandLine        command to execute (can include additional args). Must be correctly escaped. | ||||||
|  |  * @param     args               optional arguments for tool. Escaping is handled by the lib. | ||||||
|  |  * @param     options            optional exec options.  See ExecOptions | ||||||
|  |  * @returns   Promise<number>    exit code | ||||||
|  |  */ | ||||||
|  | function exec(commandLine, args, options) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         const commandArgs = tr.argStringToArray(commandLine); | ||||||
|  |         if (commandArgs.length === 0) { | ||||||
|  |             throw new Error(`Parameter 'commandLine' cannot be null or empty.`); | ||||||
|  |         } | ||||||
|  |         // Path to tool to execute should be first arg
 | ||||||
|  |         const toolPath = commandArgs[0]; | ||||||
|  |         args = commandArgs.slice(1).concat(args || []); | ||||||
|  |         const runner = new tr.ToolRunner(toolPath, args, options); | ||||||
|  |         return runner.exec(); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.exec = exec; | ||||||
|  | //# sourceMappingURL=exec.js.map
 | ||||||
|  | 
 | ||||||
|  | /***/ }) | ||||||
|  | 
 | ||||||
|  | /******/ }); | ||||||
							
								
								
									
										
											BIN
										
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										35284
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35284
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										0
									
								
								dist/unzip → dist/setup/unzip
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								dist/unzip → dist/setup/unzip
									
									
									
									
										vendored
									
									
								
							
							
								
								
									
										78
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										78
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -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", | ||||||
| @ -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", | ||||||
|  | |||||||
| @ -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": { | ||||||
| @ -29,7 +29,8 @@ | |||||||
|     "@actions/http-client": "^1.0.6", |     "@actions/http-client": "^1.0.6", | ||||||
|     "@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", | ||||||
|  | |||||||
							
								
								
									
										82
									
								
								src/auth.ts
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								src/auth.ts
									
									
									
									
									
								
							| @ -3,60 +3,72 @@ 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'; | ||||||
| 
 | 
 | ||||||
| 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('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, | ||||||
| 
 |     generate(id, username, password, gpgPassphrase) | ||||||
| function escapeXML(value: string) { |   ); | ||||||
|   return value |  | ||||||
|     .replace(/&/g, '&') |  | ||||||
|     .replace(/</g, '<') |  | ||||||
|     .replace(/>/g, '>') |  | ||||||
|     .replace(/"/g, '"') |  | ||||||
|     .replace(/'/g, '''); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // 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) { | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								src/cleanup-java.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/cleanup-java.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | import * as core from '@actions/core'; | ||||||
|  | import * as gpg from './gpg'; | ||||||
|  | 
 | ||||||
|  | async function run() { | ||||||
|  |   if (core.getInput('gpg-private-key', {required: false})) { | ||||||
|  |     console.log('removing private key from keychain'); | ||||||
|  |     try { | ||||||
|  |       const keyFingerprint = core.getState('gpg-private-key-fingerprint'); | ||||||
|  |       await gpg.deleteKey(keyFingerprint); | ||||||
|  |     } catch (error) { | ||||||
|  |       core.setFailed(error.message); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | run(); | ||||||
							
								
								
									
										58
									
								
								src/gpg.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/gpg.ts
									
									
									
									
									
										Normal 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} | ||||||
|  |   ); | ||||||
|  | } | ||||||
| @ -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, | ||||||
|  | |||||||
| @ -1,10 +1,20 @@ | |||||||
| 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 path from 'path'; | import * as path from 'path'; | ||||||
| 
 | 
 | ||||||
|  | const DEFAULT_ID = 'github'; | ||||||
|  | const DEFAULT_USERNAME = 'GITHUB_ACTOR'; | ||||||
|  | const DEFAULT_PASSWORD = 'GITHUB_TOKEN'; | ||||||
|  | const DEFAULT_GPG_PRIVATE_KEY = undefined; | ||||||
|  | const DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE'; | ||||||
|  | 
 | ||||||
| async function run() { | async function run() { | ||||||
|   try { |   try { | ||||||
|  |     // Set secrets before use
 | ||||||
|  |     core.setSecret('gpg-private-key'); | ||||||
|  | 
 | ||||||
|     let version = core.getInput('version'); |     let version = core.getInput('version'); | ||||||
|     if (!version) { |     if (!version) { | ||||||
|       version = core.getInput('java-version', {required: true}); |       version = core.getInput('java-version', {required: true}); | ||||||
| @ -15,16 +25,28 @@ async function run() { | |||||||
| 
 | 
 | ||||||
|     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')}`); |     console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); | ||||||
| 
 | 
 | ||||||
|     const id = core.getInput('server-id', {required: false}) || undefined; |     const id = core.getInput('server-id', {required: false}) || DEFAULT_ID; | ||||||
|     const username = |     const username = | ||||||
|       core.getInput('server-username', {required: false}) || undefined; |       core.getInput('server-username', {required: false}) || DEFAULT_USERNAME; | ||||||
|     const password = |     const password = | ||||||
|       core.getInput('server-password', {required: false}) || undefined; |       core.getInput('server-password', {required: false}) || DEFAULT_PASSWORD; | ||||||
|  |     const gpgPrivateKey = | ||||||
|  |       core.getInput('gpg-private-key', {required: false}) || | ||||||
|  |       DEFAULT_GPG_PRIVATE_KEY; | ||||||
|  |     const gpgPassphrase = | ||||||
|  |       core.getInput('gpg-passphrase', {required: false}) || | ||||||
|  |       (gpgPrivateKey ? DEFAULT_GPG_PASSPHRASE : undefined); | ||||||
| 
 | 
 | ||||||
|     await auth.configAuthentication(id, username, password); |     await auth.configAuthentication(id, username, password, gpgPassphrase); | ||||||
|  | 
 | ||||||
|  |     if (gpgPrivateKey) { | ||||||
|  |       console.log('importing private key'); | ||||||
|  |       const keyFingerprint = (await gpg.importKey(gpgPrivateKey)) || ''; | ||||||
|  |       core.saveState('gpg-private-key-fingerprint', keyFingerprint); | ||||||
|  |     } | ||||||
|   } catch (error) { |   } catch (error) { | ||||||
|     core.setFailed(error.message); |     core.setFailed(error.message); | ||||||
|   } |   } | ||||||
|  | |||||||
							
								
								
									
										26
									
								
								src/util.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/util.ts
									
									
									
									
									
										Normal 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'; | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user