feat: infer github server and api urls
This commit is contained in:
parent
02a8f71e34
commit
1e6bff9d94
9 changed files with 431 additions and 401 deletions
|
@ -1,32 +1,32 @@
|
|||
import {GitCommandManager} from '../lib/git-command-manager'
|
||||
import {GitAuthHelper} from '../lib/git-auth-helper'
|
||||
import {GitConfigHelper} from '../lib/git-config-helper'
|
||||
|
||||
const REPO_PATH = '/git/local/test-base'
|
||||
|
||||
const extraheaderConfigKey = 'http.https://github.com/.extraheader'
|
||||
|
||||
describe('git-auth-helper tests', () => {
|
||||
describe('git-config-helper integration tests', () => {
|
||||
let git: GitCommandManager
|
||||
let gitAuthHelper: GitAuthHelper
|
||||
let gitConfigHelper: GitConfigHelper
|
||||
|
||||
beforeAll(async () => {
|
||||
git = await GitCommandManager.create(REPO_PATH)
|
||||
gitAuthHelper = new GitAuthHelper(git)
|
||||
gitConfigHelper = await GitConfigHelper.create(git)
|
||||
})
|
||||
|
||||
it('tests save and restore with no persisted auth', async () => {
|
||||
await gitAuthHelper.savePersistedAuth()
|
||||
await gitAuthHelper.restorePersistedAuth()
|
||||
await gitConfigHelper.savePersistedAuth()
|
||||
await gitConfigHelper.restorePersistedAuth()
|
||||
})
|
||||
|
||||
it('tests configure and removal of auth', async () => {
|
||||
await gitAuthHelper.configureToken('github-token')
|
||||
await gitConfigHelper.configureToken('github-token')
|
||||
expect(await git.configExists(extraheaderConfigKey)).toBeTruthy()
|
||||
expect(await git.getConfigValue(extraheaderConfigKey)).toEqual(
|
||||
'AUTHORIZATION: basic eC1hY2Nlc3MtdG9rZW46Z2l0aHViLXRva2Vu'
|
||||
)
|
||||
|
||||
await gitAuthHelper.removeAuth()
|
||||
await gitConfigHelper.removeAuth()
|
||||
expect(await git.configExists(extraheaderConfigKey)).toBeFalsy()
|
||||
})
|
||||
|
||||
|
@ -34,31 +34,31 @@ describe('git-auth-helper tests', () => {
|
|||
const extraheaderConfigValue = 'AUTHORIZATION: basic ***persisted-auth***'
|
||||
await git.config(extraheaderConfigKey, extraheaderConfigValue)
|
||||
|
||||
await gitAuthHelper.savePersistedAuth()
|
||||
await gitConfigHelper.savePersistedAuth()
|
||||
|
||||
const exists = await git.configExists(extraheaderConfigKey)
|
||||
expect(exists).toBeFalsy()
|
||||
|
||||
await gitAuthHelper.restorePersistedAuth()
|
||||
await gitConfigHelper.restorePersistedAuth()
|
||||
|
||||
const configValue = await git.getConfigValue(extraheaderConfigKey)
|
||||
expect(configValue).toEqual(extraheaderConfigValue)
|
||||
|
||||
await gitAuthHelper.removeAuth()
|
||||
await gitConfigHelper.removeAuth()
|
||||
})
|
||||
|
||||
it('tests adding and removing the safe.directory config', async () => {
|
||||
await git.config('safe.directory', '/another-value', true, true)
|
||||
|
||||
await gitAuthHelper.removeSafeDirectory()
|
||||
await gitAuthHelper.addSafeDirectory()
|
||||
await gitConfigHelper.removeSafeDirectory()
|
||||
await gitConfigHelper.addSafeDirectory()
|
||||
|
||||
expect(
|
||||
await git.configExists('safe.directory', REPO_PATH, true)
|
||||
).toBeTruthy()
|
||||
|
||||
await gitAuthHelper.addSafeDirectory()
|
||||
await gitAuthHelper.removeSafeDirectory()
|
||||
await gitConfigHelper.addSafeDirectory()
|
||||
await gitConfigHelper.removeSafeDirectory()
|
||||
|
||||
expect(
|
||||
await git.configExists('safe.directory', REPO_PATH, true)
|
83
__test__/git-config-helper.unit.test.ts
Normal file
83
__test__/git-config-helper.unit.test.ts
Normal file
|
@ -0,0 +1,83 @@
|
|||
import {GitConfigHelper} from '../lib/git-config-helper'
|
||||
|
||||
describe('git-config-helper unit tests', () => {
|
||||
test('parseGitRemote successfully parses HTTPS remote URLs', async () => {
|
||||
const remote1 = GitConfigHelper.parseGitRemote(
|
||||
'https://github.com/peter-evans/create-pull-request'
|
||||
)
|
||||
expect(remote1.hostname).toEqual('github.com')
|
||||
expect(remote1.protocol).toEqual('HTTPS')
|
||||
expect(remote1.repository).toEqual('peter-evans/create-pull-request')
|
||||
|
||||
const remote2 = GitConfigHelper.parseGitRemote(
|
||||
'https://xxx:x-oauth-basic@github.com/peter-evans/create-pull-request'
|
||||
)
|
||||
expect(remote2.hostname).toEqual('github.com')
|
||||
expect(remote2.protocol).toEqual('HTTPS')
|
||||
expect(remote2.repository).toEqual('peter-evans/create-pull-request')
|
||||
|
||||
const remote3 = GitConfigHelper.parseGitRemote(
|
||||
'https://github.com/peter-evans/create-pull-request.git'
|
||||
)
|
||||
expect(remote3.hostname).toEqual('github.com')
|
||||
expect(remote3.protocol).toEqual('HTTPS')
|
||||
expect(remote3.repository).toEqual('peter-evans/create-pull-request')
|
||||
|
||||
const remote4 = GitConfigHelper.parseGitRemote(
|
||||
'https://github.com/peter-evans/ungit'
|
||||
)
|
||||
expect(remote4.hostname).toEqual('github.com')
|
||||
expect(remote4.protocol).toEqual('HTTPS')
|
||||
expect(remote4.repository).toEqual('peter-evans/ungit')
|
||||
|
||||
const remote5 = GitConfigHelper.parseGitRemote(
|
||||
'https://github.com/peter-evans/ungit.git'
|
||||
)
|
||||
expect(remote5.hostname).toEqual('github.com')
|
||||
expect(remote5.protocol).toEqual('HTTPS')
|
||||
expect(remote5.repository).toEqual('peter-evans/ungit')
|
||||
|
||||
const remote6 = GitConfigHelper.parseGitRemote(
|
||||
'https://github.internal.company/peter-evans/create-pull-request'
|
||||
)
|
||||
expect(remote6.hostname).toEqual('github.internal.company')
|
||||
expect(remote6.protocol).toEqual('HTTPS')
|
||||
expect(remote6.repository).toEqual('peter-evans/create-pull-request')
|
||||
})
|
||||
|
||||
test('parseGitRemote successfully parses SSH remote URLs', async () => {
|
||||
const remote1 = GitConfigHelper.parseGitRemote(
|
||||
'git@github.com:peter-evans/create-pull-request.git'
|
||||
)
|
||||
expect(remote1.hostname).toEqual('github.com')
|
||||
expect(remote1.protocol).toEqual('SSH')
|
||||
expect(remote1.repository).toEqual('peter-evans/create-pull-request')
|
||||
|
||||
const remote2 = GitConfigHelper.parseGitRemote(
|
||||
'git@github.com:peter-evans/ungit.git'
|
||||
)
|
||||
expect(remote2.hostname).toEqual('github.com')
|
||||
expect(remote2.protocol).toEqual('SSH')
|
||||
expect(remote2.repository).toEqual('peter-evans/ungit')
|
||||
|
||||
const remote3 = GitConfigHelper.parseGitRemote(
|
||||
'git@github.internal.company:peter-evans/create-pull-request.git'
|
||||
)
|
||||
expect(remote3.hostname).toEqual('github.internal.company')
|
||||
expect(remote3.protocol).toEqual('SSH')
|
||||
expect(remote3.repository).toEqual('peter-evans/create-pull-request')
|
||||
})
|
||||
|
||||
test('parseGitRemote fails to parse a remote URL', async () => {
|
||||
const remoteUrl = 'https://github.com/peter-evans'
|
||||
try {
|
||||
GitConfigHelper.parseGitRemote(remoteUrl)
|
||||
// Fail the test if an error wasn't thrown
|
||||
expect(true).toEqual(false)
|
||||
} catch (e: any) {
|
||||
expect(e.message).toEqual(
|
||||
`The format of '${remoteUrl}' is not a valid GitHub repository URL`
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
|
@ -44,63 +44,6 @@ describe('utils tests', () => {
|
|||
)
|
||||
})
|
||||
|
||||
test('getRemoteDetail successfully parses remote URLs', async () => {
|
||||
const remote1 = utils.getRemoteDetail(
|
||||
'https://github.com/peter-evans/create-pull-request'
|
||||
)
|
||||
expect(remote1.protocol).toEqual('HTTPS')
|
||||
expect(remote1.repository).toEqual('peter-evans/create-pull-request')
|
||||
|
||||
const remote2 = utils.getRemoteDetail(
|
||||
'https://xxx:x-oauth-basic@github.com/peter-evans/create-pull-request'
|
||||
)
|
||||
expect(remote2.protocol).toEqual('HTTPS')
|
||||
expect(remote2.repository).toEqual('peter-evans/create-pull-request')
|
||||
|
||||
const remote3 = utils.getRemoteDetail(
|
||||
'git@github.com:peter-evans/create-pull-request.git'
|
||||
)
|
||||
expect(remote3.protocol).toEqual('SSH')
|
||||
expect(remote3.repository).toEqual('peter-evans/create-pull-request')
|
||||
|
||||
const remote4 = utils.getRemoteDetail(
|
||||
'https://github.com/peter-evans/create-pull-request.git'
|
||||
)
|
||||
expect(remote4.protocol).toEqual('HTTPS')
|
||||
expect(remote4.repository).toEqual('peter-evans/create-pull-request')
|
||||
|
||||
const remote5 = utils.getRemoteDetail(
|
||||
'https://github.com/peter-evans/ungit'
|
||||
)
|
||||
expect(remote5.protocol).toEqual('HTTPS')
|
||||
expect(remote5.repository).toEqual('peter-evans/ungit')
|
||||
|
||||
const remote6 = utils.getRemoteDetail(
|
||||
'https://github.com/peter-evans/ungit.git'
|
||||
)
|
||||
expect(remote6.protocol).toEqual('HTTPS')
|
||||
expect(remote6.repository).toEqual('peter-evans/ungit')
|
||||
|
||||
const remote7 = utils.getRemoteDetail(
|
||||
'git@github.com:peter-evans/ungit.git'
|
||||
)
|
||||
expect(remote7.protocol).toEqual('SSH')
|
||||
expect(remote7.repository).toEqual('peter-evans/ungit')
|
||||
})
|
||||
|
||||
test('getRemoteDetail fails to parse a remote URL', async () => {
|
||||
const remoteUrl = 'https://github.com/peter-evans'
|
||||
try {
|
||||
utils.getRemoteDetail(remoteUrl)
|
||||
// Fail the test if an error wasn't thrown
|
||||
expect(true).toEqual(false)
|
||||
} catch (e: any) {
|
||||
expect(e.message).toEqual(
|
||||
`The format of '${remoteUrl}' is not a valid GitHub repository URL`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
test('getRemoteUrl successfully returns remote URLs', async () => {
|
||||
const url1 = utils.getRemoteUrl(
|
||||
'HTTPS',
|
||||
|
|
463
dist/index.js
vendored
463
dist/index.js
vendored
|
@ -316,46 +316,21 @@ const core = __importStar(__nccwpck_require__(2186));
|
|||
const create_or_update_branch_1 = __nccwpck_require__(8363);
|
||||
const github_helper_1 = __nccwpck_require__(446);
|
||||
const git_command_manager_1 = __nccwpck_require__(738);
|
||||
const git_auth_helper_1 = __nccwpck_require__(2565);
|
||||
const git_config_helper_1 = __nccwpck_require__(8384);
|
||||
const utils = __importStar(__nccwpck_require__(918));
|
||||
function createPullRequest(inputs) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let gitAuthHelper, git;
|
||||
let gitConfigHelper, git;
|
||||
try {
|
||||
if (!inputs.token) {
|
||||
throw new Error(`Input 'token' not supplied. Unable to continue.`);
|
||||
}
|
||||
if (inputs.bodyPath) {
|
||||
if (!utils.fileExistsSync(inputs.bodyPath)) {
|
||||
throw new Error(`File '${inputs.bodyPath}' does not exist.`);
|
||||
}
|
||||
// Update the body input with the contents of the file
|
||||
inputs.body = utils.readFile(inputs.bodyPath);
|
||||
}
|
||||
// 65536 characters is the maximum allowed for the pull request body.
|
||||
if (inputs.body.length > 65536) {
|
||||
core.warning(`Pull request body is too long. Truncating to 65536 characters.`);
|
||||
const truncateWarning = '...*[Pull request body truncated]*';
|
||||
inputs.body =
|
||||
inputs.body.substring(0, 65536 - truncateWarning.length) +
|
||||
truncateWarning;
|
||||
}
|
||||
// Get the repository path
|
||||
const repoPath = utils.getRepoPath(inputs.path);
|
||||
// Create a git command manager
|
||||
git = yield git_command_manager_1.GitCommandManager.create(repoPath);
|
||||
// Save and unset the extraheader auth config if it exists
|
||||
core.startGroup('Prepare git configuration');
|
||||
gitAuthHelper = new git_auth_helper_1.GitAuthHelper(git);
|
||||
yield gitAuthHelper.addSafeDirectory();
|
||||
yield gitAuthHelper.savePersistedAuth();
|
||||
const repoPath = utils.getRepoPath(inputs.path);
|
||||
git = yield git_command_manager_1.GitCommandManager.create(repoPath);
|
||||
gitConfigHelper = yield git_config_helper_1.GitConfigHelper.create(git);
|
||||
core.endGroup();
|
||||
// Init the GitHub client
|
||||
const githubHelper = new github_helper_1.GitHubHelper(inputs.token);
|
||||
core.startGroup('Determining the base and head repositories');
|
||||
// Determine the base repository from git config
|
||||
const remoteUrl = yield git.tryGetRemoteUrl();
|
||||
const baseRemote = utils.getRemoteDetail(remoteUrl);
|
||||
const baseRemote = gitConfigHelper.getGitRemote();
|
||||
// Init the GitHub client
|
||||
const githubHelper = new github_helper_1.GitHubHelper(baseRemote.hostname, inputs.token);
|
||||
// Determine the head repository; the target for the pull request branch
|
||||
const branchRemoteName = inputs.pushToFork ? 'fork' : 'origin';
|
||||
const branchRepository = inputs.pushToFork
|
||||
|
@ -382,7 +357,7 @@ function createPullRequest(inputs) {
|
|||
// Configure auth
|
||||
if (baseRemote.protocol == 'HTTPS') {
|
||||
core.startGroup('Configuring credential for HTTPS authentication');
|
||||
yield gitAuthHelper.configureToken(inputs.gitToken);
|
||||
yield gitConfigHelper.configureToken(inputs.gitToken);
|
||||
core.endGroup();
|
||||
}
|
||||
core.startGroup('Checking the base repository state');
|
||||
|
@ -509,14 +484,11 @@ function createPullRequest(inputs) {
|
|||
core.setFailed(utils.getErrorMessage(error));
|
||||
}
|
||||
finally {
|
||||
// Remove auth and restore persisted auth config if it existed
|
||||
core.startGroup('Restore git configuration');
|
||||
if (inputs.pushToFork) {
|
||||
yield git.exec(['remote', 'rm', 'fork']);
|
||||
}
|
||||
yield gitAuthHelper.removeAuth();
|
||||
yield gitAuthHelper.restorePersistedAuth();
|
||||
yield gitAuthHelper.removeSafeDirectory();
|
||||
yield gitConfigHelper.close();
|
||||
core.endGroup();
|
||||
}
|
||||
});
|
||||
|
@ -524,163 +496,6 @@ function createPullRequest(inputs) {
|
|||
exports.createPullRequest = createPullRequest;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 2565:
|
||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
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 }));
|
||||
exports.GitAuthHelper = void 0;
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const fs = __importStar(__nccwpck_require__(7147));
|
||||
const path = __importStar(__nccwpck_require__(1017));
|
||||
const url_1 = __nccwpck_require__(7310);
|
||||
const utils = __importStar(__nccwpck_require__(918));
|
||||
class GitAuthHelper {
|
||||
constructor(git) {
|
||||
this.gitConfigPath = '';
|
||||
this.safeDirectoryConfigKey = 'safe.directory';
|
||||
this.safeDirectoryAdded = false;
|
||||
this.extraheaderConfigPlaceholderValue = 'AUTHORIZATION: basic ***';
|
||||
this.extraheaderConfigValueRegex = '^AUTHORIZATION:';
|
||||
this.persistedExtraheaderConfigValue = '';
|
||||
this.git = git;
|
||||
this.workingDirectory = this.git.getWorkingDirectory();
|
||||
const serverUrl = this.getServerUrl();
|
||||
this.extraheaderConfigKey = `http.${serverUrl.origin}/.extraheader`;
|
||||
}
|
||||
addSafeDirectory() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const exists = yield this.git.configExists(this.safeDirectoryConfigKey, this.workingDirectory, true);
|
||||
if (!exists) {
|
||||
yield this.git.config(this.safeDirectoryConfigKey, this.workingDirectory, true, true);
|
||||
this.safeDirectoryAdded = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
removeSafeDirectory() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.safeDirectoryAdded) {
|
||||
yield this.git.tryConfigUnset(this.safeDirectoryConfigKey, this.workingDirectory, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
savePersistedAuth() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Save and unset persisted extraheader credential in git config if it exists
|
||||
this.persistedExtraheaderConfigValue = yield this.getAndUnset();
|
||||
});
|
||||
}
|
||||
restorePersistedAuth() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.persistedExtraheaderConfigValue) {
|
||||
try {
|
||||
yield this.setExtraheaderConfig(this.persistedExtraheaderConfigValue);
|
||||
core.info('Persisted git credentials restored');
|
||||
}
|
||||
catch (e) {
|
||||
core.warning(utils.getErrorMessage(e));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
configureToken(token) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Encode and configure the basic credential for HTTPS access
|
||||
const basicCredential = Buffer.from(`x-access-token:${token}`, 'utf8').toString('base64');
|
||||
core.setSecret(basicCredential);
|
||||
const extraheaderConfigValue = `AUTHORIZATION: basic ${basicCredential}`;
|
||||
yield this.setExtraheaderConfig(extraheaderConfigValue);
|
||||
});
|
||||
}
|
||||
removeAuth() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield this.getAndUnset();
|
||||
});
|
||||
}
|
||||
setExtraheaderConfig(extraheaderConfigValue) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Configure a placeholder value. This approach avoids the credential being captured
|
||||
// by process creation audit events, which are commonly logged. For more information,
|
||||
// refer to https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing
|
||||
// See https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts#L267-L274
|
||||
yield this.git.config(this.extraheaderConfigKey, this.extraheaderConfigPlaceholderValue);
|
||||
// Replace the placeholder
|
||||
yield this.gitConfigStringReplace(this.extraheaderConfigPlaceholderValue, extraheaderConfigValue);
|
||||
});
|
||||
}
|
||||
getAndUnset() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let configValue = '';
|
||||
// Save and unset persisted extraheader credential in git config if it exists
|
||||
if (yield this.git.configExists(this.extraheaderConfigKey, this.extraheaderConfigValueRegex)) {
|
||||
configValue = yield this.git.getConfigValue(this.extraheaderConfigKey, this.extraheaderConfigValueRegex);
|
||||
if (yield this.git.tryConfigUnset(this.extraheaderConfigKey, this.extraheaderConfigValueRegex)) {
|
||||
core.info(`Unset config key '${this.extraheaderConfigKey}'`);
|
||||
}
|
||||
else {
|
||||
core.warning(`Failed to unset config key '${this.extraheaderConfigKey}'`);
|
||||
}
|
||||
}
|
||||
return configValue;
|
||||
});
|
||||
}
|
||||
gitConfigStringReplace(find, replace) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.gitConfigPath.length === 0) {
|
||||
const gitDir = yield this.git.getGitDirectory();
|
||||
this.gitConfigPath = path.join(this.workingDirectory, gitDir, 'config');
|
||||
}
|
||||
let content = (yield fs.promises.readFile(this.gitConfigPath)).toString();
|
||||
const index = content.indexOf(find);
|
||||
if (index < 0 || index != content.lastIndexOf(find)) {
|
||||
throw new Error(`Unable to replace '${find}' in ${this.gitConfigPath}`);
|
||||
}
|
||||
content = content.replace(find, replace);
|
||||
yield fs.promises.writeFile(this.gitConfigPath, content);
|
||||
});
|
||||
}
|
||||
getServerUrl() {
|
||||
return new url_1.URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com');
|
||||
}
|
||||
}
|
||||
exports.GitAuthHelper = GitAuthHelper;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 738:
|
||||
|
@ -1012,6 +827,208 @@ class GitOutput {
|
|||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 8384:
|
||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
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 }));
|
||||
exports.GitConfigHelper = void 0;
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const fs = __importStar(__nccwpck_require__(7147));
|
||||
const path = __importStar(__nccwpck_require__(1017));
|
||||
const url_1 = __nccwpck_require__(7310);
|
||||
const utils = __importStar(__nccwpck_require__(918));
|
||||
class GitConfigHelper {
|
||||
constructor(git) {
|
||||
this.gitConfigPath = '';
|
||||
this.safeDirectoryConfigKey = 'safe.directory';
|
||||
this.safeDirectoryAdded = false;
|
||||
this.remoteUrl = '';
|
||||
this.extraheaderConfigKey = '';
|
||||
this.extraheaderConfigPlaceholderValue = 'AUTHORIZATION: basic ***';
|
||||
this.extraheaderConfigValueRegex = '^AUTHORIZATION:';
|
||||
this.persistedExtraheaderConfigValue = '';
|
||||
this.git = git;
|
||||
this.workingDirectory = this.git.getWorkingDirectory();
|
||||
}
|
||||
static create(git) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const gitConfigHelper = new GitConfigHelper(git);
|
||||
yield gitConfigHelper.addSafeDirectory();
|
||||
yield gitConfigHelper.fetchRemoteDetail();
|
||||
yield gitConfigHelper.savePersistedAuth();
|
||||
return gitConfigHelper;
|
||||
});
|
||||
}
|
||||
close() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Remove auth and restore persisted auth config if it existed
|
||||
yield this.removeAuth();
|
||||
yield this.restorePersistedAuth();
|
||||
yield this.removeSafeDirectory();
|
||||
});
|
||||
}
|
||||
addSafeDirectory() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const exists = yield this.git.configExists(this.safeDirectoryConfigKey, this.workingDirectory, true);
|
||||
if (!exists) {
|
||||
yield this.git.config(this.safeDirectoryConfigKey, this.workingDirectory, true, true);
|
||||
this.safeDirectoryAdded = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
removeSafeDirectory() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.safeDirectoryAdded) {
|
||||
yield this.git.tryConfigUnset(this.safeDirectoryConfigKey, this.workingDirectory, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
fetchRemoteDetail() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
this.remoteUrl = yield this.git.tryGetRemoteUrl();
|
||||
});
|
||||
}
|
||||
getGitRemote() {
|
||||
return GitConfigHelper.parseGitRemote(this.remoteUrl);
|
||||
}
|
||||
static parseGitRemote(remoteUrl) {
|
||||
const httpsUrlPattern = new RegExp('^(https?)://(?:.+@)?(.+?)/(.+/.+?)(\\.git)?$', 'i');
|
||||
const sshUrlPattern = new RegExp('^git@(.+?):(.+/.+)\\.git$', 'i');
|
||||
const httpsMatch = remoteUrl.match(httpsUrlPattern);
|
||||
if (httpsMatch) {
|
||||
return {
|
||||
hostname: httpsMatch[2],
|
||||
protocol: 'HTTPS',
|
||||
repository: httpsMatch[3]
|
||||
};
|
||||
}
|
||||
const sshMatch = remoteUrl.match(sshUrlPattern);
|
||||
if (sshMatch) {
|
||||
return {
|
||||
hostname: sshMatch[1],
|
||||
protocol: 'SSH',
|
||||
repository: sshMatch[2]
|
||||
};
|
||||
}
|
||||
throw new Error(`The format of '${remoteUrl}' is not a valid GitHub repository URL`);
|
||||
}
|
||||
savePersistedAuth() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const serverUrl = new url_1.URL(`https://${this.getGitRemote().hostname}`);
|
||||
this.extraheaderConfigKey = `http.${serverUrl.origin}/.extraheader`;
|
||||
// Save and unset persisted extraheader credential in git config if it exists
|
||||
this.persistedExtraheaderConfigValue = yield this.getAndUnset();
|
||||
});
|
||||
}
|
||||
restorePersistedAuth() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.persistedExtraheaderConfigValue) {
|
||||
try {
|
||||
yield this.setExtraheaderConfig(this.persistedExtraheaderConfigValue);
|
||||
core.info('Persisted git credentials restored');
|
||||
}
|
||||
catch (e) {
|
||||
core.warning(utils.getErrorMessage(e));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
configureToken(token) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Encode and configure the basic credential for HTTPS access
|
||||
const basicCredential = Buffer.from(`x-access-token:${token}`, 'utf8').toString('base64');
|
||||
core.setSecret(basicCredential);
|
||||
const extraheaderConfigValue = `AUTHORIZATION: basic ${basicCredential}`;
|
||||
yield this.setExtraheaderConfig(extraheaderConfigValue);
|
||||
});
|
||||
}
|
||||
removeAuth() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield this.getAndUnset();
|
||||
});
|
||||
}
|
||||
setExtraheaderConfig(extraheaderConfigValue) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Configure a placeholder value. This approach avoids the credential being captured
|
||||
// by process creation audit events, which are commonly logged. For more information,
|
||||
// refer to https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing
|
||||
// See https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts#L267-L274
|
||||
yield this.git.config(this.extraheaderConfigKey, this.extraheaderConfigPlaceholderValue);
|
||||
// Replace the placeholder
|
||||
yield this.gitConfigStringReplace(this.extraheaderConfigPlaceholderValue, extraheaderConfigValue);
|
||||
});
|
||||
}
|
||||
getAndUnset() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let configValue = '';
|
||||
// Save and unset persisted extraheader credential in git config if it exists
|
||||
if (yield this.git.configExists(this.extraheaderConfigKey, this.extraheaderConfigValueRegex)) {
|
||||
configValue = yield this.git.getConfigValue(this.extraheaderConfigKey, this.extraheaderConfigValueRegex);
|
||||
if (yield this.git.tryConfigUnset(this.extraheaderConfigKey, this.extraheaderConfigValueRegex)) {
|
||||
core.info(`Unset config key '${this.extraheaderConfigKey}'`);
|
||||
}
|
||||
else {
|
||||
core.warning(`Failed to unset config key '${this.extraheaderConfigKey}'`);
|
||||
}
|
||||
}
|
||||
return configValue;
|
||||
});
|
||||
}
|
||||
gitConfigStringReplace(find, replace) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.gitConfigPath.length === 0) {
|
||||
const gitDir = yield this.git.getGitDirectory();
|
||||
this.gitConfigPath = path.join(this.workingDirectory, gitDir, 'config');
|
||||
}
|
||||
let content = (yield fs.promises.readFile(this.gitConfigPath)).toString();
|
||||
const index = content.indexOf(find);
|
||||
if (index < 0 || index != content.lastIndexOf(find)) {
|
||||
throw new Error(`Unable to replace '${find}' in ${this.gitConfigPath}`);
|
||||
}
|
||||
content = content.replace(find, replace);
|
||||
yield fs.promises.writeFile(this.gitConfigPath, content);
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.GitConfigHelper = GitConfigHelper;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 446:
|
||||
|
@ -1058,12 +1075,17 @@ const octokit_client_1 = __nccwpck_require__(5040);
|
|||
const utils = __importStar(__nccwpck_require__(918));
|
||||
const ERROR_PR_REVIEW_TOKEN_SCOPE = 'Validation Failed: "Could not resolve to a node with the global id of';
|
||||
class GitHubHelper {
|
||||
constructor(token) {
|
||||
constructor(githubServerHostname, token) {
|
||||
const options = {};
|
||||
if (token) {
|
||||
options.auth = `${token}`;
|
||||
}
|
||||
options.baseUrl = process.env['GITHUB_API_URL'] || 'https://api.github.com';
|
||||
if (githubServerHostname !== 'github.com') {
|
||||
options.baseUrl = `https://${githubServerHostname}/api/v3`;
|
||||
}
|
||||
else {
|
||||
options.baseUrl = 'https://api.github.com';
|
||||
}
|
||||
this.octokit = new octokit_client_1.Octokit(options);
|
||||
}
|
||||
parseRepository(repository) {
|
||||
|
@ -1239,9 +1261,24 @@ function run() {
|
|||
draft: core.getBooleanInput('draft')
|
||||
};
|
||||
core.debug(`Inputs: ${(0, util_1.inspect)(inputs)}`);
|
||||
if (!inputs.token) {
|
||||
throw new Error(`Input 'token' not supplied. Unable to continue.`);
|
||||
}
|
||||
if (!inputs.gitToken) {
|
||||
inputs.gitToken = inputs.token;
|
||||
}
|
||||
if (inputs.bodyPath) {
|
||||
if (!utils.fileExistsSync(inputs.bodyPath)) {
|
||||
throw new Error(`File '${inputs.bodyPath}' does not exist.`);
|
||||
}
|
||||
// Update the body input with the contents of the file
|
||||
inputs.body = utils.readFile(inputs.bodyPath);
|
||||
}
|
||||
// 65536 characters is the maximum allowed for the pull request body.
|
||||
if (inputs.body.length > 65536) {
|
||||
core.warning(`Pull request body is too long. Truncating to 65536 characters.`);
|
||||
inputs.body = inputs.body.substring(0, 65536);
|
||||
}
|
||||
yield (0, create_pull_request_1.createPullRequest)(inputs);
|
||||
}
|
||||
catch (error) {
|
||||
|
@ -1309,7 +1346,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.getErrorMessage = exports.readFile = exports.fileExistsSync = exports.parseDisplayNameEmail = exports.randomString = exports.secondsSinceEpoch = exports.getRemoteUrl = exports.getRemoteDetail = exports.getRepoPath = exports.stripOrgPrefixFromTeams = exports.getStringAsArray = exports.getInputAsArray = void 0;
|
||||
exports.getErrorMessage = exports.readFile = exports.fileExistsSync = exports.parseDisplayNameEmail = exports.randomString = exports.secondsSinceEpoch = exports.getRemoteUrl = exports.getRepoPath = exports.stripOrgPrefixFromTeams = exports.getStringAsArray = exports.getInputAsArray = void 0;
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const fs = __importStar(__nccwpck_require__(7147));
|
||||
const path = __importStar(__nccwpck_require__(1017));
|
||||
|
@ -1348,36 +1385,6 @@ function getRepoPath(relativePath) {
|
|||
return repoPath;
|
||||
}
|
||||
exports.getRepoPath = getRepoPath;
|
||||
function getRemoteDetail(remoteUrl) {
|
||||
// Parse the protocol and github repository from a URL
|
||||
// e.g. HTTPS, peter-evans/create-pull-request
|
||||
const githubUrl = process.env['GITHUB_SERVER_URL'] || 'https://github.com';
|
||||
const githubServerMatch = githubUrl.match(/^https?:\/\/(.+)$/i);
|
||||
if (!githubServerMatch) {
|
||||
throw new Error('Could not parse GitHub Server name');
|
||||
}
|
||||
const hostname = githubServerMatch[1];
|
||||
const httpsUrlPattern = new RegExp('^https?://.*@?' + hostname + '/(.+/.+?)(\\.git)?$', 'i');
|
||||
const sshUrlPattern = new RegExp('^git@' + hostname + ':(.+/.+)\\.git$', 'i');
|
||||
const httpsMatch = remoteUrl.match(httpsUrlPattern);
|
||||
if (httpsMatch) {
|
||||
return {
|
||||
hostname,
|
||||
protocol: 'HTTPS',
|
||||
repository: httpsMatch[1]
|
||||
};
|
||||
}
|
||||
const sshMatch = remoteUrl.match(sshUrlPattern);
|
||||
if (sshMatch) {
|
||||
return {
|
||||
hostname,
|
||||
protocol: 'SSH',
|
||||
repository: sshMatch[1]
|
||||
};
|
||||
}
|
||||
throw new Error(`The format of '${remoteUrl}' is not a valid GitHub repository URL`);
|
||||
}
|
||||
exports.getRemoteDetail = getRemoteDetail;
|
||||
function getRemoteUrl(protocol, hostname, repository) {
|
||||
return protocol == 'HTTPS'
|
||||
? `https://${hostname}/${repository}`
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
} from './create-or-update-branch'
|
||||
import {GitHubHelper} from './github-helper'
|
||||
import {GitCommandManager} from './git-command-manager'
|
||||
import {GitAuthHelper} from './git-auth-helper'
|
||||
import {GitConfigHelper} from './git-config-helper'
|
||||
import * as utils from './utils'
|
||||
|
||||
export interface Inputs {
|
||||
|
@ -35,48 +35,18 @@ export interface Inputs {
|
|||
}
|
||||
|
||||
export async function createPullRequest(inputs: Inputs): Promise<void> {
|
||||
let gitAuthHelper, git
|
||||
let gitConfigHelper, git
|
||||
try {
|
||||
if (!inputs.token) {
|
||||
throw new Error(`Input 'token' not supplied. Unable to continue.`)
|
||||
}
|
||||
if (inputs.bodyPath) {
|
||||
if (!utils.fileExistsSync(inputs.bodyPath)) {
|
||||
throw new Error(`File '${inputs.bodyPath}' does not exist.`)
|
||||
}
|
||||
// Update the body input with the contents of the file
|
||||
inputs.body = utils.readFile(inputs.bodyPath)
|
||||
}
|
||||
// 65536 characters is the maximum allowed for the pull request body.
|
||||
if (inputs.body.length > 65536) {
|
||||
core.warning(
|
||||
`Pull request body is too long. Truncating to 65536 characters.`
|
||||
)
|
||||
const truncateWarning = '...*[Pull request body truncated]*'
|
||||
inputs.body =
|
||||
inputs.body.substring(0, 65536 - truncateWarning.length) +
|
||||
truncateWarning
|
||||
}
|
||||
|
||||
// Get the repository path
|
||||
const repoPath = utils.getRepoPath(inputs.path)
|
||||
// Create a git command manager
|
||||
git = await GitCommandManager.create(repoPath)
|
||||
|
||||
// Save and unset the extraheader auth config if it exists
|
||||
core.startGroup('Prepare git configuration')
|
||||
gitAuthHelper = new GitAuthHelper(git)
|
||||
await gitAuthHelper.addSafeDirectory()
|
||||
await gitAuthHelper.savePersistedAuth()
|
||||
const repoPath = utils.getRepoPath(inputs.path)
|
||||
git = await GitCommandManager.create(repoPath)
|
||||
gitConfigHelper = await GitConfigHelper.create(git)
|
||||
core.endGroup()
|
||||
|
||||
// Init the GitHub client
|
||||
const githubHelper = new GitHubHelper(inputs.token)
|
||||
|
||||
core.startGroup('Determining the base and head repositories')
|
||||
// Determine the base repository from git config
|
||||
const remoteUrl = await git.tryGetRemoteUrl()
|
||||
const baseRemote = utils.getRemoteDetail(remoteUrl)
|
||||
const baseRemote = gitConfigHelper.getGitRemote()
|
||||
// Init the GitHub client
|
||||
const githubHelper = new GitHubHelper(baseRemote.hostname, inputs.token)
|
||||
// Determine the head repository; the target for the pull request branch
|
||||
const branchRemoteName = inputs.pushToFork ? 'fork' : 'origin'
|
||||
const branchRepository = inputs.pushToFork
|
||||
|
@ -121,7 +91,7 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
|||
// Configure auth
|
||||
if (baseRemote.protocol == 'HTTPS') {
|
||||
core.startGroup('Configuring credential for HTTPS authentication')
|
||||
await gitAuthHelper.configureToken(inputs.gitToken)
|
||||
await gitConfigHelper.configureToken(inputs.gitToken)
|
||||
core.endGroup()
|
||||
}
|
||||
|
||||
|
@ -281,14 +251,11 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
|||
} catch (error) {
|
||||
core.setFailed(utils.getErrorMessage(error))
|
||||
} finally {
|
||||
// Remove auth and restore persisted auth config if it existed
|
||||
core.startGroup('Restore git configuration')
|
||||
if (inputs.pushToFork) {
|
||||
await git.exec(['remote', 'rm', 'fork'])
|
||||
}
|
||||
await gitAuthHelper.removeAuth()
|
||||
await gitAuthHelper.restorePersistedAuth()
|
||||
await gitAuthHelper.removeSafeDirectory()
|
||||
await gitConfigHelper.close()
|
||||
core.endGroup()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,22 +5,42 @@ import * as path from 'path'
|
|||
import {URL} from 'url'
|
||||
import * as utils from './utils'
|
||||
|
||||
export class GitAuthHelper {
|
||||
interface GitRemote {
|
||||
hostname: string
|
||||
protocol: string
|
||||
repository: string
|
||||
}
|
||||
|
||||
export class GitConfigHelper {
|
||||
private git: GitCommandManager
|
||||
private gitConfigPath = ''
|
||||
private workingDirectory: string
|
||||
private safeDirectoryConfigKey = 'safe.directory'
|
||||
private safeDirectoryAdded = false
|
||||
private extraheaderConfigKey: string
|
||||
private remoteUrl = ''
|
||||
private extraheaderConfigKey = ''
|
||||
private extraheaderConfigPlaceholderValue = 'AUTHORIZATION: basic ***'
|
||||
private extraheaderConfigValueRegex = '^AUTHORIZATION:'
|
||||
private persistedExtraheaderConfigValue = ''
|
||||
|
||||
constructor(git: GitCommandManager) {
|
||||
private constructor(git: GitCommandManager) {
|
||||
this.git = git
|
||||
this.workingDirectory = this.git.getWorkingDirectory()
|
||||
const serverUrl = this.getServerUrl()
|
||||
this.extraheaderConfigKey = `http.${serverUrl.origin}/.extraheader`
|
||||
}
|
||||
|
||||
static async create(git: GitCommandManager): Promise<GitConfigHelper> {
|
||||
const gitConfigHelper = new GitConfigHelper(git)
|
||||
await gitConfigHelper.addSafeDirectory()
|
||||
await gitConfigHelper.fetchRemoteDetail()
|
||||
await gitConfigHelper.savePersistedAuth()
|
||||
return gitConfigHelper
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
// Remove auth and restore persisted auth config if it existed
|
||||
await this.removeAuth()
|
||||
await this.restorePersistedAuth()
|
||||
await this.removeSafeDirectory()
|
||||
}
|
||||
|
||||
async addSafeDirectory(): Promise<void> {
|
||||
|
@ -50,7 +70,47 @@ export class GitAuthHelper {
|
|||
}
|
||||
}
|
||||
|
||||
async fetchRemoteDetail(): Promise<void> {
|
||||
this.remoteUrl = await this.git.tryGetRemoteUrl()
|
||||
}
|
||||
|
||||
getGitRemote(): GitRemote {
|
||||
return GitConfigHelper.parseGitRemote(this.remoteUrl)
|
||||
}
|
||||
|
||||
static parseGitRemote(remoteUrl: string): GitRemote {
|
||||
const httpsUrlPattern = new RegExp(
|
||||
'^(https?)://(?:.+@)?(.+?)/(.+/.+?)(\\.git)?$',
|
||||
'i'
|
||||
)
|
||||
const sshUrlPattern = new RegExp('^git@(.+?):(.+/.+)\\.git$', 'i')
|
||||
|
||||
const httpsMatch = remoteUrl.match(httpsUrlPattern)
|
||||
if (httpsMatch) {
|
||||
return {
|
||||
hostname: httpsMatch[2],
|
||||
protocol: 'HTTPS',
|
||||
repository: httpsMatch[3]
|
||||
}
|
||||
}
|
||||
|
||||
const sshMatch = remoteUrl.match(sshUrlPattern)
|
||||
if (sshMatch) {
|
||||
return {
|
||||
hostname: sshMatch[1],
|
||||
protocol: 'SSH',
|
||||
repository: sshMatch[2]
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`The format of '${remoteUrl}' is not a valid GitHub repository URL`
|
||||
)
|
||||
}
|
||||
|
||||
async savePersistedAuth(): Promise<void> {
|
||||
const serverUrl = new URL(`https://${this.getGitRemote().hostname}`)
|
||||
this.extraheaderConfigKey = `http.${serverUrl.origin}/.extraheader`
|
||||
// Save and unset persisted extraheader credential in git config if it exists
|
||||
this.persistedExtraheaderConfigValue = await this.getAndUnset()
|
||||
}
|
||||
|
@ -144,8 +204,4 @@ export class GitAuthHelper {
|
|||
content = content.replace(find, replace)
|
||||
await fs.promises.writeFile(this.gitConfigPath, content)
|
||||
}
|
||||
|
||||
private getServerUrl(): URL {
|
||||
return new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com')
|
||||
}
|
||||
}
|
|
@ -20,12 +20,16 @@ interface Pull {
|
|||
export class GitHubHelper {
|
||||
private octokit: InstanceType<typeof Octokit>
|
||||
|
||||
constructor(token: string) {
|
||||
constructor(githubServerHostname: string, token: string) {
|
||||
const options: OctokitOptions = {}
|
||||
if (token) {
|
||||
options.auth = `${token}`
|
||||
}
|
||||
options.baseUrl = process.env['GITHUB_API_URL'] || 'https://api.github.com'
|
||||
if (githubServerHostname !== 'github.com') {
|
||||
options.baseUrl = `https://${githubServerHostname}/api/v3`
|
||||
} else {
|
||||
options.baseUrl = 'https://api.github.com'
|
||||
}
|
||||
this.octokit = new Octokit(options)
|
||||
}
|
||||
|
||||
|
|
17
src/main.ts
17
src/main.ts
|
@ -31,9 +31,26 @@ async function run(): Promise<void> {
|
|||
}
|
||||
core.debug(`Inputs: ${inspect(inputs)}`)
|
||||
|
||||
if (!inputs.token) {
|
||||
throw new Error(`Input 'token' not supplied. Unable to continue.`)
|
||||
}
|
||||
if (!inputs.gitToken) {
|
||||
inputs.gitToken = inputs.token
|
||||
}
|
||||
if (inputs.bodyPath) {
|
||||
if (!utils.fileExistsSync(inputs.bodyPath)) {
|
||||
throw new Error(`File '${inputs.bodyPath}' does not exist.`)
|
||||
}
|
||||
// Update the body input with the contents of the file
|
||||
inputs.body = utils.readFile(inputs.bodyPath)
|
||||
}
|
||||
// 65536 characters is the maximum allowed for the pull request body.
|
||||
if (inputs.body.length > 65536) {
|
||||
core.warning(
|
||||
`Pull request body is too long. Truncating to 65536 characters.`
|
||||
)
|
||||
inputs.body = inputs.body.substring(0, 65536)
|
||||
}
|
||||
|
||||
await createPullRequest(inputs)
|
||||
} catch (error) {
|
||||
|
|
47
src/utils.ts
47
src/utils.ts
|
@ -41,53 +41,6 @@ export function getRepoPath(relativePath?: string): string {
|
|||
return repoPath
|
||||
}
|
||||
|
||||
interface RemoteDetail {
|
||||
hostname: string
|
||||
protocol: string
|
||||
repository: string
|
||||
}
|
||||
|
||||
export function getRemoteDetail(remoteUrl: string): RemoteDetail {
|
||||
// Parse the protocol and github repository from a URL
|
||||
// e.g. HTTPS, peter-evans/create-pull-request
|
||||
const githubUrl = process.env['GITHUB_SERVER_URL'] || 'https://github.com'
|
||||
|
||||
const githubServerMatch = githubUrl.match(/^https?:\/\/(.+)$/i)
|
||||
if (!githubServerMatch) {
|
||||
throw new Error('Could not parse GitHub Server name')
|
||||
}
|
||||
|
||||
const hostname = githubServerMatch[1]
|
||||
|
||||
const httpsUrlPattern = new RegExp(
|
||||
'^https?://.*@?' + hostname + '/(.+/.+?)(\\.git)?$',
|
||||
'i'
|
||||
)
|
||||
const sshUrlPattern = new RegExp('^git@' + hostname + ':(.+/.+)\\.git$', 'i')
|
||||
|
||||
const httpsMatch = remoteUrl.match(httpsUrlPattern)
|
||||
if (httpsMatch) {
|
||||
return {
|
||||
hostname,
|
||||
protocol: 'HTTPS',
|
||||
repository: httpsMatch[1]
|
||||
}
|
||||
}
|
||||
|
||||
const sshMatch = remoteUrl.match(sshUrlPattern)
|
||||
if (sshMatch) {
|
||||
return {
|
||||
hostname,
|
||||
protocol: 'SSH',
|
||||
repository: sshMatch[1]
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`The format of '${remoteUrl}' is not a valid GitHub repository URL`
|
||||
)
|
||||
}
|
||||
|
||||
export function getRemoteUrl(
|
||||
protocol: string,
|
||||
hostname: string,
|
||||
|
|
Loading…
Reference in a new issue