@toptal/davinci-ci 1.13.4-alpha-fx-upgrade-stylelint-rules.1335 → 1.14.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Change Log
2
2
 
3
+ ## 1.14.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1047](https://github.com/toptal/davinci/pull/1047) [`850d14f9`](https://github.com/toptal/davinci/commit/850d14f9574d6b32abe6425e3f3248afb1d2e0b4) Thanks [@dmaklygin1](https://github.com/dmaklygin1)! - Remove npx package
8
+
9
+ ### Patch Changes
10
+
11
+ - [#1042](https://github.com/toptal/davinci/pull/1042) [`da14a73e`](https://github.com/toptal/davinci/commit/da14a73e3ec62f34b709baf80b15cffe3b080bb9) Thanks [@OndrejTuma](https://github.com/OndrejTuma)! - More verbose error of toptal commit message check. Now it tells you where the problem is and hints the correct version
12
+
13
+ - Updated dependencies [[`850d14f9`](https://github.com/toptal/davinci/commit/850d14f9574d6b32abe6425e3f3248afb1d2e0b4)]:
14
+ - @toptal/davinci-cli-shared@1.5.0
15
+
3
16
  ## 1.13.3
4
17
 
5
18
  ### Patch Changes
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@toptal/davinci-ci",
3
+ "version": "1.14.0",
4
+ "description": "Continuos integrations tools for frontend projects",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "keywords": [
9
+ "jenkins",
10
+ "docker",
11
+ "ci"
12
+ ],
13
+ "author": "Toptal",
14
+ "homepage": "https://github.com/toptal/davinci/tree/master/packages/ci#readme",
15
+ "license": "ISC",
16
+ "bin": {
17
+ "davinci-code": "./bin/davinci-ci.js"
18
+ },
19
+ "main": "./src/index.js",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/toptal/davinci.git"
23
+ },
24
+ "scripts": {
25
+ "build:package": "../../bin/build-package.js",
26
+ "prepublishOnly": "../../bin/prepublish.js",
27
+ "test": "echo \"Error: run tests from root\" && exit 1"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/toptal/davinci/issues"
31
+ },
32
+ "dependencies": {
33
+ "@commitlint/cli": "^12.1.4",
34
+ "@commitlint/config-conventional": "^12.1.4",
35
+ "@toptal/davinci-cli-shared": "^1.5.0",
36
+ "danger": "^10.7.1",
37
+ "markdown-table": "^2.0.0"
38
+ }
39
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toptal/davinci-ci",
3
- "version": "1.13.4-alpha-fx-upgrade-stylelint-rules.1335+72109f9",
3
+ "version": "1.14.0",
4
4
  "description": "Continuos integrations tools for frontend projects",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -32,9 +32,8 @@
32
32
  "dependencies": {
33
33
  "@commitlint/cli": "^12.1.4",
34
34
  "@commitlint/config-conventional": "^12.1.4",
35
- "@toptal/davinci-cli-shared": "1.4.2-alpha-fx-upgrade-stylelint-rules.1335+72109f9",
35
+ "@toptal/davinci-cli-shared": "^1.5.0",
36
36
  "danger": "^10.7.1",
37
37
  "markdown-table": "^2.0.0"
38
- },
39
- "gitHead": "72109f93ee9cf82099b24934b322929fe3e9b883"
38
+ }
40
39
  }
