mirror of
https://code.forgejo.org/actions/checkout.git
synced 2024-11-27 22:49:17 +01:00
Inject GitHub host to be able to clone from another GitHub instance (#922)
* Adding the ability to specify the GitHub Server URL and allowing for it to differ from the Actions workflow host * Adding tests for injecting the GitHub URL * Addressing code review comments for PR #922
This commit is contained in:
parent
2541b1294d
commit
e6d535c99c
13 changed files with 220 additions and 67 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@ __test__/_temp
|
||||||
_temp/
|
_temp/
|
||||||
lib/
|
lib/
|
||||||
node_modules/
|
node_modules/
|
||||||
|
.vscode/
|
|
@ -97,6 +97,12 @@ When Git 2.18 or higher is not in your PATH, falls back to the REST API to downl
|
||||||
# config --global --add safe.directory <path>`
|
# config --global --add safe.directory <path>`
|
||||||
# Default: true
|
# Default: true
|
||||||
set-safe-directory: ''
|
set-safe-directory: ''
|
||||||
|
|
||||||
|
# The base URL for the GitHub instance that you are trying to clone from, will use
|
||||||
|
# environment defaults to fetch from the same instance that the workflow is
|
||||||
|
# running from unless specified. Example URLs are https://github.com or
|
||||||
|
# https://my-ghes-server.example.com
|
||||||
|
github-server-url: ''
|
||||||
```
|
```
|
||||||
<!-- end usage -->
|
<!-- end usage -->
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ let tempHomedir: string
|
||||||
let git: IGitCommandManager & {env: {[key: string]: string}}
|
let git: IGitCommandManager & {env: {[key: string]: string}}
|
||||||
let settings: IGitSourceSettings
|
let settings: IGitSourceSettings
|
||||||
let sshPath: string
|
let sshPath: string
|
||||||
|
let githubServerUrl: string
|
||||||
|
|
||||||
describe('git-auth-helper tests', () => {
|
describe('git-auth-helper tests', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
@ -67,11 +68,18 @@ describe('git-auth-helper tests', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const configureAuth_configuresAuthHeader =
|
async function testAuthHeader(
|
||||||
'configureAuth configures auth header'
|
testName: string,
|
||||||
it(configureAuth_configuresAuthHeader, async () => {
|
serverUrl: string | undefined = undefined
|
||||||
|
) {
|
||||||
// Arrange
|
// Arrange
|
||||||
await setup(configureAuth_configuresAuthHeader)
|
let expectedServerUrl = 'https://github.com'
|
||||||
|
if (serverUrl) {
|
||||||
|
githubServerUrl = serverUrl
|
||||||
|
expectedServerUrl = githubServerUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
await setup(testName)
|
||||||
expect(settings.authToken).toBeTruthy() // sanity check
|
expect(settings.authToken).toBeTruthy() // sanity check
|
||||||
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
|
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
|
||||||
|
|
||||||
|
@ -88,9 +96,33 @@ describe('git-auth-helper tests', () => {
|
||||||
).toString('base64')
|
).toString('base64')
|
||||||
expect(
|
expect(
|
||||||
configContent.indexOf(
|
configContent.indexOf(
|
||||||
`http.https://github.com/.extraheader AUTHORIZATION: basic ${basicCredential}`
|
`http.${expectedServerUrl}/.extraheader AUTHORIZATION: basic ${basicCredential}`
|
||||||
)
|
)
|
||||||
).toBeGreaterThanOrEqual(0)
|
).toBeGreaterThanOrEqual(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const configureAuth_configuresAuthHeader =
|
||||||
|
'configureAuth configures auth header'
|
||||||
|
it(configureAuth_configuresAuthHeader, async () => {
|
||||||
|
await testAuthHeader(configureAuth_configuresAuthHeader)
|
||||||
|
})
|
||||||
|
|
||||||
|
const configureAuth_AcceptsGitHubServerUrl =
|
||||||
|
'inject https://my-ghes-server.com as github server url'
|
||||||
|
it(configureAuth_AcceptsGitHubServerUrl, async () => {
|
||||||
|
await testAuthHeader(
|
||||||
|
configureAuth_AcceptsGitHubServerUrl,
|
||||||
|
'https://my-ghes-server.com'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const configureAuth_AcceptsGitHubServerUrlSetToGHEC =
|
||||||
|
'inject https://github.com as github server url'
|
||||||
|
it(configureAuth_AcceptsGitHubServerUrlSetToGHEC, async () => {
|
||||||
|
await testAuthHeader(
|
||||||
|
configureAuth_AcceptsGitHubServerUrl,
|
||||||
|
'https://github.com'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const configureAuth_configuresAuthHeaderEvenWhenPersistCredentialsFalse =
|
const configureAuth_configuresAuthHeaderEvenWhenPersistCredentialsFalse =
|
||||||
|
@ -778,7 +810,8 @@ async function setup(testName: string): Promise<void> {
|
||||||
sshKnownHosts: '',
|
sshKnownHosts: '',
|
||||||
sshStrict: true,
|
sshStrict: true,
|
||||||
workflowOrganizationId: 123456,
|
workflowOrganizationId: 123456,
|
||||||
setSafeDirectory: true
|
setSafeDirectory: true,
|
||||||
|
githubServerUrl: githubServerUrl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,9 @@ inputs:
|
||||||
set-safe-directory:
|
set-safe-directory:
|
||||||
description: Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory <path>`
|
description: Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory <path>`
|
||||||
default: true
|
default: true
|
||||||
|
github-server-url:
|
||||||
|
description: The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com
|
||||||
|
required: false
|
||||||
runs:
|
runs:
|
||||||
using: node16
|
using: node16
|
||||||
main: dist/index.js
|
main: dist/index.js
|
||||||
|
|
114
dist/index.js
vendored
114
dist/index.js
vendored
|
@ -1935,13 +1935,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.getServerUrl = exports.getFetchUrl = void 0;
|
exports.isGhes = exports.getServerApiUrl = exports.getServerUrl = exports.getFetchUrl = void 0;
|
||||||
const assert = __importStar(__webpack_require__(357));
|
const assert = __importStar(__webpack_require__(357));
|
||||||
const url_1 = __webpack_require__(835);
|
const url_1 = __webpack_require__(835);
|
||||||
function getFetchUrl(settings) {
|
function getFetchUrl(settings) {
|
||||||
assert.ok(settings.repositoryOwner, 'settings.repositoryOwner must be defined');
|
assert.ok(settings.repositoryOwner, 'settings.repositoryOwner must be defined');
|
||||||
assert.ok(settings.repositoryName, 'settings.repositoryName must be defined');
|
assert.ok(settings.repositoryName, 'settings.repositoryName must be defined');
|
||||||
const serviceUrl = getServerUrl();
|
const serviceUrl = getServerUrl(settings.githubServerUrl);
|
||||||
const encodedOwner = encodeURIComponent(settings.repositoryOwner);
|
const encodedOwner = encodeURIComponent(settings.repositoryOwner);
|
||||||
const encodedName = encodeURIComponent(settings.repositoryName);
|
const encodedName = encodeURIComponent(settings.repositoryName);
|
||||||
if (settings.sshKey) {
|
if (settings.sshKey) {
|
||||||
|
@ -1951,13 +1951,27 @@ function getFetchUrl(settings) {
|
||||||
return `${serviceUrl.origin}/${encodedOwner}/${encodedName}`;
|
return `${serviceUrl.origin}/${encodedOwner}/${encodedName}`;
|
||||||
}
|
}
|
||||||
exports.getFetchUrl = getFetchUrl;
|
exports.getFetchUrl = getFetchUrl;
|
||||||
function getServerUrl() {
|
function getServerUrl(url) {
|
||||||
// todo: remove GITHUB_URL after support for GHES Alpha is no longer needed
|
let urlValue = url && url.trim().length > 0
|
||||||
return new url_1.URL(process.env['GITHUB_SERVER_URL'] ||
|
? url
|
||||||
process.env['GITHUB_URL'] ||
|
: process.env['GITHUB_SERVER_URL'] || 'https://github.com';
|
||||||
'https://github.com');
|
return new url_1.URL(urlValue);
|
||||||
}
|
}
|
||||||
exports.getServerUrl = getServerUrl;
|
exports.getServerUrl = getServerUrl;
|
||||||
|
function getServerApiUrl(url) {
|
||||||
|
let apiUrl = 'https://api.github.com';
|
||||||
|
if (isGhes(url)) {
|
||||||
|
const serverUrl = getServerUrl(url);
|
||||||
|
apiUrl = new url_1.URL(`${serverUrl.origin}/api/v3`).toString();
|
||||||
|
}
|
||||||
|
return apiUrl;
|
||||||
|
}
|
||||||
|
exports.getServerApiUrl = getServerApiUrl;
|
||||||
|
function isGhes(url) {
|
||||||
|
const ghUrl = getServerUrl(url);
|
||||||
|
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
|
||||||
|
}
|
||||||
|
exports.isGhes = isGhes;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
@ -4066,6 +4080,51 @@ function authenticationPlugin(octokit, options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 195:
|
||||||
|
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (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;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.getOctokit = exports.Octokit = void 0;
|
||||||
|
const github = __importStar(__webpack_require__(469));
|
||||||
|
const url_helper_1 = __webpack_require__(81);
|
||||||
|
// Centralize all Octokit references by re-exporting
|
||||||
|
var rest_1 = __webpack_require__(0);
|
||||||
|
Object.defineProperty(exports, "Octokit", { enumerable: true, get: function () { return rest_1.Octokit; } });
|
||||||
|
function getOctokit(authToken, opts) {
|
||||||
|
const options = {
|
||||||
|
baseUrl: (0, url_helper_1.getServerApiUrl)(opts.baseUrl)
|
||||||
|
};
|
||||||
|
if (opts.userAgent) {
|
||||||
|
options.userAgent = opts.userAgent;
|
||||||
|
}
|
||||||
|
return new github.GitHub(authToken, options);
|
||||||
|
}
|
||||||
|
exports.getOctokit = getOctokit;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 197:
|
/***/ 197:
|
||||||
|
@ -4279,9 +4338,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.checkCommitInfo = exports.testRef = exports.getRefSpec = exports.getRefSpecForAllHistory = exports.getCheckoutInfo = exports.tagsRefSpec = void 0;
|
exports.checkCommitInfo = exports.testRef = exports.getRefSpec = exports.getRefSpecForAllHistory = exports.getCheckoutInfo = exports.tagsRefSpec = void 0;
|
||||||
const url_1 = __webpack_require__(835);
|
|
||||||
const core = __importStar(__webpack_require__(470));
|
const core = __importStar(__webpack_require__(470));
|
||||||
const github = __importStar(__webpack_require__(469));
|
const github = __importStar(__webpack_require__(469));
|
||||||
|
const octokit_provider_1 = __webpack_require__(195);
|
||||||
|
const url_helper_1 = __webpack_require__(81);
|
||||||
exports.tagsRefSpec = '+refs/tags/*:refs/tags/*';
|
exports.tagsRefSpec = '+refs/tags/*:refs/tags/*';
|
||||||
function getCheckoutInfo(git, ref, commit) {
|
function getCheckoutInfo(git, ref, commit) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
@ -4431,12 +4491,12 @@ function testRef(git, ref, commit) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.testRef = testRef;
|
exports.testRef = testRef;
|
||||||
function checkCommitInfo(token, commitInfo, repositoryOwner, repositoryName, ref, commit) {
|
function checkCommitInfo(token, commitInfo, repositoryOwner, repositoryName, ref, commit, baseUrl) {
|
||||||
var _a, _b;
|
var _a, _b;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
// GHES?
|
// GHES?
|
||||||
if (isGhes()) {
|
if ((0, url_helper_1.isGhes)(baseUrl)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Auth token?
|
// Auth token?
|
||||||
|
@ -4481,7 +4541,8 @@ function checkCommitInfo(token, commitInfo, repositoryOwner, repositoryName, ref
|
||||||
const actualHeadSha = match[1];
|
const actualHeadSha = match[1];
|
||||||
if (actualHeadSha !== expectedHeadSha) {
|
if (actualHeadSha !== expectedHeadSha) {
|
||||||
core.debug(`Expected head sha ${expectedHeadSha}; actual head sha ${actualHeadSha}`);
|
core.debug(`Expected head sha ${expectedHeadSha}; actual head sha ${actualHeadSha}`);
|
||||||
const octokit = new github.GitHub(token, {
|
const octokit = (0, octokit_provider_1.getOctokit)(token, {
|
||||||
|
baseUrl: baseUrl,
|
||||||
userAgent: `actions-checkout-tracepoint/1.0 (code=STALE_MERGE;owner=${repositoryOwner};repo=${repositoryName};pr=${fromPayload('number')};run_id=${process.env['GITHUB_RUN_ID']};expected_head_sha=${expectedHeadSha};actual_head_sha=${actualHeadSha})`
|
userAgent: `actions-checkout-tracepoint/1.0 (code=STALE_MERGE;owner=${repositoryOwner};repo=${repositoryName};pr=${fromPayload('number')};run_id=${process.env['GITHUB_RUN_ID']};expected_head_sha=${expectedHeadSha};actual_head_sha=${actualHeadSha})`
|
||||||
});
|
});
|
||||||
yield octokit.repos.get({ owner: repositoryOwner, repo: repositoryName });
|
yield octokit.repos.get({ owner: repositoryOwner, repo: repositoryName });
|
||||||
|
@ -4507,10 +4568,6 @@ function select(obj, path) {
|
||||||
const key = path.substr(0, i);
|
const key = path.substr(0, i);
|
||||||
return select(obj[key], path.substr(i + 1));
|
return select(obj[key], path.substr(i + 1));
|
||||||
}
|
}
|
||||||
function isGhes() {
|
|
||||||
const ghUrl = new url_1.URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com');
|
|
||||||
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
@ -6561,7 +6618,7 @@ class GitAuthHelper {
|
||||||
this.git = gitCommandManager;
|
this.git = gitCommandManager;
|
||||||
this.settings = gitSourceSettings || {};
|
this.settings = gitSourceSettings || {};
|
||||||
// Token auth header
|
// Token auth header
|
||||||
const serverUrl = urlHelper.getServerUrl();
|
const serverUrl = urlHelper.getServerUrl(this.settings.githubServerUrl);
|
||||||
this.tokenConfigKey = `http.${serverUrl.origin}/.extraheader`; // "origin" is SCHEME://HOSTNAME[:PORT]
|
this.tokenConfigKey = `http.${serverUrl.origin}/.extraheader`; // "origin" is SCHEME://HOSTNAME[:PORT]
|
||||||
const basicCredential = Buffer.from(`x-access-token:${this.settings.authToken}`, 'utf8').toString('base64');
|
const basicCredential = Buffer.from(`x-access-token:${this.settings.authToken}`, 'utf8').toString('base64');
|
||||||
core.setSecret(basicCredential);
|
core.setSecret(basicCredential);
|
||||||
|
@ -7382,7 +7439,7 @@ function getSource(settings) {
|
||||||
else if (settings.sshKey) {
|
else if (settings.sshKey) {
|
||||||
throw new Error(`Input 'ssh-key' not supported when falling back to download using the GitHub REST API. To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH.`);
|
throw new Error(`Input 'ssh-key' not supported when falling back to download using the GitHub REST API. To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH.`);
|
||||||
}
|
}
|
||||||
yield githubApiHelper.downloadRepository(settings.authToken, settings.repositoryOwner, settings.repositoryName, settings.ref, settings.commit, settings.repositoryPath);
|
yield githubApiHelper.downloadRepository(settings.authToken, settings.repositoryOwner, settings.repositoryName, settings.ref, settings.commit, settings.repositoryPath, settings.githubServerUrl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Save state for POST action
|
// Save state for POST action
|
||||||
|
@ -7415,7 +7472,7 @@ function getSource(settings) {
|
||||||
settings.ref = yield git.getDefaultBranch(repositoryUrl);
|
settings.ref = yield git.getDefaultBranch(repositoryUrl);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
settings.ref = yield githubApiHelper.getDefaultBranch(settings.authToken, settings.repositoryOwner, settings.repositoryName);
|
settings.ref = yield githubApiHelper.getDefaultBranch(settings.authToken, settings.repositoryOwner, settings.repositoryName, settings.githubServerUrl);
|
||||||
}
|
}
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
}
|
}
|
||||||
|
@ -7481,7 +7538,7 @@ function getSource(settings) {
|
||||||
// Log commit sha
|
// Log commit sha
|
||||||
yield git.log1("--format='%H'");
|
yield git.log1("--format='%H'");
|
||||||
// Check for incorrect pull request merge commit
|
// Check for incorrect pull request merge commit
|
||||||
yield refHelper.checkCommitInfo(settings.authToken, commitInfo, settings.repositoryOwner, settings.repositoryName, settings.ref, settings.commit);
|
yield refHelper.checkCommitInfo(settings.authToken, commitInfo, settings.repositoryOwner, settings.repositoryName, settings.ref, settings.commit, settings.githubServerUrl);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
// Remove auth
|
// Remove auth
|
||||||
|
@ -10966,24 +11023,24 @@ exports.getDefaultBranch = exports.downloadRepository = void 0;
|
||||||
const assert = __importStar(__webpack_require__(357));
|
const assert = __importStar(__webpack_require__(357));
|
||||||
const core = __importStar(__webpack_require__(470));
|
const core = __importStar(__webpack_require__(470));
|
||||||
const fs = __importStar(__webpack_require__(747));
|
const fs = __importStar(__webpack_require__(747));
|
||||||
const github = __importStar(__webpack_require__(469));
|
|
||||||
const io = __importStar(__webpack_require__(1));
|
const io = __importStar(__webpack_require__(1));
|
||||||
const path = __importStar(__webpack_require__(622));
|
const path = __importStar(__webpack_require__(622));
|
||||||
const retryHelper = __importStar(__webpack_require__(587));
|
const retryHelper = __importStar(__webpack_require__(587));
|
||||||
const toolCache = __importStar(__webpack_require__(533));
|
const toolCache = __importStar(__webpack_require__(533));
|
||||||
const v4_1 = __importDefault(__webpack_require__(826));
|
const v4_1 = __importDefault(__webpack_require__(826));
|
||||||
|
const octokit_provider_1 = __webpack_require__(195);
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
const IS_WINDOWS = process.platform === 'win32';
|
||||||
function downloadRepository(authToken, owner, repo, ref, commit, repositoryPath) {
|
function downloadRepository(authToken, owner, repo, ref, commit, repositoryPath, baseUrl) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
// Determine the default branch
|
// Determine the default branch
|
||||||
if (!ref && !commit) {
|
if (!ref && !commit) {
|
||||||
core.info('Determining the default branch');
|
core.info('Determining the default branch');
|
||||||
ref = yield getDefaultBranch(authToken, owner, repo);
|
ref = yield getDefaultBranch(authToken, owner, repo, baseUrl);
|
||||||
}
|
}
|
||||||
// Download the archive
|
// Download the archive
|
||||||
let archiveData = yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
|
let archiveData = yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
|
||||||
core.info('Downloading the archive');
|
core.info('Downloading the archive');
|
||||||
return yield downloadArchive(authToken, owner, repo, ref, commit);
|
return yield downloadArchive(authToken, owner, repo, ref, commit, baseUrl);
|
||||||
}));
|
}));
|
||||||
// Write archive to disk
|
// Write archive to disk
|
||||||
core.info('Writing archive to disk');
|
core.info('Writing archive to disk');
|
||||||
|
@ -11027,12 +11084,12 @@ exports.downloadRepository = downloadRepository;
|
||||||
/**
|
/**
|
||||||
* Looks up the default branch name
|
* Looks up the default branch name
|
||||||
*/
|
*/
|
||||||
function getDefaultBranch(authToken, owner, repo) {
|
function getDefaultBranch(authToken, owner, repo, baseUrl) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
return yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
|
return yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
|
||||||
var _a;
|
var _a;
|
||||||
core.info('Retrieving the default branch name');
|
core.info('Retrieving the default branch name');
|
||||||
const octokit = new github.GitHub(authToken);
|
const octokit = (0, octokit_provider_1.getOctokit)(authToken, { baseUrl: baseUrl });
|
||||||
let result;
|
let result;
|
||||||
try {
|
try {
|
||||||
// Get the default branch from the repo info
|
// Get the default branch from the repo info
|
||||||
|
@ -11062,9 +11119,9 @@ function getDefaultBranch(authToken, owner, repo) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.getDefaultBranch = getDefaultBranch;
|
exports.getDefaultBranch = getDefaultBranch;
|
||||||
function downloadArchive(authToken, owner, repo, ref, commit) {
|
function downloadArchive(authToken, owner, repo, ref, commit, baseUrl) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const octokit = new github.GitHub(authToken);
|
const octokit = (0, octokit_provider_1.getOctokit)(authToken, { baseUrl: baseUrl });
|
||||||
const params = {
|
const params = {
|
||||||
owner: owner,
|
owner: owner,
|
||||||
repo: repo,
|
repo: repo,
|
||||||
|
@ -17330,6 +17387,9 @@ function getInputs() {
|
||||||
// Set safe.directory in git global config.
|
// Set safe.directory in git global config.
|
||||||
result.setSafeDirectory =
|
result.setSafeDirectory =
|
||||||
(core.getInput('set-safe-directory') || 'true').toUpperCase() === 'TRUE';
|
(core.getInput('set-safe-directory') || 'true').toUpperCase() === 'TRUE';
|
||||||
|
// Determine the GitHub URL that the repository is being hosted from
|
||||||
|
result.githubServerUrl = core.getInput('github-server-url');
|
||||||
|
core.debug(`GitHub Host URL = ${result.githubServerUrl}`);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ class GitAuthHelper {
|
||||||
this.settings = gitSourceSettings || (({} as unknown) as IGitSourceSettings)
|
this.settings = gitSourceSettings || (({} as unknown) as IGitSourceSettings)
|
||||||
|
|
||||||
// Token auth header
|
// Token auth header
|
||||||
const serverUrl = urlHelper.getServerUrl()
|
const serverUrl = urlHelper.getServerUrl(this.settings.githubServerUrl)
|
||||||
this.tokenConfigKey = `http.${serverUrl.origin}/.extraheader` // "origin" is SCHEME://HOSTNAME[:PORT]
|
this.tokenConfigKey = `http.${serverUrl.origin}/.extraheader` // "origin" is SCHEME://HOSTNAME[:PORT]
|
||||||
const basicCredential = Buffer.from(
|
const basicCredential = Buffer.from(
|
||||||
`x-access-token:${this.settings.authToken}`,
|
`x-access-token:${this.settings.authToken}`,
|
||||||
|
|
|
@ -93,7 +93,8 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
|
||||||
settings.repositoryName,
|
settings.repositoryName,
|
||||||
settings.ref,
|
settings.ref,
|
||||||
settings.commit,
|
settings.commit,
|
||||||
settings.repositoryPath
|
settings.repositoryPath,
|
||||||
|
settings.githubServerUrl
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -138,7 +139,8 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
|
||||||
settings.ref = await githubApiHelper.getDefaultBranch(
|
settings.ref = await githubApiHelper.getDefaultBranch(
|
||||||
settings.authToken,
|
settings.authToken,
|
||||||
settings.repositoryOwner,
|
settings.repositoryOwner,
|
||||||
settings.repositoryName
|
settings.repositoryName,
|
||||||
|
settings.githubServerUrl
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
core.endGroup()
|
core.endGroup()
|
||||||
|
@ -232,7 +234,8 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
|
||||||
settings.repositoryOwner,
|
settings.repositoryOwner,
|
||||||
settings.repositoryName,
|
settings.repositoryName,
|
||||||
settings.ref,
|
settings.ref,
|
||||||
settings.commit
|
settings.commit,
|
||||||
|
settings.githubServerUrl
|
||||||
)
|
)
|
||||||
} finally {
|
} finally {
|
||||||
// Remove auth
|
// Remove auth
|
||||||
|
|
|
@ -83,4 +83,9 @@ export interface IGitSourceSettings {
|
||||||
* Indicates whether to add repositoryPath as safe.directory in git global config
|
* Indicates whether to add repositoryPath as safe.directory in git global config
|
||||||
*/
|
*/
|
||||||
setSafeDirectory: boolean
|
setSafeDirectory: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User override on the GitHub Server/Host URL that hosts the repository to be cloned
|
||||||
|
*/
|
||||||
|
githubServerUrl: string | undefined
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import * as assert from 'assert'
|
import * as assert from 'assert'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as github from '@actions/github'
|
|
||||||
import * as io from '@actions/io'
|
import * as io from '@actions/io'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as retryHelper from './retry-helper'
|
import * as retryHelper from './retry-helper'
|
||||||
import * as toolCache from '@actions/tool-cache'
|
import * as toolCache from '@actions/tool-cache'
|
||||||
import {default as uuid} from 'uuid/v4'
|
import {default as uuid} from 'uuid/v4'
|
||||||
import {Octokit} from '@octokit/rest'
|
import {getOctokit, Octokit} from './octokit-provider'
|
||||||
|
|
||||||
const IS_WINDOWS = process.platform === 'win32'
|
const IS_WINDOWS = process.platform === 'win32'
|
||||||
|
|
||||||
|
@ -17,18 +16,19 @@ export async function downloadRepository(
|
||||||
repo: string,
|
repo: string,
|
||||||
ref: string,
|
ref: string,
|
||||||
commit: string,
|
commit: string,
|
||||||
repositoryPath: string
|
repositoryPath: string,
|
||||||
|
baseUrl?: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// Determine the default branch
|
// Determine the default branch
|
||||||
if (!ref && !commit) {
|
if (!ref && !commit) {
|
||||||
core.info('Determining the default branch')
|
core.info('Determining the default branch')
|
||||||
ref = await getDefaultBranch(authToken, owner, repo)
|
ref = await getDefaultBranch(authToken, owner, repo, baseUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download the archive
|
// Download the archive
|
||||||
let archiveData = await retryHelper.execute(async () => {
|
let archiveData = await retryHelper.execute(async () => {
|
||||||
core.info('Downloading the archive')
|
core.info('Downloading the archive')
|
||||||
return await downloadArchive(authToken, owner, repo, ref, commit)
|
return await downloadArchive(authToken, owner, repo, ref, commit, baseUrl)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Write archive to disk
|
// Write archive to disk
|
||||||
|
@ -79,11 +79,12 @@ export async function downloadRepository(
|
||||||
export async function getDefaultBranch(
|
export async function getDefaultBranch(
|
||||||
authToken: string,
|
authToken: string,
|
||||||
owner: string,
|
owner: string,
|
||||||
repo: string
|
repo: string,
|
||||||
|
baseUrl?: string
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
return await retryHelper.execute(async () => {
|
return await retryHelper.execute(async () => {
|
||||||
core.info('Retrieving the default branch name')
|
core.info('Retrieving the default branch name')
|
||||||
const octokit = new github.GitHub(authToken)
|
const octokit = getOctokit(authToken, {baseUrl: baseUrl})
|
||||||
let result: string
|
let result: string
|
||||||
try {
|
try {
|
||||||
// Get the default branch from the repo info
|
// Get the default branch from the repo info
|
||||||
|
@ -121,9 +122,10 @@ async function downloadArchive(
|
||||||
owner: string,
|
owner: string,
|
||||||
repo: string,
|
repo: string,
|
||||||
ref: string,
|
ref: string,
|
||||||
commit: string
|
commit: string,
|
||||||
|
baseUrl?: string
|
||||||
): Promise<Buffer> {
|
): Promise<Buffer> {
|
||||||
const octokit = new github.GitHub(authToken)
|
const octokit = getOctokit(authToken, {baseUrl: baseUrl})
|
||||||
const params: Octokit.ReposGetArchiveLinkParams = {
|
const params: Octokit.ReposGetArchiveLinkParams = {
|
||||||
owner: owner,
|
owner: owner,
|
||||||
repo: repo,
|
repo: repo,
|
||||||
|
|
|
@ -125,5 +125,10 @@ export async function getInputs(): Promise<IGitSourceSettings> {
|
||||||
// Set safe.directory in git global config.
|
// Set safe.directory in git global config.
|
||||||
result.setSafeDirectory =
|
result.setSafeDirectory =
|
||||||
(core.getInput('set-safe-directory') || 'true').toUpperCase() === 'TRUE'
|
(core.getInput('set-safe-directory') || 'true').toUpperCase() === 'TRUE'
|
||||||
|
|
||||||
|
// Determine the GitHub URL that the repository is being hosted from
|
||||||
|
result.githubServerUrl = core.getInput('github-server-url')
|
||||||
|
core.debug(`GitHub Host URL = ${result.githubServerUrl}`)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
23
src/octokit-provider.ts
Normal file
23
src/octokit-provider.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import * as github from '@actions/github'
|
||||||
|
import {Octokit} from '@octokit/rest'
|
||||||
|
import {getServerApiUrl} from './url-helper'
|
||||||
|
|
||||||
|
// Centralize all Octokit references by re-exporting
|
||||||
|
export {Octokit} from '@octokit/rest'
|
||||||
|
|
||||||
|
export type OctokitOptions = {
|
||||||
|
baseUrl?: string
|
||||||
|
userAgent?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getOctokit(authToken: string, opts: OctokitOptions) {
|
||||||
|
const options: Octokit.Options = {
|
||||||
|
baseUrl: getServerApiUrl(opts.baseUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.userAgent) {
|
||||||
|
options.userAgent = opts.userAgent
|
||||||
|
}
|
||||||
|
|
||||||
|
return new github.GitHub(authToken, options)
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
import {URL} from 'url'
|
|
||||||
import {IGitCommandManager} from './git-command-manager'
|
import {IGitCommandManager} from './git-command-manager'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as github from '@actions/github'
|
import * as github from '@actions/github'
|
||||||
|
import {getOctokit} from './octokit-provider'
|
||||||
|
import {isGhes} from './url-helper'
|
||||||
|
|
||||||
export const tagsRefSpec = '+refs/tags/*:refs/tags/*'
|
export const tagsRefSpec = '+refs/tags/*:refs/tags/*'
|
||||||
|
|
||||||
|
@ -183,11 +184,12 @@ export async function checkCommitInfo(
|
||||||
repositoryOwner: string,
|
repositoryOwner: string,
|
||||||
repositoryName: string,
|
repositoryName: string,
|
||||||
ref: string,
|
ref: string,
|
||||||
commit: string
|
commit: string,
|
||||||
|
baseUrl?: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
// GHES?
|
// GHES?
|
||||||
if (isGhes()) {
|
if (isGhes(baseUrl)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +245,8 @@ export async function checkCommitInfo(
|
||||||
core.debug(
|
core.debug(
|
||||||
`Expected head sha ${expectedHeadSha}; actual head sha ${actualHeadSha}`
|
`Expected head sha ${expectedHeadSha}; actual head sha ${actualHeadSha}`
|
||||||
)
|
)
|
||||||
const octokit = new github.GitHub(token, {
|
const octokit = getOctokit(token, {
|
||||||
|
baseUrl: baseUrl,
|
||||||
userAgent: `actions-checkout-tracepoint/1.0 (code=STALE_MERGE;owner=${repositoryOwner};repo=${repositoryName};pr=${fromPayload(
|
userAgent: `actions-checkout-tracepoint/1.0 (code=STALE_MERGE;owner=${repositoryOwner};repo=${repositoryName};pr=${fromPayload(
|
||||||
'number'
|
'number'
|
||||||
)};run_id=${
|
)};run_id=${
|
||||||
|
@ -276,10 +279,3 @@ function select(obj: any, path: string): any {
|
||||||
const key = path.substr(0, i)
|
const key = path.substr(0, i)
|
||||||
return select(obj[key], path.substr(i + 1))
|
return select(obj[key], path.substr(i + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
function isGhes(): boolean {
|
|
||||||
const ghUrl = new URL(
|
|
||||||
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
|
|
||||||
)
|
|
||||||
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM'
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as assert from 'assert'
|
import * as assert from 'assert'
|
||||||
import {IGitSourceSettings} from './git-source-settings'
|
|
||||||
import {URL} from 'url'
|
import {URL} from 'url'
|
||||||
|
import {IGitSourceSettings} from './git-source-settings'
|
||||||
|
|
||||||
export function getFetchUrl(settings: IGitSourceSettings): string {
|
export function getFetchUrl(settings: IGitSourceSettings): string {
|
||||||
assert.ok(
|
assert.ok(
|
||||||
|
@ -8,7 +8,7 @@ export function getFetchUrl(settings: IGitSourceSettings): string {
|
||||||
'settings.repositoryOwner must be defined'
|
'settings.repositoryOwner must be defined'
|
||||||
)
|
)
|
||||||
assert.ok(settings.repositoryName, 'settings.repositoryName must be defined')
|
assert.ok(settings.repositoryName, 'settings.repositoryName must be defined')
|
||||||
const serviceUrl = getServerUrl()
|
const serviceUrl = getServerUrl(settings.githubServerUrl)
|
||||||
const encodedOwner = encodeURIComponent(settings.repositoryOwner)
|
const encodedOwner = encodeURIComponent(settings.repositoryOwner)
|
||||||
const encodedName = encodeURIComponent(settings.repositoryName)
|
const encodedName = encodeURIComponent(settings.repositoryName)
|
||||||
if (settings.sshKey) {
|
if (settings.sshKey) {
|
||||||
|
@ -19,11 +19,27 @@ export function getFetchUrl(settings: IGitSourceSettings): string {
|
||||||
return `${serviceUrl.origin}/${encodedOwner}/${encodedName}`
|
return `${serviceUrl.origin}/${encodedOwner}/${encodedName}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getServerUrl(): URL {
|
export function getServerUrl(url?: string): URL {
|
||||||
// todo: remove GITHUB_URL after support for GHES Alpha is no longer needed
|
let urlValue =
|
||||||
return new URL(
|
url && url.trim().length > 0
|
||||||
process.env['GITHUB_SERVER_URL'] ||
|
? url
|
||||||
process.env['GITHUB_URL'] ||
|
: process.env['GITHUB_SERVER_URL'] || 'https://github.com'
|
||||||
'https://github.com'
|
return new URL(urlValue)
|
||||||
)
|
}
|
||||||
|
|
||||||
|
export function getServerApiUrl(url?: string): string {
|
||||||
|
let apiUrl = 'https://api.github.com'
|
||||||
|
|
||||||
|
if (isGhes(url)) {
|
||||||
|
const serverUrl = getServerUrl(url)
|
||||||
|
apiUrl = new URL(`${serverUrl.origin}/api/v3`).toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
return apiUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isGhes(url?: string): boolean {
|
||||||
|
const ghUrl = getServerUrl(url)
|
||||||
|
|
||||||
|
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM'
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue