diff --git a/BuildServer/lib/builder.ts b/BuildServer/lib/builder.ts index 7713291..deae832 100644 --- a/BuildServer/lib/builder.ts +++ b/BuildServer/lib/builder.ts @@ -197,7 +197,6 @@ export const build = (settings: Settings, options, buildCallback) => { release, reponame, rev, - tmp, versionInfo, }, (processErr, result) => { if (processErr) { diff --git a/BuildServer/lib/routes/artifact.ts b/BuildServer/lib/routes/artifact.ts index 57b3f60..188236c 100644 --- a/BuildServer/lib/routes/artifact.ts +++ b/BuildServer/lib/routes/artifact.ts @@ -1,8 +1,10 @@ "use strict"; +import * as express from "express"; + import { getSettings } from "../settings-wrapper"; -export default (req, res) => { +export default ((req, res) => { const options = { branch: `/refs/heads/${req.params.branch}`, branchName: req.params.branch, @@ -17,4 +19,4 @@ export default (req, res) => { const pathParts = [settings.releasepath, options.owner, options.reponame, options.branch, options.rev, options.file]; res.sendfile(pathParts.join("/")); -}; +}) as express.RequestHandler; diff --git a/BuildServer/lib/routes/index.ts b/BuildServer/lib/routes/index.ts index 125109f..f65483d 100644 --- a/BuildServer/lib/routes/index.ts +++ b/BuildServer/lib/routes/index.ts @@ -1,11 +1,13 @@ "use strict"; +import * as express from "express"; + import artifact from "./artifact"; import * as manual from "./manual"; import postreceive from "./postreceive"; import release from "./release"; import * as status from "./status"; -const index = (req, res) => res.render("index", { title: `Express
\r\n${req}` }); +const index: express.RequestHandler = (req, res) => res.render("index", { title: `Express
\r\n${req}` }); export { index, postreceive, manual, status, artifact, release }; diff --git a/BuildServer/lib/routes/manual.ts b/BuildServer/lib/routes/manual.ts index baebd88..7391572 100644 --- a/BuildServer/lib/routes/manual.ts +++ b/BuildServer/lib/routes/manual.ts @@ -1,12 +1,14 @@ "use strict"; +import * as express from "express"; import * as _ from "underscore"; + import { build } from "../builder"; import { getSettings } from "../settings-wrapper"; -export const get = (req, res) => res.render("manual"); +export const get: express.RequestHandler = (req, res) => res.render("manual"); -export const post = (req, res) => { +export const post: express.RequestHandler = (req, res) => { const settings = getSettings(req.app); const options = { diff --git a/BuildServer/lib/routes/postreceive.ts b/BuildServer/lib/routes/postreceive.ts index 73deefe..3d87b13 100644 --- a/BuildServer/lib/routes/postreceive.ts +++ b/BuildServer/lib/routes/postreceive.ts @@ -1,13 +1,23 @@ "use strict"; +import * as express from "express"; import * as JSONParse from "json-parse-safe"; + import { build } from "../builder"; import { commentOnPullRequest } from "../commenter"; import { getSettings } from "../settings-wrapper"; +import { HookParameters, HookPullRequestPayload, HookPushPayload } from "../types"; + +interface IBaseRepoOptions { + branch: string; + branchname?: string; + owner: string; + reponame: string; +} -const getBranchDescription = (options) => `${options.owner}/${options.reponame}:${options.branchname || options.branch}`; +const getBranchDescription = (options: IBaseRepoOptions) => `${options.owner}/${options.reponame}:${options.branchname || options.branch}`; -const processPush = (req, res, payload) => { +const processPush = (req: express.Request, res: express.Response, payload: HookPushPayload) => { const settings = getSettings(req.app); const repository = payload.repository; const options = { @@ -27,7 +37,7 @@ const processPush = (req, res, payload) => { }); }; -const processPullRequest = (req, res, payload) => { +const processPullRequest = (req: express.Request, res: express.Response, payload: HookPullRequestPayload) => { const action = payload.action; const pullRequestNumber = payload.number; const pullRequest = payload.pull_request; @@ -44,6 +54,7 @@ const processPullRequest = (req, res, payload) => { const base = pullRequest.base; const baseRepo = base.repo; const baseRepoOptions = { + branch: `refs/heads/${base.ref}`, branchname: base.ref, owner: baseRepo.owner.name || baseRepo.owner.login, reponame: baseRepo.name, @@ -79,7 +90,7 @@ const processPullRequest = (req, res, payload) => { return res.send(""); } - return commentOnPullRequest(settings, (action === "closed" && masterOptions) || options, (err, data) => { + return commentOnPullRequest(settings, options, (err, data) => { if (err) { console.log(`Unable to post comment: ${err}`); } @@ -96,23 +107,27 @@ const getPayload = (body) => { return JSONParse(body.payload).value; }; -export default (req, res) => { +const getParameters = (req: express.Request): HookParameters => ({ + eventType: req.header("x-github-event") as any, + payload: getPayload(req.body), +}); + +export default ((req, res) => { if (!req.body || (!req.body.payload && !req.body.repository)) { return res.end(); } - const eventType = req.header("x-github-event"); - const payload = getPayload(req.body); + const parameters = getParameters(req); - if (eventType === "push") { - return processPush(req, res, payload); + if (parameters.eventType === "push") { + return processPush(req, res, parameters.payload); } - if (eventType === "pull_request") { - return processPullRequest(req, res, payload); + if (parameters.eventType === "pull_request") { + return processPullRequest(req, res, parameters.payload); } - console.log(`Got "${eventType}" event:`); + console.log(`Got "${parameters.eventType}" event:`); return res.send("Only push/pull_request events are supported"); -}; +}) as express.RequestHandler; diff --git a/BuildServer/lib/routes/release.ts b/BuildServer/lib/routes/release.ts index e46f512..2793fe8 100644 --- a/BuildServer/lib/routes/release.ts +++ b/BuildServer/lib/routes/release.ts @@ -1,6 +1,7 @@ "use strict"; import { create as createArchiver } from "archiver"; +import * as express from "express"; import { join } from "path"; import { readReport } from "../report-processor"; @@ -24,7 +25,7 @@ const getDatePart = (report) => { return `${year}.${month}.${day}.${hours}.${minutes}.${seconds}`; }; -export default (req, res, next) => { +export default ((req, res, next) => { const options = { branch: `/refs/heads/${req.params.branch}`, branchName: req.params.branch, @@ -43,10 +44,10 @@ export default (req, res, next) => { const archive = createArchiver("zip"); archive.on("error", next); - res.attachment(`${options.reponame}.${getDatePart(report)}.${options.rev}.zip`, "."); + res.attachment(`${options.reponame}.${getDatePart(report)}.${options.rev}.zip`); archive.pipe(res); archive.directory(releasePath, false); return archive.finalize(); }); -}; +}) as express.RequestHandler; diff --git a/BuildServer/lib/routes/status.ts b/BuildServer/lib/routes/status.ts index 7140fdc..9cdf802 100644 --- a/BuildServer/lib/routes/status.ts +++ b/BuildServer/lib/routes/status.ts @@ -1,5 +1,6 @@ "use strict"; +import * as express from "express"; import * as _ from "underscore"; import { parse } from "url"; @@ -35,7 +36,7 @@ const parseOptionsFromReferer = (path, callback) => { }); }; -const createShowReport = (res) => (err, inputOptions) => { +const createShowReport = (res: express.Response) => (err, inputOptions) => { const options = { ...inputOptions || {}, err, @@ -44,7 +45,7 @@ const createShowReport = (res) => (err, inputOptions) => { res.render("status", options); }; -export const image = (req, res) => { +export const image: express.RequestHandler = (req, res) => { const getAdditionalOptions = (err, options) => { if (err === "ReportFileNotFound") { return { status: "Building" }; @@ -106,7 +107,7 @@ export const image = (req, res) => { }); }; -export const page = (req, res) => { +export const page: express.RequestHandler = (req, res) => { const options = { branch: `/refs/heads/${req.params.branch}`, branchName: req.params.branch, @@ -118,10 +119,10 @@ export const page = (req, res) => { getReport(getSettings(req.app), options, createShowReport(res)); }; -export const pageFromGithub = (req, res) => parseOptionsFromReferer(req.params[0], (err, options) => { +export const pageFromGithub: express.RequestHandler = (req, res) => parseOptionsFromReferer(req.params[0], (err, options) => { if (err) { return createShowReport(res)(err, options); } - return getReport(req.app /* xxx */, options, createShowReport(res)); + return getReport(getSettings(req.app), options, createShowReport(res)); }); diff --git a/BuildServer/lib/task-processor.ts b/BuildServer/lib/task-processor.ts index e874300..91b005f 100644 --- a/BuildServer/lib/task-processor.ts +++ b/BuildServer/lib/task-processor.ts @@ -3,7 +3,7 @@ import * as _ from "underscore"; import tasks from "./tasks"; -import { MessagesRoot, Settings, TaskInfo, TaskProcessor, TaskProcessorCallback, TaskProcessorCore } from "./types"; +import { MessagesRoot, ProcessTaskContext, Settings, TaskInfo, TaskProcessor, TaskProcessorCallback, TaskProcessorCore } from "./types"; // TaskProcessor does not look like EventEmitter, so no need to extend EventEmitter and use `emit' here. const createTaskProcessor = (task: TaskInfo, outerProcessor: TaskProcessorCore, callback: TaskProcessorCallback) => { @@ -66,7 +66,7 @@ const addFlag = (flags) => (flagName) => { const containsFlag = (flags) => (flagName) => flags[flagName]; -export const processTask = (settings: Settings, task, context, callback) => { +export const processTask = (settings: Settings, task, context: ProcessTaskContext, callback) => { const errors: MessagesRoot = { $allMessages: [] }; const warns: MessagesRoot = { $allMessages: [] }; const infos: MessagesRoot = { $allMessages: [] }; diff --git a/BuildServer/lib/tasks/dotnetbuilderwrapper.ts b/BuildServer/lib/tasks/dotnetbuilderwrapper.ts index 77f9cc9..fc9763a 100644 --- a/BuildServer/lib/tasks/dotnetbuilderwrapper.ts +++ b/BuildServer/lib/tasks/dotnetbuilderwrapper.ts @@ -1,12 +1,12 @@ "use strict"; -import { spawn } from "child_process"; +import { ChildProcess, spawn } from "child_process"; import * as JSONParse from "json-parse-safe"; import { WritableStreamBuffer } from "stream-buffers"; import { Task } from "../types"; -const wrapBuilder = (builder, input, onExit) => { +const wrapBuilder = (builder: ChildProcess, input: string, onExit: (code: number, result: string, builderError: string) => void) => { const stdoutPromise = new Promise((resolve, reject) => { const streamBuffer = new WritableStreamBuffer(); builder.stdout @@ -39,8 +39,8 @@ const wrapBuilder = (builder, input, onExit) => { Promise.all([stdoutPromise, stderrPromise, builderPromise]).then((values) => { const [result, builderError, code] = values; - onExit(code, result, builderError); - }).catch((err) => onExit(0, undefined, err)); + onExit(code as number, result as string, builderError as string); + }).catch((err) => onExit(0, "", err)); }; export default ((params, processor) => () => { diff --git a/BuildServer/lib/tasks/dotnetnugetprocessinternal.ts b/BuildServer/lib/tasks/dotnetnugetprocessinternal.ts index 9e7929d..ec81bf6 100644 --- a/BuildServer/lib/tasks/dotnetnugetprocessinternal.ts +++ b/BuildServer/lib/tasks/dotnetnugetprocessinternal.ts @@ -2,14 +2,14 @@ import { join } from "path"; -import { Task } from "../types"; +import { Task, TaskProcessor } from "../types"; import sequential from "./sequential"; const postfixLength = 16; const fourDigits = 10000; const twoDigits = 100; -const addPostfix = (version, params, processor) => { +const addPostfix = (version, params, processor: TaskProcessor) => { if (params.withoutCommitSha) { return version; } diff --git a/BuildServer/lib/tasks/dotnetrewrite.ts b/BuildServer/lib/tasks/dotnetrewrite.ts index 3380652..bae6f19 100644 --- a/BuildServer/lib/tasks/dotnetrewrite.ts +++ b/BuildServer/lib/tasks/dotnetrewrite.ts @@ -5,18 +5,19 @@ import { readFile, writeFile } from "fs"; import * as glob from "glob"; import { join } from "path"; -import { Settings, Task } from "../types"; +import { Settings, Task, TaskProcessor } from "../types"; const flagDoneName = "dotnetrewriterDone"; -const processAssemblyInfo = (params, processor, appendInformationalVersion) => (originalContent, cb) => { +const processAssemblyInfo = (params, processor: TaskProcessor, appendInformationalVersion: boolean) => (originalContent, cb) => { const processInternalsVisible = (content) => { - if (params.skipCodeSigning || processor.settings.xxxskipCodeSigning) { + if (processor.settings.skipCodeSigning || params.skipCodeSigning) { return content; } + const publicKey = processor.settings.codeSigningPublicKey; const pattern = /InternalsVisibleTo\s*\(\s*"([\w.]+)"\s*\)/g; - const replacer = (match, p1) => `InternalsVisibleTo("${p1},PublicKey=${processor.settings.codeSigningPublicKey}")`; + const replacer = (match, p1) => `InternalsVisibleTo("${p1},PublicKey=${publicKey}")`; return content.replace(pattern, replacer); }; diff --git a/BuildServer/lib/tasks/parallel.ts b/BuildServer/lib/tasks/parallel.ts index add34db..6923e5a 100644 --- a/BuildServer/lib/tasks/parallel.ts +++ b/BuildServer/lib/tasks/parallel.ts @@ -2,8 +2,8 @@ import { parallel } from "async"; -import { Task } from "../types"; +import { Task, TaskProcessor } from "../types"; -const mapper = (processor) => (task) => (callback) => processor.processTask(task, callback); +const mapper = (processor: TaskProcessor) => (task) => (callback) => processor.processTask(task, callback); export default ((params, processor) => () => parallel(params.tasks.map(mapper(processor)), processor.done)) as Task; diff --git a/BuildServer/lib/tasks/sequential.ts b/BuildServer/lib/tasks/sequential.ts index 760d25e..7509d8a 100644 --- a/BuildServer/lib/tasks/sequential.ts +++ b/BuildServer/lib/tasks/sequential.ts @@ -2,8 +2,8 @@ import { series } from "async"; -import { Task } from "../types"; +import { Task, TaskProcessor } from "../types"; -const mapper = (processor) => (task) => (callback) => processor.processTask(task, callback); +const mapper = (processor: TaskProcessor) => (task) => (callback) => processor.processTask(task, callback); export default ((params, processor) => () => series(params.tasks.map(mapper(processor)), processor.done)) as Task; diff --git a/BuildServer/lib/types/github-types.ts b/BuildServer/lib/types/github-types.ts new file mode 100644 index 0000000..870d45e --- /dev/null +++ b/BuildServer/lib/types/github-types.ts @@ -0,0 +1,50 @@ +interface IOwnerInfo { + readonly name: string; + readonly login: string; +} + +interface IRepositoryInfo { + readonly owner: IOwnerInfo; + readonly name: string; + readonly url: string; +} + +interface ITargetInfo { + readonly repo: IRepositoryInfo; + readonly ref: string; + readonly sha: string; +} + +interface IPullRequestInfo { + readonly head: ITargetInfo; + readonly base: ITargetInfo; + readonly merged: boolean; +} + +export interface IHookPushPayload { + readonly repository: IRepositoryInfo; + readonly ref: string; + readonly after: string; +} + +export interface IHookPullRequestPayload { + readonly action: "opened" | "reopened" | "closed" | "synchronize" | "other-unsupported-actions"; + readonly number: number; + readonly pull_request: IPullRequestInfo; +} + +interface IHookPushParameters { + readonly eventType: "push"; + readonly payload: IHookPushPayload; +} + +interface IHookPullRequestParameters { + readonly eventType: "pull_request"; + readonly payload: IHookPullRequestPayload; +} + +interface IHookUnsupportedRequestParameters { + readonly eventType: "other-unsupported-events"; +} + +export type HookParameters = IHookPushParameters | IHookPullRequestParameters | IHookUnsupportedRequestParameters; diff --git a/BuildServer/lib/types/index.ts b/BuildServer/lib/types/index.ts index f1b61d1..fe46036 100644 --- a/BuildServer/lib/types/index.ts +++ b/BuildServer/lib/types/index.ts @@ -1,7 +1,12 @@ +import * as GithubTypes from "./github-types"; import * as ReportTypes from "./report-types"; import * as SettingsTypes from "./settings-types"; import * as TaskProcessorTypes from "./task-processor-types"; +export type HookPushPayload = GithubTypes.IHookPushPayload; +export type HookPullRequestPayload = GithubTypes.IHookPullRequestPayload; +export type HookParameters = GithubTypes.HookParameters; + export type Message = ReportTypes.IMessage; export type Messages = ReportTypes.Messages; export type MessagesRoot = ReportTypes.MessagesRoot; @@ -10,6 +15,7 @@ export type ReportResult = ReportTypes.IReportResult; export type Settings = SettingsTypes.Settings; +export type ProcessTaskContext = TaskProcessorTypes.IProcessTaskContext; export type Task = TaskProcessorTypes.Task; export type TaskInfo = TaskProcessorTypes.ITaskInfo; export type TaskProcessor = TaskProcessorTypes.ITaskProcessor; diff --git a/BuildServer/lib/types/settings-types.ts b/BuildServer/lib/types/settings-types.ts index d2d7aa9..ccc4848 100644 --- a/BuildServer/lib/types/settings-types.ts +++ b/BuildServer/lib/types/settings-types.ts @@ -1,66 +1,66 @@ import * as Github from "github"; interface IBuilderSettings { - builderExecutable: string; + readonly builderExecutable: string; } interface ICodeAnalysisSettingsUnsupported { - isCodeAnalysisUnsupported: true; + readonly isCodeAnalysisUnsupported: true; } interface ICodeAnalysisSettingsSupported { - eslintBrowserConfig: string; - ignoreCodeAnalysisByDefault: boolean; - isCodeAnalysisUnsupported: false; + readonly eslintBrowserConfig: string; + readonly ignoreCodeAnalysisByDefault: boolean; + readonly isCodeAnalysisUnsupported: false; } type CodeAnalysisSettings = ICodeAnalysisSettingsUnsupported | ICodeAnalysisSettingsSupported; interface ICodeSigningSettingsUnsupported { - skipCodeSigning: true; + readonly skipCodeSigning: true; } interface ICodeSigningSettingsSupported { - codeSigningKeyFile: string; - codeSigningPublicKey: string; - skipCodeSigning: false; + readonly codeSigningKeyFile: string; + readonly codeSigningPublicKey: string; + readonly skipCodeSigning: false; } type CodeSigningSettings = ICodeSigningSettingsUnsupported | ICodeSigningSettingsSupported; interface IStorageSettings { - gitpath: string; - releasepath: string; - tmpcodepath: string; + readonly gitpath: string; + readonly releasepath: string; + readonly tmpcodepath: string; } interface INugetSettings { - nugetApiKey: string; - nugetHost: string; + readonly nugetApiKey: string; + readonly nugetHost: string; } interface ISmtpSettings { - smtp: { - auth: { - pass: string; - user: string; + readonly smtp: { + readonly auth: { + readonly pass: string; + readonly user: string; }, - host: string; - receiver: string; - sender: string; + readonly host: string; + readonly receiver: string; + readonly sender: string; }; } interface ISiteSettings { - port: number | string; - siteRoot: string; - viewspath: string; - faviconpath: string; - staticcontentpath: string; + readonly port: number | string; + readonly siteRoot: string; + readonly viewspath: string; + readonly faviconpath: string; + readonly staticcontentpath: string; } interface IGithubSettings { - createGithub: (repoOwner: string) => Github; + readonly createGithub: (repoOwner: string) => Github; } export type Settings = IBuilderSettings & CodeAnalysisSettings & CodeSigningSettings & IStorageSettings & INugetSettings & ISmtpSettings & ISiteSettings & IGithubSettings; diff --git a/BuildServer/lib/types/task-processor-types.ts b/BuildServer/lib/types/task-processor-types.ts index 68f744b..223d178 100644 --- a/BuildServer/lib/types/task-processor-types.ts +++ b/BuildServer/lib/types/task-processor-types.ts @@ -1,5 +1,20 @@ import { Settings } from "./settings-types"; +export interface IProcessTaskContext { + readonly exported: string; + readonly release: string; + readonly owner: string; + readonly reponame: string; + readonly branch: string; + readonly rev: string; + readonly versionInfo: string; +} + +interface ITaskProcessorContext extends IProcessTaskContext { + readonly addFlag: (flagName: string) => void; + readonly containsFlag: (flagName: string) => boolean; +} + export type TaskProcessorCallback = (err: string) => void; export interface ITaskProcessorCore { @@ -7,7 +22,7 @@ export interface ITaskProcessorCore { readonly onWarn: (message: string, prefix?: string) => void; readonly onInfo: (message: string, prefix?: string) => void; readonly settings: Settings; - readonly context?: any; + readonly context: ITaskProcessorContext; } export interface ITaskProcessor extends ITaskProcessorCore { @@ -17,9 +32,9 @@ export interface ITaskProcessor extends ITaskProcessorCore { } export interface ITaskInfo { - name?: string; - type: string; - params: any; + readonly name?: string; + readonly type: string; + readonly params: any; } export type Task = (params: any, processor: ITaskProcessor) => () => void;