@@ -36,7 +36,7 @@ const dangerCommand = ({ options }) => {
36
36
  : toptalCommitsDangerfilePath
37
37
 
38
38
  runSync(
39
- 'npx',
39
+ 'yarn',
40
40
  [
41
41
  'danger',
42
42
  local ? 'local' : 'ci',
@@ -1,6 +1,12 @@
1
1
  const WHITELISTED_USERS = ['dependabot-preview[bot]', 'dependabot[bot]', 'toptal-devbot']
2
2
  const VALID_PR_CODE_REGEX = /\[[A-Z]{1,4}-.*]\s/
3
- const VALID_COMMIT_MESSAGE_REGEX = /^[A-Z]\w[^.\n]*[^.\s](\n\n(.|\n)*)*$/
3
+ // Valid commit titles:
4
+ // "Regular commit message"
5
+ // "Commit with sentence. But does not end with a full-stop"
6
+ // "[FOO-1234] Commit with prefix"
7
+ // "[FOO] Prefix numbers can be omitted"
8
+ // "[FOO][BAR] Prefixes can couple"
9
+ const VALID_COMMIT_TITLE_REGEX = /^((\[[A-Z]+(-\d+)?])+ )?[A-Z]\w[^\n]*[^.]$/
4
10
  const MAX_COMMIT_LINE_LENGTH = 79
5
11
  const ENGINEERING_DOCS_LINK =
6
12
  'https://toptal-core.atlassian.net/wiki/spaces/ENG/pages/210665897/Commit+Message+Quality'
@@ -14,7 +20,7 @@ module.exports = {
14
20
  ENGINEERING_DOCS_LINK,
15
21
  MAX_COMMIT_LINE_LENGTH,
16
22
  MISSING_TICKET_CODE_ERROR_MESSAGE,
17
- VALID_COMMIT_MESSAGE_REGEX,
23
+ VALID_COMMIT_TITLE_REGEX,
18
24
  VALID_PR_CODE_REGEX,
19
25
  WHITELISTED_USERS
20
26
  }
@@ -1,6 +1,6 @@
1
1
  const {
2
2
  MAX_COMMIT_LINE_LENGTH,
3
- VALID_COMMIT_MESSAGE_REGEX,
3
+ VALID_COMMIT_TITLE_REGEX,
4
4
  WHITELISTED_USERS
5
5
  } = require('../../config')
6
6
 
@@ -8,14 +8,20 @@ const validateCommitMessage = message => {
8
8
  const errors = []
9
9
  const [title = '', body = ''] = message.split(/\n\n/)
10
10
  const bodyLines = body.split(/\n/)
11
- const isFormatValid = VALID_COMMIT_MESSAGE_REGEX.test(message)
11
+ const isTitleFormatValid = VALID_COMMIT_TITLE_REGEX.test(title)
12
12
  const isTitleLengthValid = title.length <= MAX_COMMIT_LINE_LENGTH
13
13
  const isBodyLinesLengthValid = bodyLines.every(
14
14
  line => line.length <= MAX_COMMIT_LINE_LENGTH
15
15
  )
16
16
 
17
- if (!isFormatValid) {
18
- errors.push('- format of commit title or body is not correct')
17
+ if (!isTitleFormatValid) {
18
+ errors.push(`- format of commit title is not correct ([read more](https://toptal-core.atlassian.net/wiki/spaces/ENG/pages/210665897/Commit+Message+Quality)):
19
+ - Title should start with capital letter
20
+ - Title should not end with a full-stop (i.e .)\n
21
+ Example of a valid commit title:
22
+ - Regular commit message
23
+ - [FOO-1234] Commit with prefix
24
+ - [FOO][BAR] Coupled prefixes`)
19
25
  }
20
26
 
21
27
  if (!isTitleLengthValid) {
@@ -0,0 +1,128 @@
1
+ const { toptalCommits } = require('.')
2
+
3
+ const prepareCommitsWithMessages = (messages = []) => ({
4
+ commits: messages.map(message => ({
5
+ message,
6
+ sha: '123'
7
+ }))
8
+ })
9
+
10
+ describe('commit danger plugin', () => {
11
+ beforeEach(() => {
12
+ global.fail = jest.fn()
13
+ global.danger = {
14
+ github: {
15
+ pr: {
16
+ user: {
17
+ login: 'user'
18
+ }
19
+ }
20
+ }
21
+ }
22
+ })
23
+
24
+ afterEach(() => {
25
+ global.fail = undefined
26
+ global.danger = undefined
27
+ })
28
+
29
+ test('commit with title only', () => {
30
+ global.danger.git = prepareCommitsWithMessages(['Hello world'])
31
+ toptalCommits()
32
+
33
+ expect(global.fail).toHaveBeenCalledTimes(0)
34
+ })
35
+
36
+ test('commit with title and body', () => {
37
+ global.danger.git = prepareCommitsWithMessages([
38
+ 'Hello world\n\nSome commit body here.'
39
+ ])
40
+ toptalCommits()
41
+
42
+ expect(global.fail).toHaveBeenCalledTimes(0)
43
+ })
44
+
45
+ test('commit with multi-line body', () => {
46
+ global.danger.git = prepareCommitsWithMessages([
47
+ 'Hello world\n\nFirst line of commit body\nSecond line of commit body'
48
+ ])
49
+ toptalCommits()
50
+
51
+ expect(global.fail).toHaveBeenCalledTimes(0)
52
+ })
53
+
54
+ test('commit with title longer than allowed', () => {
55
+ global.danger.git = prepareCommitsWithMessages([
56
+ 'This commit message is a teeny tiny bit longer than allowed length of 79 characters'
57
+ ])
58
+ toptalCommits()
59
+
60
+ expect(global.fail).toHaveBeenCalledTimes(1)
61
+ })
62
+
63
+ test('commit with body lines longer than allowed', () => {
64
+ global.danger.git = prepareCommitsWithMessages([
65
+ 'Short commit title\n\nBut this body line commit message is a bit longer than allowed length of 79 characters\nAnd this one is fine again.'
66
+ ])
67
+ toptalCommits()
68
+
69
+ expect(global.fail).toHaveBeenCalledTimes(1)
70
+ })
71
+
72
+ test('commit message not starting with an uppercase letter', () => {
73
+ global.danger.git = prepareCommitsWithMessages([
74
+ '23432 starts with a number',
75
+ 'starts with a lowercase letter',
76
+ '* starts with a symbol',
77
+ ' starts with a space'
78
+ ])
79
+ toptalCommits()
80
+
81
+ expect(global.fail).toHaveBeenCalledTimes(4)
82
+ })
83
+
84
+ test('commit message ending with a period in title', () => {
85
+ global.danger.git = prepareCommitsWithMessages([
86
+ 'Commit title ending with period.',
87
+ ])
88
+ toptalCommits()
89
+
90
+ expect(global.fail).toHaveBeenCalledTimes(1)
91
+ })
92
+
93
+ test('commit without a blank line between title and body', () => {
94
+ global.danger.git = prepareCommitsWithMessages([
95
+ 'Commit title\nBody without a blank line after title'
96
+ ])
97
+ toptalCommits()
98
+
99
+ expect(global.fail).toHaveBeenCalledTimes(1)
100
+ })
101
+
102
+ test('valid commit titles', () => {
103
+ global.danger.git = prepareCommitsWithMessages([
104
+ 'Regular commit title',
105
+ 'Commit with sentence. But does not end with a full-stop',
106
+ '[FOO-1234] Commit with prefix',
107
+ '[FOO] Prefix numbers can be omitted',
108
+ '[FOO][BAR] Prefixes can couple',
109
+ '[FOO-1234][BAR] Mixed prefixes',
110
+ '[FOO-1234][BAR-123][BAZ] Everything. Together',
111
+ ])
112
+ toptalCommits()
113
+
114
+ expect(global.fail).toHaveBeenCalledTimes(0)
115
+ })
116
+
117
+ test('invalid commit title prefixes', () => {
118
+ global.danger.git = prepareCommitsWithMessages([
119
+ '[FOO-1234] commit with lowercase',
120
+ '[FOO-BAR] Prefix with letter after dash',
121
+ '[FOO] [BAR] Prefixes with space between',
122
+ '[FOO]Prefix without space',
123
+ ])
124
+ toptalCommits()
125
+
126
+ expect(global.fail).toHaveBeenCalledTimes(4)
127
+ })
128
+ })
@@ -1,5 +1,5 @@
1
1
  const {
2
- VALID_COMMIT_MESSAGE_REGEX,
2
+ VALID_COMMIT_TITLE_REGEX,
3
3
  VALID_PR_CODE_REGEX,
4
4
  WHITELISTED_USERS,
5
5
  DEFAULT_PR_TITLE_ERROR_MESSAGE,
@@ -47,7 +47,7 @@ const toptalPRTitle = () => {
47
47
  }
48
48
 
49
49
  const titleText = splitTitle[splitTitle.length - 1]
50
- const isTitleFormatValid = VALID_COMMIT_MESSAGE_REGEX.test(titleText)
50
+ const isTitleFormatValid = VALID_COMMIT_TITLE_REGEX.test(titleText)
51
51
 
52
52
  if (!isTitleFormatValid) {
53
53
  showError()
@@ -0,0 +1,66 @@
1
+ const { toptalPRTitle } = require('.')
2
+ const {
3
+ MISSING_TICKET_CODE_ERROR_MESSAGE,
4
+ DEFAULT_PR_TITLE_ERROR_MESSAGE
5
+ } = require('../../config')
6
+
7
+ const VALID_PR_TITLE = '[ASD-123] Hello world'
8
+ const INVALID_PR_TITLE = '[ASD-123] hello world'
9
+ const NO_TICKET_CODE_PR_TITLE = 'Hello world'
10
+
11
+ describe('commit danger plugin', () => {
12
+ beforeEach(() => {
13
+ global.fail = jest.fn()
14
+ global.danger = {
15
+ github: {
16
+ issue: {
17
+ labels: [
18
+ { name: 'My Team' }
19
+ ]
20
+ },
21
+ pr: {
22
+ title: '',
23
+ user: {
24
+ login: 'user'
25
+ }
26
+ }
27
+ }
28
+ }
29
+ })
30
+
31
+ afterEach(() => {
32
+ global.fail = undefined
33
+ global.danger = undefined
34
+ })
35
+
36
+ test('should pass valid PR title', () => {
37
+ global.danger.github.pr.title = VALID_PR_TITLE
38
+
39
+ toptalPRTitle()
40
+ expect(global.fail).toHaveBeenCalledTimes(0)
41
+ })
42
+
43
+ test('should fail PR title with missing ticket code', () => {
44
+ global.danger.github.pr.title = NO_TICKET_CODE_PR_TITLE
45
+
46
+ toptalPRTitle()
47
+ expect(global.fail).toHaveBeenCalledTimes(1)
48
+ expect(global.fail).toHaveBeenCalledWith(MISSING_TICKET_CODE_ERROR_MESSAGE)
49
+ })
50
+
51
+ test('should pass valid PR title with missing ticket code and no-jira label', () => {
52
+ global.danger.github.pr.title = NO_TICKET_CODE_PR_TITLE
53
+ global.danger.github.issue.labels = [{ name: 'no-jira' }]
54
+
55
+ toptalPRTitle()
56
+ expect(global.fail).toHaveBeenCalledTimes(0)
57
+ })
58
+
59
+ test('should fail invalid PR title', () => {
60
+ global.danger.github.pr.title = INVALID_PR_TITLE
61
+
62
+ toptalPRTitle()
63
+ expect(global.fail).toHaveBeenCalledTimes(1)
64
+ expect(global.fail).toHaveBeenCalledWith(DEFAULT_PR_TITLE_ERROR_MESSAGE)
65
+ })
66
+ })
@@ -166,7 +166,7 @@ pipeline {
166
166
  -e BUILD_URL=${BUILD_URL} \
167
167
  -e DANGER_GITHUB_API_TOKEN=${DANGER_GITHUB_API_TOKEN} \
168
168
  gcr.io/toptal-hub/${repositoryName}:${commitId} \
169
- npx davinci ci danger
169
+ yarn davinci ci danger
170
170
  """
171
171
  }
172
172
  } //steps
@@ -126,7 +126,7 @@ pipeline {
126
126
  -v ${PWD}/.git:/app/.git \
127
127
  gcr.io/toptal-hub/${repositoryName}:${commitId} \
128
128
  /bin/bash -c "yarn ${params.BUILD_PACKAGE_SCRIPT_NAME} && \
129
- npx davinci engine publish-package \
129
+ yarn davinci engine publish-package \
130
130
  --alpha \
131
131
  --outputVersion /artifacts/.version \
132
132
  --branch ${sourceBranch}"