@atomist/sdm
Version:
Atomist Software Delivery Machine SDK
166 lines • 8.13 kB
JavaScript
;
/*
* Copyright © 2020 Atomist, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.listTopics = exports.updateIssue = exports.isPublicRepo = exports.tipOfDefaultBranch = exports.authHeaders = exports.listCommitsBetween = exports.createRelease = exports.deleteRepository = exports.createTagReference = exports.createTag = exports.createStatus = void 0;
const GitHubRepoRef_1 = require("@atomist/automation-client/lib/operations/common/GitHubRepoRef");
const logger_1 = require("@atomist/automation-client/lib/util/logger");
const retry_1 = require("@atomist/automation-client/lib/util/retry");
/* tslint:disable:import-blacklist */
const axios_1 = require("axios");
const toToken_1 = require("../../../api-helper/misc/credentials/toToken");
/**
* Create a GitHub status
* @param {string | ProjectOperationCredentials} creds
* @param {GitHubRepoRef} rr
* @param {Status} inputStatus
* @return {AxiosPromise}
*/
function createStatus(creds, rr, inputStatus) {
const config = authHeaders(toToken_1.toToken(creds));
const saferStatus = ensureValidUrl(inputStatus);
const url = `${rr.scheme}${rr.apiBase}/repos/${rr.owner}/${rr.repo}/statuses/${rr.sha}`;
logger_1.logger.debug("Updating github status: %s to %j", url, saferStatus);
return retry_1.doWithRetry(() => axios_1.default.post(url, saferStatus, config).catch(err => Promise.reject(new Error(`Error hitting ${url} to set status ${JSON.stringify(saferStatus)}: ${err.message}`))), `Updating github status: ${url} to ${JSON.stringify(saferStatus)}`, {});
}
exports.createStatus = createStatus;
/*
* If you send a targetUrl that doesn't work, GitHub will not accept the status.
* Commonly on findArtifact, we get a Docker image name instead, and people really want
* to put that in the URL but it doesn't work.
*
* This limitation exists only because we are using GitHub Statuses for Goals right now,
* and when we move to a custom event it won't be the same problem. So it makes sense
* to encode the limitation here.
*
* Yes the description is going to be ugly. Deal with it.
*/
function ensureValidUrl(inputStatus) {
if (!inputStatus.target_url) {
return inputStatus;
}
if (inputStatus.target_url.startsWith("http")) {
return inputStatus;
}
return {
target_url: undefined,
description: inputStatus.description + " at " + inputStatus.target_url,
state: inputStatus.state,
context: inputStatus.context,
};
}
function createTag(creds, rr, tag) {
const config = authHeaders(toToken_1.toToken(creds));
const url = `${rr.scheme}${rr.apiBase}/repos/${rr.owner}/${rr.repo}/git/tags`;
logger_1.logger.debug("Updating github tag: %s to %j", url, tag);
return retry_1.doWithRetry(() => axios_1.default.post(url, tag, config)
.catch(err => Promise.reject(new Error(`Error hitting ${url} to set tag ${JSON.stringify(tag)}: ${err.message}`))), `Updating github tag: ${url} to ${JSON.stringify(tag)}`, {});
}
exports.createTag = createTag;
function createTagReference(creds, rr, tag) {
const config = authHeaders(toToken_1.toToken(creds));
const url = `${rr.scheme}${rr.apiBase}/repos/${rr.owner}/${rr.repo}/git/refs`;
logger_1.logger.debug("Creating github reference: %s to %j", url, tag);
return retry_1.doWithRetry(() => axios_1.default.post(url, { ref: `refs/tags/${tag.tag}`, sha: tag.object }, config)
.catch(err => Promise.reject(new Error(`Error hitting ${url} to set tag ${JSON.stringify(tag)}: ${err.message}`))), `Updating github tag: ${url} to ${JSON.stringify(tag)}`, {});
}
exports.createTagReference = createTagReference;
function deleteRepository(creds, rr) {
const config = authHeaders(toToken_1.toToken(creds));
const url = `${rr.scheme}${rr.apiBase}/repos/${rr.owner}/${rr.repo}`;
logger_1.logger.debug("Deleting repository: %s", url);
return axios_1.default.delete(url, config)
.catch(err => {
logger_1.logger.error(err.message);
logger_1.logger.error(err.response.body);
return Promise.reject(new Error(`Error hitting ${url} to delete repo`));
});
}
exports.deleteRepository = deleteRepository;
function createRelease(creds, rr, release) {
const config = authHeaders(toToken_1.toToken(creds));
const url = `${rr.scheme}${rr.apiBase}/repos/${rr.owner}/${rr.repo}/releases`;
logger_1.logger.debug("Updating github release: %s to %j", url, release);
return retry_1.doWithRetry(() => axios_1.default.post(url, release, config)
.catch(err => Promise.reject(new Error(`Error hitting ${url} to set release ${JSON.stringify(release)}: ${err.message}`))), `Updating github release: ${url} to ${JSON.stringify(release)}`, {});
}
exports.createRelease = createRelease;
/**
* List commits between these shas
* @param {string | ProjectOperationCredentials} creds
* @param {GitHubRepoRef} rr
* @param {string} startSha
* @param {string} endSha
* @return {Promise<GitHubCommitsBetween>}
*/
function listCommitsBetween(creds, rr, startSha, endSha) {
const config = authHeaders(toToken_1.toToken(creds));
const url = `${rr.scheme}${rr.apiBase}/repos/${rr.owner}/${rr.repo}/compare/${startSha}...${endSha}`;
return axios_1.default.get(url, config)
.then(ap => ap.data);
}
exports.listCommitsBetween = listCommitsBetween;
function authHeaders(token) {
return token ? {
headers: {
Authorization: `token ${token}`,
},
}
: {};
}
exports.authHeaders = authHeaders;
function tipOfDefaultBranch(creds, rr) {
// TODO: use real default branch
const config = authHeaders(toToken_1.toToken(creds));
const url = `${rr.scheme}${rr.apiBase}/repos/${rr.owner}/${rr.repo}/branches/master`;
return axios_1.default.get(url, config)
.then(ap => ap.data.commit.sha);
}
exports.tipOfDefaultBranch = tipOfDefaultBranch;
function isPublicRepo(creds, rr) {
const config = authHeaders(toToken_1.toToken(creds));
const url = `${rr.scheme}${rr.apiBase}/repos/${rr.owner}/${rr.repo}`;
return axios_1.default.get(url, config)
.then(ap => {
const privateness = ap.data.private;
logger_1.logger.debug(`Retrieved ${url}. Private is '${privateness}'`);
return !privateness;
})
.catch(err => {
logger_1.logger.warn(`Could not access ${url} to determine repo visibility: ${err.message}`);
return false;
});
}
exports.isPublicRepo = isPublicRepo;
// TODO move to client
function updateIssue(creds, rr, issueNumber, issue) {
const grr = GitHubRepoRef_1.isGitHubRepoRef(rr) ? rr : new GitHubRepoRef_1.GitHubRepoRef(rr.owner, rr.repo, rr.sha);
const url = `${grr.scheme}${grr.apiBase}/repos/${grr.owner}/${grr.repo}/issues/${issueNumber}`;
logger_1.logger.debug(`Request to '${url}' to update issue`);
return axios_1.default.patch(url, issue, authHeaders(toToken_1.toToken(creds)));
}
exports.updateIssue = updateIssue;
async function listTopics(creds, rr) {
const headers = {
headers: Object.assign(Object.assign({}, authHeaders(toToken_1.toToken(creds)).headers), { Accept: "application/vnd.github.mercy-preview+json" }),
};
const grr = GitHubRepoRef_1.isGitHubRepoRef(rr) ? rr : new GitHubRepoRef_1.GitHubRepoRef(rr.owner, rr.repo, rr.sha);
const url = `${grr.scheme}${grr.apiBase}/repos/${grr.owner}/${grr.repo}/topics`;
const topics = await axios_1.default.get(url, headers);
return topics.data.names;
}
exports.listTopics = listTopics;
//# sourceMappingURL=ghub.js.map