screwdriver-data-schema 21.23.1 → 21.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/api/validator.js CHANGED
@@ -39,6 +39,7 @@ const SCHEMA_JOB_PERMUTATION = Joi.object()
39
39
  secrets: Job.secrets,
40
40
  settings: Job.settings,
41
41
  sourcePaths: Job.sourcePaths,
42
+ stages: Base.stages,
42
43
  subscribe: Base.subscribe,
43
44
  templateId: Job.templateId
44
45
  })
@@ -66,6 +67,7 @@ const SCHEMA_OUTPUT = Joi.object()
66
67
  workflowGraph: WorkflowGraph.workflowGraph,
67
68
  parameters: Parameters.parameters.default({}),
68
69
  warnMessages: Joi.array().optional(),
70
+ stages: Base.stages.optional(),
69
71
  subscribe: Base.subscribe
70
72
  })
71
73
  .label('Execution information');
package/config/base.js CHANGED
@@ -42,6 +42,25 @@ const SCHEMA_CHILD_PIPELINES = Joi.object()
42
42
  })
43
43
  .unknown(false);
44
44
 
45
+ const SCHEMA_STAGE = Joi.object()
46
+ .keys({
47
+ description: Joi.string(),
48
+ jobs: Joi.array()
49
+ .items(Job.jobName)
50
+ .min(0),
51
+ color: Joi.string().regex(Regex.STAGE_COLOR)
52
+ })
53
+ .unknown(false);
54
+
55
+ const SCHEMA_STAGES = Joi.object()
56
+ // Stages can only be named with A-Z,a-z,0-9,-,_
57
+ // Stages only contain an object with the stages
58
+ .pattern(Regex.STAGE_NAME, SCHEMA_STAGE)
59
+ // All others are marked as invalid
60
+ .unknown(false)
61
+ // Add documentation
62
+ .messages({ 'object.unknown': '{{#label}} only supports the following characters A-Z,a-z,0-9,-,_' });
63
+
45
64
  const SCHEMA_SUBSCRIBE = Joi.object().keys({
46
65
  scmUrls: Joi.array().items(
47
66
  Joi.object().pattern(Regex.CHECKOUT_URL, Joi.array().items(Joi.string().regex(Regex.WEBHOOK_EVENT)))
@@ -59,6 +78,7 @@ const SCHEMA_CONFIG = Joi.object()
59
78
  shared: SCHEMA_SHARED,
60
79
  cache: SCHEMA_CACHE,
61
80
  childPipelines: SCHEMA_CHILD_PIPELINES,
81
+ stages: SCHEMA_STAGES,
62
82
  subscribe: SCHEMA_SUBSCRIBE,
63
83
  parameters: Parameters.parameters.default({})
64
84
  })
@@ -76,5 +96,7 @@ module.exports = {
76
96
  cachePerm: SCHEMA_CACHE_PERMUTATION,
77
97
  childPipelines: SCHEMA_CHILD_PIPELINES,
78
98
  config: SCHEMA_CONFIG,
99
+ stage: SCHEMA_STAGE,
100
+ stages: SCHEMA_STAGES,
79
101
  subscribe: SCHEMA_SUBSCRIBE
80
102
  };
package/config/regex.js CHANGED
@@ -47,6 +47,10 @@ module.exports = {
47
47
  ALL_JOB_NAME: /^(PR-[0-9]+:)?[\w-@:]+$/,
48
48
  // Internal trigger like ~component or ~main
49
49
  INTERNAL_TRIGGER: /^~([\w-]+)$/,
50
+ // Stages can only be named with A-Z,a-z,0-9,-,_
51
+ STAGE_NAME: /^[\w-]+$/,
52
+ // Stages can only be named with valid hex CSS color
53
+ STAGE_COLOR: /^#(?:[0-9a-fA-F]{3}){1,2}$/,
50
54
 
51
55
  // Don't combine EXTERNAL_TRIGGER and EXTERNAL_TRIGGER_AND for backward compatibility
52
56
  // BlockBy does not support EXTERNAL_TRIGGER_AND
@@ -0,0 +1,56 @@
1
+ /* eslint-disable new-cap */
2
+
3
+ 'use strict';
4
+
5
+ const prefix = process.env.DATASTORE_SEQUELIZE_PREFIX || '';
6
+ const table = `${prefix}stages`;
7
+
8
+ module.exports = {
9
+ up: async (queryInterface, Sequelize) => {
10
+ await queryInterface.sequelize.transaction(async transaction => {
11
+ await queryInterface.createTable(
12
+ table,
13
+ {
14
+ id: {
15
+ allowNull: false,
16
+ autoIncrement: true,
17
+ primaryKey: true,
18
+ type: Sequelize.INTEGER.UNSIGNED
19
+ },
20
+ pipelineId: {
21
+ type: Sequelize.DOUBLE
22
+ },
23
+ name: {
24
+ type: Sequelize.STRING(64)
25
+ },
26
+ jobIds: {
27
+ type: Sequelize.TEXT
28
+ },
29
+ state: {
30
+ type: Sequelize.STRING(10)
31
+ },
32
+ description: {
33
+ type: Sequelize.STRING(256)
34
+ },
35
+ color: {
36
+ type: Sequelize.STRING(10)
37
+ }
38
+ },
39
+ { transaction }
40
+ );
41
+
42
+ await queryInterface.addConstraint(table, {
43
+ name: `${table}_pipeline_id_name_key`,
44
+ fields: ['pipelineId', 'name'],
45
+ type: 'unique',
46
+ transaction
47
+ });
48
+
49
+ await queryInterface.addIndex(table, {
50
+ name: `${table}_pipeline_id`,
51
+ fields: ['pipelineId'],
52
+ transaction
53
+ });
54
+ });
55
+ }
56
+ };
@@ -0,0 +1,23 @@
1
+ 'use strict';
2
+
3
+ const prefix = process.env.DATASTORE_SEQUELIZE_PREFIX || '';
4
+ const table = `${prefix}jobs`;
5
+
6
+ module.exports = {
7
+ // eslint-disable-next-line no-unused-vars
8
+ async up(queryInterface, Sequelize) {
9
+ await queryInterface.sequelize.transaction(async transaction => {
10
+ const dialect = queryInterface.sequelize.getDialect();
11
+ // sqlite
12
+ let query = `DELETE FROM "${table}" WHERE "name" LIKE 'PR-%' AND INSTR(name, ':') = 0`;
13
+
14
+ if (dialect === 'postgres') {
15
+ query = `DELETE FROM "${table}" WHERE "name" LIKE 'PR-%' AND POSITION(':' IN "name") = 0`;
16
+ } else if (dialect === 'mysql') {
17
+ query = `DELETE FROM \`${table}\` WHERE name LIKE 'PR-%' AND POSITION(':' IN name) = 0`;
18
+ }
19
+
20
+ await queryInterface.sequelize.query(query, { transaction });
21
+ });
22
+ }
23
+ };
package/models/index.js CHANGED
@@ -9,6 +9,7 @@ const job = require('./job');
9
9
  const pipeline = require('./pipeline');
10
10
  const user = require('./user');
11
11
  const secret = require('./secret');
12
+ const stage = require('./stage');
12
13
  const template = require('./template');
13
14
  const templateTag = require('./templateTag');
14
15
  const token = require('./token');
@@ -27,6 +28,7 @@ module.exports = {
27
28
  pipeline,
28
29
  user,
29
30
  secret,
31
+ stage,
30
32
  template,
31
33
  templateTag,
32
34
  token,
@@ -0,0 +1,102 @@
1
+ 'use strict';
2
+
3
+ const Joi = require('joi');
4
+ const Regex = require('../config/regex');
5
+
6
+ const MODEL = {
7
+ id: Joi.number()
8
+ .integer()
9
+ .positive()
10
+ .example(12345),
11
+
12
+ pipelineId: Joi.number()
13
+ .integer()
14
+ .positive()
15
+ .description('Pipeline associated with the Stage')
16
+ .example(123345),
17
+
18
+ name: Joi.string()
19
+ .regex(Regex.STAGE_NAME)
20
+ .max(110)
21
+ .description('Name of the Stage')
22
+ .example('deploy'),
23
+
24
+ jobIds: Joi.array()
25
+ .items(
26
+ Joi.number()
27
+ .integer()
28
+ .positive()
29
+ .description('Identifier for this job')
30
+ .example(123345)
31
+ .optional()
32
+ .allow(null)
33
+ )
34
+ .description('Job IDs in this Stage'),
35
+
36
+ state: Joi.string()
37
+ .valid('ARCHIVED', 'ACTIVE')
38
+ .max(10)
39
+ .description('Current state of the Stage')
40
+ .example('ARCHIVED')
41
+ .default('ACTIVE'),
42
+
43
+ description: Joi.string()
44
+ .max(256)
45
+ .description('Description of the Stage')
46
+ .example('Deploys canary jobs'),
47
+
48
+ color: Joi.string()
49
+ .regex(Regex.STAGE_COLOR)
50
+ .max(7)
51
+ .description('Color for the Stage')
52
+ .example('#FFFF00')
53
+ };
54
+
55
+ module.exports = {
56
+ /**
57
+ * All the available properties of Stage
58
+ *
59
+ * @property base
60
+ * @type {Joi}
61
+ */
62
+ base: Joi.object(MODEL).label('Stage'),
63
+
64
+ /**
65
+ * All the available properties of Stage
66
+ *
67
+ * @property fields
68
+ * @type {Object}
69
+ */
70
+ fields: MODEL,
71
+
72
+ /**
73
+ * List of fields that determine a unique row
74
+ *
75
+ * @property keys
76
+ * @type {Array}
77
+ */
78
+ keys: ['pipelineId', 'name'],
79
+
80
+ /**
81
+ * List of all fields in the model
82
+ * @property allKeys
83
+ * @type {Array}
84
+ */
85
+ allKeys: Object.keys(MODEL),
86
+
87
+ /**
88
+ * Tablename to be used in the datastore
89
+ *
90
+ * @property tableName
91
+ * @type {String}
92
+ */
93
+ tableName: 'stages',
94
+
95
+ /**
96
+ * List of indexes to create in the datastore
97
+ *
98
+ * @property indexes
99
+ * @type {Array}
100
+ */
101
+ indexes: [{ fields: ['pipelineId'] }]
102
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "screwdriver-data-schema",
3
- "version": "21.23.1",
3
+ "version": "21.25.1",
4
4
  "description": "Internal Data Schema of Screwdriver",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -50,7 +50,7 @@
50
50
  "npx": "^10.2.2",
51
51
  "nyc": "^15.0.0",
52
52
  "pg": "^7.18.2",
53
- "sequelize": "^6.20.1",
53
+ "sequelize": "^6.21.0",
54
54
  "sequelize-cli": "^6.4.1",
55
55
  "sqlite3": "^4.2.0"
56
56
  },
package/plugins/scm.js CHANGED
@@ -113,6 +113,8 @@ const ADD_PR_COMMENT = Joi.object()
113
113
  token,
114
114
  prNum: core.scm.hook.extract('prNum').required(),
115
115
  comment: Joi.string().required(),
116
+ jobName,
117
+ pipelineId,
116
118
  scmContext
117
119
  })
118
120
  .required();