ci(docs-infra): add explicit return types to methods
This commit is contained in:
parent
36c4c8daa9
commit
d604ef7cf0
|
@ -24,7 +24,7 @@ export class BuildCleaner {
|
|||
}
|
||||
|
||||
// Methods - Public
|
||||
public async cleanUp() {
|
||||
public async cleanUp(): Promise<void> {
|
||||
try {
|
||||
this.logger.log('Cleaning up builds and downloads');
|
||||
const openPrs = await this.getOpenPrNumbers();
|
||||
|
@ -38,17 +38,17 @@ export class BuildCleaner {
|
|||
}
|
||||
}
|
||||
|
||||
public async cleanBuilds(openPrs: number[]) {
|
||||
public async cleanBuilds(openPrs: number[]): Promise<void> {
|
||||
const existingBuilds = await this.getExistingBuildNumbers();
|
||||
await this.removeUnnecessaryBuilds(existingBuilds, openPrs);
|
||||
}
|
||||
|
||||
public async cleanDownloads(openPrs: number[]) {
|
||||
public async cleanDownloads(openPrs: number[]): Promise<void> {
|
||||
const existingDownloads = await this.getExistingDownloads();
|
||||
await this.removeUnnecessaryDownloads(existingDownloads, openPrs);
|
||||
}
|
||||
|
||||
public getExistingBuildNumbers() {
|
||||
public getExistingBuildNumbers(): Promise<number[]> {
|
||||
return new Promise<number[]>((resolve, reject) => {
|
||||
fs.readdir(this.buildsDir, (err, files) => {
|
||||
if (err) {
|
||||
|
@ -65,14 +65,14 @@ export class BuildCleaner {
|
|||
});
|
||||
}
|
||||
|
||||
public async getOpenPrNumbers() {
|
||||
public async getOpenPrNumbers(): Promise<number[]> {
|
||||
const api = new GithubApi(this.githubToken);
|
||||
const githubPullRequests = new GithubPullRequests(api, this.githubOrg, this.githubRepo);
|
||||
const prs = await githubPullRequests.fetchAll('open');
|
||||
return prs.map(pr => pr.number);
|
||||
}
|
||||
|
||||
public removeDir(dir: string) {
|
||||
public removeDir(dir: string): void {
|
||||
try {
|
||||
if (shell.test('-d', dir)) {
|
||||
shell.chmod('-R', 'a+w', dir);
|
||||
|
@ -83,7 +83,7 @@ export class BuildCleaner {
|
|||
}
|
||||
}
|
||||
|
||||
public removeUnnecessaryBuilds(existingBuildNumbers: number[], openPrNumbers: number[]) {
|
||||
public removeUnnecessaryBuilds(existingBuildNumbers: number[], openPrNumbers: number[]): void {
|
||||
const toRemove = existingBuildNumbers.filter(num => !openPrNumbers.includes(num));
|
||||
|
||||
this.logger.log(`Existing builds: ${existingBuildNumbers.length}`);
|
||||
|
@ -100,7 +100,7 @@ export class BuildCleaner {
|
|||
forEach(dir => this.removeDir(dir));
|
||||
}
|
||||
|
||||
public getExistingDownloads() {
|
||||
public getExistingDownloads(): Promise<string[]> {
|
||||
const artifactFile = path.basename(this.artifactPath);
|
||||
return new Promise<string[]>((resolve, reject) => {
|
||||
fs.readdir(this.downloadsDir, (err, files) => {
|
||||
|
@ -113,7 +113,7 @@ export class BuildCleaner {
|
|||
});
|
||||
}
|
||||
|
||||
public removeUnnecessaryDownloads(existingDownloads: string[], openPrNumbers: number[]) {
|
||||
public removeUnnecessaryDownloads(existingDownloads: string[], openPrNumbers: number[]): void {
|
||||
const toRemove = existingDownloads.filter(filePath => {
|
||||
const {pr} = getPrInfoFromDownloadPath(filePath);
|
||||
return !openPrNumbers.includes(pr);
|
||||
|
|
|
@ -13,7 +13,7 @@ import {BuildCleaner} from './build-cleaner';
|
|||
_main();
|
||||
|
||||
// Functions
|
||||
function _main() {
|
||||
function _main(): void {
|
||||
const buildCleaner = new BuildCleaner(
|
||||
AIO_BUILDS_DIR,
|
||||
AIO_GITHUB_ORGANIZATION,
|
||||
|
|
|
@ -55,7 +55,7 @@ export class CircleCiApi {
|
|||
* @param buildNumber The CircleCI build number that generated the artifact.
|
||||
* @returns A promise to the info about the build
|
||||
*/
|
||||
public async getBuildInfo(buildNumber: number) {
|
||||
public async getBuildInfo(buildNumber: number): Promise<BuildInfo> {
|
||||
try {
|
||||
const baseUrl = `${CIRCLE_CI_API_URL}/${this.githubOrg}/${this.githubRepo}/${buildNumber}`;
|
||||
const response = await fetch(`${baseUrl}?${this.tokenParam}`);
|
||||
|
@ -73,7 +73,7 @@ export class CircleCiApi {
|
|||
* @param artifactPath The path, within the build to the artifact.
|
||||
* @returns A promise to the URL that can be requested to download the actual build artifact file.
|
||||
*/
|
||||
public async getBuildArtifactUrl(buildNumber: number, artifactPath: string) {
|
||||
public async getBuildArtifactUrl(buildNumber: number, artifactPath: string): Promise<string> {
|
||||
const baseUrl = `${CIRCLE_CI_API_URL}/${this.githubOrg}/${this.githubRepo}/${buildNumber}`;
|
||||
try {
|
||||
const response = await fetch(`${baseUrl}/artifacts?${this.tokenParam}`);
|
||||
|
|
|
@ -56,7 +56,7 @@ export class GithubApi {
|
|||
}
|
||||
|
||||
// Methods - Protected
|
||||
protected buildPath(pathname: string, params?: RequestParamsOrNull) {
|
||||
protected buildPath(pathname: string, params?: RequestParamsOrNull): string {
|
||||
if (params == null) {
|
||||
return pathname;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ export class GithubApi {
|
|||
return `${pathname}${joiner}${search}`;
|
||||
}
|
||||
|
||||
protected request<T>(method: string, path: string, data: any = null) {
|
||||
protected request<T>(method: string, path: string, data: any = null): Promise<T> {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
const options = {
|
||||
headers: {...this.requestHeaders},
|
||||
|
@ -101,7 +101,7 @@ export class GithubApi {
|
|||
});
|
||||
}
|
||||
|
||||
protected serializeSearchParams(params: RequestParams) {
|
||||
protected serializeSearchParams(params: RequestParams): string {
|
||||
return Object.keys(params).
|
||||
filter(key => params[key] != null).
|
||||
map(key => `${key}=${encodeURIComponent(String(params[key]))}`).
|
||||
|
|
|
@ -38,7 +38,7 @@ export class GithubPullRequests {
|
|||
* @param body The body of the comment to post.
|
||||
* @returns A promise that resolves when the comment has been posted.
|
||||
*/
|
||||
public addComment(pr: number, body: string) {
|
||||
public addComment(pr: number, body: string): Promise<any> {
|
||||
assert(pr > 0, `Invalid PR number: ${pr}`);
|
||||
assert(!!body, `Invalid or empty comment body: ${body}`);
|
||||
return this.api.post<any>(`/repos/${this.repoSlug}/issues/${pr}/comments`, null, {body});
|
||||
|
@ -49,7 +49,7 @@ export class GithubPullRequests {
|
|||
* @param pr The number of the PR for which to request info.
|
||||
* @returns A promise that is resolves with information about the specified PR.
|
||||
*/
|
||||
public fetch(pr: number) {
|
||||
public fetch(pr: number): Promise<PullRequest> {
|
||||
assert(pr > 0, `Invalid PR number: ${pr}`);
|
||||
// Using the `/issues/` URL, because the `/pulls/` one does not provide labels.
|
||||
return this.api.get<PullRequest>(`/repos/${this.repoSlug}/issues/${pr}`);
|
||||
|
@ -60,7 +60,7 @@ export class GithubPullRequests {
|
|||
* @param state Only retrieve PRs that have this state.
|
||||
* @returns A promise that is resolved with information about the requested PRs.
|
||||
*/
|
||||
public fetchAll(state: PullRequestState = 'all') {
|
||||
public fetchAll(state: PullRequestState = 'all'): Promise<PullRequest[]> {
|
||||
const pathname = `/repos/${this.repoSlug}/pulls`;
|
||||
const params = {state};
|
||||
|
||||
|
@ -72,7 +72,7 @@ export class GithubPullRequests {
|
|||
* @param pr The number of the PR for which to request files.
|
||||
* @returns A promise that resolves to an array of file information
|
||||
*/
|
||||
public fetchFiles(pr: number) {
|
||||
public fetchFiles(pr: number): Promise<FileInfo[]> {
|
||||
assert(pr > 0, `Invalid PR number: ${pr}`);
|
||||
return this.api.get<FileInfo[]>(`/repos/${this.repoSlug}/pulls/${pr}/files`);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ export class GithubTeams {
|
|||
* Request information about all the organisation's teams in GitHub.
|
||||
* @returns A promise that is resolved with information about the teams.
|
||||
*/
|
||||
public fetchAll() {
|
||||
public fetchAll(): Promise<Team[]> {
|
||||
return this.api.getPaginated<Team>(`/orgs/${this.githubOrg}/teams`);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ export class GithubTeams {
|
|||
* @param teamIds The team to check for the username.
|
||||
* @returns a Promise that resolves to `true` if the username is a member of the team.
|
||||
*/
|
||||
public async isMemberById(username: string, teamIds: number[]) {
|
||||
public async isMemberById(username: string, teamIds: number[]): Promise<boolean> {
|
||||
|
||||
const getMembership = async (teamId: number) => {
|
||||
try {
|
||||
|
@ -60,7 +60,7 @@ export class GithubTeams {
|
|||
* @param teamSlugs A collection of slugs that represent the teams to check for the the username.
|
||||
* @returns a Promise that resolves to `true` if the usernane is a member of at least one of the specified teams.
|
||||
*/
|
||||
public async isMemberBySlug(username: string, teamSlugs: string[]) {
|
||||
public async isMemberBySlug(username: string, teamSlugs: string[]): Promise<boolean> {
|
||||
try {
|
||||
const teams = await this.fetchAll();
|
||||
const teamIds = teams.filter(team => teamSlugs.includes(team.slug)).map(team => team.id);
|
||||
|
|
|
@ -119,7 +119,7 @@ export class BuildCreator extends EventEmitter {
|
|||
});
|
||||
}
|
||||
|
||||
protected getCandidatePrDirs(pr: number, isPublic: boolean) {
|
||||
protected getCandidatePrDirs(pr: number, isPublic: boolean): {oldPrDir: string, newPrDir: string} {
|
||||
const hiddenPrDir = path.join(this.buildsDir, HIDDEN_DIR_PREFIX + pr);
|
||||
const publicPrDir = path.join(this.buildsDir, `${pr}`);
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ export class BuildRetriever {
|
|||
* @param buildNum The number of the build for which to retrieve the info.
|
||||
* @returns The Github org, repo, PR and latest SHA for the specified build.
|
||||
*/
|
||||
public async getGithubInfo(buildNum: number) {
|
||||
public async getGithubInfo(buildNum: number): Promise<GithubInfo> {
|
||||
const buildInfo = await this.api.getBuildInfo(buildNum);
|
||||
const githubInfo: GithubInfo = {
|
||||
org: buildInfo.username,
|
||||
|
@ -50,7 +50,7 @@ export class BuildRetriever {
|
|||
* @param artifactPath the path on CircleCI where the artifact was stored.
|
||||
* @returns A promise to the file path where the downloaded file was stored.
|
||||
*/
|
||||
public async downloadBuildArtifact(buildNum: number, pr: number, sha: string, artifactPath: string) {
|
||||
public async downloadBuildArtifact(buildNum: number, pr: number, sha: string, artifactPath: string): Promise<string> {
|
||||
try {
|
||||
const outPath = computeArtifactDownloadPath(this.downloadDir, pr, sha, artifactPath);
|
||||
const downloadExists = await new Promise(resolve => fs.exists(outPath, exists => resolve(exists)));
|
||||
|
@ -73,7 +73,7 @@ export class BuildRetriever {
|
|||
}
|
||||
}
|
||||
|
||||
function getPrfromBranch(branch: string) {
|
||||
function getPrfromBranch(branch: string): number {
|
||||
// CircleCI only exposes PR numbers via the `branch` field :-(
|
||||
const match = /^pull\/(\d+)$/.exec(branch);
|
||||
if (!match) {
|
||||
|
|
|
@ -24,7 +24,7 @@ export class BuildVerifier {
|
|||
* @param pr The number of the PR to check
|
||||
* @param significantFilePattern A regex that selects files that are significant.
|
||||
*/
|
||||
public async getSignificantFilesChanged(pr: number, significantFilePattern: RegExp) {
|
||||
public async getSignificantFilesChanged(pr: number, significantFilePattern: RegExp): Promise<boolean> {
|
||||
const files = await this.prs.fetchFiles(pr);
|
||||
return files.some(file => significantFilePattern.test(file.filename));
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ export class BuildVerifier {
|
|||
(await this.teams.isMemberBySlug(prInfo.user.login, this.allowedTeamSlugs));
|
||||
}
|
||||
|
||||
protected hasLabel(prInfo: PullRequest, label: string) {
|
||||
protected hasLabel(prInfo: PullRequest, label: string): boolean {
|
||||
return prInfo.labels.some(labelObj => labelObj.name === label);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import {UploadServerFactory} from './upload-server-factory';
|
|||
_main();
|
||||
|
||||
// Functions
|
||||
function _main() {
|
||||
function _main(): void {
|
||||
UploadServerFactory
|
||||
.create({
|
||||
buildArtifactPath: AIO_ARTIFACT_PATH,
|
||||
|
|
|
@ -156,7 +156,7 @@ export class UploadServerFactory {
|
|||
return middleware;
|
||||
}
|
||||
|
||||
public static createBuildCreator(prs: GithubPullRequests, buildsDir: string, domainName: string) {
|
||||
public static createBuildCreator(prs: GithubPullRequests, buildsDir: string, domainName: string): BuildCreator {
|
||||
const buildCreator = new BuildCreator(buildsDir);
|
||||
const postPreviewsComment = (pr: number, shas: string[]) => {
|
||||
const body = shas.
|
||||
|
|
|
@ -7,7 +7,7 @@ import {UploadError} from './upload-error';
|
|||
* @param res The response to configure as an error.
|
||||
* @param err The error that needs to be reported.
|
||||
*/
|
||||
export async function respondWithError(res: express.Response, err: any) {
|
||||
export async function respondWithError(res: express.Response, err: any): Promise<void> {
|
||||
if (!(err instanceof UploadError)) {
|
||||
err = new UploadError(500, String((err && err.message) || err));
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class Helper {
|
|||
}
|
||||
|
||||
// Methods - Public
|
||||
public cleanUp() {
|
||||
public cleanUp(): void {
|
||||
while (this.cleanUpFns.length) {
|
||||
// Clean-up fns remove themselves from the list.
|
||||
this.cleanUpFns[0]();
|
||||
|
@ -66,7 +66,7 @@ class Helper {
|
|||
}
|
||||
}
|
||||
|
||||
public createDummyBuild(pr: number, sha: string, isPublic = true, force = false, legacy = false) {
|
||||
public createDummyBuild(pr: number, sha: string, isPublic = true, force = false, legacy = false): CleanUpFn {
|
||||
const prDir = this.getPrDir(pr, isPublic);
|
||||
const shaDir = this.getShaDir(prDir, sha, legacy);
|
||||
const idxPath = path.join(shaDir, 'index.html');
|
||||
|
@ -101,7 +101,7 @@ class Helper {
|
|||
});
|
||||
}
|
||||
|
||||
public runForAllSupportedSchemes(suiteFactory: TestSuiteFactory) {
|
||||
public runForAllSupportedSchemes(suiteFactory: TestSuiteFactory): void {
|
||||
Object.keys(this.portPerScheme).forEach(scheme => suiteFactory(scheme, this.portPerScheme[scheme]));
|
||||
}
|
||||
|
||||
|
@ -137,13 +137,13 @@ class Helper {
|
|||
}
|
||||
|
||||
public writeBuildFile(pr: number, sha: string, relFilePath: string, content: string, isPublic = true,
|
||||
legacy = false) {
|
||||
legacy = false): void {
|
||||
const shaDir = this.getShaDir(this.getPrDir(pr, isPublic), sha, legacy);
|
||||
const absFilePath = path.join(shaDir, relFilePath);
|
||||
this.writeFile(absFilePath, {content}, true);
|
||||
}
|
||||
|
||||
public writeFile(filePath: string, {content, size}: FileSpecs, force = false) {
|
||||
public writeFile(filePath: string, {content, size}: FileSpecs, force = false): void {
|
||||
if (!force && fs.existsSync(filePath)) {
|
||||
throw new Error(`Refusing to overwrite existing file '${filePath}'.`);
|
||||
}
|
||||
|
@ -206,7 +206,18 @@ export function makeCurl(baseUrl: string) {
|
|||
};
|
||||
}
|
||||
|
||||
export function payload(buildNum: number) {
|
||||
export interface PayloadData {
|
||||
data: {
|
||||
payload: {
|
||||
build_num: number,
|
||||
build_parameters: {
|
||||
CIRCLE_JOB: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export function payload(buildNum: number): PayloadData {
|
||||
return {
|
||||
data: {
|
||||
payload: {
|
||||
|
|
|
@ -6,7 +6,7 @@ import {computeShortSha} from '../common/utils';
|
|||
import {SHA} from './constants';
|
||||
import {helper} from './helper';
|
||||
|
||||
function checkFile(filePath: string, remove: boolean) {
|
||||
function checkFile(filePath: string, remove: boolean): boolean {
|
||||
const exists = existsSync(filePath);
|
||||
if (exists && remove) {
|
||||
// if we expected the file to exist then we remove it to prevent leftover file errors
|
||||
|
@ -15,7 +15,7 @@ function checkFile(filePath: string, remove: boolean) {
|
|||
return exists;
|
||||
}
|
||||
|
||||
function getArtifactPath(prNum: number, sha: string = SHA) {
|
||||
function getArtifactPath(prNum: number, sha: string = SHA): string {
|
||||
return `${AIO_DOWNLOADS_DIR}/${prNum}-${computeShortSha(sha)}-aio-snapshot.tgz`;
|
||||
}
|
||||
|
||||
|
@ -35,8 +35,8 @@ function checkFiles(prNum: number, isPublic: boolean, sha: string, isLegacy: boo
|
|||
return { existingFiles, missingFiles };
|
||||
}
|
||||
|
||||
class ToExistAsAFile {
|
||||
public compare(actual: string, remove = true) {
|
||||
class ToExistAsAFile implements jasmine.CustomMatcher {
|
||||
public compare(actual: string, remove = true): jasmine.CustomMatcherResult {
|
||||
const pass = checkFile(actual, remove);
|
||||
return {
|
||||
message: `Expected file at "${actual}" ${pass ? 'not' : ''} to exist`,
|
||||
|
@ -45,8 +45,8 @@ class ToExistAsAFile {
|
|||
}
|
||||
}
|
||||
|
||||
class ToExistAsAnArtifact {
|
||||
public compare(actual: {prNum: number, sha?: string}, remove = true) {
|
||||
class ToExistAsAnArtifact implements jasmine.CustomMatcher {
|
||||
public compare(actual: {prNum: number, sha?: string}, remove = true): jasmine.CustomMatcherResult {
|
||||
const { prNum, sha = SHA } = actual;
|
||||
const filePath = getArtifactPath(prNum, sha);
|
||||
const pass = checkFile(filePath, remove);
|
||||
|
@ -57,8 +57,9 @@ class ToExistAsAnArtifact {
|
|||
}
|
||||
}
|
||||
|
||||
class ToExistAsABuild {
|
||||
public compare(actual: {prNum: number, isPublic?: boolean, sha?: string, isLegacy?: boolean}, remove = true) {
|
||||
class ToExistAsABuild implements jasmine.CustomMatcher {
|
||||
public compare(actual: {prNum: number, isPublic?: boolean, sha?: string, isLegacy?: boolean}, remove = true):
|
||||
jasmine.CustomMatcherResult {
|
||||
const {prNum, isPublic = true, sha = SHA, isLegacy = false} = actual;
|
||||
const {missingFiles} = checkFiles(prNum, isPublic, sha, isLegacy, remove);
|
||||
return {
|
||||
|
@ -67,7 +68,8 @@ class ToExistAsABuild {
|
|||
pass: missingFiles.length === 0,
|
||||
};
|
||||
}
|
||||
public negativeCompare(actual: {prNum: number, isPublic?: boolean, sha?: string, isLegacy?: boolean}) {
|
||||
public negativeCompare(actual: {prNum: number, isPublic?: boolean, sha?: string, isLegacy?: boolean}):
|
||||
jasmine.CustomMatcherResult {
|
||||
const {prNum, isPublic = true, sha = SHA, isLegacy = false} = actual;
|
||||
const { existingFiles } = checkFiles(prNum, isPublic, sha, isLegacy, false);
|
||||
return {
|
||||
|
|
Loading…
Reference in New Issue