feat(worker): convert 'branch' to typescript (#4449)

Co-Authored-By: Jamie Magee <JamieMagee@users.noreply.github.com>
This commit is contained in:
Michael Kriese 2019-10-18 14:30:51 +02:00 committed by Rhys Arkins
parent 4d6b98f9b0
commit 2a4de19c77
12 changed files with 165 additions and 91 deletions

View file

@ -157,7 +157,7 @@ export interface Upgrade<T = Record<string, any>>
version?: string;
}
interface ArtifactError {
export interface ArtifactError {
lockFile?: string;
stderr?: string;
}

View file

@ -2,6 +2,11 @@ import got from 'got';
import Git from 'simple-git/promise';
import { RenovateConfig } from '../config/common';
export interface FileData {
name: string;
contents: string;
}
export interface GotApiOptions {
useCache?: boolean;
hostType?: string;

View file

@ -1,11 +1,18 @@
const { logger } = require('../../logger');
const { platform } = require('../../platform');
import { logger } from '../../logger';
import { RenovateConfig } from '../../config';
import { platform } from '../../platform';
module.exports = {
tryBranchAutomerge,
};
export type AutomergeResult =
| 'automerged'
| 'automerge aborted - PR exists'
| 'branch status error'
| 'failed'
| 'no automerge'
| 'not ready';
async function tryBranchAutomerge(config) {
export async function tryBranchAutomerge(
config: RenovateConfig
): Promise<AutomergeResult> {
logger.debug('Checking if we can automerge branch');
if (!(config.automerge && config.automergeType === 'branch')) {
return 'no automerge';

View file

@ -1,11 +1,11 @@
const { logger } = require('../../logger');
const { platform } = require('../../platform');
import { logger } from '../../logger';
import { RenovateConfig } from '../../config';
import { platform } from '../../platform';
module.exports = {
prAlreadyExisted,
};
async function prAlreadyExisted(config) {
/** TODO: Proper return type */
export async function prAlreadyExisted(
config: RenovateConfig
): Promise<any | null> {
logger.trace({ config }, 'prAlreadyExisted');
if (config.recreateClosed) {
logger.debug('recreateClosed is true');

View file

@ -1,12 +1,21 @@
import is from '@sindresorhus/is';
import { platform } from '../../platform';
import minimatch from 'minimatch';
import { FileData, platform } from '../../platform';
import { logger } from '../../logger';
import { RenovateConfig } from '../../config';
const minimatch = require('minimatch');
const { logger } = require('../../logger');
export type CommitConfig = RenovateConfig & {
baseBranch?: string;
branchName: string;
commitMessage: string;
excludeCommitPaths?: string[];
updatedPackageFiles: FileData[];
updatedArtifacts: FileData[];
};
export { commitFilesToBranch };
async function commitFilesToBranch(config) {
export async function commitFilesToBranch(
config: CommitConfig
): Promise<boolean> {
let updatedFiles = config.updatedPackageFiles.concat(config.updatedArtifacts);
// istanbul ignore if
if (is.nonEmptyArray(config.excludeCommitPaths)) {

View file

@ -1,17 +1,25 @@
import is from '@sindresorhus/is';
import { platform } from '../../platform';
import { FileData, platform } from '../../platform';
import { logger } from '../../logger';
import { get } from '../../manager';
import { RenovateConfig } from '../../config';
import { UpdateArtifactsConfig, ArtifactError } from '../../manager/common';
const { logger } = require('../../logger');
const { get } = require('../../manager');
export interface PackageFilesResult {
artifactErrors: ArtifactError[];
parentBranch: string;
updatedPackageFiles: FileData[];
updatedArtifacts: FileData[];
}
export { getUpdatedPackageFiles };
async function getUpdatedPackageFiles(config) {
export async function getUpdatedPackageFiles(
config: RenovateConfig & UpdateArtifactsConfig
): Promise<PackageFilesResult> {
logger.debug('manager.getUpdatedPackageFiles()');
logger.trace({ config });
const updatedFileContents = {};
const packageFileManagers = {};
const packageFileUpdatedDeps = {};
const updatedFileContents: Record<string, string> = {};
const packageFileManagers: Record<string, string> = {};
const packageFileUpdatedDeps: Record<string, string[]> = {};
const lockFileMaintenanceFiles = [];
for (const upgrade of config.upgrades) {
const { manager, packageFile, depName } = upgrade;
@ -68,8 +76,8 @@ async function getUpdatedPackageFiles(config) {
name,
contents: updatedFileContents[name],
}));
const updatedArtifacts = [];
const artifactErrors = [];
const updatedArtifacts: FileData[] = [];
const artifactErrors: ArtifactError[] = [];
for (const packageFile of updatedPackageFiles) {
const manager = packageFileManagers[packageFile.name];
const updatedDeps = packageFileUpdatedDeps[packageFile.name];
@ -82,7 +90,7 @@ async function getUpdatedPackageFiles(config) {
config
);
if (is.nonEmptyArray(results)) {
for (/** @type any */ const res of results) {
for (const res of results) {
const { file, artifactError } = res;
if (file) {
updatedArtifacts.push(file);
@ -109,7 +117,7 @@ async function getUpdatedPackageFiles(config) {
config
);
if (is.nonEmptyArray(results)) {
for (/** @type any */ const res of results) {
for (const res of results) {
const { file, artifactError } = res;
if (file) {
updatedArtifacts.push(file);

View file

@ -1,26 +1,52 @@
const { DateTime } = require('luxon');
import { DateTime } from 'luxon';
const { logger, setMeta } = require('../../logger');
const schedule = require('./schedule');
const { getUpdatedPackageFiles } = require('./get-updated');
const { getAdditionalFiles } = require('../../manager/npm/post-update');
const { commitFilesToBranch } = require('./commit');
const { getParentBranch } = require('./parent');
const { tryBranchAutomerge } = require('./automerge');
const { setStability, setUnpublishable } = require('./status-checks');
const { prAlreadyExisted } = require('./check-existing');
const prWorker = require('../pr');
const { appName, appSlug } = require('../../config/app-strings');
const { platform } = require('../../platform');
const { emojify } = require('../../util/emoji');
import { logger, setMeta } from '../../logger';
import { isScheduledNow } from './schedule';
import { getUpdatedPackageFiles } from './get-updated';
import {
getAdditionalFiles,
AdditionalPackageFiles,
} from '../../manager/npm/post-update';
import { commitFilesToBranch, CommitConfig } from './commit';
import { getParentBranch } from './parent';
import { tryBranchAutomerge } from './automerge';
import {
setStability,
setUnpublishable,
StabilityConfig,
UnpublishableConfig,
} from './status-checks';
import { prAlreadyExisted } from './check-existing';
import { ensurePr, checkAutoMerge } from '../pr';
import { appName, appSlug } from '../../config/app-strings';
import { RenovateConfig } from '../../config';
import { platform } from '../../platform';
import { emojify } from '../../util/emoji';
const { isScheduledNow } = schedule;
export type BranchConfig = RenovateConfig &
StabilityConfig &
UnpublishableConfig &
CommitConfig;
module.exports = {
processBranch,
};
export type ProcessBranchResult =
| 'already-existed'
| 'automerged'
| 'done'
| 'error'
| 'needs-approval'
| 'needs-pr-approval'
| 'not-scheduled'
| 'no-work'
| 'pending'
| 'pr-created'
| 'pr-edited'
| 'pr-hourly-limit-reached';
async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
export async function processBranch(
branchConfig: BranchConfig,
prHourlyLimitReached?: boolean,
packageFiles?: AdditionalPackageFiles
): Promise<ProcessBranchResult> {
const config = { ...branchConfig };
const dependencies = config.upgrades
.map(upgrade => upgrade.depName)
@ -418,7 +444,7 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
logger.debug(
`There are ${config.errors.length} errors and ${config.warnings.length} warnings`
);
const pr = await prWorker.ensurePr(config);
const pr = await ensurePr(config);
// TODO: ensurePr should check for automerge itself
if (pr === 'needs-pr-approval') {
return 'needs-pr-approval';
@ -504,7 +530,7 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
await platform.ensureCommentRemoval(pr.number, topic);
}
}
const prAutomerged = await prWorker.checkAutoMerge(pr, config);
const prAutomerged = await checkAutoMerge(pr, config);
if (prAutomerged) {
return 'automerged';
}
@ -530,7 +556,8 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
return 'done';
}
function rebaseCheck(config, branchPr) {
// TODO: proper typings
function rebaseCheck(config: RenovateConfig, branchPr: any): boolean {
const titleRebase = branchPr.title && branchPr.title.startsWith('rebase!');
const labelRebase =
branchPr.labels && branchPr.labels.includes(config.rebaseLabel);

View file

@ -1,12 +1,13 @@
const { logger } = require('../../logger');
const { appSlug } = require('../../config/app-strings');
const { platform } = require('../../platform');
import { logger } from '../../logger';
import { appSlug } from '../../config/app-strings';
import { RenovateConfig } from '../../config';
import { platform } from '../../platform';
module.exports = {
getParentBranch,
};
type ParentBranch = { parentBranch: string | undefined; isModified?: boolean };
async function getParentBranch(config) {
export async function getParentBranch(
config: RenovateConfig
): Promise<ParentBranch> {
const { branchName } = config;
// Check if branch exists
const branchExists = await platform.branchExists(branchName);

View file

@ -1,35 +1,30 @@
import is from '@sindresorhus/is';
const later = require('later');
const moment = require('moment-timezone');
const { logger } = require('../../logger');
export { hasValidTimezone, hasValidSchedule, isScheduledNow };
import later from 'later';
import moment from 'moment-timezone';
import { logger } from '../../logger';
const scheduleMappings = {
'every month': 'before 3am on the first day of the month',
monthly: 'before 3am on the first day of the month',
};
function fixShortHours(input) {
function fixShortHours(input: string): string {
return input.replace(/( \d?\d)((a|p)m)/g, '$1:00$2');
}
/**
* @returns {[boolean] | [boolean, string]}
*/
function hasValidTimezone(timezone) {
export function hasValidTimezone(
timezone: string
): [boolean] | [boolean, string] {
if (!moment.tz.zone(timezone)) {
return [false, `Invalid timezone: ${timezone}`];
}
return [true];
}
/**
* @returns {[boolean] | [boolean, string]}
*/
function hasValidSchedule(schedule) {
let message;
export function hasValidSchedule(
schedule: string[] | null | 'at any time'
): [boolean] | [boolean, string] {
let message: string;
if (
!schedule ||
schedule === 'at any time' ||
@ -70,7 +65,7 @@ function hasValidSchedule(schedule) {
return [true, ''];
}
function isScheduledNow(config) {
export function isScheduledNow(config) {
let configSchedule = config.schedule;
logger.debug(`Checking schedule(${configSchedule}, ${config.timezone})`);
if (

View file

@ -1,13 +1,14 @@
const { logger } = require('../../logger');
const { appSlug, urls } = require('../../config/app-strings');
const { platform } = require('../../platform');
import { logger } from '../../logger';
import { appSlug, urls } from '../../config/app-strings';
import { RenovateConfig } from '../../config';
import { platform } from '../../platform';
module.exports = {
setStability,
setUnpublishable,
};
async function setStatusCheck(branchName, context, description, state) {
async function setStatusCheck(
branchName: string,
context: string,
description: string,
state: string
) {
const existingState = await platform.getBranchStatusCheck(
branchName,
context
@ -27,7 +28,12 @@ async function setStatusCheck(branchName, context, description, state) {
}
}
async function setStability(config) {
export type StabilityConfig = RenovateConfig & {
stabilityStatus: string;
branchName: string;
};
export async function setStability(config: StabilityConfig) {
if (!config.stabilityStatus) {
return;
}
@ -44,7 +50,15 @@ async function setStability(config) {
);
}
async function setUnpublishable(config) {
export type UnpublishableConfig = RenovateConfig & {
unpublishSafe?: boolean;
canBeUnpublished?: boolean;
branchName: string;
};
export async function setUnpublishable(
config: UnpublishableConfig
): Promise<void> {
if (!config.unpublishSafe) {
return;
}

View file

@ -182,6 +182,7 @@
"@types/later": "1.2.5",
"@types/lodash": "4.14.144",
"@types/luxon": "1.15.2",
"@types/moment-timezone": "0.5.12",
"@types/nock": "10.0.3",
"@types/node": "11.13.22",
"@types/node-emoji": "1.8.1",

View file

@ -1236,6 +1236,13 @@
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
"@types/moment-timezone@0.5.12":
version "0.5.12"
resolved "https://registry.yarnpkg.com/@types/moment-timezone/-/moment-timezone-0.5.12.tgz#0fb680c03db194fe8ff4551eaeb1eec8d3d80e9f"
integrity sha512-hnHH2+Efg2vExr/dSz+IX860nSiyk9Sk4pJF2EmS11lRpMcNXeB4KBW5xcgw2QPsb9amTXdsVNEe5IoJXiT0uw==
dependencies:
moment ">=2.14.0"
"@types/nock@10.0.3":
version "10.0.3"
resolved "https://registry.yarnpkg.com/@types/nock/-/nock-10.0.3.tgz#dab1d18ffbccfbf2db811dab9584304eeb6e1c4c"
@ -6163,7 +6170,7 @@ moment-timezone@0.5.26:
dependencies:
moment ">= 2.9.0"
moment@2.24.0, "moment@>= 2.9.0", moment@^2.10.6:
moment@2.24.0, "moment@>= 2.9.0", moment@>=2.14.0, moment@^2.10.6:
version "2.24.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==