fix(eslint): '@typescript-eslint/explicit-function-return-… (#4872)
This commit is contained in:
Родитель
d210191fec
Коммит
f0d4995fda
|
@ -25,6 +25,8 @@ module.exports = {
|
|||
'prefer-template': 'off',
|
||||
'no-underscore-dangle': 0,
|
||||
|
||||
'@typescript-eslint/explicit-function-return-type': 'error',
|
||||
|
||||
// TODO: fix lint
|
||||
'@typescript-eslint/camelcase': 'off', // disabled until ??
|
||||
'@typescript-eslint/no-explicit-any': 0,
|
||||
|
|
|
@ -9,16 +9,22 @@ import { logger } from '../../logger';
|
|||
import got from '../../util/got';
|
||||
import * as hostRules from '../../util/host-rules';
|
||||
import { PkgReleaseConfig, ReleaseResult } from '../common';
|
||||
import { GotResponse } from '../../platform';
|
||||
|
||||
// TODO: add got typings when available
|
||||
// TODO: replace www-authenticate with https://www.npmjs.com/package/auth-header ?
|
||||
|
||||
const ecrRegex = /\d+\.dkr\.ecr\.([-a-z0-9]+)\.amazonaws\.com/;
|
||||
|
||||
export interface RegistryRepository {
|
||||
registry: string;
|
||||
repository: string;
|
||||
}
|
||||
|
||||
export function getRegistryRepository(
|
||||
lookupName: string,
|
||||
registryUrls: string[]
|
||||
) {
|
||||
): RegistryRepository {
|
||||
let registry: string;
|
||||
const split = lookupName.split('/');
|
||||
if (split.length > 1 && (split[0].includes('.') || split[0].includes(':'))) {
|
||||
|
@ -48,7 +54,10 @@ export function getRegistryRepository(
|
|||
};
|
||||
}
|
||||
|
||||
function getECRAuthToken(region: string, opts: hostRules.HostRule) {
|
||||
function getECRAuthToken(
|
||||
region: string,
|
||||
opts: hostRules.HostRule
|
||||
): Promise<string | null> {
|
||||
const config = { region, accessKeyId: undefined, secretAccessKey: undefined };
|
||||
if (opts.username && opts.password) {
|
||||
config.accessKeyId = opts.username;
|
||||
|
@ -171,22 +180,22 @@ async function getAuthHeaders(
|
|||
}
|
||||
}
|
||||
|
||||
function digestFromManifestStr(str: hasha.HashaInput) {
|
||||
function digestFromManifestStr(str: hasha.HashaInput): string {
|
||||
return 'sha256:' + hasha(str, { algorithm: 'sha256' });
|
||||
}
|
||||
|
||||
function extractDigestFromResponse(manifestResponse) {
|
||||
function extractDigestFromResponse(manifestResponse: GotResponse): string {
|
||||
if (manifestResponse.headers['docker-content-digest'] === undefined) {
|
||||
return digestFromManifestStr(manifestResponse.body);
|
||||
}
|
||||
return manifestResponse.headers['docker-content-digest'];
|
||||
return manifestResponse.headers['docker-content-digest'] as string;
|
||||
}
|
||||
|
||||
async function getManifestResponse(
|
||||
registry: string,
|
||||
repository: string,
|
||||
tag: string
|
||||
) {
|
||||
): Promise<GotResponse> {
|
||||
logger.debug(`getManifestResponse(${registry}, ${repository}, ${tag})`);
|
||||
try {
|
||||
const headers = await getAuthHeaders(registry, repository);
|
||||
|
@ -408,12 +417,15 @@ async function getTags(
|
|||
}
|
||||
}
|
||||
|
||||
export function getConfigResponse(url: string, headers: OutgoingHttpHeaders) {
|
||||
export function getConfigResponse(
|
||||
url: string,
|
||||
headers: OutgoingHttpHeaders
|
||||
): Promise<GotResponse> {
|
||||
return got(url, {
|
||||
headers,
|
||||
hooks: {
|
||||
beforeRedirect: [
|
||||
(options: any) => {
|
||||
(options: any): void => {
|
||||
if (
|
||||
options.search &&
|
||||
options.search.indexOf('X-Amz-Algorithm') !== -1
|
||||
|
|
|
@ -66,7 +66,7 @@ export async function getPreset(
|
|||
}
|
||||
|
||||
const cacheNamespace = 'datasource-github';
|
||||
function getCacheKey(repo: string, type: string) {
|
||||
function getCacheKey(repo: string, type: string): string {
|
||||
return `${repo}:${type}`;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@ const glGot = api.get;
|
|||
|
||||
const GitLabApiUrl = 'https://gitlab.com/api/v4/projects';
|
||||
|
||||
async function getDefaultBranchName(urlEncodedPkgName: string) {
|
||||
async function getDefaultBranchName(
|
||||
urlEncodedPkgName: string
|
||||
): Promise<string> {
|
||||
const branchesUrl = `${GitLabApiUrl}/${urlEncodedPkgName}/repository/branches`;
|
||||
type GlBranch = {
|
||||
default: boolean;
|
||||
|
@ -61,7 +63,11 @@ export async function getPreset(
|
|||
}
|
||||
|
||||
const cacheNamespace = 'datasource-gitlab';
|
||||
function getCacheKey(depHost: string, repo: string, lookupType: string) {
|
||||
function getCacheKey(
|
||||
depHost: string,
|
||||
repo: string,
|
||||
lookupType: string
|
||||
): string {
|
||||
const type = lookupType || 'tags';
|
||||
return `${depHost}:${repo}:${type}`;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,9 @@ async function fetchReleases(
|
|||
return dep;
|
||||
}
|
||||
|
||||
function getRawReleases(config: PkgReleaseConfig): Promise<ReleaseResult> {
|
||||
function getRawReleases(
|
||||
config: PkgReleaseConfig
|
||||
): Promise<ReleaseResult | null> {
|
||||
const cacheKey =
|
||||
cacheNamespace +
|
||||
config.datasource +
|
||||
|
@ -88,7 +90,9 @@ function getRawReleases(config: PkgReleaseConfig): Promise<ReleaseResult> {
|
|||
return global.repoCache[cacheKey];
|
||||
}
|
||||
|
||||
export async function getPkgReleases(config: PkgReleaseConfig) {
|
||||
export async function getPkgReleases(
|
||||
config: PkgReleaseConfig
|
||||
): Promise<ReleaseResult | null> {
|
||||
const res = await getRawReleases({
|
||||
...config,
|
||||
lookupName: config.lookupName || config.depName,
|
||||
|
@ -101,7 +105,7 @@ export async function getPkgReleases(config: PkgReleaseConfig) {
|
|||
// Filter by version scheme
|
||||
const version = versioning.get(versionScheme);
|
||||
// Return a sorted list of valid Versions
|
||||
function sortReleases(release1: Release, release2: Release) {
|
||||
function sortReleases(release1: Release, release2: Release): number {
|
||||
return version.sortVersions(release1.version, release2.version);
|
||||
}
|
||||
if (res.releases) {
|
||||
|
@ -112,7 +116,7 @@ export async function getPkgReleases(config: PkgReleaseConfig) {
|
|||
return res;
|
||||
}
|
||||
|
||||
export function supportsDigests(config: DigestConfig) {
|
||||
export function supportsDigests(config: DigestConfig): boolean {
|
||||
return !!datasources[config.datasource].getDigest;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@ import url from 'url';
|
|||
import got from '../../util/got';
|
||||
import { logger } from '../../logger';
|
||||
|
||||
function isMavenCentral(pkgUrl: url.URL | string) {
|
||||
function isMavenCentral(pkgUrl: url.URL | string): boolean {
|
||||
return (
|
||||
(typeof pkgUrl === 'string' ? pkgUrl : pkgUrl.host) === 'central.maven.org'
|
||||
);
|
||||
}
|
||||
|
||||
function isTemporalError(err: { code: string; statusCode: number }) {
|
||||
function isTemporalError(err: { code: string; statusCode: number }): boolean {
|
||||
return (
|
||||
err.code === 'ECONNRESET' ||
|
||||
err.statusCode === 429 ||
|
||||
|
@ -16,19 +16,19 @@ function isTemporalError(err: { code: string; statusCode: number }) {
|
|||
);
|
||||
}
|
||||
|
||||
function isHostError(err: { code: string }) {
|
||||
function isHostError(err: { code: string }): boolean {
|
||||
return err.code === 'ETIMEDOUT';
|
||||
}
|
||||
|
||||
function isNotFoundError(err: { code: string; statusCode: number }) {
|
||||
function isNotFoundError(err: { code: string; statusCode: number }): boolean {
|
||||
return err.code === 'ENOTFOUND' || err.statusCode === 404;
|
||||
}
|
||||
|
||||
function isPermissionsIssue(err: { statusCode: number }) {
|
||||
function isPermissionsIssue(err: { statusCode: number }): boolean {
|
||||
return err.statusCode === 401 || err.statusCode === 403;
|
||||
}
|
||||
|
||||
function isConnectionError(err: { code: string }) {
|
||||
function isConnectionError(err: { code: string }): boolean {
|
||||
return err.code === 'ECONNREFUSED';
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ export async function downloadHttpProtocol(
|
|||
hostType,
|
||||
hooks: {
|
||||
beforeRedirect: [
|
||||
(options: any) => {
|
||||
(options: any): void => {
|
||||
if (
|
||||
options.search &&
|
||||
options.search.indexOf('X-Amz-Algorithm') !== -1
|
||||
|
|
|
@ -67,7 +67,7 @@ export function addMetaData(
|
|||
dep?: ReleaseResult,
|
||||
datasource?: string,
|
||||
lookupName?: string
|
||||
) {
|
||||
): void {
|
||||
if (!dep) {
|
||||
return;
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ export function addMetaData(
|
|||
/**
|
||||
* @param {string} url
|
||||
*/
|
||||
const massageGithubUrl = url => {
|
||||
const massageGithubUrl = (url: string): string => {
|
||||
return url
|
||||
.replace('http:', 'https:')
|
||||
.replace('www.github.com', 'github.com')
|
||||
|
|
|
@ -15,12 +15,12 @@ import { Release, ReleaseResult } from '../common';
|
|||
|
||||
let memcache = {};
|
||||
|
||||
export function resetMemCache() {
|
||||
export function resetMemCache(): void {
|
||||
logger.debug('resetMemCache()');
|
||||
memcache = {};
|
||||
}
|
||||
|
||||
export function resetCache() {
|
||||
export function resetCache(): void {
|
||||
resetMemCache();
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ function envReplace(value: any, env = process.env): any {
|
|||
});
|
||||
}
|
||||
|
||||
export function setNpmrc(input?: string) {
|
||||
export function setNpmrc(input?: string): void {
|
||||
if (input) {
|
||||
if (input === npmrcRaw) {
|
||||
return;
|
||||
|
|
|
@ -4,7 +4,7 @@ import { logger } from '../../logger';
|
|||
import got from '../../util/got';
|
||||
import { ReleaseResult } from '../common';
|
||||
|
||||
function getPkgProp(pkgInfo: XmlElement, propName: string) {
|
||||
function getPkgProp(pkgInfo: XmlElement, propName: string): string {
|
||||
return pkgInfo.childNamed('m:properties').childNamed(`d:${propName}`).val;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import { ReleaseResult } from '../common';
|
|||
const defaultNugetFeed = 'https://api.nuget.org/v3/index.json';
|
||||
const cacheNamespace = 'datasource-nuget';
|
||||
|
||||
export function getDefaultFeed() {
|
||||
export function getDefaultFeed(): string {
|
||||
return defaultNugetFeed;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@ import parse from 'github-url-from-git';
|
|||
import pAll from 'p-all';
|
||||
import { logger } from '../../logger';
|
||||
|
||||
import got from '../../util/got';
|
||||
import got, { GotJSONOptions } from '../../util/got';
|
||||
import * as hostRules from '../../util/host-rules';
|
||||
import { PkgReleaseConfig, ReleaseResult } from '../common';
|
||||
|
||||
function getHostOpts(url: string) {
|
||||
const opts: any = {
|
||||
function getHostOpts(url: string): GotJSONOptions {
|
||||
const opts: GotJSONOptions = {
|
||||
json: true,
|
||||
};
|
||||
const { username, password } = hostRules.find({ hostType: 'packagist', url });
|
||||
|
@ -173,7 +173,9 @@ async function getAllPackages(regUrl: string): Promise<AllPackages | null> {
|
|||
const { packages, providersUrl, files, includesFiles } = registryMeta;
|
||||
const providerPackages: Record<string, string> = {};
|
||||
if (files) {
|
||||
const queue = files.map(file => () => getPackagistFile(regUrl, file));
|
||||
const queue = files.map(file => (): Promise<PackagistFile> =>
|
||||
getPackagistFile(regUrl, file)
|
||||
);
|
||||
const resolvedFiles = await pAll(queue, { concurrency: 5 });
|
||||
for (const res of resolvedFiles) {
|
||||
for (const [name, val] of Object.entries(res.providers)) {
|
||||
|
@ -204,7 +206,7 @@ async function getAllPackages(regUrl: string): Promise<AllPackages | null> {
|
|||
return allPackages;
|
||||
}
|
||||
|
||||
async function packagistOrgLookup(name: string) {
|
||||
async function packagistOrgLookup(name: string): Promise<ReleaseResult> {
|
||||
const cacheNamespace = 'datasource-packagist-org';
|
||||
const cachedResult = await renovateCache.get<ReleaseResult>(
|
||||
cacheNamespace,
|
||||
|
|
|
@ -6,14 +6,14 @@ import { matches } from '../../versioning/pep440';
|
|||
import got from '../../util/got';
|
||||
import { PkgReleaseConfig, ReleaseResult } from '../common';
|
||||
|
||||
function normalizeName(input: string) {
|
||||
function normalizeName(input: string): string {
|
||||
return input.toLowerCase().replace(/(-|\.)/g, '_');
|
||||
}
|
||||
|
||||
function compatibleVersions(
|
||||
releases: Record<string, { requires_python?: boolean }[]>,
|
||||
compatibility: Record<string, string>
|
||||
) {
|
||||
): string[] {
|
||||
const versions = Object.keys(releases);
|
||||
if (!(compatibility && compatibility.python)) {
|
||||
return versions;
|
||||
|
|
|
@ -6,7 +6,7 @@ let lastSync = new Date('2000-01-01');
|
|||
let packageReleases: Record<string, string[]> = Object.create(null); // Because we might need a "constructor" key
|
||||
let contentLength = 0;
|
||||
|
||||
async function updateRubyGemsVersions() {
|
||||
async function updateRubyGemsVersions(): Promise<void> {
|
||||
const url = 'https://rubygems.org/versions';
|
||||
const options = {
|
||||
headers: {
|
||||
|
@ -30,7 +30,7 @@ async function updateRubyGemsVersions() {
|
|||
return;
|
||||
}
|
||||
|
||||
function processLine(line: string) {
|
||||
function processLine(line: string): void {
|
||||
let split: string[];
|
||||
let pkg: string;
|
||||
let versions: string;
|
||||
|
@ -68,14 +68,14 @@ async function updateRubyGemsVersions() {
|
|||
lastSync = new Date();
|
||||
}
|
||||
|
||||
function isDataStale() {
|
||||
function isDataStale(): boolean {
|
||||
const minutesElapsed = Math.floor(
|
||||
(new Date().getTime() - lastSync.getTime()) / (60 * 1000)
|
||||
);
|
||||
return minutesElapsed >= 5;
|
||||
}
|
||||
|
||||
async function syncVersions() {
|
||||
async function syncVersions(): Promise<void> {
|
||||
if (isDataStale()) {
|
||||
global.updateRubyGemsVersions =
|
||||
global.updateRubyGemsVersions || updateRubyGemsVersions();
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { OutgoingHttpHeaders } from 'http';
|
||||
import { logger } from '../../logger';
|
||||
import got from '../../util/got';
|
||||
import { maskToken } from '../../util/mask';
|
||||
|
@ -9,7 +10,7 @@ const INFO_PATH = '/api/v1/gems';
|
|||
const VERSIONS_PATH = '/api/v1/versions';
|
||||
|
||||
// istanbul ignore next
|
||||
const processError = ({ err, ...rest }) => {
|
||||
const processError = ({ err, ...rest }): null => {
|
||||
const { statusCode, headers = {} } = err;
|
||||
const data = {
|
||||
...rest,
|
||||
|
@ -33,11 +34,11 @@ const processError = ({ err, ...rest }) => {
|
|||
return null;
|
||||
};
|
||||
|
||||
const getHeaders = () => {
|
||||
const getHeaders = (): OutgoingHttpHeaders => {
|
||||
return { hostType: 'rubygems' };
|
||||
};
|
||||
|
||||
const fetch = async ({ dependency, registry, path }) => {
|
||||
const fetch = async ({ dependency, registry, path }): Promise<any> => {
|
||||
const json = true;
|
||||
|
||||
const retry = { retries: retriable() };
|
||||
|
|
|
@ -38,7 +38,7 @@ export type HTTPError = InstanceType<got.GotInstance['HTTPError']>;
|
|||
export default (numberOfRetries = NUMBER_OF_RETRIES): got.RetryFunction => (
|
||||
_?: number,
|
||||
err?: Partial<HTTPError>
|
||||
) => {
|
||||
): number => {
|
||||
if (numberOfRetries === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ async function resolvePackageReleases(
|
|||
const indexContent = await downloadHttpProtocol(searchRoot, 'sbt');
|
||||
if (indexContent) {
|
||||
const releases: string[] = [];
|
||||
const parseSubdirs = (content: string) =>
|
||||
const parseSubdirs = (content: string): string[] =>
|
||||
parseIndexDir(content, x => {
|
||||
if (x === artifact) return true;
|
||||
if (x.indexOf(`${artifact}_native`) === 0) return false;
|
||||
|
@ -27,7 +27,7 @@ async function resolvePackageReleases(
|
|||
) {
|
||||
searchSubdirs = [`${artifact}_${scalaVersion}`];
|
||||
}
|
||||
const parseReleases = (content: string) =>
|
||||
const parseReleases = (content: string): string[] =>
|
||||
parseIndexDir(content, x => !/^\.+$/.test(x));
|
||||
for (const searchSubdir of searchSubdirs) {
|
||||
const content = await downloadHttpProtocol(
|
||||
|
@ -49,9 +49,9 @@ async function resolvePluginReleases(
|
|||
rootUrl: string,
|
||||
artifact: string,
|
||||
scalaVersion: string
|
||||
) {
|
||||
): Promise<string[]> {
|
||||
const searchRoot = `${rootUrl}/${artifact}`;
|
||||
const parse = (content: string) =>
|
||||
const parse = (content: string): string[] =>
|
||||
parseIndexDir(content, x => !/^\.+$/.test(x));
|
||||
const indexContent = await downloadHttpProtocol(searchRoot, 'sbt');
|
||||
if (indexContent) {
|
||||
|
|
|
@ -3,8 +3,8 @@ export const SBT_PLUGINS_REPO =
|
|||
|
||||
export function parseIndexDir(
|
||||
content: string,
|
||||
filterFn = (x: string) => !/^\.+/.test(x)
|
||||
) {
|
||||
filterFn = (x: string): boolean => !/^\.+/.test(x)
|
||||
): string[] {
|
||||
const unfiltered = content.match(/(?<=href=['"])[^'"]*(?=\/['"])/g) || [];
|
||||
return unfiltered.filter(filterFn);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,15 @@ import { logger } from '../../logger';
|
|||
import got from '../../util/got';
|
||||
import { PkgReleaseConfig, ReleaseResult } from '../common';
|
||||
|
||||
function getRegistryRepository(lookupName: string, registryUrls: string[]) {
|
||||
interface RegistryRepository {
|
||||
registry: string;
|
||||
repository: string;
|
||||
}
|
||||
|
||||
function getRegistryRepository(
|
||||
lookupName: string,
|
||||
registryUrls: string[]
|
||||
): RegistryRepository {
|
||||
let registry: string;
|
||||
const split = lookupName.split('/');
|
||||
if (split.length > 3 && split[0].includes('.')) {
|
||||
|
|
|
@ -76,7 +76,7 @@ export function getDetails(rec: BunyanRecord): string {
|
|||
.join(',\n')}\n`;
|
||||
}
|
||||
|
||||
export function formatRecord(rec: BunyanRecord) {
|
||||
export function formatRecord(rec: BunyanRecord): string {
|
||||
const level = levels[rec.level];
|
||||
const msg = `${indent(rec.msg)}`;
|
||||
const meta = getMeta(rec);
|
||||
|
@ -96,7 +96,7 @@ export class RenovateStream extends Stream {
|
|||
}
|
||||
|
||||
// istanbul ignore next
|
||||
write(data: BunyanRecord) {
|
||||
write(data: BunyanRecord): boolean {
|
||||
this.emit('data', formatRecord(data));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -24,19 +24,19 @@ export class ErrorStream extends Stream {
|
|||
this.writable = true;
|
||||
}
|
||||
|
||||
write(data: BunyanRecord) {
|
||||
write(data: BunyanRecord): boolean {
|
||||
const err = { ...data };
|
||||
for (const prop of excludeProps) delete err[prop];
|
||||
this._errors.push(err);
|
||||
return true;
|
||||
}
|
||||
|
||||
getErrors() {
|
||||
getErrors(): BunyanRecord[] {
|
||||
return this._errors;
|
||||
}
|
||||
}
|
||||
|
||||
function sanitizeValue(value: any, seen = new WeakMap()) {
|
||||
function sanitizeValue(value: any, seen = new WeakMap()): any {
|
||||
if (Array.isArray(value)) {
|
||||
const length = value.length;
|
||||
const arrayResult = Array(length);
|
||||
|
@ -76,7 +76,7 @@ export function withSanitizer(streamConfig): bunyan.Stream {
|
|||
|
||||
const stream = streamConfig.stream;
|
||||
if (stream && stream.writable) {
|
||||
const write = (chunk: BunyanRecord, enc, cb) => {
|
||||
const write = (chunk: BunyanRecord, enc, cb): void => {
|
||||
const raw = sanitizeValue(chunk);
|
||||
const result =
|
||||
streamConfig.type === 'raw'
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import * as azure from 'azure-devops-node-api';
|
||||
import { IGitApi } from 'azure-devops-node-api/GitApi';
|
||||
import { ICoreApi } from 'azure-devops-node-api/CoreApi';
|
||||
import { IPolicyApi } from 'azure-devops-node-api/PolicyApi';
|
||||
import * as hostRules from '../../util/host-rules';
|
||||
|
||||
const hostType = 'azure';
|
||||
let endpoint: string;
|
||||
|
||||
export function azureObj() {
|
||||
export function azureObj(): azure.WebApi {
|
||||
const config = hostRules.find({ hostType, url: endpoint });
|
||||
if (!(config && config.token)) {
|
||||
throw new Error(`No token found for azure`);
|
||||
|
@ -13,18 +16,18 @@ export function azureObj() {
|
|||
return new azure.WebApi(endpoint, authHandler);
|
||||
}
|
||||
|
||||
export function gitApi() {
|
||||
export function gitApi(): Promise<IGitApi> {
|
||||
return azureObj().getGitApi();
|
||||
}
|
||||
|
||||
export function coreApi() {
|
||||
export function coreApi(): Promise<ICoreApi> {
|
||||
return azureObj().getCoreApi();
|
||||
}
|
||||
|
||||
export function policyApi() {
|
||||
export function policyApi(): Promise<IPolicyApi> {
|
||||
return azureObj().getPolicyApi();
|
||||
}
|
||||
|
||||
export function setEndpoint(e: string) {
|
||||
export function setEndpoint(e: string): void {
|
||||
endpoint = e;
|
||||
}
|
||||
|
|
|
@ -1,18 +1,26 @@
|
|||
import { GitPullRequestMergeStrategy } from 'azure-devops-node-api/interfaces/GitInterfaces';
|
||||
import {
|
||||
GitPullRequestMergeStrategy,
|
||||
GitRef,
|
||||
GitCommit,
|
||||
GitPullRequest,
|
||||
} from 'azure-devops-node-api/interfaces/GitInterfaces';
|
||||
|
||||
import * as azureApi from './azure-got-wrapper';
|
||||
import { logger } from '../../logger';
|
||||
import { Pr } from '../common';
|
||||
|
||||
const mergePolicyGuid = 'fa4e907d-c16b-4a4c-9dfa-4916e5d171ab'; // Magic GUID for merge strategy policy configurations
|
||||
|
||||
export function getNewBranchName(branchName?: string) {
|
||||
export function getNewBranchName(branchName?: string): string {
|
||||
if (branchName && !branchName.startsWith('refs/heads/')) {
|
||||
return `refs/heads/${branchName}`;
|
||||
}
|
||||
return branchName;
|
||||
}
|
||||
|
||||
export function getBranchNameWithoutRefsheadsPrefix(branchPath: string) {
|
||||
export function getBranchNameWithoutRefsheadsPrefix(
|
||||
branchPath: string
|
||||
): string | undefined {
|
||||
if (!branchPath) {
|
||||
logger.error(`getBranchNameWithoutRefsheadsPrefix(${branchPath})`);
|
||||
return undefined;
|
||||
|
@ -26,7 +34,9 @@ export function getBranchNameWithoutRefsheadsPrefix(branchPath: string) {
|
|||
return branchPath.substring(11, branchPath.length);
|
||||
}
|
||||
|
||||
function getBranchNameWithoutRefsPrefix(branchPath?: string) {
|
||||
function getBranchNameWithoutRefsPrefix(
|
||||
branchPath?: string
|
||||
): string | undefined {
|
||||
if (!branchPath) {
|
||||
logger.error(`getBranchNameWithoutRefsPrefix(${branchPath})`);
|
||||
return undefined;
|
||||
|
@ -40,7 +50,10 @@ function getBranchNameWithoutRefsPrefix(branchPath?: string) {
|
|||
return branchPath.substring(5, branchPath.length);
|
||||
}
|
||||
|
||||
export async function getRefs(repoId: string, branchName?: string) {
|
||||
export async function getRefs(
|
||||
repoId: string,
|
||||
branchName?: string
|
||||
): Promise<GitRef[]> {
|
||||
logger.debug(`getRefs(${repoId}, ${branchName})`);
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
const refs = await azureApiGit.getRefs(
|
||||
|
@ -51,11 +64,16 @@ export async function getRefs(repoId: string, branchName?: string) {
|
|||
return refs;
|
||||
}
|
||||
|
||||
export interface AzureBranchObj {
|
||||
name: string;
|
||||
oldObjectId: string;
|
||||
}
|
||||
|
||||
export async function getAzureBranchObj(
|
||||
repoId: string,
|
||||
branchName: string,
|
||||
from?: string
|
||||
) {
|
||||
): Promise<AzureBranchObj> {
|
||||
const fromBranchName = getNewBranchName(from);
|
||||
const refs = await getRefs(repoId, fromBranchName);
|
||||
if (refs.length === 0) {
|
||||
|
@ -71,7 +89,7 @@ export async function getAzureBranchObj(
|
|||
};
|
||||
}
|
||||
|
||||
async function streamToString(stream: NodeJS.ReadableStream) {
|
||||
async function streamToString(stream: NodeJS.ReadableStream): Promise<string> {
|
||||
const chunks: string[] = [];
|
||||
/* eslint-disable promise/avoid-new */
|
||||
const p = await new Promise<string>(resolve => {
|
||||
|
@ -90,7 +108,7 @@ export async function getFile(
|
|||
repoId: string,
|
||||
filePath: string,
|
||||
branchName: string
|
||||
) {
|
||||
): Promise<string | null> {
|
||||
logger.trace(`getFile(filePath=${filePath}, branchName=${branchName})`);
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
const item = await azureApiGit.getItemText(
|
||||
|
@ -129,50 +147,15 @@ export async function getFile(
|
|||
return null; // no file found
|
||||
}
|
||||
|
||||
export async function getChanges(
|
||||
files: { name: string; contents: any }[],
|
||||
repoId: string,
|
||||
branchName: string
|
||||
) {
|
||||
const changes = [];
|
||||
for (const file of files) {
|
||||
// Add or update
|
||||
let changeType = 1;
|
||||
const fileAlreadyThere = await getFile(repoId, file.name, branchName);
|
||||
if (fileAlreadyThere) {
|
||||
changeType = 2;
|
||||
}
|
||||
|
||||
changes.push({
|
||||
changeType,
|
||||
item: {
|
||||
path: file.name,
|
||||
},
|
||||
newContent: {
|
||||
Content: file.contents,
|
||||
ContentType: 0, // RawText
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
export function max4000Chars(str: string) {
|
||||
export function max4000Chars(str: string): string {
|
||||
if (str && str.length >= 4000) {
|
||||
return str.substring(0, 3999);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
export function getRenovatePRFormat(azurePr: {
|
||||
pullRequestId: any;
|
||||
description: any;
|
||||
status: number;
|
||||
mergeStatus: number;
|
||||
targetRefName: string;
|
||||
}) {
|
||||
const pr = azurePr as any;
|
||||
export function getRenovatePRFormat(azurePr: GitPullRequest): Pr {
|
||||
const pr: Pr = azurePr as any;
|
||||
|
||||
pr.displayNumber = `Pull Request #${azurePr.pullRequestId}`;
|
||||
pr.number = azurePr.pullRequestId;
|
||||
|
@ -213,14 +196,19 @@ export function getRenovatePRFormat(azurePr: {
|
|||
return pr;
|
||||
}
|
||||
|
||||
export async function getCommitDetails(commit: string, repoId: string) {
|
||||
export async function getCommitDetails(
|
||||
commit: string,
|
||||
repoId: string
|
||||
): Promise<GitCommit> {
|
||||
logger.debug(`getCommitDetails(${commit}, ${repoId})`);
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
const results = await azureApiGit.getCommit(commit, repoId);
|
||||
return results;
|
||||
}
|
||||
|
||||
export function getProjectAndRepo(str: string) {
|
||||
export function getProjectAndRepo(
|
||||
str: string
|
||||
): { project: string; repo: string } {
|
||||
logger.trace(`getProjectAndRepo(${str})`);
|
||||
const strSplited = str.split(`/`);
|
||||
if (strSplited.length === 1) {
|
||||
|
|
|
@ -4,9 +4,16 @@ import * as azureHelper from './azure-helper';
|
|||
import * as azureApi from './azure-got-wrapper';
|
||||
import * as hostRules from '../../util/host-rules';
|
||||
import { appSlug } from '../../config/app-strings';
|
||||
import GitStorage from '../git/storage';
|
||||
import GitStorage, { StatusResult, File } from '../git/storage';
|
||||
import { logger } from '../../logger';
|
||||
import { PlatformConfig, RepoParams, RepoConfig } from '../common';
|
||||
import {
|
||||
PlatformConfig,
|
||||
RepoParams,
|
||||
RepoConfig,
|
||||
Pr,
|
||||
Issue,
|
||||
VulnerabilityAlert,
|
||||
} from '../common';
|
||||
import { sanitize } from '../../util/sanitize';
|
||||
import { smartTruncate } from '../utils/pr-body';
|
||||
|
||||
|
@ -37,7 +44,7 @@ export function initPlatform({
|
|||
}: {
|
||||
endpoint: string;
|
||||
token: string;
|
||||
}) {
|
||||
}): PlatformConfig {
|
||||
if (!endpoint) {
|
||||
throw new Error('Init: You must configure an Azure DevOps endpoint');
|
||||
}
|
||||
|
@ -56,14 +63,14 @@ export function initPlatform({
|
|||
return platformConfig;
|
||||
}
|
||||
|
||||
export async function getRepos() {
|
||||
export async function getRepos(): Promise<string[]> {
|
||||
logger.info('Autodiscovering Azure DevOps repositories');
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
const repos = await azureApiGit.getRepositories();
|
||||
return repos.map(repo => `${repo.project!.name}/${repo.name}`);
|
||||
}
|
||||
|
||||
async function getBranchCommit(fullBranchName: string) {
|
||||
async function getBranchCommit(fullBranchName: string): Promise<string> {
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
const commit = await azureApiGit.getBranch(
|
||||
config.repoId,
|
||||
|
@ -77,7 +84,7 @@ export async function initRepo({
|
|||
localDir,
|
||||
azureWorkItemId,
|
||||
optimizeForDisabled,
|
||||
}: RepoParams) {
|
||||
}: RepoParams): Promise<RepoConfig> {
|
||||
logger.debug(`initRepo("${repository}")`);
|
||||
config = { repository, azureWorkItemId } as any;
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
|
@ -141,19 +148,21 @@ export async function initRepo({
|
|||
return repoConfig;
|
||||
}
|
||||
|
||||
export function getRepoForceRebase() {
|
||||
export function getRepoForceRebase(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Search
|
||||
|
||||
export /* istanbul ignore next */ function getFileList(branchName: string) {
|
||||
export /* istanbul ignore next */ function getFileList(
|
||||
branchName: string
|
||||
): Promise<string[]> {
|
||||
return config.storage.getFileList(branchName);
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ async function setBaseBranch(
|
||||
branchName = config.baseBranch
|
||||
) {
|
||||
): Promise<void> {
|
||||
logger.debug(`Setting baseBranch to ${branchName}`);
|
||||
config.baseBranch = branchName;
|
||||
delete config.baseCommitSHA;
|
||||
|
@ -164,35 +173,39 @@ export /* istanbul ignore next */ async function setBaseBranch(
|
|||
|
||||
export /* istanbul ignore next */ function setBranchPrefix(
|
||||
branchPrefix: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
return config.storage.setBranchPrefix(branchPrefix);
|
||||
}
|
||||
|
||||
// Branch
|
||||
|
||||
export /* istanbul ignore next */ function branchExists(branchName: string) {
|
||||
export /* istanbul ignore next */ function branchExists(
|
||||
branchName: string
|
||||
): Promise<boolean> {
|
||||
return config.storage.branchExists(branchName);
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function getAllRenovateBranches(
|
||||
branchPrefix: string
|
||||
) {
|
||||
): Promise<string[]> {
|
||||
return config.storage.getAllRenovateBranches(branchPrefix);
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function isBranchStale(branchName: string) {
|
||||
export /* istanbul ignore next */ function isBranchStale(
|
||||
branchName: string
|
||||
): Promise<boolean> {
|
||||
return config.storage.isBranchStale(branchName);
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function getFile(
|
||||
filePath: string,
|
||||
branchName: string
|
||||
) {
|
||||
): Promise<string> {
|
||||
return config.storage.getFile(filePath, branchName);
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
async function abandonPr(prNo: number) {
|
||||
async function abandonPr(prNo: number): Promise<void> {
|
||||
logger.debug(`abandonPr(prNo)(${prNo})`);
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
await azureApiGit.updatePullRequest(
|
||||
|
@ -204,7 +217,7 @@ async function abandonPr(prNo: number) {
|
|||
);
|
||||
}
|
||||
|
||||
export async function getPr(pullRequestId: number) {
|
||||
export async function getPr(pullRequestId: number): Promise<Pr | null> {
|
||||
logger.debug(`getPr(${pullRequestId})`);
|
||||
if (!pullRequestId) {
|
||||
return null;
|
||||
|
@ -231,8 +244,9 @@ export async function findPr(
|
|||
branchName: string,
|
||||
prTitle: string | null,
|
||||
state = 'all'
|
||||
) {
|
||||
): Promise<Pr | null> {
|
||||
logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);
|
||||
// TODO: fix typing
|
||||
let prsFiltered: any[] = [];
|
||||
try {
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
|
@ -271,7 +285,7 @@ export async function findPr(
|
|||
return prsFiltered[0];
|
||||
}
|
||||
|
||||
export async function getBranchPr(branchName: string) {
|
||||
export async function getBranchPr(branchName: string): Promise<Pr | null> {
|
||||
logger.debug(`getBranchPr(${branchName})`);
|
||||
const existingPr = await findPr(branchName, null, 'open');
|
||||
return existingPr ? getPr(existingPr.pullRequestId) : null;
|
||||
|
@ -280,7 +294,7 @@ export async function getBranchPr(branchName: string) {
|
|||
export /* istanbul ignore next */ async function deleteBranch(
|
||||
branchName: string,
|
||||
abandonAssociatedPr = false
|
||||
) {
|
||||
): Promise<void> {
|
||||
await config.storage.deleteBranch(branchName);
|
||||
if (abandonAssociatedPr) {
|
||||
const pr = await getBranchPr(branchName);
|
||||
|
@ -290,24 +304,28 @@ export /* istanbul ignore next */ async function deleteBranch(
|
|||
|
||||
export /* istanbul ignore next */ function getBranchLastCommitTime(
|
||||
branchName: string
|
||||
) {
|
||||
): Promise<Date> {
|
||||
return config.storage.getBranchLastCommitTime(branchName);
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function getRepoStatus() {
|
||||
export /* istanbul ignore next */ function getRepoStatus(): Promise<
|
||||
StatusResult
|
||||
> {
|
||||
return config.storage.getRepoStatus();
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function mergeBranch(branchName: string) {
|
||||
export /* istanbul ignore next */ function mergeBranch(
|
||||
branchName: string
|
||||
): Promise<void> {
|
||||
return config.storage.mergeBranch(branchName);
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function commitFilesToBranch(
|
||||
branchName: string,
|
||||
files: any[],
|
||||
files: File[],
|
||||
message: string,
|
||||
parentBranch = config.baseBranch
|
||||
) {
|
||||
): Promise<void> {
|
||||
return config.storage.commitFilesToBranch(
|
||||
branchName,
|
||||
files,
|
||||
|
@ -316,18 +334,20 @@ export /* istanbul ignore next */ function commitFilesToBranch(
|
|||
);
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function getCommitMessages() {
|
||||
export /* istanbul ignore next */ function getCommitMessages(): Promise<
|
||||
string[]
|
||||
> {
|
||||
return config.storage.getCommitMessages();
|
||||
}
|
||||
|
||||
export function getPrList() {
|
||||
export function getPrList(): Pr[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
export async function getBranchStatusCheck(
|
||||
branchName: string,
|
||||
context?: string
|
||||
) {
|
||||
): Promise<string> {
|
||||
logger.trace(`getBranchStatusCheck(${branchName}, ${context})`);
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
const branch = await azureApiGit.getBranch(
|
||||
|
@ -343,7 +363,7 @@ export async function getBranchStatusCheck(
|
|||
export async function getBranchStatus(
|
||||
branchName: string,
|
||||
requiredStatusChecks: any
|
||||
) {
|
||||
): Promise<string> {
|
||||
logger.debug(`getBranchStatus(${branchName})`);
|
||||
if (!requiredStatusChecks) {
|
||||
// null means disable status checks, so it always succeeds
|
||||
|
@ -365,7 +385,7 @@ export async function createPr(
|
|||
labels: string[],
|
||||
useDefaultBranch?: boolean,
|
||||
platformOptions: any = {}
|
||||
) {
|
||||
): Promise<Pr> {
|
||||
const sourceRefName = azureHelper.getNewBranchName(branchName);
|
||||
const targetRefName = azureHelper.getNewBranchName(
|
||||
useDefaultBranch ? config.defaultBranch : config.baseBranch
|
||||
|
@ -402,6 +422,7 @@ export async function createPr(
|
|||
pr.pullRequestId!
|
||||
);
|
||||
}
|
||||
// TODO: fixme
|
||||
await labels.forEach(async label => {
|
||||
await azureApiGit.createPullRequestLabel(
|
||||
{
|
||||
|
@ -415,7 +436,11 @@ export async function createPr(
|
|||
return azureHelper.getRenovatePRFormat(pr);
|
||||
}
|
||||
|
||||
export async function updatePr(prNo: number, title: string, body?: string) {
|
||||
export async function updatePr(
|
||||
prNo: number,
|
||||
title: string,
|
||||
body?: string
|
||||
): Promise<void> {
|
||||
logger.debug(`updatePr(${prNo}, ${title}, body)`);
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
const objToUpdate: any = {
|
||||
|
@ -431,7 +456,7 @@ export async function ensureComment(
|
|||
issueNo: number,
|
||||
topic: string | null,
|
||||
content: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
logger.debug(`ensureComment(${issueNo}, ${topic}, content)`);
|
||||
const body = `### ${topic}\n\n${sanitize(content)}`;
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
|
@ -445,7 +470,10 @@ export async function ensureComment(
|
|||
);
|
||||
}
|
||||
|
||||
export async function ensureCommentRemoval(issueNo: number, topic: string) {
|
||||
export async function ensureCommentRemoval(
|
||||
issueNo: number,
|
||||
topic: string
|
||||
): Promise<void> {
|
||||
logger.debug(`ensureCommentRemoval(issueNo, topic)(${issueNo}, ${topic})`);
|
||||
if (issueNo) {
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
|
@ -477,18 +505,18 @@ export function setBranchStatus(
|
|||
description: string,
|
||||
state: string,
|
||||
targetUrl: string
|
||||
) {
|
||||
): void {
|
||||
logger.debug(
|
||||
`setBranchStatus(${branchName}, ${context}, ${description}, ${state}, ${targetUrl}) - Not supported by Azure DevOps (yet!)`
|
||||
);
|
||||
}
|
||||
|
||||
export async function mergePr(pr: number) {
|
||||
export async function mergePr(pr: number): Promise<void> {
|
||||
logger.info(`mergePr(pr)(${pr}) - Not supported by Azure DevOps (yet!)`);
|
||||
await null;
|
||||
}
|
||||
|
||||
export function getPrBody(input: string) {
|
||||
export function getPrBody(input: string): string {
|
||||
// Remove any HTML we use
|
||||
return smartTruncate(input, 4000)
|
||||
.replace(new RegExp(`\n---\n\n.*?<!-- ${appSlug}-rebase -->.*?\n`), '')
|
||||
|
@ -498,18 +526,19 @@ export function getPrBody(input: string) {
|
|||
.replace('</details>', '');
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function findIssue() {
|
||||
export /* istanbul ignore next */ function findIssue(): Issue | null {
|
||||
logger.warn(`findIssue() is not implemented`);
|
||||
return null;
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function ensureIssue() {
|
||||
export /* istanbul ignore next */ function ensureIssue(): void {
|
||||
logger.warn(`ensureIssue() is not implemented`);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
export /* istanbul ignore next */ function ensureIssueClosing() {}
|
||||
export /* istanbul ignore next */ function ensureIssueClosing(): void {}
|
||||
|
||||
export /* istanbul ignore next */ function getIssueList() {
|
||||
export /* istanbul ignore next */ function getIssueList(): Issue[] {
|
||||
logger.debug(`getIssueList()`);
|
||||
// TODO: Needs implementation
|
||||
return [];
|
||||
|
@ -520,7 +549,10 @@ export /* istanbul ignore next */ function getIssueList() {
|
|||
* @param {number} issueNo
|
||||
* @param {string[]} assignees
|
||||
*/
|
||||
export async function addAssignees(issueNo: number, assignees: string[]) {
|
||||
export async function addAssignees(
|
||||
issueNo: number,
|
||||
assignees: string[]
|
||||
): Promise<void> {
|
||||
logger.trace(`addAssignees(${issueNo}, ${assignees})`);
|
||||
await ensureComment(
|
||||
issueNo,
|
||||
|
@ -534,7 +566,10 @@ export async function addAssignees(issueNo: number, assignees: string[]) {
|
|||
* @param {number} prNo
|
||||
* @param {string[]} reviewers
|
||||
*/
|
||||
export async function addReviewers(prNo: number, reviewers: string[]) {
|
||||
export async function addReviewers(
|
||||
prNo: number,
|
||||
reviewers: string[]
|
||||
): Promise<void> {
|
||||
logger.trace(`addReviewers(${prNo}, ${reviewers})`);
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
const azureApiCore = await azureApi.coreApi();
|
||||
|
@ -594,25 +629,25 @@ export async function addReviewers(prNo: number, reviewers: string[]) {
|
|||
export /* istanbul ignore next */ async function deleteLabel(
|
||||
prNumber: number,
|
||||
label: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
logger.debug(`Deleting label ${label} from #${prNumber}`);
|
||||
const azureApiGit = await azureApi.gitApi();
|
||||
await azureApiGit.deletePullRequestLabels(config.repoId, prNumber, label);
|
||||
}
|
||||
|
||||
// to become async?
|
||||
export function getPrFiles(prNo: number) {
|
||||
export function getPrFiles(prNo: number): string[] {
|
||||
logger.info(
|
||||
`getPrFiles(prNo)(${prNo}) - Not supported by Azure DevOps (yet!)`
|
||||
);
|
||||
return [];
|
||||
}
|
||||
|
||||
export function getVulnerabilityAlerts() {
|
||||
export function getVulnerabilityAlerts(): VulnerabilityAlert[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
export function cleanRepo() {
|
||||
export function cleanRepo(): void {
|
||||
// istanbul ignore if
|
||||
if (config.storage && config.storage.cleanRepo) {
|
||||
config.storage.cleanRepo();
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import URL from 'url';
|
||||
import { GotJSONOptions } from 'got';
|
||||
import got from '../../util/got';
|
||||
import { GotApi, GotApiOptions } from '../common';
|
||||
import { GotApi, GotApiOptions, GotResponse } from '../common';
|
||||
|
||||
let baseUrl: string;
|
||||
|
||||
function get(path: string, options: GotApiOptions & GotJSONOptions) {
|
||||
function get(
|
||||
path: string,
|
||||
options: GotApiOptions & GotJSONOptions
|
||||
): Promise<GotResponse> {
|
||||
const url = URL.resolve(baseUrl, path);
|
||||
const opts: GotApiOptions & GotJSONOptions = {
|
||||
hostType: 'bitbucket-server',
|
||||
|
@ -24,11 +27,11 @@ const helpers = ['get', 'post', 'put', 'patch', 'head', 'delete'];
|
|||
export const api: GotApi = {} as any;
|
||||
|
||||
for (const x of helpers) {
|
||||
(api as any)[x] = (url: string, opts: any) =>
|
||||
(api as any)[x] = (url: string, opts: any): Promise<GotResponse> =>
|
||||
get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
|
||||
}
|
||||
|
||||
api.setBaseUrl = (e: string) => {
|
||||
api.setBaseUrl = (e: string): void => {
|
||||
baseUrl = e;
|
||||
};
|
||||
|
||||
|
|
|
@ -4,9 +4,17 @@ import delay from 'delay';
|
|||
import { api } from './bb-got-wrapper';
|
||||
import * as utils from './utils';
|
||||
import * as hostRules from '../../util/host-rules';
|
||||
import GitStorage from '../git/storage';
|
||||
import GitStorage, { File, StatusResult } from '../git/storage';
|
||||
import { logger } from '../../logger';
|
||||
import { PlatformConfig, RepoParams, RepoConfig } from '../common';
|
||||
import {
|
||||
PlatformConfig,
|
||||
RepoParams,
|
||||
RepoConfig,
|
||||
Pr,
|
||||
Issue,
|
||||
VulnerabilityAlert,
|
||||
GotResponse,
|
||||
} from '../common';
|
||||
import { sanitize } from '../../util/sanitize';
|
||||
import { smartTruncate } from '../utils/pr-body';
|
||||
|
||||
|
@ -27,7 +35,7 @@ interface BbsConfig {
|
|||
fileList: any[];
|
||||
mergeMethod: string;
|
||||
owner: string;
|
||||
prList: any[];
|
||||
prList: Pr[];
|
||||
projectKey: string;
|
||||
repository: string;
|
||||
repositorySlug: string;
|
||||
|
@ -45,7 +53,7 @@ const defaults: any = {
|
|||
};
|
||||
|
||||
/* istanbul ignore next */
|
||||
function updatePrVersion(pr: number, version: number) {
|
||||
function updatePrVersion(pr: number, version: number): number {
|
||||
const res = Math.max(config.prVersions.get(pr) || 0, version);
|
||||
config.prVersions.set(pr, res);
|
||||
return res;
|
||||
|
@ -59,7 +67,7 @@ export function initPlatform({
|
|||
endpoint: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}) {
|
||||
}): PlatformConfig {
|
||||
if (!endpoint) {
|
||||
throw new Error('Init: You must configure a Bitbucket Server endpoint');
|
||||
}
|
||||
|
@ -78,7 +86,7 @@ export function initPlatform({
|
|||
}
|
||||
|
||||
// Get all repositories that the user has access to
|
||||
export async function getRepos() {
|
||||
export async function getRepos(): Promise<string[]> {
|
||||
logger.info('Autodiscovering Bitbucket Server repositories');
|
||||
try {
|
||||
const repos = await utils.accumulateValues(
|
||||
|
@ -96,7 +104,7 @@ export async function getRepos() {
|
|||
}
|
||||
}
|
||||
|
||||
export function cleanRepo() {
|
||||
export function cleanRepo(): void {
|
||||
logger.debug(`cleanRepo()`);
|
||||
if (config.storage) {
|
||||
config.storage.cleanRepo();
|
||||
|
@ -111,7 +119,7 @@ export async function initRepo({
|
|||
localDir,
|
||||
optimizeForDisabled,
|
||||
bbUseDefaultReviewers,
|
||||
}: RepoParams) {
|
||||
}: RepoParams): Promise<RepoConfig> {
|
||||
logger.debug(
|
||||
`initRepo("${JSON.stringify({ repository, localDir }, null, 2)}")`
|
||||
);
|
||||
|
@ -208,7 +216,7 @@ export async function initRepo({
|
|||
}
|
||||
}
|
||||
|
||||
export function getRepoForceRebase() {
|
||||
export function getRepoForceRebase(): boolean {
|
||||
logger.debug(`getRepoForceRebase()`);
|
||||
// TODO if applicable
|
||||
// This function should return true only if the user has enabled a setting on the repo that enforces PRs to be kept up to date with master
|
||||
|
@ -217,21 +225,25 @@ export function getRepoForceRebase() {
|
|||
return false;
|
||||
}
|
||||
|
||||
export async function setBaseBranch(branchName: string = config.defaultBranch) {
|
||||
export async function setBaseBranch(
|
||||
branchName: string = config.defaultBranch
|
||||
): Promise<void> {
|
||||
config.baseBranch = branchName;
|
||||
await config.storage.setBaseBranch(branchName);
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function setBranchPrefix(
|
||||
branchPrefix: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
return config.storage.setBranchPrefix(branchPrefix);
|
||||
}
|
||||
|
||||
// Search
|
||||
|
||||
// Get full file list
|
||||
export function getFileList(branchName: string = config.baseBranch) {
|
||||
export function getFileList(
|
||||
branchName: string = config.baseBranch
|
||||
): Promise<string[]> {
|
||||
logger.debug(`getFileList(${branchName})`);
|
||||
return config.storage.getFileList(branchName);
|
||||
}
|
||||
|
@ -239,18 +251,21 @@ export function getFileList(branchName: string = config.baseBranch) {
|
|||
// Branch
|
||||
|
||||
// Returns true if branch exists, otherwise false
|
||||
export function branchExists(branchName: string) {
|
||||
export function branchExists(branchName: string): Promise<boolean> {
|
||||
logger.debug(`branchExists(${branchName})`);
|
||||
return config.storage.branchExists(branchName);
|
||||
}
|
||||
|
||||
export function isBranchStale(branchName: string) {
|
||||
export function isBranchStale(branchName: string): Promise<boolean> {
|
||||
logger.debug(`isBranchStale(${branchName})`);
|
||||
return config.storage.isBranchStale(branchName);
|
||||
}
|
||||
|
||||
// Gets details for a PR
|
||||
export async function getPr(prNo: number, refreshCache?: boolean) {
|
||||
export async function getPr(
|
||||
prNo: number,
|
||||
refreshCache?: boolean
|
||||
): Promise<Pr | null> {
|
||||
logger.debug(`getPr(${prNo})`);
|
||||
if (!prNo) {
|
||||
return null;
|
||||
|
@ -314,7 +329,7 @@ export async function getPr(prNo: number, refreshCache?: boolean) {
|
|||
|
||||
// TODO: coverage
|
||||
// istanbul ignore next
|
||||
function matchesState(state: string, desiredState: string) {
|
||||
function matchesState(state: string, desiredState: string): boolean {
|
||||
if (desiredState === 'all') {
|
||||
return true;
|
||||
}
|
||||
|
@ -330,14 +345,14 @@ const isRelevantPr = (
|
|||
branchName: string,
|
||||
prTitle: string | null | undefined,
|
||||
state: string
|
||||
) => (p: { branchName: string; title: string; state: string }) =>
|
||||
) => (p: Pr): boolean =>
|
||||
p.branchName === branchName &&
|
||||
(!prTitle || p.title === prTitle) &&
|
||||
matchesState(p.state, state);
|
||||
|
||||
// TODO: coverage
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export async function getPrList(_args?: any) {
|
||||
export async function getPrList(_args?: any): Promise<Pr[]> {
|
||||
logger.debug(`getPrList()`);
|
||||
// istanbul ignore next
|
||||
if (!config.prList) {
|
||||
|
@ -365,7 +380,7 @@ export async function findPr(
|
|||
prTitle?: string,
|
||||
state = 'all',
|
||||
refreshCache?: boolean
|
||||
) {
|
||||
): Promise<Pr | null> {
|
||||
logger.debug(`findPr(${branchName}, "${prTitle}", "${state}")`);
|
||||
const prList = await getPrList({ refreshCache });
|
||||
const pr = prList.find(isRelevantPr(branchName, prTitle, state));
|
||||
|
@ -378,23 +393,28 @@ export async function findPr(
|
|||
}
|
||||
|
||||
// Returns the Pull Request for a branch. Null if not exists.
|
||||
export async function getBranchPr(branchName: string, refreshCache?: boolean) {
|
||||
export async function getBranchPr(
|
||||
branchName: string,
|
||||
refreshCache?: boolean
|
||||
): Promise<Pr | null> {
|
||||
logger.debug(`getBranchPr(${branchName})`);
|
||||
const existingPr = await findPr(branchName, undefined, 'open');
|
||||
return existingPr ? getPr(existingPr.number, refreshCache) : null;
|
||||
}
|
||||
|
||||
export function getAllRenovateBranches(branchPrefix: string) {
|
||||
export function getAllRenovateBranches(
|
||||
branchPrefix: string
|
||||
): Promise<string[]> {
|
||||
logger.debug('getAllRenovateBranches');
|
||||
return config.storage.getAllRenovateBranches(branchPrefix);
|
||||
}
|
||||
|
||||
export async function commitFilesToBranch(
|
||||
branchName: string,
|
||||
files: any[],
|
||||
files: File[],
|
||||
message: string,
|
||||
parentBranch: string = config.baseBranch
|
||||
) {
|
||||
): Promise<void> {
|
||||
logger.debug(
|
||||
`commitFilesToBranch(${JSON.stringify(
|
||||
{ branchName, filesLength: files.length, message, parentBranch },
|
||||
|
@ -415,12 +435,15 @@ export async function commitFilesToBranch(
|
|||
await getBranchPr(branchName, true);
|
||||
}
|
||||
|
||||
export function getFile(filePath: string, branchName: string) {
|
||||
export function getFile(filePath: string, branchName: string): Promise<string> {
|
||||
logger.debug(`getFile(${filePath}, ${branchName})`);
|
||||
return config.storage.getFile(filePath, branchName);
|
||||
}
|
||||
|
||||
export async function deleteBranch(branchName: string, closePr = false) {
|
||||
export async function deleteBranch(
|
||||
branchName: string,
|
||||
closePr = false
|
||||
): Promise<void> {
|
||||
logger.debug(`deleteBranch(${branchName}, closePr=${closePr})`);
|
||||
// TODO: coverage
|
||||
// istanbul ignore next
|
||||
|
@ -428,27 +451,29 @@ export async function deleteBranch(branchName: string, closePr = false) {
|
|||
// getBranchPr
|
||||
const pr = await getBranchPr(branchName);
|
||||
if (pr) {
|
||||
const { body } = await api.post(
|
||||
const { body } = await api.post<{ version: number }>(
|
||||
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${pr.number}/decline?version=${pr.version}`
|
||||
);
|
||||
|
||||
updatePrVersion(pr, body);
|
||||
updatePrVersion(pr.number, body.version);
|
||||
}
|
||||
}
|
||||
return config.storage.deleteBranch(branchName);
|
||||
}
|
||||
|
||||
export function mergeBranch(branchName: string) {
|
||||
export function mergeBranch(branchName: string): Promise<void> {
|
||||
logger.debug(`mergeBranch(${branchName})`);
|
||||
return config.storage.mergeBranch(branchName);
|
||||
}
|
||||
|
||||
export function getBranchLastCommitTime(branchName: string) {
|
||||
export function getBranchLastCommitTime(branchName: string): Promise<Date> {
|
||||
logger.debug(`getBranchLastCommitTime(${branchName})`);
|
||||
return config.storage.getBranchLastCommitTime(branchName);
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function getRepoStatus() {
|
||||
export /* istanbul ignore next */ function getRepoStatus(): Promise<
|
||||
StatusResult
|
||||
> {
|
||||
return config.storage.getRepoStatus();
|
||||
}
|
||||
|
||||
|
@ -458,7 +483,7 @@ export /* istanbul ignore next */ function getRepoStatus() {
|
|||
export async function getBranchStatus(
|
||||
branchName: string,
|
||||
requiredStatusChecks?: string[] | boolean | null
|
||||
) {
|
||||
): Promise<string> {
|
||||
logger.debug(
|
||||
`getBranchStatus(${branchName}, requiredStatusChecks=${!!requiredStatusChecks})`
|
||||
);
|
||||
|
@ -495,7 +520,7 @@ export async function getBranchStatus(
|
|||
export async function getBranchStatusCheck(
|
||||
branchName: string,
|
||||
context: string
|
||||
) {
|
||||
): Promise<string | null> {
|
||||
logger.debug(`getBranchStatusCheck(${branchName}, context=${context})`);
|
||||
|
||||
const branchCommit = await config.storage.getBranchCommit(branchName);
|
||||
|
@ -530,7 +555,7 @@ export async function setBranchStatus(
|
|||
description: string,
|
||||
state: string | null,
|
||||
targetUrl?: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
logger.debug(`setBranchStatus(${branchName})`);
|
||||
|
||||
const existingStatus = await getBranchStatusCheck(branchName, context);
|
||||
|
@ -577,7 +602,9 @@ export async function setBranchStatus(
|
|||
// return [];
|
||||
// }
|
||||
|
||||
export /* istanbul ignore next */ function findIssue(title: string) {
|
||||
export /* istanbul ignore next */ function findIssue(
|
||||
title: string
|
||||
): Issue | null {
|
||||
logger.debug(`findIssue(${title})`);
|
||||
// TODO: Needs implementation
|
||||
// This is used by Renovate when creating its own issues, e.g. for deprecated package warnings, config error notifications, or "masterIssue"
|
||||
|
@ -588,7 +615,7 @@ export /* istanbul ignore next */ function findIssue(title: string) {
|
|||
export /* istanbul ignore next */ function ensureIssue(
|
||||
title: string,
|
||||
body: string
|
||||
) {
|
||||
): Promise<'updated' | 'created' | null> {
|
||||
logger.warn({ title }, 'Cannot ensure issue');
|
||||
// TODO: Needs implementation
|
||||
// This is used by Renovate when creating its own issues, e.g. for deprecated package warnings, config error notifications, or "masterIssue"
|
||||
|
@ -596,13 +623,15 @@ export /* istanbul ignore next */ function ensureIssue(
|
|||
return null;
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function getIssueList() {
|
||||
export /* istanbul ignore next */ function getIssueList(): Issue[] {
|
||||
logger.debug(`getIssueList()`);
|
||||
// TODO: Needs implementation
|
||||
return [];
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function ensureIssueClosing(title: string) {
|
||||
export /* istanbul ignore next */ function ensureIssueClosing(
|
||||
title: string
|
||||
): void {
|
||||
logger.debug(`ensureIssueClosing(${title})`);
|
||||
// TODO: Needs implementation
|
||||
// This is used by Renovate when creating its own issues, e.g. for deprecated package warnings, config error notifications, or "masterIssue"
|
||||
|
@ -610,14 +639,17 @@ export /* istanbul ignore next */ function ensureIssueClosing(title: string) {
|
|||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export function addAssignees(iid: number, assignees: string[]) {
|
||||
export function addAssignees(iid: number, assignees: string[]): void {
|
||||
logger.debug(`addAssignees(${iid}, ${assignees})`);
|
||||
// TODO: Needs implementation
|
||||
// Currently Renovate does "Create PR" and then "Add assignee" as a two-step process, with this being the second step.
|
||||
// BB Server doesnt support assignees
|
||||
}
|
||||
|
||||
export async function addReviewers(prNo: number, reviewers: string[]) {
|
||||
export async function addReviewers(
|
||||
prNo: number,
|
||||
reviewers: string[]
|
||||
): Promise<void> {
|
||||
logger.debug(`Adding reviewers ${reviewers} to #${prNo}`);
|
||||
|
||||
try {
|
||||
|
@ -653,13 +685,15 @@ export async function addReviewers(prNo: number, reviewers: string[]) {
|
|||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export function deleteLabel(issueNo: number, label: string) {
|
||||
export function deleteLabel(issueNo: number, label: string): void {
|
||||
logger.debug(`deleteLabel(${issueNo}, ${label})`);
|
||||
// TODO: Needs implementation
|
||||
// Only used for the "request Renovate to rebase a PR using a label" feature
|
||||
}
|
||||
|
||||
async function getComments(prNo: number) {
|
||||
type Comment = { text: string; id: number };
|
||||
|
||||
async function getComments(prNo: number): Promise<Comment[]> {
|
||||
// GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/activities
|
||||
let comments = await utils.accumulateValues(
|
||||
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/activities`
|
||||
|
@ -670,14 +704,14 @@ async function getComments(prNo: number) {
|
|||
(a: { action: string; commentAction: string }) =>
|
||||
a.action === 'COMMENTED' && a.commentAction === 'ADDED'
|
||||
)
|
||||
.map((a: { comment: string }) => a.comment);
|
||||
.map((a: { comment: Comment }) => a.comment);
|
||||
|
||||
logger.debug(`Found ${comments.length} comments`);
|
||||
|
||||
return comments;
|
||||
}
|
||||
|
||||
async function addComment(prNo: number, text: string) {
|
||||
async function addComment(prNo: number, text: string): Promise<void> {
|
||||
// POST /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments
|
||||
await api.post(
|
||||
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments`,
|
||||
|
@ -687,7 +721,10 @@ async function addComment(prNo: number, text: string) {
|
|||
);
|
||||
}
|
||||
|
||||
async function getCommentVersion(prNo: number, commentId: number) {
|
||||
async function getCommentVersion(
|
||||
prNo: number,
|
||||
commentId: number
|
||||
): Promise<number> {
|
||||
// GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
|
||||
const { version } = (await api.get(
|
||||
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments/${commentId}`
|
||||
|
@ -696,7 +733,11 @@ async function getCommentVersion(prNo: number, commentId: number) {
|
|||
return version;
|
||||
}
|
||||
|
||||
async function editComment(prNo: number, commentId: number, text: string) {
|
||||
async function editComment(
|
||||
prNo: number,
|
||||
commentId: number,
|
||||
text: string
|
||||
): Promise<void> {
|
||||
const version = await getCommentVersion(prNo, commentId);
|
||||
|
||||
// PUT /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
|
||||
|
@ -708,7 +749,7 @@ async function editComment(prNo: number, commentId: number, text: string) {
|
|||
);
|
||||
}
|
||||
|
||||
async function deleteComment(prNo: number, commentId: number) {
|
||||
async function deleteComment(prNo: number, commentId: number): Promise<void> {
|
||||
const version = await getCommentVersion(prNo, commentId);
|
||||
|
||||
// DELETE /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
|
||||
|
@ -721,7 +762,7 @@ export async function ensureComment(
|
|||
prNo: number,
|
||||
topic: string | null,
|
||||
rawContent: string
|
||||
) {
|
||||
): Promise<boolean> {
|
||||
const content = sanitize(rawContent);
|
||||
try {
|
||||
const comments = await getComments(prNo);
|
||||
|
@ -731,7 +772,7 @@ export async function ensureComment(
|
|||
if (topic) {
|
||||
logger.debug(`Ensuring comment "${topic}" in #${prNo}`);
|
||||
body = `### ${topic}\n\n${content}`;
|
||||
comments.forEach((comment: { text: string; id: number }) => {
|
||||
comments.forEach(comment => {
|
||||
if (comment.text.startsWith(`### ${topic}\n\n`)) {
|
||||
commentId = comment.id;
|
||||
commentNeedsUpdating = comment.text !== body;
|
||||
|
@ -740,7 +781,7 @@ export async function ensureComment(
|
|||
} else {
|
||||
logger.debug(`Ensuring content-only comment in #${prNo}`);
|
||||
body = `${content}`;
|
||||
comments.forEach((comment: { text: string; id: number }) => {
|
||||
comments.forEach(comment => {
|
||||
if (comment.text === body) {
|
||||
commentId = comment.id;
|
||||
commentNeedsUpdating = false;
|
||||
|
@ -766,12 +807,15 @@ export async function ensureComment(
|
|||
}
|
||||
}
|
||||
|
||||
export async function ensureCommentRemoval(prNo: number, topic: string) {
|
||||
export async function ensureCommentRemoval(
|
||||
prNo: number,
|
||||
topic: string
|
||||
): Promise<void> {
|
||||
try {
|
||||
logger.debug(`Ensuring comment "${topic}" in #${prNo} is removed`);
|
||||
const comments = await getComments(prNo);
|
||||
let commentId;
|
||||
comments.forEach((comment: { text: string; id: any }) => {
|
||||
let commentId: number;
|
||||
comments.forEach(comment => {
|
||||
if (comment.text.startsWith(`### ${topic}\n\n`)) {
|
||||
commentId = comment.id;
|
||||
}
|
||||
|
@ -786,7 +830,8 @@ export async function ensureCommentRemoval(prNo: number, topic: string) {
|
|||
|
||||
// Pull Request
|
||||
|
||||
const escapeHash = input => (input ? input.replace(/#/g, '%23') : input);
|
||||
const escapeHash = (input: string): string =>
|
||||
input ? input.replace(/#/g, '%23') : input;
|
||||
|
||||
export async function createPr(
|
||||
branchName: string,
|
||||
|
@ -794,7 +839,7 @@ export async function createPr(
|
|||
rawDescription: string,
|
||||
_labels?: string[] | null,
|
||||
useDefaultBranch?: boolean
|
||||
) {
|
||||
): Promise<Pr> {
|
||||
const description = sanitize(rawDescription);
|
||||
logger.debug(`createPr(${branchName}, title=${title})`);
|
||||
const base = useDefaultBranch ? config.defaultBranch : config.baseBranch;
|
||||
|
@ -831,7 +876,7 @@ export async function createPr(
|
|||
},
|
||||
reviewers,
|
||||
};
|
||||
let prInfoRes;
|
||||
let prInfoRes: GotResponse;
|
||||
try {
|
||||
prInfoRes = await api.post(
|
||||
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests`,
|
||||
|
@ -854,7 +899,7 @@ export async function createPr(
|
|||
throw err;
|
||||
}
|
||||
|
||||
const pr = {
|
||||
const pr: Pr = {
|
||||
id: prInfoRes.body.id,
|
||||
displayNumber: `Pull Request #${prInfoRes.body.id}`,
|
||||
isModified: false,
|
||||
|
@ -873,24 +918,24 @@ export async function createPr(
|
|||
|
||||
// Return a list of all modified files in a PR
|
||||
// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-rest.html
|
||||
export async function getPrFiles(prNo: number) {
|
||||
export async function getPrFiles(prNo: number): Promise<string[]> {
|
||||
logger.debug(`getPrFiles(${prNo})`);
|
||||
if (!prNo) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/changes
|
||||
const values = await utils.accumulateValues(
|
||||
const values = await utils.accumulateValues<{ path: { toString: string } }>(
|
||||
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/changes?withComments=false`
|
||||
);
|
||||
return values.map((f: { path: string }) => f.path.toString);
|
||||
return values.map(f => f.path.toString);
|
||||
}
|
||||
|
||||
export async function updatePr(
|
||||
prNo: number,
|
||||
title: string,
|
||||
rawDescription: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
const description = sanitize(rawDescription);
|
||||
logger.debug(`updatePr(${prNo}, title=${title})`);
|
||||
|
||||
|
@ -900,7 +945,7 @@ export async function updatePr(
|
|||
throw Object.assign(new Error('not-found'), { statusCode: 404 });
|
||||
}
|
||||
|
||||
const { body } = await api.put(
|
||||
const { body } = await api.put<{ version: number }>(
|
||||
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}`,
|
||||
{
|
||||
body: {
|
||||
|
@ -926,7 +971,10 @@ export async function updatePr(
|
|||
}
|
||||
|
||||
// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-rest.html#idp261
|
||||
export async function mergePr(prNo: number, branchName: string) {
|
||||
export async function mergePr(
|
||||
prNo: number,
|
||||
branchName: string
|
||||
): Promise<boolean> {
|
||||
logger.debug(`mergePr(${prNo}, ${branchName})`);
|
||||
// Used for "automerge" feature
|
||||
try {
|
||||
|
@ -934,7 +982,7 @@ export async function mergePr(prNo: number, branchName: string) {
|
|||
if (!pr) {
|
||||
throw Object.assign(new Error('not-found'), { statusCode: 404 });
|
||||
}
|
||||
const { body } = await api.post(
|
||||
const { body } = await api.post<{ version: number }>(
|
||||
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/merge?version=${pr.version}`
|
||||
);
|
||||
updatePrVersion(prNo, body.version);
|
||||
|
@ -956,7 +1004,7 @@ export async function mergePr(prNo: number, branchName: string) {
|
|||
return true;
|
||||
}
|
||||
|
||||
export function getPrBody(input: string) {
|
||||
export function getPrBody(input: string): string {
|
||||
logger.debug(`getPrBody(${input.split('\n')[0]})`);
|
||||
// Remove any HTML we use
|
||||
return smartTruncate(input, 30000)
|
||||
|
@ -966,12 +1014,12 @@ export function getPrBody(input: string) {
|
|||
.replace(new RegExp('<!--.*?-->', 'g'), '');
|
||||
}
|
||||
|
||||
export function getCommitMessages() {
|
||||
export function getCommitMessages(): Promise<string[]> {
|
||||
logger.debug(`getCommitMessages()`);
|
||||
return config.storage.getCommitMessages();
|
||||
}
|
||||
|
||||
export function getVulnerabilityAlerts() {
|
||||
export function getVulnerabilityAlerts(): VulnerabilityAlert[] {
|
||||
logger.debug(`getVulnerabilityAlerts()`);
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// SEE for the reference https://github.com/renovatebot/renovate/blob/c3e9e572b225085448d94aa121c7ec81c14d3955/lib/platform/bitbucket/utils.js
|
||||
import url from 'url';
|
||||
import { api } from './bb-got-wrapper';
|
||||
import { Pr } from '../common';
|
||||
|
||||
// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-rest.html#idp250
|
||||
const prStateMapping: any = {
|
||||
|
@ -9,7 +10,7 @@ const prStateMapping: any = {
|
|||
OPEN: 'open',
|
||||
};
|
||||
|
||||
export function prInfo(pr: any) {
|
||||
export function prInfo(pr: any): Pr {
|
||||
return {
|
||||
version: pr.version,
|
||||
number: pr.id,
|
||||
|
@ -23,7 +24,7 @@ export function prInfo(pr: any) {
|
|||
};
|
||||
}
|
||||
|
||||
const addMaxLength = (inputUrl: string, limit = 100) => {
|
||||
const addMaxLength = (inputUrl: string, limit = 100): string => {
|
||||
const { search, ...parsedUrl } = url.parse(inputUrl, true); // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
const maxedUrl = url.format({
|
||||
...parsedUrl,
|
||||
|
@ -32,13 +33,13 @@ const addMaxLength = (inputUrl: string, limit = 100) => {
|
|||
return maxedUrl;
|
||||
};
|
||||
|
||||
export async function accumulateValues(
|
||||
export async function accumulateValues<T = any>(
|
||||
reqUrl: string,
|
||||
method = 'get',
|
||||
options?: any,
|
||||
limit?: number
|
||||
) {
|
||||
let accumulator: any = [];
|
||||
): Promise<T[]> {
|
||||
let accumulator: T[] = [];
|
||||
let nextUrl = addMaxLength(reqUrl, limit);
|
||||
const lowerCaseMethod = method.toLocaleLowerCase();
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import { GotJSONOptions } from 'got';
|
||||
import got from '../../util/got';
|
||||
import { GotApi, GotApiOptions } from '../common';
|
||||
import { GotApi, GotApiOptions, GotResponse } from '../common';
|
||||
|
||||
async function get(path: string, options: GotApiOptions & GotJSONOptions) {
|
||||
async function get(
|
||||
path: string,
|
||||
options: GotApiOptions & GotJSONOptions
|
||||
): Promise<GotResponse> {
|
||||
const opts: GotApiOptions & GotJSONOptions = {
|
||||
json: true,
|
||||
hostType: 'bitbucket',
|
||||
|
@ -18,7 +21,7 @@ const helpers = ['get', 'post', 'put', 'patch', 'head', 'delete'];
|
|||
export const api: GotApi = {} as any;
|
||||
|
||||
for (const x of helpers) {
|
||||
(api as any)[x] = (url: string, opts: any) =>
|
||||
(api as any)[x] = (url: string, opts: any): Promise<GotResponse> =>
|
||||
get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,10 @@ interface Comment {
|
|||
|
||||
export type CommentsConfig = Pick<Config, 'repository'>;
|
||||
|
||||
async function getComments(config: CommentsConfig, prNo: number) {
|
||||
async function getComments(
|
||||
config: CommentsConfig,
|
||||
prNo: number
|
||||
): Promise<Comment[]> {
|
||||
const comments = await accumulateValues<Comment>(
|
||||
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/comments`
|
||||
);
|
||||
|
@ -18,7 +21,11 @@ async function getComments(config: CommentsConfig, prNo: number) {
|
|||
return comments;
|
||||
}
|
||||
|
||||
async function addComment(config: CommentsConfig, prNo: number, raw: string) {
|
||||
async function addComment(
|
||||
config: CommentsConfig,
|
||||
prNo: number,
|
||||
raw: string
|
||||
): Promise<void> {
|
||||
await api.post(
|
||||
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/comments`,
|
||||
{
|
||||
|
@ -32,7 +39,7 @@ async function editComment(
|
|||
prNo: number,
|
||||
commentId: number,
|
||||
raw: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
await api.put(
|
||||
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/comments/${commentId}`,
|
||||
{
|
||||
|
@ -45,7 +52,7 @@ async function deleteComment(
|
|||
config: CommentsConfig,
|
||||
prNo: number,
|
||||
commentId: number
|
||||
) {
|
||||
): Promise<void> {
|
||||
await api.delete(
|
||||
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/comments/${commentId}`
|
||||
);
|
||||
|
@ -56,7 +63,7 @@ export async function ensureComment(
|
|||
prNo: number,
|
||||
topic: string | null,
|
||||
content: string
|
||||
) {
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
const comments = await getComments(config, prNo);
|
||||
let body: string;
|
||||
|
@ -104,11 +111,11 @@ export async function ensureCommentRemoval(
|
|||
config: CommentsConfig,
|
||||
prNo: number,
|
||||
topic: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
try {
|
||||
logger.debug(`Ensuring comment "${topic}" in #${prNo} is removed`);
|
||||
const comments = await getComments(config, prNo);
|
||||
let commentId;
|
||||
let commentId: number;
|
||||
comments.forEach(comment => {
|
||||
if (comment.content.raw.startsWith(`### ${topic}\n\n`)) {
|
||||
commentId = comment.id;
|
||||
|
|
|
@ -4,11 +4,18 @@ import { api } from './bb-got-wrapper';
|
|||
import * as utils from './utils';
|
||||
import * as hostRules from '../../util/host-rules';
|
||||
import { logger } from '../../logger';
|
||||
import GitStorage from '../git/storage';
|
||||
import GitStorage, { StatusResult, File } from '../git/storage';
|
||||
import { readOnlyIssueBody } from '../utils/read-only-issue-body';
|
||||
import { appSlug } from '../../config/app-strings';
|
||||
import * as comments from './comments';
|
||||
import { PlatformConfig, RepoParams, RepoConfig } from '../common';
|
||||
import {
|
||||
PlatformConfig,
|
||||
RepoParams,
|
||||
RepoConfig,
|
||||
Pr,
|
||||
Issue,
|
||||
VulnerabilityAlert,
|
||||
} from '../common';
|
||||
import { sanitize } from '../../util/sanitize';
|
||||
import { smartTruncate } from '../utils/pr-body';
|
||||
|
||||
|
@ -22,7 +29,7 @@ export function initPlatform({
|
|||
endpoint?: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}) {
|
||||
}): PlatformConfig {
|
||||
if (!(username && password)) {
|
||||
throw new Error(
|
||||
'Init: You must configure a Bitbucket username and password'
|
||||
|
@ -41,13 +48,13 @@ export function initPlatform({
|
|||
}
|
||||
|
||||
// Get all repositories that the user has access to
|
||||
export async function getRepos() {
|
||||
export async function getRepos(): Promise<string[]> {
|
||||
logger.info('Autodiscovering Bitbucket Cloud repositories');
|
||||
try {
|
||||
const repos = await utils.accumulateValues(
|
||||
const repos = await utils.accumulateValues<{ full_name: string }>(
|
||||
`/2.0/repositories/?role=contributor`
|
||||
);
|
||||
return repos.map((repo: { full_name: string }) => repo.full_name);
|
||||
return repos.map(repo => repo.full_name);
|
||||
} catch (err) /* istanbul ignore next */ {
|
||||
logger.error({ err }, `bitbucket getRepos error`);
|
||||
throw err;
|
||||
|
@ -60,7 +67,7 @@ export async function initRepo({
|
|||
localDir,
|
||||
optimizeForDisabled,
|
||||
bbUseDefaultReviewers,
|
||||
}: RepoParams) {
|
||||
}: RepoParams): Promise<RepoConfig> {
|
||||
logger.debug(`initRepo("${repository}")`);
|
||||
const opts = hostRules.find({
|
||||
hostType: 'bitbucket',
|
||||
|
@ -71,7 +78,7 @@ export async function initRepo({
|
|||
username: opts!.username,
|
||||
bbUseDefaultReviewers: bbUseDefaultReviewers !== false,
|
||||
} as any;
|
||||
let info;
|
||||
let info: utils.RepoInfo;
|
||||
try {
|
||||
info = utils.repoInfoTransformer(
|
||||
(await api.get(`/2.0/repositories/${repository}`)).body
|
||||
|
@ -133,7 +140,7 @@ export async function initRepo({
|
|||
}
|
||||
|
||||
// Returns true if repository has rule enforcing PRs are up-to-date with base branch before merging
|
||||
export function getRepoForceRebase() {
|
||||
export function getRepoForceRebase(): boolean {
|
||||
// BB doesnt have an option to flag staled branches
|
||||
return false;
|
||||
}
|
||||
|
@ -141,11 +148,13 @@ export function getRepoForceRebase() {
|
|||
// Search
|
||||
|
||||
// Get full file list
|
||||
export function getFileList(branchName?: string) {
|
||||
export function getFileList(branchName?: string): Promise<string[]> {
|
||||
return config.storage.getFileList(branchName);
|
||||
}
|
||||
|
||||
export async function setBaseBranch(branchName = config.baseBranch) {
|
||||
export async function setBaseBranch(
|
||||
branchName = config.baseBranch
|
||||
): Promise<void> {
|
||||
logger.debug(`Setting baseBranch to ${branchName}`);
|
||||
config.baseBranch = branchName;
|
||||
delete config.baseCommitSHA;
|
||||
|
@ -156,31 +165,36 @@ export async function setBaseBranch(branchName = config.baseBranch) {
|
|||
|
||||
export /* istanbul ignore next */ function setBranchPrefix(
|
||||
branchPrefix: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
return config.storage.setBranchPrefix(branchPrefix);
|
||||
}
|
||||
|
||||
// Branch
|
||||
|
||||
// Returns true if branch exists, otherwise false
|
||||
export function branchExists(branchName: string) {
|
||||
export function branchExists(branchName: string): Promise<boolean> {
|
||||
return config.storage.branchExists(branchName);
|
||||
}
|
||||
|
||||
export function getAllRenovateBranches(branchPrefix: string) {
|
||||
export function getAllRenovateBranches(
|
||||
branchPrefix: string
|
||||
): Promise<string[]> {
|
||||
return config.storage.getAllRenovateBranches(branchPrefix);
|
||||
}
|
||||
|
||||
export function isBranchStale(branchName: string) {
|
||||
export function isBranchStale(branchName: string): Promise<boolean> {
|
||||
return config.storage.isBranchStale(branchName);
|
||||
}
|
||||
|
||||
export function getFile(filePath: string, branchName?: string) {
|
||||
export function getFile(
|
||||
filePath: string,
|
||||
branchName?: string
|
||||
): Promise<string> {
|
||||
return config.storage.getFile(filePath, branchName);
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
function matchesState(state: string, desiredState: string) {
|
||||
function matchesState(state: string, desiredState: string): boolean {
|
||||
if (desiredState === 'all') {
|
||||
return true;
|
||||
}
|
||||
|
@ -190,7 +204,7 @@ function matchesState(state: string, desiredState: string) {
|
|||
return state === desiredState;
|
||||
}
|
||||
|
||||
export async function getPrList() {
|
||||
export async function getPrList(): Promise<Pr[]> {
|
||||
logger.debug('getPrList()');
|
||||
if (!config.prList) {
|
||||
logger.debug('Retrieving PR list');
|
||||
|
@ -207,11 +221,11 @@ export async function findPr(
|
|||
branchName: string,
|
||||
prTitle?: string | null,
|
||||
state = 'all'
|
||||
) {
|
||||
): Promise<Pr | null> {
|
||||
logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);
|
||||
const prList = await getPrList();
|
||||
const pr = prList.find(
|
||||
(p: { branchName: string; title: string; state: string }) =>
|
||||
p =>
|
||||
p.branchName === branchName &&
|
||||
(!prTitle || p.title === prTitle) &&
|
||||
matchesState(p.state, state)
|
||||
|
@ -222,7 +236,10 @@ export async function findPr(
|
|||
return pr;
|
||||
}
|
||||
|
||||
export async function deleteBranch(branchName: string, closePr?: boolean) {
|
||||
export async function deleteBranch(
|
||||
branchName: string,
|
||||
closePr?: boolean
|
||||
): Promise<void> {
|
||||
if (closePr) {
|
||||
const pr = await findPr(branchName, null, 'open');
|
||||
if (pr) {
|
||||
|
@ -234,25 +251,25 @@ export async function deleteBranch(branchName: string, closePr?: boolean) {
|
|||
return config.storage.deleteBranch(branchName);
|
||||
}
|
||||
|
||||
export function getBranchLastCommitTime(branchName: string) {
|
||||
export function getBranchLastCommitTime(branchName: string): Promise<Date> {
|
||||
return config.storage.getBranchLastCommitTime(branchName);
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export function getRepoStatus() {
|
||||
export function getRepoStatus(): Promise<StatusResult> {
|
||||
return config.storage.getRepoStatus();
|
||||
}
|
||||
|
||||
export function mergeBranch(branchName: string) {
|
||||
export function mergeBranch(branchName: string): Promise<void> {
|
||||
return config.storage.mergeBranch(branchName);
|
||||
}
|
||||
|
||||
export function commitFilesToBranch(
|
||||
branchName: string,
|
||||
files: any[],
|
||||
files: File[],
|
||||
message: string,
|
||||
parentBranch = config.baseBranch
|
||||
) {
|
||||
): Promise<void> {
|
||||
return config.storage.commitFilesToBranch(
|
||||
branchName,
|
||||
files,
|
||||
|
@ -261,11 +278,11 @@ export function commitFilesToBranch(
|
|||
);
|
||||
}
|
||||
|
||||
export function getCommitMessages() {
|
||||
export function getCommitMessages(): Promise<string[]> {
|
||||
return config.storage.getCommitMessages();
|
||||
}
|
||||
|
||||
async function isPrConflicted(prNo: number) {
|
||||
async function isPrConflicted(prNo: number): Promise<boolean> {
|
||||
const diff = (await api.get(
|
||||
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/diff`,
|
||||
{ json: false } as any
|
||||
|
@ -275,7 +292,7 @@ async function isPrConflicted(prNo: number) {
|
|||
}
|
||||
|
||||
// Gets details for a PR
|
||||
export async function getPr(prNo: number) {
|
||||
export async function getPr(prNo: number): Promise<Pr | null> {
|
||||
const pr = (await api.get(
|
||||
`/2.0/repositories/${config.repository}/pullrequests/${prNo}`
|
||||
)).body;
|
||||
|
@ -330,10 +347,11 @@ export async function getPr(prNo: number) {
|
|||
return res;
|
||||
}
|
||||
|
||||
const escapeHash = input => (input ? input.replace(/#/g, '%23') : input);
|
||||
const escapeHash = (input: string): string =>
|
||||
input ? input.replace(/#/g, '%23') : input;
|
||||
|
||||
// Return the commit SHA for a branch
|
||||
async function getBranchCommit(branchName: string) {
|
||||
async function getBranchCommit(branchName: string): Promise<string | null> {
|
||||
try {
|
||||
const branch = (await api.get(
|
||||
`/2.0/repositories/${config.repository}/refs/branches/${escapeHash(
|
||||
|
@ -348,7 +366,7 @@ async function getBranchCommit(branchName: string) {
|
|||
}
|
||||
|
||||
// Returns the Pull Request for a branch. Null if not exists.
|
||||
export async function getBranchPr(branchName: string) {
|
||||
export async function getBranchPr(branchName: string): Promise<Pr | null> {
|
||||
logger.debug(`getBranchPr(${branchName})`);
|
||||
const existingPr = await findPr(branchName, null, 'open');
|
||||
return existingPr ? getPr(existingPr.number) : null;
|
||||
|
@ -358,7 +376,7 @@ export async function getBranchPr(branchName: string) {
|
|||
export async function getBranchStatus(
|
||||
branchName: string,
|
||||
requiredStatusChecks?: string[]
|
||||
) {
|
||||
): Promise<string> {
|
||||
logger.debug(`getBranchStatus(${branchName})`);
|
||||
if (!requiredStatusChecks) {
|
||||
// null means disable status checks, so it always succeeds
|
||||
|
@ -400,7 +418,7 @@ export async function getBranchStatus(
|
|||
export async function getBranchStatusCheck(
|
||||
branchName: string,
|
||||
context: string
|
||||
) {
|
||||
): Promise<string | null> {
|
||||
const sha = await getBranchCommit(branchName);
|
||||
const statuses = await utils.accumulateValues(
|
||||
`/2.0/repositories/${config.repository}/commit/${sha}/statuses`
|
||||
|
@ -422,7 +440,7 @@ export async function setBranchStatus(
|
|||
description: string,
|
||||
state: string,
|
||||
targetUrl?: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
const sha = await getBranchCommit(branchName);
|
||||
|
||||
// TargetUrl can not be empty so default to bitbucket
|
||||
|
@ -442,7 +460,9 @@ export async function setBranchStatus(
|
|||
);
|
||||
}
|
||||
|
||||
async function findOpenIssues(title: string) {
|
||||
type BbIssue = { id: number; content?: { raw: string } };
|
||||
|
||||
async function findOpenIssues(title: string): Promise<BbIssue[]> {
|
||||
try {
|
||||
const filter = encodeURIComponent(
|
||||
[
|
||||
|
@ -462,7 +482,7 @@ async function findOpenIssues(title: string) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function findIssue(title: string) {
|
||||
export async function findIssue(title: string): Promise<Issue> {
|
||||
logger.debug(`findIssue(${title})`);
|
||||
|
||||
/* istanbul ignore if */
|
||||
|
@ -481,7 +501,7 @@ export async function findIssue(title: string) {
|
|||
};
|
||||
}
|
||||
|
||||
async function closeIssue(issueNumber: number) {
|
||||
async function closeIssue(issueNumber: number): Promise<void> {
|
||||
await api.put(
|
||||
`/2.0/repositories/${config.repository}/issues/${issueNumber}`,
|
||||
{
|
||||
|
@ -490,7 +510,7 @@ async function closeIssue(issueNumber: number) {
|
|||
);
|
||||
}
|
||||
|
||||
export function getPrBody(input: string) {
|
||||
export function getPrBody(input: string): string {
|
||||
// Remove any HTML we use
|
||||
return smartTruncate(input, 50000)
|
||||
.replace(/<\/?summary>/g, '**')
|
||||
|
@ -499,7 +519,10 @@ export function getPrBody(input: string) {
|
|||
.replace(/\]\(\.\.\/pull\//g, '](../../pull-requests/');
|
||||
}
|
||||
|
||||
export async function ensureIssue(title: string, body: string) {
|
||||
export async function ensureIssue(
|
||||
title: string,
|
||||
body: string
|
||||
): Promise<string | null> {
|
||||
logger.debug(`ensureIssue()`);
|
||||
const description = getPrBody(sanitize(body));
|
||||
|
||||
|
@ -554,7 +577,9 @@ export async function ensureIssue(title: string, body: string) {
|
|||
return null;
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ async function getIssueList() {
|
||||
export /* istanbul ignore next */ async function getIssueList(): Promise<
|
||||
Issue[]
|
||||
> {
|
||||
logger.debug(`getIssueList()`);
|
||||
|
||||
/* istanbul ignore if */
|
||||
|
@ -580,7 +605,7 @@ export /* istanbul ignore next */ async function getIssueList() {
|
|||
}
|
||||
}
|
||||
|
||||
export async function ensureIssueClosing(title: string) {
|
||||
export async function ensureIssueClosing(title: string): Promise<void> {
|
||||
/* istanbul ignore if */
|
||||
if (!config.has_issues) {
|
||||
logger.debug('Issues are disabled - cannot ensureIssueClosing');
|
||||
|
@ -593,13 +618,19 @@ export async function ensureIssueClosing(title: string) {
|
|||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function addAssignees(_prNr: number, _assignees: string[]) {
|
||||
export function addAssignees(
|
||||
_prNr: number,
|
||||
_assignees: string[]
|
||||
): Promise<void> {
|
||||
// Bitbucket supports "participants" and "reviewers" so does not seem to have the concept of "assignee"
|
||||
logger.warn('Cannot add assignees');
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
export async function addReviewers(prId: number, reviewers: string[]) {
|
||||
export async function addReviewers(
|
||||
prId: number,
|
||||
reviewers: string[]
|
||||
): Promise<void> {
|
||||
logger.debug(`Adding reviewers ${reviewers} to #${prId}`);
|
||||
|
||||
const { title } = await getPr(prId);
|
||||
|
@ -614,7 +645,7 @@ export async function addReviewers(prId: number, reviewers: string[]) {
|
|||
});
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function deleteLabel() {
|
||||
export /* istanbul ignore next */ function deleteLabel(): never {
|
||||
throw new Error('deleteLabel not implemented');
|
||||
}
|
||||
|
||||
|
@ -622,12 +653,15 @@ export function ensureComment(
|
|||
prNo: number,
|
||||
topic: string | null,
|
||||
content: string
|
||||
) {
|
||||
): Promise<boolean> {
|
||||
// https://developer.atlassian.com/bitbucket/api/2/reference/search?q=pullrequest+comment
|
||||
return comments.ensureComment(config, prNo, topic, sanitize(content));
|
||||
}
|
||||
|
||||
export function ensureCommentRemoval(prNo: number, topic: string) {
|
||||
export function ensureCommentRemoval(
|
||||
prNo: number,
|
||||
topic: string
|
||||
): Promise<void> {
|
||||
return comments.ensureCommentRemoval(config, prNo, topic);
|
||||
}
|
||||
|
||||
|
@ -638,7 +672,7 @@ export async function createPr(
|
|||
description: string,
|
||||
_labels?: string[],
|
||||
useDefaultBranch = true
|
||||
) {
|
||||
): Promise<Pr> {
|
||||
// labels is not supported in Bitbucket: https://bitbucket.org/site/master/issues/11976/ability-to-add-labels-to-pull-requests-bb
|
||||
|
||||
const base = useDefaultBranch
|
||||
|
@ -679,11 +713,12 @@ export async function createPr(
|
|||
`/2.0/repositories/${config.repository}/pullrequests`,
|
||||
{ body }
|
||||
)).body;
|
||||
const pr = {
|
||||
// TODO: fix types
|
||||
const pr: Pr = {
|
||||
number: prInfo.id,
|
||||
displayNumber: `Pull Request #${prInfo.id}`,
|
||||
isModified: false,
|
||||
};
|
||||
} as any;
|
||||
// istanbul ignore if
|
||||
if (config.prList) {
|
||||
config.prList.push(pr);
|
||||
|
@ -700,7 +735,7 @@ interface Commit {
|
|||
}
|
||||
|
||||
// Return a list of all modified files in a PR
|
||||
export async function getPrFiles(prNo: number) {
|
||||
export async function getPrFiles(prNo: number): Promise<string[]> {
|
||||
logger.debug({ prNo }, 'getPrFiles');
|
||||
const diff = (await api.get(
|
||||
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/diff`,
|
||||
|
@ -714,14 +749,17 @@ export async function updatePr(
|
|||
prNo: number,
|
||||
title: string,
|
||||
description: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
logger.debug(`updatePr(${prNo}, ${title}, body)`);
|
||||
await api.put(`/2.0/repositories/${config.repository}/pullrequests/${prNo}`, {
|
||||
body: { title, description: sanitize(description) },
|
||||
});
|
||||
}
|
||||
|
||||
export async function mergePr(prNo: number, branchName: string) {
|
||||
export async function mergePr(
|
||||
prNo: number,
|
||||
branchName: string
|
||||
): Promise<boolean> {
|
||||
logger.debug(`mergePr(${prNo}, ${branchName})`);
|
||||
|
||||
try {
|
||||
|
@ -745,7 +783,7 @@ export async function mergePr(prNo: number, branchName: string) {
|
|||
|
||||
// Pull Request
|
||||
|
||||
export function cleanRepo() {
|
||||
export function cleanRepo(): void {
|
||||
// istanbul ignore if
|
||||
if (config.storage && config.storage.cleanRepo) {
|
||||
config.storage.cleanRepo();
|
||||
|
@ -753,6 +791,6 @@ export function cleanRepo() {
|
|||
config = {} as any;
|
||||
}
|
||||
|
||||
export function getVulnerabilityAlerts() {
|
||||
export function getVulnerabilityAlerts(): VulnerabilityAlert[] {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import url from 'url';
|
||||
import { api } from './bb-got-wrapper';
|
||||
import { Storage } from '../git/storage';
|
||||
import { GotResponse } from '../common';
|
||||
import { GotResponse, Pr } from '../common';
|
||||
|
||||
export interface Config {
|
||||
baseBranch: string;
|
||||
|
@ -11,7 +11,7 @@ export interface Config {
|
|||
has_issues: boolean;
|
||||
mergeMethod: string;
|
||||
owner: string;
|
||||
prList: any[];
|
||||
prList: Pr[];
|
||||
repository: string;
|
||||
storage: Storage;
|
||||
bbUseDefaultReviewers: boolean;
|
||||
|
@ -26,7 +26,15 @@ export interface PagedResult<T = any> {
|
|||
values: T[];
|
||||
}
|
||||
|
||||
export function repoInfoTransformer(repoInfoBody: any) {
|
||||
export interface RepoInfo {
|
||||
isFork: boolean;
|
||||
owner: string;
|
||||
mainbranch: string;
|
||||
mergeMethod: string;
|
||||
has_issues: boolean;
|
||||
}
|
||||
|
||||
export function repoInfoTransformer(repoInfoBody: any): RepoInfo {
|
||||
return {
|
||||
isFork: !!repoInfoBody.parent,
|
||||
owner: repoInfoBody.owner.username,
|
||||
|
@ -55,7 +63,7 @@ export const buildStates: {
|
|||
pending: 'INPROGRESS',
|
||||
};
|
||||
|
||||
const addMaxLength = (inputUrl: string, pagelen = 100) => {
|
||||
const addMaxLength = (inputUrl: string, pagelen = 100): string => {
|
||||
const { search, ...parsedUrl } = url.parse(inputUrl, true); // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
const maxedUrl = url.format({
|
||||
...parsedUrl,
|
||||
|
@ -69,7 +77,7 @@ export async function accumulateValues<T = any>(
|
|||
method = 'get',
|
||||
options?: any,
|
||||
pagelen?: number
|
||||
) {
|
||||
): Promise<T[]> {
|
||||
let accumulator: T[] = [];
|
||||
let nextUrl = addMaxLength(reqUrl, pagelen);
|
||||
const lowerCaseMethod = method.toLocaleLowerCase();
|
||||
|
@ -86,7 +94,7 @@ export async function accumulateValues<T = any>(
|
|||
return accumulator;
|
||||
}
|
||||
|
||||
export /* istanbul ignore next */ function isConflicted(files: any) {
|
||||
export /* istanbul ignore next */ function isConflicted(files: any): boolean {
|
||||
for (const file of files) {
|
||||
for (const chunk of file.chunks) {
|
||||
for (const change of chunk.changes) {
|
||||
|
@ -99,7 +107,7 @@ export /* istanbul ignore next */ function isConflicted(files: any) {
|
|||
return false;
|
||||
}
|
||||
|
||||
export function prInfo(pr: any) {
|
||||
export function prInfo(pr: any): Pr {
|
||||
return {
|
||||
number: pr.id,
|
||||
body: pr.summary ? pr.summary.raw : /* istanbul ignore next */ undefined,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import got from 'got';
|
||||
import Git from 'simple-git/promise';
|
||||
import { RenovateConfig } from '../config/common';
|
||||
import { File } from './git/storage';
|
||||
|
||||
export interface FileData {
|
||||
name: string;
|
||||
|
@ -77,7 +78,10 @@ export interface RepoParams {
|
|||
/**
|
||||
* TODO: Proper typing
|
||||
*/
|
||||
export type Pr = any;
|
||||
export type Pr = { branchName: string; title: string; state: string } & Record<
|
||||
string,
|
||||
any
|
||||
>;
|
||||
|
||||
/**
|
||||
* TODO: Proper typing
|
||||
|
@ -158,7 +162,7 @@ export interface Platform {
|
|||
setBaseBranch(baseBranch: string): Promise<void>;
|
||||
commitFilesToBranch(
|
||||
branchName: string,
|
||||
updatedFiles: any[],
|
||||
updatedFiles: File[],
|
||||
commitMessage: string,
|
||||
parentBranch?: string
|
||||
): Promise<void>;
|
||||
|
@ -173,7 +177,7 @@ export interface Platform {
|
|||
branchName: string,
|
||||
requiredStatusChecks?: string[] | null
|
||||
): Promise<BranchStatus>;
|
||||
getBranchPr(branchName: string): Promise<Pr>;
|
||||
getBranchPr(branchName: string): Promise<Pr | null>;
|
||||
getRepoStatus(): Promise<Git.StatusResult>;
|
||||
getFile(lockFileName: string, branchName?: string): Promise<string>;
|
||||
initPlatform(config: RenovateConfig): Promise<PlatformConfig>;
|
||||
|
|
|
@ -11,6 +11,23 @@ declare module 'fs-extra' {
|
|||
export function exists(pathLike: string): Promise<boolean>;
|
||||
}
|
||||
|
||||
export type StatusResult = Git.StatusResult;
|
||||
|
||||
/**
|
||||
* File to commit to branch
|
||||
*/
|
||||
export interface File {
|
||||
/**
|
||||
* Relative file path
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* file contents
|
||||
*/
|
||||
contents: string;
|
||||
}
|
||||
|
||||
interface StorageConfig {
|
||||
localDir: string;
|
||||
baseBranch?: string;
|
||||
|
@ -21,12 +38,12 @@ interface StorageConfig {
|
|||
interface LocalConfig extends StorageConfig {
|
||||
baseBranch: string;
|
||||
baseBranchSha: string;
|
||||
branchExists: { [branch: string]: boolean };
|
||||
branchExists: Record<string, boolean>;
|
||||
branchPrefix: string;
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
function checkForPlatformFailure(err: Error) {
|
||||
function checkForPlatformFailure(err: Error): void {
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
return;
|
||||
}
|
||||
|
@ -47,11 +64,11 @@ function checkForPlatformFailure(err: Error) {
|
|||
}
|
||||
}
|
||||
|
||||
function localName(branchName: string) {
|
||||
function localName(branchName: string): string {
|
||||
return branchName.replace(/^origin\//, '');
|
||||
}
|
||||
|
||||
function throwBaseBranchValidationError(branchName) {
|
||||
function throwBaseBranchValidationError(branchName: string): never {
|
||||
const error = new Error('config-validation');
|
||||
error.validationError = 'baseBranch not found';
|
||||
error.validationMessage =
|
||||
|
@ -66,7 +83,7 @@ export class Storage {
|
|||
|
||||
private _cwd: string | undefined;
|
||||
|
||||
private async _resetToBranch(branchName: string) {
|
||||
private async _resetToBranch(branchName: string): Promise<void> {
|
||||
logger.debug(`resetToBranch(${branchName})`);
|
||||
await this._git!.raw(['reset', '--hard']);
|
||||
await this._git!.checkout(branchName);
|
||||
|
@ -74,7 +91,7 @@ export class Storage {
|
|||
await this._git!.raw(['clean', '-fd']);
|
||||
}
|
||||
|
||||
private async _cleanLocalBranches() {
|
||||
private async _cleanLocalBranches(): Promise<void> {
|
||||
const existingBranches = (await this._git!.raw(['branch']))
|
||||
.split('\n')
|
||||
.map(branch => branch.trim())
|
||||
|
@ -86,7 +103,7 @@ export class Storage {
|
|||
}
|
||||
}
|
||||
|
||||
async initRepo(args: StorageConfig) {
|
||||
async initRepo(args: StorageConfig): Promise<void> {
|
||||
this.cleanRepo();
|
||||
// eslint-disable-next-line no-multi-assign
|
||||
const config: LocalConfig = (this._config = { ...args } as any);
|
||||
|
@ -98,7 +115,7 @@ export class Storage {
|
|||
let clone = true;
|
||||
|
||||
// TODO: move to private class scope
|
||||
async function determineBaseBranch(git: Git.SimpleGit) {
|
||||
async function determineBaseBranch(git: Git.SimpleGit): Promise<void> {
|
||||
// see https://stackoverflow.com/a/44750379/1438522
|
||||
try {
|
||||
config.baseBranch =
|
||||
|
@ -197,11 +214,11 @@ export class Storage {
|
|||
}
|
||||
|
||||
// istanbul ignore next
|
||||
getRepoStatus() {
|
||||
getRepoStatus(): Promise<StatusResult> {
|
||||
return this._git!.status();
|
||||
}
|
||||
|
||||
async createBranch(branchName: string, sha: string) {
|
||||
async createBranch(branchName: string, sha: string): Promise<void> {
|
||||
logger.debug(`createBranch(${branchName})`);
|
||||
await this._git!.reset('hard');
|
||||
await this._git!.raw(['clean', '-fd']);
|
||||
|
@ -211,7 +228,7 @@ export class Storage {
|
|||
}
|
||||
|
||||
// Return the commit SHA for a branch
|
||||
async getBranchCommit(branchName: string) {
|
||||
async getBranchCommit(branchName: string): Promise<string> {
|
||||
if (!(await this.branchExists(branchName))) {
|
||||
throw Error(
|
||||
'Cannot fetch commit for branch that does not exist: ' + branchName
|
||||
|
@ -221,7 +238,7 @@ export class Storage {
|
|||
return res.trim();
|
||||
}
|
||||
|
||||
async getCommitMessages() {
|
||||
async getCommitMessages(): Promise<string[]> {
|
||||
logger.debug('getCommitMessages');
|
||||
const res = await this._git!.log({
|
||||
n: 10,
|
||||
|
@ -230,7 +247,7 @@ export class Storage {
|
|||
return res.all.map(commit => commit.message);
|
||||
}
|
||||
|
||||
async setBaseBranch(branchName: string) {
|
||||
async setBaseBranch(branchName: string): Promise<void> {
|
||||
if (branchName) {
|
||||
if (!(await this.branchExists(branchName))) {
|
||||
throwBaseBranchValidationError(branchName);
|
||||
|
@ -266,7 +283,7 @@ export class Storage {
|
|||
* When we initially clone, we clone only the default branch so how no knowledge of other branches existing.
|
||||
* By calling this function once the repo's branchPrefix is known, we can fetch all of Renovate's branches in one command.
|
||||
*/
|
||||
async setBranchPrefix(branchPrefix: string) {
|
||||
async setBranchPrefix(branchPrefix: string): Promise<void> {
|
||||
logger.debug('Setting branchPrefix: ' + branchPrefix);
|
||||
this._config.branchPrefix = branchPrefix;
|
||||
const ref = `refs/heads/${branchPrefix}*:refs/remotes/origin/${branchPrefix}*`;
|
||||
|
@ -278,7 +295,7 @@ export class Storage {
|
|||
}
|
||||
}
|
||||
|
||||
async getFileList(branchName?: string) {
|
||||
async getFileList(branchName?: string): Promise<string[]> {
|
||||
const branch = branchName || this._config.baseBranch;
|
||||
const exists = await this.branchExists(branch);
|
||||
if (!exists) {
|
||||
|
@ -303,7 +320,7 @@ export class Storage {
|
|||
);
|
||||
}
|
||||
|
||||
async getSubmodules() {
|
||||
async getSubmodules(): Promise<string[]> {
|
||||
return (
|
||||
(await this._git!.raw([
|
||||
'config',
|
||||
|
@ -318,7 +335,7 @@ export class Storage {
|
|||
.filter((_e: string, i: number) => i % 2);
|
||||
}
|
||||
|
||||
async branchExists(branchName: string) {
|
||||
async branchExists(branchName: string): Promise<boolean> {
|
||||
// First check cache
|
||||
if (this._config.branchExists[branchName] !== undefined) {
|
||||
return this._config.branchExists[branchName];
|
||||
|
@ -349,14 +366,14 @@ export class Storage {
|
|||
}
|
||||
}
|
||||
|
||||
async getAllRenovateBranches(branchPrefix: string) {
|
||||
async getAllRenovateBranches(branchPrefix: string): Promise<string[]> {
|
||||
const branches = await this._git!.branch(['--remotes', '--verbose']);
|
||||
return branches.all
|
||||
.map(localName)
|
||||
.filter(branchName => branchName.startsWith(branchPrefix));
|
||||
}
|
||||
|
||||
async isBranchStale(branchName: string) {
|
||||
async isBranchStale(branchName: string): Promise<boolean> {
|
||||
if (!(await this.branchExists(branchName))) {
|
||||
throw Error(
|
||||
'Cannot check staleness for branch that does not exist: ' + branchName
|
||||
|
@ -371,11 +388,11 @@ export class Storage {
|
|||
return !branches.all.map(localName).includes(branchName);
|
||||
}
|
||||
|
||||
private async _deleteLocalBranch(branchName: string) {
|
||||
private async _deleteLocalBranch(branchName: string): Promise<void> {
|
||||
await this._git!.branch(['-D', branchName]);
|
||||
}
|
||||
|
||||
async deleteBranch(branchName: string) {
|
||||
async deleteBranch(branchName: string): Promise<void> {
|
||||
try {
|
||||
await this._git!.raw(['push', '--delete', 'origin', branchName]);
|
||||
logger.debug({ branchName }, 'Deleted remote branch');
|
||||
|
@ -394,7 +411,7 @@ export class Storage {
|
|||
this._config.branchExists[branchName] = false;
|
||||
}
|
||||
|
||||
async mergeBranch(branchName: string) {
|
||||
async mergeBranch(branchName: string): Promise<void> {
|
||||
await this._git!.reset('hard');
|
||||
await this._git!.checkout(['-B', branchName, 'origin/' + branchName]);
|
||||
await this._git!.checkout(this._config.baseBranch);
|
||||
|
@ -403,7 +420,7 @@ export class Storage {
|
|||
limits.incrementLimit('prCommitsPerRunLimit');
|
||||
}
|
||||
|
||||
async getBranchLastCommitTime(branchName: string) {
|
||||
async getBranchLastCommitTime(branchName: string): Promise<Date> {
|
||||
try {
|
||||
const time = await this._git!.show([
|
||||
'-s',
|
||||
|
@ -417,7 +434,7 @@ export class Storage {
|
|||
}
|
||||
}
|
||||
|
||||
async getFile(filePath: string, branchName?: string) {
|
||||
async getFile(filePath: string, branchName?: string): Promise<string | null> {
|
||||
if (branchName) {
|
||||
const exists = await this.branchExists(branchName);
|
||||
if (!exists) {
|
||||
|
@ -438,10 +455,10 @@ export class Storage {
|
|||
|
||||
async commitFilesToBranch(
|
||||
branchName: string,
|
||||
files: any[],
|
||||
files: File[],
|
||||
message: string,
|
||||
parentBranch = this._config.baseBranch
|
||||
) {
|
||||
): Promise<void> {
|
||||
logger.debug(`Committing files to branch ${branchName}`);
|
||||
try {
|
||||
await this._git!.reset('hard');
|
||||
|
@ -494,7 +511,7 @@ export class Storage {
|
|||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
cleanRepo() {}
|
||||
cleanRepo(): void {}
|
||||
|
||||
static getUrl({
|
||||
protocol,
|
||||
|
@ -508,7 +525,7 @@ export class Storage {
|
|||
hostname?: string;
|
||||
host?: string;
|
||||
repository: string;
|
||||
}) {
|
||||
}): string {
|
||||
if (protocol === 'ssh') {
|
||||
return `git@${hostname}:${repository}.git`;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import pAll from 'p-all';
|
|||
|
||||
import got from '../../util/got';
|
||||
import { maskToken } from '../../util/mask';
|
||||
import { GotApi } from '../common';
|
||||
import { GotApi, GotResponse } from '../common';
|
||||
import { logger } from '../../logger';
|
||||
|
||||
const hostType = 'github';
|
||||
|
@ -14,7 +14,7 @@ async function get(
|
|||
path: string,
|
||||
options?: any,
|
||||
okToRetry = true
|
||||
): Promise<any> {
|
||||
): Promise<GotResponse> {
|
||||
const opts = {
|
||||
hostType,
|
||||
baseUrl,
|
||||
|
@ -58,7 +58,7 @@ async function get(
|
|||
new Array(lastPage),
|
||||
(x, i) => i + 1
|
||||
).slice(1);
|
||||
const queue = pageNumbers.map(page => () => {
|
||||
const queue = pageNumbers.map(page => (): Promise<GotResponse> => {
|
||||
const nextUrl = URL.parse(linkHeader.next.url, true);
|
||||
delete nextUrl.search;
|
||||
nextUrl.query.page = page.toString();
|
||||
|
@ -163,11 +163,11 @@ async function get(
|
|||
const helpers = ['get', 'post', 'put', 'patch', 'head', 'delete'];
|
||||
|
||||
for (const x of helpers) {
|
||||
(get as any)[x] = (url: string, opts: any) =>
|
||||
(get as any)[x] = (url: string, opts: any): Promise<GotResponse> =>
|
||||
get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
|
||||
}
|
||||
|
||||
get.setBaseUrl = (u: string) => {
|
||||
get.setBaseUrl = (u: string): void => {
|
||||
baseUrl = u;
|
||||
};
|
||||
|
||||
|
|
|
@ -6,8 +6,14 @@ import URL from 'url';
|
|||
import { logger } from '../../logger';
|
||||
import { api } from './gh-got-wrapper';
|
||||
import * as hostRules from '../../util/host-rules';
|
||||
import GitStorage from '../git/storage';
|
||||
import { PlatformConfig, RepoParams, RepoConfig } from '../common';
|
||||
import GitStorage, { StatusResult, File } from '../git/storage';
|
||||
import {
|
||||
PlatformConfig,
|
||||
RepoParams,
|
||||
RepoConfig,
|
||||
Issue,
|
||||
VulnerabilityAlert,
|
||||
} from '../common';
|
||||
|
||||
import {
|
||||
appName,
|
||||
|
@ -50,8 +56,8 @@ interface LocalRepoConfig {
|
|||
parentRepo: string;
|
||||
baseCommitSHA: string | null;
|
||||
forkToken?: string;
|
||||
closedPrList: { [num: number]: Pr } | null;
|
||||
openPrList: { [num: number]: Pr } | null;
|
||||
closedPrList: PrList | null;
|
||||
openPrList: PrList | null;
|
||||
prList: Pr[] | null;
|
||||
issueList: any[] | null;
|
||||
mergeMethod: string;
|
||||
|
@ -66,6 +72,9 @@ interface LocalRepoConfig {
|
|||
renovateUsername: string;
|
||||
}
|
||||
|
||||
type BranchProtection = any;
|
||||
type PrList = Record<number, Pr>;
|
||||
|
||||
let config: LocalRepoConfig = {} as any;
|
||||
|
||||
const defaults = {
|
||||
|
@ -73,7 +82,8 @@ const defaults = {
|
|||
endpoint: 'https://api.github.com/',
|
||||
};
|
||||
|
||||
const escapeHash = input => (input ? input.replace(/#/g, '%23') : input);
|
||||
const escapeHash = (input: string): string =>
|
||||
input ? input.replace(/#/g, '%23') : input;
|
||||
|
||||
export async function initPlatform({
|
||||
endpoint,
|
||||
|
@ -81,7 +91,7 @@ export async function initPlatform({
|
|||
}: {
|
||||
endpoint: string;
|
||||
token: string;
|
||||
}) {
|
||||
}): Promise<PlatformConfig> {
|
||||
if (!token) {
|
||||
throw new Error('Init: You must configure a GitHub personal access token');
|
||||
}
|
||||
|
@ -130,7 +140,7 @@ export async function initPlatform({
|
|||
}
|
||||
|
||||
// Get all repositories that the user has access to
|
||||
export async function getRepos() {
|
||||
export async function getRepos(): Promise<string[]> {
|
||||
logger.info('Autodiscovering GitHub repositories');
|
||||
try {
|
||||
const res = await api.get('user/repos?per_page=100', { paginate: true });
|
||||
|
@ -141,7 +151,7 @@ export async function getRepos() {
|
|||
}
|
||||
}
|
||||
|
||||
export function cleanRepo() {
|
||||
export function cleanRepo(): void {
|
||||
// istanbul ignore if
|
||||
if (config.storage) {
|
||||
config.storage.cleanRepo();
|
||||
|
@ -150,7 +160,9 @@ export function cleanRepo() {
|
|||
config = {} as any;
|
||||
}
|
||||
|
||||
async function getBranchProtection(branchName: string) {
|
||||
async function getBranchProtection(
|
||||
branchName: string
|
||||
): Promise<BranchProtection> {
|
||||
// istanbul ignore if
|
||||
if (config.parentRepo) {
|
||||
return {};
|
||||
|
@ -162,7 +174,7 @@ async function getBranchProtection(branchName: string) {
|
|||
}
|
||||
|
||||
// Return the commit SHA for a branch
|
||||
async function getBranchCommit(branchName: string) {
|
||||
async function getBranchCommit(branchName: string): Promise<string> {
|
||||
try {
|
||||
const res = await api.get(
|
||||
`repos/${config.repository}/git/refs/heads/${escapeHash(branchName)}`
|
||||
|
@ -180,7 +192,7 @@ async function getBranchCommit(branchName: string) {
|
|||
}
|
||||
}
|
||||
|
||||
async function getBaseCommitSHA() {
|
||||
async function getBaseCommitSHA(): Promise<string> {
|
||||
if (!config.baseCommitSHA) {
|
||||
config.baseCommitSHA = await getBranchCommit(config.baseBranch);
|
||||
}
|
||||
|
@ -198,7 +210,7 @@ export async function initRepo({
|
|||
includeForks,
|
||||
renovateUsername,
|
||||
optimizeForDisabled,
|
||||
}: RepoParams) {
|
||||
}: RepoParams): Promise<RepoConfig> {
|
||||
logger.debug(`initRepo("${repository}")`);
|
||||
logger.info('Authenticated as user: ' + renovateUsername);
|
||||
logger.info('Using renovate version: ' + global.renovateVersion);
|
||||
|
@ -421,7 +433,7 @@ export async function initRepo({
|
|||
return repoConfig;
|
||||
}
|
||||
|
||||
export async function getRepoForceRebase() {
|
||||
export async function getRepoForceRebase(): Promise<boolean> {
|
||||
if (config.repoForceRebase === undefined) {
|
||||
try {
|
||||
config.repoForceRebase = false;
|
||||
|
@ -467,63 +479,73 @@ export async function getRepoForceRebase() {
|
|||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export async function setBaseBranch(branchName = config.baseBranch) {
|
||||
export async function setBaseBranch(
|
||||
branchName = config.baseBranch
|
||||
): Promise<void> {
|
||||
config.baseBranch = branchName;
|
||||
config.baseCommitSHA = null;
|
||||
await config.storage.setBaseBranch(branchName);
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export function setBranchPrefix(branchPrefix: string) {
|
||||
export function setBranchPrefix(branchPrefix: string): Promise<void> {
|
||||
return config.storage.setBranchPrefix(branchPrefix);
|
||||
}
|
||||
|
||||
// Search
|
||||
|
||||
// istanbul ignore next
|
||||
export function getFileList(branchName = config.baseBranch) {
|
||||
export function getFileList(branchName = config.baseBranch): Promise<string[]> {
|
||||
return config.storage.getFileList(branchName);
|
||||
}
|
||||
|
||||
// Branch
|
||||
|
||||
// istanbul ignore next
|
||||
export function branchExists(branchName: string) {
|
||||
export function branchExists(branchName: string): Promise<boolean> {
|
||||
return config.storage.branchExists(branchName);
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export function getAllRenovateBranches(branchPrefix: string) {
|
||||
export function getAllRenovateBranches(
|
||||
branchPrefix: string
|
||||
): Promise<string[]> {
|
||||
return config.storage.getAllRenovateBranches(branchPrefix);
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export function isBranchStale(branchName: string) {
|
||||
export function isBranchStale(branchName: string): Promise<boolean> {
|
||||
return config.storage.isBranchStale(branchName);
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export function getFile(filePath: string, branchName?: string) {
|
||||
export function getFile(
|
||||
filePath: string,
|
||||
branchName?: string
|
||||
): Promise<string> {
|
||||
return config.storage.getFile(filePath, branchName);
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export function deleteBranch(branchName: string, closePr?: boolean) {
|
||||
export function deleteBranch(
|
||||
branchName: string,
|
||||
closePr?: boolean
|
||||
): Promise<void> {
|
||||
return config.storage.deleteBranch(branchName);
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export function getBranchLastCommitTime(branchName: string) {
|
||||
export function getBranchLastCommitTime(branchName: string): Promise<Date> {
|
||||
return config.storage.getBranchLastCommitTime(branchName);
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export function getRepoStatus() {
|
||||
export function getRepoStatus(): Promise<StatusResult> {
|
||||
return config.storage.getRepoStatus();
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export function mergeBranch(branchName: string) {
|
||||
export function mergeBranch(branchName: string): Promise<void> {
|
||||
if (config.pushProtection) {
|
||||
logger.info(
|
||||
{ branch: branchName },
|
||||
|
@ -536,10 +558,10 @@ export function mergeBranch(branchName: string) {
|
|||
// istanbul ignore next
|
||||
export function commitFilesToBranch(
|
||||
branchName: string,
|
||||
files: any[],
|
||||
files: File[],
|
||||
message: string,
|
||||
parentBranch = config.baseBranch
|
||||
) {
|
||||
): Promise<void> {
|
||||
return config.storage.commitFilesToBranch(
|
||||
branchName,
|
||||
files,
|
||||
|
@ -549,11 +571,11 @@ export function commitFilesToBranch(
|
|||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export function getCommitMessages() {
|
||||
export function getCommitMessages(): Promise<string[]> {
|
||||
return config.storage.getCommitMessages();
|
||||
}
|
||||
|
||||
async function getClosedPrs() {
|
||||
async function getClosedPrs(): Promise<PrList> {
|
||||
if (!config.closedPrList) {
|
||||
config.closedPrList = {};
|
||||
let query;
|
||||
|
@ -619,7 +641,7 @@ async function getClosedPrs() {
|
|||
return config.closedPrList;
|
||||
}
|
||||
|
||||
async function getOpenPrs() {
|
||||
async function getOpenPrs(): Promise<PrList> {
|
||||
// istanbul ignore if
|
||||
if (config.isGhe) {
|
||||
logger.debug(
|
||||
|
@ -786,7 +808,7 @@ async function getOpenPrs() {
|
|||
}
|
||||
|
||||
// Gets details for a PR
|
||||
export async function getPr(prNo: number) {
|
||||
export async function getPr(prNo: number): Promise<Pr | null> {
|
||||
if (!prNo) {
|
||||
return null;
|
||||
}
|
||||
|
@ -896,7 +918,7 @@ export async function getPr(prNo: number) {
|
|||
return pr;
|
||||
}
|
||||
|
||||
function matchesState(state: string, desiredState: string) {
|
||||
function matchesState(state: string, desiredState: string): boolean {
|
||||
if (desiredState === 'all') {
|
||||
return true;
|
||||
}
|
||||
|
@ -906,7 +928,7 @@ function matchesState(state: string, desiredState: string) {
|
|||
return state === desiredState;
|
||||
}
|
||||
|
||||
export async function getPrList() {
|
||||
export async function getPrList(): Promise<Pr[]> {
|
||||
logger.trace('getPrList()');
|
||||
if (!config.prList) {
|
||||
logger.debug('Retrieving PR list');
|
||||
|
@ -948,7 +970,7 @@ export async function findPr(
|
|||
branchName: string,
|
||||
prTitle?: string | null,
|
||||
state = 'all'
|
||||
) {
|
||||
): Promise<Pr | null> {
|
||||
logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);
|
||||
const prList = await getPrList();
|
||||
const pr = prList.find(
|
||||
|
@ -964,7 +986,7 @@ export async function findPr(
|
|||
}
|
||||
|
||||
// Returns the Pull Request for a branch. Null if not exists.
|
||||
export async function getBranchPr(branchName: string) {
|
||||
export async function getBranchPr(branchName: string): Promise<Pr | null> {
|
||||
logger.debug(`getBranchPr(${branchName})`);
|
||||
const existingPr = await findPr(branchName, null, 'open');
|
||||
return existingPr ? getPr(existingPr.number) : null;
|
||||
|
@ -974,7 +996,7 @@ export async function getBranchPr(branchName: string) {
|
|||
export async function getBranchStatus(
|
||||
branchName: string,
|
||||
requiredStatusChecks: any
|
||||
) {
|
||||
): Promise<string> {
|
||||
logger.debug(`getBranchStatus(${branchName})`);
|
||||
if (!requiredStatusChecks) {
|
||||
// null means disable status checks, so it always succeeds
|
||||
|
@ -1066,7 +1088,7 @@ export async function getBranchStatus(
|
|||
export async function getBranchStatusCheck(
|
||||
branchName: string,
|
||||
context: string
|
||||
) {
|
||||
): Promise<string> {
|
||||
const branchCommit = await config.storage.getBranchCommit(branchName);
|
||||
const url = `repos/${config.repository}/commits/${branchCommit}/statuses`;
|
||||
try {
|
||||
|
@ -1092,7 +1114,7 @@ export async function setBranchStatus(
|
|||
description: string,
|
||||
state: string,
|
||||
targetUrl?: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
// istanbul ignore if
|
||||
if (config.parentRepo) {
|
||||
logger.info('Cannot set branch status when in forking mode');
|
||||
|
@ -1119,7 +1141,9 @@ export async function setBranchStatus(
|
|||
// Issue
|
||||
|
||||
/* istanbul ignore next */
|
||||
async function getGraphqlIssues(afterCursor: string | null = null) {
|
||||
async function getGraphqlIssues(
|
||||
afterCursor: string | null = null
|
||||
): Promise<[boolean, Issue[], string | null]> {
|
||||
const url = 'graphql';
|
||||
const headers = {
|
||||
accept: 'application/vnd.github.merge-info-preview+json',
|
||||
|
@ -1170,7 +1194,7 @@ async function getGraphqlIssues(afterCursor: string | null = null) {
|
|||
}
|
||||
|
||||
// istanbul ignore next
|
||||
async function getRestIssues() {
|
||||
async function getRestIssues(): Promise<Issue[]> {
|
||||
logger.debug('Retrieving issueList');
|
||||
const res = await api.get<
|
||||
{
|
||||
|
@ -1197,7 +1221,7 @@ async function getRestIssues() {
|
|||
}));
|
||||
}
|
||||
|
||||
export async function getIssueList() {
|
||||
export async function getIssueList(): Promise<Issue[]> {
|
||||
if (!config.issueList) {
|
||||
logger.debug('Retrieving issueList');
|
||||
const filterBySupportMinimumGheVersion = '2.17.0';
|
||||
|
@ -1228,7 +1252,7 @@ export async function getIssueList() {
|
|||
return config.issueList;
|
||||
}
|
||||
|
||||
export async function findIssue(title: string) {
|
||||
export async function findIssue(title: string): Promise<Issue | null> {
|
||||
logger.debug(`findIssue(${title})`);
|
||||
const [issue] = (await getIssueList()).filter(
|
||||
i => i.state === 'open' && i.title === title
|
||||
|
@ -1246,7 +1270,7 @@ export async function findIssue(title: string) {
|
|||
};
|
||||
}
|
||||
|
||||
async function closeIssue(issueNumber: number) {
|
||||
async function closeIssue(issueNumber: number): Promise<void> {
|
||||
logger.debug(`closeIssue(${issueNumber})`);
|
||||
await api.patch(
|
||||
`repos/${config.parentRepo || config.repository}/issues/${issueNumber}`,
|
||||
|
@ -1261,7 +1285,7 @@ export async function ensureIssue(
|
|||
rawbody: string,
|
||||
once = false,
|
||||
reopen = true
|
||||
) {
|
||||
): Promise<string | null> {
|
||||
logger.debug(`ensureIssue(${title})`);
|
||||
const body = sanitize(rawbody);
|
||||
try {
|
||||
|
@ -1332,7 +1356,7 @@ export async function ensureIssue(
|
|||
return null;
|
||||
}
|
||||
|
||||
export async function ensureIssueClosing(title: string) {
|
||||
export async function ensureIssueClosing(title: string): Promise<void> {
|
||||
logger.debug(`ensureIssueClosing(${title})`);
|
||||
const issueList = await getIssueList();
|
||||
for (const issue of issueList) {
|
||||
|
@ -1343,7 +1367,10 @@ export async function ensureIssueClosing(title: string) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function addAssignees(issueNo: number, assignees: string[]) {
|
||||
export async function addAssignees(
|
||||
issueNo: number,
|
||||
assignees: string[]
|
||||
): Promise<void> {
|
||||
logger.debug(`Adding assignees ${assignees} to #${issueNo}`);
|
||||
const repository = config.parentRepo || config.repository;
|
||||
await api.post(`repos/${repository}/issues/${issueNo}/assignees`, {
|
||||
|
@ -1353,7 +1380,10 @@ export async function addAssignees(issueNo: number, assignees: string[]) {
|
|||
});
|
||||
}
|
||||
|
||||
export async function addReviewers(prNo: number, reviewers: string[]) {
|
||||
export async function addReviewers(
|
||||
prNo: number,
|
||||
reviewers: string[]
|
||||
): Promise<void> {
|
||||
logger.debug(`Adding reviewers ${reviewers} to #${prNo}`);
|
||||
|
||||
const userReviewers = reviewers.filter(e => !e.startsWith('team:'));
|
||||
|
@ -1373,7 +1403,10 @@ export async function addReviewers(prNo: number, reviewers: string[]) {
|
|||
);
|
||||
}
|
||||
|
||||
async function addLabels(issueNo: number, labels: string[] | null) {
|
||||
async function addLabels(
|
||||
issueNo: number,
|
||||
labels: string[] | null
|
||||
): Promise<void> {
|
||||
logger.debug(`Adding labels ${labels} to #${issueNo}`);
|
||||
const repository = config.parentRepo || config.repository;
|
||||
if (is.array(labels) && labels.length) {
|
||||
|
@ -1383,7 +1416,10 @@ async function addLabels(issueNo: number, labels: string[] | null) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function deleteLabel(issueNo: number, label: string) {
|
||||
export async function deleteLabel(
|
||||
issueNo: number,
|
||||
label: string
|
||||
): Promise<void> {
|
||||
logger.debug(`Deleting label ${label} from #${issueNo}`);
|
||||
const repository = config.parentRepo || config.repository;
|
||||
try {
|
||||
|
@ -1393,7 +1429,7 @@ export async function deleteLabel(issueNo: number, label: string) {
|
|||
}
|
||||
}
|
||||
|
||||
async function addComment(issueNo: number, body: string) {
|
||||
async function addComment(issueNo: number, body: string): Promise<void> {
|
||||
// POST /repos/:owner/:repo/issues/:number/comments
|
||||
await api.post(
|
||||
`repos/${config.parentRepo ||
|
||||
|
@ -1404,7 +1440,7 @@ async function addComment(issueNo: number, body: string) {
|
|||
);
|
||||
}
|
||||
|
||||
async function editComment(commentId: number, body: string) {
|
||||
async function editComment(commentId: number, body: string): Promise<void> {
|
||||
// PATCH /repos/:owner/:repo/issues/comments/:id
|
||||
await api.patch(
|
||||
`repos/${config.parentRepo ||
|
||||
|
@ -1415,7 +1451,7 @@ async function editComment(commentId: number, body: string) {
|
|||
);
|
||||
}
|
||||
|
||||
async function deleteComment(commentId: number) {
|
||||
async function deleteComment(commentId: number): Promise<void> {
|
||||
// DELETE /repos/:owner/:repo/issues/comments/:id
|
||||
await api.delete(
|
||||
`repos/${config.parentRepo ||
|
||||
|
@ -1423,7 +1459,7 @@ async function deleteComment(commentId: number) {
|
|||
);
|
||||
}
|
||||
|
||||
async function getComments(issueNo: number) {
|
||||
async function getComments(issueNo: number): Promise<Comment[]> {
|
||||
const pr = (await getClosedPrs())[issueNo];
|
||||
if (pr) {
|
||||
logger.debug('Returning closed PR list comments');
|
||||
|
@ -1452,7 +1488,7 @@ export async function ensureComment(
|
|||
issueNo: number,
|
||||
topic: string | null,
|
||||
rawContent: string
|
||||
) {
|
||||
): Promise<boolean> {
|
||||
const content = sanitize(rawContent);
|
||||
try {
|
||||
const comments = await getComments(issueNo);
|
||||
|
@ -1509,10 +1545,13 @@ export async function ensureComment(
|
|||
}
|
||||
}
|
||||
|
||||
export async function ensureCommentRemoval(issueNo: number, topic: string) {
|
||||
export async function ensureCommentRemoval(
|
||||
issueNo: number,
|
||||
topic: string
|
||||
): Promise<void> {
|
||||
logger.debug(`Ensuring comment "${topic}" in #${issueNo} is removed`);
|
||||
const comments = await getComments(issueNo);
|
||||
let commentId;
|
||||
let commentId: number;
|
||||
comments.forEach(comment => {
|
||||
if (comment.body.startsWith(`### ${topic}\n\n`)) {
|
||||
commentId = comment.id;
|
||||
|
@ -1537,7 +1576,7 @@ export async function createPr(
|
|||
labels: string[] | null,
|
||||
useDefaultBranch: boolean,
|
||||
platformOptions: { statusCheckVerify?: boolean } = {}
|
||||
) {
|
||||
): Promise<Pr> {
|
||||
const body = sanitize(rawBody);
|
||||
const base = useDefaultBranch ? config.defaultBranch : config.baseBranch;
|
||||
// Include the repository owner to handle forkMode and regular mode
|
||||
|
@ -1583,7 +1622,7 @@ export async function createPr(
|
|||
}
|
||||
|
||||
// Return a list of all modified files in a PR
|
||||
export async function getPrFiles(prNo: number) {
|
||||
export async function getPrFiles(prNo: number): Promise<string[]> {
|
||||
logger.debug({ prNo }, 'getPrFiles');
|
||||
if (!prNo) {
|
||||
return [];
|
||||
|
@ -1594,7 +1633,11 @@ export async function getPrFiles(prNo: number) {
|
|||
return files.map((f: { filename: string }) => f.filename);
|
||||
}
|
||||
|
||||
export async function updatePr(prNo: number, title: string, rawBody?: string) {
|
||||
export async function updatePr(
|
||||
prNo: number,
|
||||
title: string,
|
||||
rawBody?: string
|
||||
): Promise<void> {
|
||||
logger.debug(`updatePr(${prNo}, ${title}, body)`);
|
||||
const body = sanitize(rawBody);
|
||||
const patchBody: any = { title };
|
||||
|
@ -1622,7 +1665,10 @@ export async function updatePr(prNo: number, title: string, rawBody?: string) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function mergePr(prNo: number, branchName: string) {
|
||||
export async function mergePr(
|
||||
prNo: number,
|
||||
branchName: string
|
||||
): Promise<boolean> {
|
||||
logger.debug(`mergePr(${prNo}, ${branchName})`);
|
||||
// istanbul ignore if
|
||||
if (config.isGhe && config.pushProtection) {
|
||||
|
@ -1721,7 +1767,7 @@ export async function mergePr(prNo: number, branchName: string) {
|
|||
return true;
|
||||
}
|
||||
|
||||
export function getPrBody(input: string) {
|
||||
export function getPrBody(input: string): string {
|
||||
if (config.isGhe) {
|
||||
return smartTruncate(input, 60000);
|
||||
}
|
||||
|
@ -1733,7 +1779,7 @@ export function getPrBody(input: string) {
|
|||
return smartTruncate(massagedInput, 60000);
|
||||
}
|
||||
|
||||
export async function getVulnerabilityAlerts() {
|
||||
export async function getVulnerabilityAlerts(): Promise<VulnerabilityAlert[]> {
|
||||
// istanbul ignore if
|
||||
if (config.isGhe) {
|
||||
logger.debug(
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import parseLinkHeader from 'parse-link-header';
|
||||
|
||||
import { GotApi } from '../common';
|
||||
import { GotApi, GotResponse } from '../common';
|
||||
import got from '../../util/got';
|
||||
import { logger } from '../../logger';
|
||||
|
||||
const hostType = 'gitlab';
|
||||
let baseUrl = 'https://gitlab.com/api/v4/';
|
||||
|
||||
async function get(path: string, options: any) {
|
||||
async function get(path: string, options: any): Promise<GotResponse> {
|
||||
const opts = {
|
||||
hostType,
|
||||
baseUrl,
|
||||
|
@ -60,11 +60,11 @@ interface GlGotApi
|
|||
export const api: GlGotApi = {} as any;
|
||||
|
||||
for (const x of helpers) {
|
||||
(api as any)[x] = (url: string, opts: any) =>
|
||||
(api as any)[x] = (url: string, opts: any): Promise<GotResponse> =>
|
||||
get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
|
||||
}
|
||||
|
||||
api.setBaseUrl = e => {
|
||||
api.setBaseUrl = (e: string): void => {
|
||||
baseUrl = e;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,21 +1,24 @@
|
|||
import URL, { URLSearchParams } from 'url';
|
||||
import is from '@sindresorhus/is';
|
||||
|
||||
import { bool } from 'aws-sdk/clients/signer';
|
||||
import simplegit from 'simple-git/promise';
|
||||
import { api } from './gl-got-wrapper';
|
||||
import * as hostRules from '../../util/host-rules';
|
||||
import GitStorage from '../git/storage';
|
||||
import GitStorage, { StatusResult } from '../git/storage';
|
||||
import {
|
||||
PlatformConfig,
|
||||
RepoParams,
|
||||
RepoConfig,
|
||||
PlatformPrOptions,
|
||||
GotResponse,
|
||||
Pr,
|
||||
Issue,
|
||||
VulnerabilityAlert,
|
||||
} from '../common';
|
||||
import { configFileNames } from '../../config/app-strings';
|
||||
import { logger } from '../../logger';
|
||||
import { sanitize } from '../../util/sanitize';
|
||||
import { smartTruncate } from '../utils/pr-body';
|
||||
import { RenovateConfig } from '../../config';
|
||||
|
||||
const defaultConfigFile = configFileNames[0];
|
||||
let config: {
|
||||
|
@ -43,7 +46,7 @@ export async function initPlatform({
|
|||
}: {
|
||||
token: string;
|
||||
endpoint: string;
|
||||
}): Promise<any> {
|
||||
}): Promise<PlatformConfig> {
|
||||
if (!token) {
|
||||
throw new Error('Init: You must configure a GitLab personal access token');
|
||||
}
|
||||
|
@ -73,7 +76,7 @@ export async function initPlatform({
|
|||
}
|
||||
|
||||
// Get all repositories that the user has access to
|
||||
export async function getRepos(): Promise<any> {
|
||||
export async function getRepos(): Promise<string[]> {
|
||||
logger.info('Autodiscovering GitLab repositories');
|
||||
try {
|
||||
const url = `projects?membership=true&per_page=100`;
|
||||
|
@ -92,7 +95,7 @@ function urlEscape(str: string): string {
|
|||
return str ? str.replace(/\//g, '%2F') : str;
|
||||
}
|
||||
|
||||
export function cleanRepo(): any {
|
||||
export function cleanRepo(): void {
|
||||
// istanbul ignore if
|
||||
if (config.storage) {
|
||||
config.storage.cleanRepo();
|
||||
|
@ -106,11 +109,17 @@ export async function initRepo({
|
|||
repository,
|
||||
localDir,
|
||||
optimizeForDisabled,
|
||||
}: RepoParams): Promise<any> {
|
||||
}: RepoParams): Promise<RepoConfig> {
|
||||
config = {} as any;
|
||||
config.repository = urlEscape(repository);
|
||||
config.localDir = localDir;
|
||||
let res;
|
||||
let res: GotResponse<{
|
||||
archived: boolean;
|
||||
mirror: boolean;
|
||||
default_branch: string;
|
||||
http_url_to_repo: string;
|
||||
forked_from_project: boolean;
|
||||
}>;
|
||||
try {
|
||||
res = await api.get(`projects/${config.repository}`);
|
||||
if (res.body.archived) {
|
||||
|
@ -129,7 +138,7 @@ export async function initRepo({
|
|||
throw new Error('empty');
|
||||
}
|
||||
if (optimizeForDisabled) {
|
||||
let renovateConfig;
|
||||
let renovateConfig: RenovateConfig;
|
||||
try {
|
||||
renovateConfig = JSON.parse(
|
||||
Buffer.from(
|
||||
|
@ -158,7 +167,7 @@ export async function initRepo({
|
|||
hostType: defaults.hostType,
|
||||
url: defaults.endpoint,
|
||||
});
|
||||
let url;
|
||||
let url: string;
|
||||
if (res.body.http_url_to_repo === null) {
|
||||
logger.debug('no http_url_to_repo found. Falling back to old behaviour.');
|
||||
const { host, protocol } = URL.parse(defaults.endpoint);
|
||||
|
@ -206,13 +215,13 @@ export async function initRepo({
|
|||
return repoConfig;
|
||||
}
|
||||
|
||||
export function getRepoForceRebase(): bool {
|
||||
export function getRepoForceRebase(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function setBaseBranch(
|
||||
branchName = config.baseBranch
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
logger.debug(`Setting baseBranch to ${branchName}`);
|
||||
config.baseBranch = branchName;
|
||||
await config.storage.setBaseBranch(branchName);
|
||||
|
@ -240,7 +249,7 @@ export function branchExists(branchName: string): Promise<boolean> {
|
|||
export async function getBranchStatus(
|
||||
branchName: string,
|
||||
requiredStatusChecks?: string[] | null
|
||||
) {
|
||||
): Promise<string> {
|
||||
logger.debug(`getBranchStatus(${branchName})`);
|
||||
if (!requiredStatusChecks) {
|
||||
// null means disable status checks, so it always succeeds
|
||||
|
@ -292,7 +301,7 @@ export async function createPr(
|
|||
labels?: string[] | null,
|
||||
useDefaultBranch?: boolean,
|
||||
platformOptions?: PlatformPrOptions
|
||||
) {
|
||||
): Promise<Pr> {
|
||||
const description = sanitize(rawDescription);
|
||||
const targetBranch = useDefaultBranch
|
||||
? config.defaultBranch
|
||||
|
@ -336,7 +345,7 @@ export async function createPr(
|
|||
return pr;
|
||||
}
|
||||
|
||||
export async function getPr(iid: number) {
|
||||
export async function getPr(iid: number): Promise<Pr> {
|
||||
logger.debug(`getPr(${iid})`);
|
||||
const url = `projects/${config.repository}/merge_requests/${iid}?include_diverged_commits_count=1`;
|
||||
const pr = (await api.get(url)).body;
|
||||
|
@ -389,7 +398,7 @@ export async function getPr(iid: number) {
|
|||
}
|
||||
|
||||
// Return a list of all modified files in a PR
|
||||
export async function getPrFiles(mrNo: number) {
|
||||
export async function getPrFiles(mrNo: number): Promise<string[]> {
|
||||
logger.debug({ mrNo }, 'getPrFiles');
|
||||
if (!mrNo) {
|
||||
return [];
|
||||
|
@ -401,7 +410,7 @@ export async function getPrFiles(mrNo: number) {
|
|||
}
|
||||
|
||||
// istanbul ignore next
|
||||
async function closePr(iid: number) {
|
||||
async function closePr(iid: number): Promise<void> {
|
||||
await api.put(`projects/${config.repository}/merge_requests/${iid}`, {
|
||||
body: {
|
||||
state_event: 'close',
|
||||
|
@ -413,7 +422,7 @@ export async function updatePr(
|
|||
iid: number,
|
||||
title: string,
|
||||
description: string
|
||||
) {
|
||||
): Promise<void> {
|
||||
await api.put(`projects/${config.repository}/merge_requests/${iid}`, {
|
||||
body: {
|
||||
title,
|
||||
|
@ -422,7 +431,7 @@ export async function updatePr(
|
|||
});
|
||||
}
|
||||
|
||||
export async function mergePr(iid: number) {
|
||||
export async function mergePr(iid: number): Promise<boolean> {
|
||||
try {
|
||||
await api.put(`projects/${config.repository}/merge_requests/${iid}/merge`, {
|
||||
body: {
|
||||
|
@ -445,7 +454,7 @@ export async function mergePr(iid: number) {
|
|||
}
|
||||
}
|
||||
|
||||
export function getPrBody(input: string) {
|
||||
export function getPrBody(input: string): string {
|
||||
return smartTruncate(
|
||||
input
|
||||
.replace(/Pull Request/g, 'Merge Request')
|
||||
|
@ -458,7 +467,7 @@ export function getPrBody(input: string) {
|
|||
// Branch
|
||||
|
||||
// Returns the Pull Request for a branch. Null if not exists.
|
||||
export async function getBranchPr(branchName: string): Promise<any> {
|
||||
export async function getBranchPr(branchName: string): Promise<Pr> {
|
||||
logger.debug(`getBranchPr(${branchName})`);
|
||||
// istanbul ignore if
|
||||
if (!(await branchExists(branchName))) {
|
||||
|
@ -518,7 +527,7 @@ export function getFile(
|
|||
export async function deleteBranch(
|
||||
branchName: string,
|
||||
shouldClosePr = false
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (shouldClosePr) {
|
||||
logger.debug('Closing PR');
|
||||
const pr = await getBranchPr(branchName);
|
||||
|
@ -539,14 +548,14 @@ export function getBranchLastCommitTime(branchName: string): Promise<Date> {
|
|||
}
|
||||
|
||||
// istanbul ignore next
|
||||
export function getRepoStatus(): Promise<simplegit.StatusResult> {
|
||||
export function getRepoStatus(): Promise<StatusResult> {
|
||||
return config.storage.getRepoStatus();
|
||||
}
|
||||
|
||||
export async function getBranchStatusCheck(
|
||||
branchName: string,
|
||||
context: string
|
||||
): Promise<any> {
|
||||
): Promise<string | null> {
|
||||
// First, get the branch commit SHA
|
||||
const branchSha = await config.storage.getBranchCommit(branchName);
|
||||
// Now, check the statuses for that commit
|
||||
|
@ -623,12 +632,7 @@ export async function getIssueList(): Promise<any[]> {
|
|||
return config.issueList;
|
||||
}
|
||||
|
||||
export async function findIssue(
|
||||
title: string
|
||||
): Promise<{
|
||||
number: any;
|
||||
body: any;
|
||||
}> {
|
||||
export async function findIssue(title: string): Promise<Issue | null> {
|
||||
logger.debug(`findIssue(${title})`);
|
||||
try {
|
||||
const issueList = await getIssueList();
|
||||
|
@ -652,7 +656,7 @@ export async function findIssue(
|
|||
export async function ensureIssue(
|
||||
title: string,
|
||||
body: string
|
||||
): Promise<'updated' | 'created'> {
|
||||
): Promise<'updated' | 'created' | null> {
|
||||
logger.debug(`ensureIssue()`);
|
||||
const description = getPrBody(sanitize(body));
|
||||
try {
|
||||
|
@ -706,7 +710,7 @@ export async function ensureIssueClosing(title: string): Promise<void> {
|
|||
export async function addAssignees(
|
||||
iid: number,
|
||||
assignees: string[]
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
logger.debug(`Adding assignees ${assignees} to #${iid}`);
|
||||
try {
|
||||
let assigneeId = (await api.get(`users?username=${assignees[0]}`)).body[0]
|
||||
|
@ -731,7 +735,7 @@ export async function addAssignees(
|
|||
}
|
||||
}
|
||||
|
||||
export function addReviewers(iid: number, reviewers: string[]): any {
|
||||
export function addReviewers(iid: number, reviewers: string[]): void {
|
||||
logger.debug(`addReviewers('${iid}, '${reviewers})`);
|
||||
logger.warn('Unimplemented in GitLab: approvals');
|
||||
}
|
||||
|
@ -739,7 +743,7 @@ export function addReviewers(iid: number, reviewers: string[]): any {
|
|||
export async function deleteLabel(
|
||||
issueNo: number,
|
||||
label: string
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
logger.debug(`Deleting label ${label} from #${issueNo}`);
|
||||
try {
|
||||
const pr = await getPr(issueNo);
|
||||
|
@ -752,7 +756,7 @@ export async function deleteLabel(
|
|||
}
|
||||
}
|
||||
|
||||
async function getComments(issueNo: number): Promise<any> {
|
||||
async function getComments(issueNo: number): Promise<any[]> {
|
||||
// GET projects/:owner/:repo/merge_requests/:number/notes
|
||||
logger.debug(`Getting comments for #${issueNo}`);
|
||||
const url = `projects/${config.repository}/merge_requests/${issueNo}/notes`;
|
||||
|
@ -761,7 +765,7 @@ async function getComments(issueNo: number): Promise<any> {
|
|||
return comments;
|
||||
}
|
||||
|
||||
async function addComment(issueNo: number, body: string): Promise<any> {
|
||||
async function addComment(issueNo: number, body: string): Promise<void> {
|
||||
// POST projects/:owner/:repo/merge_requests/:number/notes
|
||||
await api.post(
|
||||
`projects/${config.repository}/merge_requests/${issueNo}/notes`,
|
||||
|
@ -775,7 +779,7 @@ async function editComment(
|
|||
issueNo: number,
|
||||
commentId: number,
|
||||
body: string
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
// PUT projects/:owner/:repo/merge_requests/:number/notes/:id
|
||||
await api.put(
|
||||
`projects/${config.repository}/merge_requests/${issueNo}/notes/${commentId}`,
|
||||
|
@ -785,7 +789,10 @@ async function editComment(
|
|||
);
|
||||
}
|
||||
|
||||
async function deleteComment(issueNo: number, commentId: number): Promise<any> {
|
||||
async function deleteComment(
|
||||
issueNo: number,
|
||||
commentId: number
|
||||
): Promise<void> {
|
||||
// DELETE projects/:owner/:repo/merge_requests/:number/notes/:id
|
||||
await api.delete(
|
||||
`projects/${config.repository}/merge_requests/${issueNo}/notes/${commentId}`
|
||||
|
@ -796,7 +803,7 @@ export async function ensureComment(
|
|||
issueNo: number,
|
||||
topic: string | null | undefined,
|
||||
rawContent: string
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
const content = sanitize(rawContent);
|
||||
const massagedTopic = topic
|
||||
? topic.replace(/Pull Request/g, 'Merge Request').replace(/PR/g, 'MR')
|
||||
|
@ -839,7 +846,7 @@ export async function ensureComment(
|
|||
export async function ensureCommentRemoval(
|
||||
issueNo: number,
|
||||
topic: string
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
logger.debug(`Ensuring comment "${topic}" in #${issueNo} is removed`);
|
||||
const comments = await getComments(issueNo);
|
||||
let commentId;
|
||||
|
@ -859,7 +866,7 @@ const mapPullRequests = (pr: {
|
|||
title: string;
|
||||
state: string;
|
||||
created_at: string;
|
||||
}) => ({
|
||||
}): Pr => ({
|
||||
number: pr.iid,
|
||||
branchName: pr.source_branch,
|
||||
title: pr.title,
|
||||
|
@ -867,7 +874,7 @@ const mapPullRequests = (pr: {
|
|||
createdAt: pr.created_at,
|
||||
});
|
||||
|
||||
async function fetchPrList(): Promise<any> {
|
||||
async function fetchPrList(): Promise<Pr[]> {
|
||||
const query = new URLSearchParams({
|
||||
per_page: '100',
|
||||
author_id: `${authorId}`,
|
||||
|
@ -885,14 +892,14 @@ async function fetchPrList(): Promise<any> {
|
|||
}
|
||||
}
|
||||
|
||||
export async function getPrList(): Promise<any> {
|
||||
export async function getPrList(): Promise<Pr[]> {
|
||||
if (!config.prList) {
|
||||
config.prList = await fetchPrList();
|
||||
}
|
||||
return config.prList;
|
||||
}
|
||||
|
||||
function matchesState(state: string, desiredState: string): bool {
|
||||
function matchesState(state: string, desiredState: string): boolean {
|
||||
if (desiredState === 'all') {
|
||||
return true;
|
||||
}
|
||||
|
@ -906,7 +913,7 @@ export async function findPr(
|
|||
branchName: string,
|
||||
prTitle?: string | null,
|
||||
state = 'all'
|
||||
): Promise<any> {
|
||||
): Promise<Pr> {
|
||||
logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);
|
||||
const prList = await getPrList();
|
||||
return prList.find(
|
||||
|
@ -921,6 +928,6 @@ export function getCommitMessages(): Promise<string[]> {
|
|||
return config.storage.getCommitMessages();
|
||||
}
|
||||
|
||||
export function getVulnerabilityAlerts(): any[] {
|
||||
export function getVulnerabilityAlerts(): VulnerabilityAlert[] {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -91,5 +91,5 @@ export const isOnboarded = async (config: RenovateConfig): Promise<boolean> => {
|
|||
throw new Error('disabled');
|
||||
};
|
||||
|
||||
export const onboardingPrExists = (): Promise<boolean> =>
|
||||
platform.getBranchPr(onboardingBranch);
|
||||
export const onboardingPrExists = async (): Promise<boolean> =>
|
||||
(await platform.getBranchPr(onboardingBranch)) != null;
|
||||
|
|
|
@ -14,36 +14,6 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`platform/azure/helpers getChanges should be get the commit obj formated (file to create) 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"changeType": 1,
|
||||
"item": Object {
|
||||
"path": "./myFilePath/test",
|
||||
},
|
||||
"newContent": Object {
|
||||
"Content": "Hello world!",
|
||||
"ContentType": 0,
|
||||
},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`platform/azure/helpers getChanges should be get the commit obj formated (file to update) 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"changeType": 2,
|
||||
"item": Object {
|
||||
"path": "./myFilePath/test",
|
||||
},
|
||||
"newContent": Object {
|
||||
"Content": "Hello world!",
|
||||
"ContentType": 0,
|
||||
},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`platform/azure/helpers getCommitDetails should get commit details 1`] = `
|
||||
Object {
|
||||
"parents": Array [
|
||||
|
|
|
@ -105,63 +105,6 @@ describe('platform/azure/helpers', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('getChanges', () => {
|
||||
it('should be get the commit obj formated (file to update)', async () => {
|
||||
let eventCount = 0;
|
||||
const mockEventStream = new Readable({
|
||||
objectMode: true,
|
||||
/* eslint-disable func-names */
|
||||
/* eslint-disable object-shorthand */
|
||||
read: function() {
|
||||
if (eventCount < 1) {
|
||||
eventCount += 1;
|
||||
return this.push('{"hello": "test"}');
|
||||
}
|
||||
return this.push(null);
|
||||
},
|
||||
});
|
||||
|
||||
azureApi.gitApi.mockImplementationOnce(
|
||||
() =>
|
||||
({
|
||||
getItemText: jest.fn(() => mockEventStream),
|
||||
} as any)
|
||||
);
|
||||
|
||||
const res = await azureHelper.getChanges(
|
||||
[
|
||||
{
|
||||
name: './myFilePath/test',
|
||||
contents: 'Hello world!',
|
||||
},
|
||||
],
|
||||
'123',
|
||||
'repository'
|
||||
);
|
||||
expect(res).toMatchSnapshot();
|
||||
});
|
||||
it('should be get the commit obj formated (file to create)', async () => {
|
||||
azureApi.gitApi.mockImplementationOnce(
|
||||
() =>
|
||||
({
|
||||
getItemText: jest.fn(() => null),
|
||||
} as any)
|
||||
);
|
||||
|
||||
const res = await azureHelper.getChanges(
|
||||
[
|
||||
{
|
||||
name: './myFilePath/test',
|
||||
contents: 'Hello world!',
|
||||
},
|
||||
],
|
||||
'123',
|
||||
'repository'
|
||||
);
|
||||
expect(res).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFile', () => {
|
||||
it('should return null error GitItemNotFoundException', async () => {
|
||||
let eventCount = 0;
|
||||
|
|
|
@ -215,12 +215,15 @@ describe('platform/azure', () => {
|
|||
azureHelper.getNewBranchName.mockImplementationOnce(
|
||||
() => 'refs/heads/branch-a'
|
||||
);
|
||||
azureHelper.getRenovatePRFormat.mockImplementationOnce(() => ({
|
||||
number: 1,
|
||||
head: { ref: 'branch-a' },
|
||||
title: 'branch a pr',
|
||||
state: 'open',
|
||||
}));
|
||||
azureHelper.getRenovatePRFormat.mockImplementationOnce(
|
||||
() =>
|
||||
({
|
||||
number: 1,
|
||||
head: { ref: 'branch-a' },
|
||||
title: 'branch a pr',
|
||||
state: 'open',
|
||||
} as any)
|
||||
);
|
||||
const res = await azure.findPr('branch-a', 'branch a pr', 'open');
|
||||
expect(res).toMatchSnapshot();
|
||||
});
|
||||
|
@ -241,12 +244,15 @@ describe('platform/azure', () => {
|
|||
azureHelper.getNewBranchName.mockImplementationOnce(
|
||||
() => 'refs/heads/branch-a'
|
||||
);
|
||||
azureHelper.getRenovatePRFormat.mockImplementationOnce(() => ({
|
||||
number: 1,
|
||||
head: { ref: 'branch-a' },
|
||||
title: 'branch a pr',
|
||||
state: 'closed',
|
||||
}));
|
||||
azureHelper.getRenovatePRFormat.mockImplementationOnce(
|
||||
() =>
|
||||
({
|
||||
number: 1,
|
||||
head: { ref: 'branch-a' },
|
||||
title: 'branch a pr',
|
||||
state: 'closed',
|
||||
} as any)
|
||||
);
|
||||
const res = await azure.findPr('branch-a', 'branch a pr', '!open');
|
||||
expect(res).toMatchSnapshot();
|
||||
});
|
||||
|
@ -267,12 +273,15 @@ describe('platform/azure', () => {
|
|||
azureHelper.getNewBranchName.mockImplementationOnce(
|
||||
() => 'refs/heads/branch-a'
|
||||
);
|
||||
azureHelper.getRenovatePRFormat.mockImplementationOnce(() => ({
|
||||
number: 1,
|
||||
head: { ref: 'branch-a' },
|
||||
title: 'branch a pr',
|
||||
state: 'closed',
|
||||
}));
|
||||
azureHelper.getRenovatePRFormat.mockImplementationOnce(
|
||||
() =>
|
||||
({
|
||||
number: 1,
|
||||
head: { ref: 'branch-a' },
|
||||
title: 'branch a pr',
|
||||
state: 'closed',
|
||||
} as any)
|
||||
);
|
||||
const res = await azure.findPr('branch-a', 'branch a pr', 'closed');
|
||||
expect(res).toMatchSnapshot();
|
||||
});
|
||||
|
@ -293,12 +302,15 @@ describe('platform/azure', () => {
|
|||
azureHelper.getNewBranchName.mockImplementationOnce(
|
||||
() => 'refs/heads/branch-a'
|
||||
);
|
||||
azureHelper.getRenovatePRFormat.mockImplementationOnce(() => ({
|
||||
number: 1,
|
||||
head: { ref: 'branch-a' },
|
||||
title: 'branch a pr',
|
||||
state: 'closed',
|
||||
}));
|
||||
azureHelper.getRenovatePRFormat.mockImplementationOnce(
|
||||
() =>
|
||||
({
|
||||
number: 1,
|
||||
head: { ref: 'branch-a' },
|
||||
title: 'branch a pr',
|
||||
state: 'closed',
|
||||
} as any)
|
||||
);
|
||||
const res = await azure.findPr('branch-a', 'branch a pr');
|
||||
expect(res).toMatchSnapshot();
|
||||
});
|
||||
|
@ -342,13 +354,16 @@ describe('platform/azure', () => {
|
|||
azureHelper.getNewBranchName.mockImplementation(
|
||||
() => 'refs/heads/branch-a'
|
||||
);
|
||||
azureHelper.getRenovatePRFormat.mockImplementation(() => ({
|
||||
pullRequestId: 1,
|
||||
number: 1,
|
||||
head: { ref: 'branch-a' },
|
||||
title: 'branch a pr',
|
||||
isClosed: false,
|
||||
}));
|
||||
azureHelper.getRenovatePRFormat.mockImplementation(
|
||||
() =>
|
||||
({
|
||||
pullRequestId: 1,
|
||||
number: 1,
|
||||
head: { ref: 'branch-a' },
|
||||
title: 'branch a pr',
|
||||
isClosed: false,
|
||||
} as any)
|
||||
);
|
||||
const pr = await azure.getBranchPr('somebranch');
|
||||
expect(pr).toMatchSnapshot();
|
||||
});
|
||||
|
@ -416,10 +431,13 @@ describe('platform/azure', () => {
|
|||
]),
|
||||
} as any)
|
||||
);
|
||||
azureHelper.getRenovatePRFormat.mockImplementation(() => ({
|
||||
pullRequestId: 1234,
|
||||
labels: ['renovate'],
|
||||
}));
|
||||
azureHelper.getRenovatePRFormat.mockImplementation(
|
||||
() =>
|
||||
({
|
||||
pullRequestId: 1234,
|
||||
labels: ['renovate'],
|
||||
} as any)
|
||||
);
|
||||
const pr = await azure.getPr(1234);
|
||||
expect(pr).toMatchSnapshot();
|
||||
});
|
||||
|
@ -438,11 +456,14 @@ describe('platform/azure', () => {
|
|||
createPullRequestLabel: jest.fn(() => ({})),
|
||||
} as any)
|
||||
);
|
||||
azureHelper.getRenovatePRFormat.mockImplementation(() => ({
|
||||
displayNumber: 'Pull Request #456',
|
||||
number: 456,
|
||||
pullRequestId: 456,
|
||||
}));
|
||||
azureHelper.getRenovatePRFormat.mockImplementation(
|
||||
() =>
|
||||
({
|
||||
displayNumber: 'Pull Request #456',
|
||||
number: 456,
|
||||
pullRequestId: 456,
|
||||
} as any)
|
||||
);
|
||||
const pr = await azure.createPr(
|
||||
'some-branch',
|
||||
'The Title',
|
||||
|
@ -463,11 +484,14 @@ describe('platform/azure', () => {
|
|||
createPullRequestLabel: jest.fn(() => ({})),
|
||||
} as any)
|
||||
);
|
||||
azureHelper.getRenovatePRFormat.mockImplementation(() => ({
|
||||
displayNumber: 'Pull Request #456',
|
||||
number: 456,
|
||||
pullRequestId: 456,
|
||||
}));
|
||||
azureHelper.getRenovatePRFormat.mockImplementation(
|
||||
() =>
|
||||
({
|
||||
displayNumber: 'Pull Request #456',
|
||||
number: 456,
|
||||
pullRequestId: 456,
|
||||
} as any)
|
||||
);
|
||||
const pr = await azure.createPr(
|
||||
'some-branch',
|
||||
'The Title',
|
||||
|
@ -507,7 +531,7 @@ describe('platform/azure', () => {
|
|||
updatePullRequest: updateFn,
|
||||
} as any)
|
||||
);
|
||||
azureHelper.getRenovatePRFormat.mockImplementation(x => x);
|
||||
azureHelper.getRenovatePRFormat.mockImplementation(x => x as any);
|
||||
const pr = await azure.createPr(
|
||||
'some-branch',
|
||||
'The Title',
|
||||
|
|
|
@ -211,7 +211,11 @@ describe('platform/bitbucket-server', () => {
|
|||
it('sends to gitFs', async () => {
|
||||
expect.assertions(1);
|
||||
await initRepo();
|
||||
await bitbucket.commitFilesToBranch('some-branch', [{}], 'message');
|
||||
await bitbucket.commitFilesToBranch(
|
||||
'some-branch',
|
||||
[{ name: 'test', contents: 'dummy' }],
|
||||
'message'
|
||||
);
|
||||
expect(api.get.mock.calls).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -260,7 +260,7 @@ describe('platform/gitlab', () => {
|
|||
describe('setBaseBranch(branchName)', () => {
|
||||
it('sets the base branch', async () => {
|
||||
await initRepo();
|
||||
await gitlab.setBaseBranch('some-branch');
|
||||
await gitlab.setBaseBranch();
|
||||
expect(api.get.mock.calls).toMatchSnapshot();
|
||||
});
|
||||
it('uses default base branch', async () => {
|
||||
|
|
|
@ -40,7 +40,7 @@ describe('lib/workers/global/autodiscover', () => {
|
|||
hostRules.find = jest.fn(() => ({
|
||||
token: 'abc',
|
||||
}));
|
||||
ghApi.getRepos = jest.fn(() => Promise.resolve([{}, {}]));
|
||||
ghApi.getRepos = jest.fn(() => Promise.resolve(['a', 'b']));
|
||||
const res = await autodiscoverRepositories(config);
|
||||
expect(res.repositories).toHaveLength(2);
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче