UNPKG

screwdriver-data-schema

Version:
265 lines (223 loc) 7.87 kB
'use strict'; const Joi = require('joi'); const mutate = require('../lib/mutate'); const Regex = require('../config/regex'); const Job = require('../config/job'); const Step = require('./step'); const ID = Joi.number().integer().positive(); const PARENT_BUILD_ID = ID; const PARENT_BUILDS_ID = Joi.alternatives().try(ID, Joi.valid(null)); const buildClusterSchema = require('./buildCluster'); const buildClusterName = buildClusterSchema.base.extract('name'); const STATUSES = [ 'ABORTED', 'CREATED', // when the build is created but not started 'FAILURE', 'QUEUED', // when the build is created and put into the queue 'RUNNING', // after the build is created, went through the queue, and has started 'SUCCESS', 'BLOCKED', 'UNSTABLE', 'COLLAPSED', // when the build is collapsed 'FROZEN' // when the build is frozen due to freeze window ]; const STATUS_MESSAGE_TYPES = ['ERROR', 'WARN', 'INFO']; const MODEL = { id: Joi.number().integer().positive().description('Identifier of this build').example(123345), environment: Job.environment, eventId: Joi.number().integer().positive().description('Identifier of the parent event').example(123345), jobId: Joi.number().integer().positive().description('Identifier of the parent job').example(123345), parentBuildId: Joi.array() .items(PARENT_BUILD_ID) .description('Identifier(s) of this parent build(s)') .example([111, 222]), parentBuilds: Joi.object() .pattern( /\d/, Joi.object({ eventId: PARENT_BUILDS_ID, jobs: Joi.object().pattern(Regex.ALL_JOB_NAME, PARENT_BUILDS_ID) }) ) .example({ 111: { eventId: 2, jobs: { jobA: 333, jobB: null } }, 222: { eventId: 3, jobs: { jobC: 555 } } }), number: Joi.number().positive().description('Timestamp of create time').example(1473900790309), container: Joi.string().description('Container this build is running in').example('node:4'), cause: Joi.string().description('Reason why this build started').example('pull request opened'), sha: Joi.string() .hex() .description('SHA this project was built on') .example('ccc49349d3cffbd12ea9e3d41521480b4aa5de5f'), subscribedConfigSha: Joi.string() .hex() .description('SHA this project was built on') .example('ccc49349d3cffbd12ea9e3d41521480b4aa5de5f'), createTime: Joi.string().isoDate().max(32).description('When this build was created'), startTime: Joi.string().isoDate().description('When this build started on a build machine'), endTime: Joi.string().isoDate().description('When this build stopped running'), parameters: Joi.object().description('Input parameters that defined this build'), meta: Joi.object().default({}).description('Key=>Value information from the build itself'), status: Joi.string() .valid(...STATUSES) .description('Current status of the build') .example('SUCCESS'), statusMessage: Joi.string() .description('Status message to describe status of the build') .example('Build failed due to infrastructure error'), statusMessageType: Joi.string() .valid(...STATUS_MESSAGE_TYPES) .max(10) .description('Severity of the status message') .example('WARN'), stats: Joi.object() .keys({ queueEnterTime: Joi.string().isoDate().description('When this build enters queue'), blockedStartTime: Joi.string().isoDate().description('When this build is blocked'), imagePullStartTime: Joi.string().isoDate().description('When this build starts pulling image'), hostname: Joi.string().description('Where this build is run') }) .unknown(true) // allow other fields .description('Stats for this build'), templateId: Joi.number().integer().positive().description("Identifier for this job's template").example(123345), buildClusterName }; const parentBuildIdSchema = Joi.alternatives() .try(MODEL.parentBuildId, PARENT_BUILD_ID) .description('Identifier(s) of this parent build'); const environmentSchema = Joi.alternatives().try(Joi.array().items(Job.environment), Job.environment); const stepsSchema = Joi.array().items(Step.get).description('List of steps'); const GET_MODEL = { ...MODEL, parentBuildId: parentBuildIdSchema, environment: environmentSchema, steps: stepsSchema }; module.exports = { /** * All the available properties of Build * * @property base * @type {Joi} */ base: Joi.object(MODEL).label('Build'), /** * All the available statuses of Build * * @property statuses * @type {Array} */ allStatuses: STATUSES, /** * All the available properties of Build * * @property fields * @type {Object} */ fields: MODEL, /** * Properties for Build that will come back during a GET request * * @property get * @type {Joi} */ get: Joi.object( mutate( GET_MODEL, ['id', 'jobId', 'number', 'cause', 'createTime', 'status'], [ 'container', 'parentBuildId', 'parentBuilds', 'sha', 'startTime', 'endTime', 'meta', 'parameters', 'steps', 'eventId', 'environment', 'statusMessage', 'statusMessageType', 'stats', 'buildClusterName', 'templateId', 'subscribedConfigSha' ] ) ).label('Get Build'), /** * Properties for Build that will be passed during an UPDATE request * * @property update * @type {Joi} */ update: Joi.object(mutate(MODEL, [], ['status', 'meta', 'statusMessage', 'statusMessageType', 'stats'])).label( 'Update Build' ), /** * Properties for Build that will be passed during a CREATE request * * @property create * @type {Joi} */ create: Joi.object(mutate(MODEL, ['jobId'], ['meta', 'stats'])).label('Create Build'), /** * Properties when getting step data * * @property getStep * @type {Joi} */ getStep: Step.get, /** * Properties when updating step data * * @property updateStep * @type {Joi} */ updateStep: Step.update, /** * List of fields that determine a unique row * * @property keys * @type {Array} */ keys: ['jobId', 'eventId'], /** * Primary column to sort queries by. * This defines queries to optionally sort a query result set by build number. * Each range key matches up with an element in the indexes property * * @property rangeKeys * @type {Array} */ rangeKeys: ['number', 'number', 'number', 'number'], /** * List of all fields in the model * @property allKeys * @type {Array} */ allKeys: Object.keys(MODEL), /** * All the available status message type * * @property allStatusMessageTypes * @type {Array} */ allStatusMessageTypes: STATUS_MESSAGE_TYPES, /** * Tablename to be used in the datastore * * @property tableName * @type {String} */ tableName: 'builds', /** * List of indexes to create in the datastore * * @property indexes * @type {Array} */ indexes: [ { fields: ['eventId', 'createTime'] }, { fields: ['jobId'] }, { fields: [{ attribute: 'parentBuildId', length: 32 }] }, { fields: ['templateId', 'createTime'] } ] };