@toptal/davinci-ci 2.0.15-alpha-fx-3248-update-davinci-to-the-latest-version-containing-metrics-in-talent-portal-frontend-97a8b1bc.7 → 2.1.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,28 @@
1
1
  # Change Log
2
2
 
3
+ ## 2.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1774](https://github.com/toptal/davinci/pull/1774) [`ca7a20f2`](https://github.com/toptal/davinci/commit/ca7a20f248784371af9db64df31e05ada1e69179) Thanks [@TomasSlama](https://github.com/TomasSlama)! - ---
8
+
9
+ ### davinci.yaml (config)
10
+
11
+ - add new options to the config
12
+
13
+ ```yaml
14
+ master:
15
+ # danger check will require every PR
16
+ # created by not whitelisted user to have an assignee
17
+ require_assignee: false
18
+ require_assignee_whitelist: ['dependabot-preview[bot]', 'dependabot[bot]']
19
+ ```
20
+
21
+ ### Patch Changes
22
+
23
+ - Updated dependencies [[`ca7a20f2`](https://github.com/toptal/davinci/commit/ca7a20f248784371af9db64df31e05ada1e69179)]:
24
+ - @toptal/davinci-cli-shared@1.10.0
25
+
3
26
  ## 2.0.14
4
27
 
5
28
  ### Patch Changes
package/README.md CHANGED
@@ -47,6 +47,9 @@ master:
47
47
  deploy_staging: false
48
48
  deploy_storybook_staging: false
49
49
  deploy: false
50
+ conventional_commits: false # danger check will require each commit to follow convential commits
51
+ require_assignee: false # danger check will require each PR to have assignee
52
+ require_assignee_whitelist: ['dependabot-preview[bot]', 'dependabot[bot]']
50
53
 
51
54
  # Customize Slack channel where the notifications will get posted
52
55
  slack_channel: 'custom-slack-channel'
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@toptal/davinci-ci",
3
+ "version": "2.1.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-ci": "./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": "^17.0.2",
34
+ "@commitlint/config-conventional": "^17.1.0",
35
+ "@toptal/davinci-cli-shared": "1.10.0",
36
+ "danger": "^11.0.7",
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": "2.0.15-alpha-fx-3248-update-davinci-to-the-latest-version-containing-metrics-in-talent-portal-frontend-97a8b1bc.7+97a8b1bc",
3
+ "version": "2.1.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": "^17.0.2",
34
34
  "@commitlint/config-conventional": "^17.1.0",
35
- "@toptal/davinci-cli-shared": "1.9.1-alpha-fx-3248-update-davinci-to-the-latest-version-containing-metrics-in-talent-portal-frontend-97a8b1bc.7+97a8b1bc",
35
+ "@toptal/davinci-cli-shared": "1.10.0",
36
36
  "danger": "^11.0.7",
37
37
  "markdown-table": "^2.0.0"
38
- },
39
- "gitHead": "97a8b1bc26ae92a5de08d4019682514bab39594d"
38
+ }
40
39
  }
@@ -1,7 +1,17 @@
1
1
  const { schedule } = require('danger')
2
+ const { davinciProjectConfig } = require('@toptal/davinci-cli-shared')
2
3
 
3
4
  const { conventionalCommits } = require('./plugins/conventional-commits')
4
5
  const { conventionalPRTitle } = require('./plugins/conventional-pr-title')
6
+ const { checkAssigneeExist } = require('../plugins/empty-assignee')
5
7
 
6
8
  schedule(conventionalCommits)
7
9
  schedule(conventionalPRTitle)
10
+
11
+ const {
12
+ master: { requireAssignee },
13
+ } = davinciProjectConfig
14
+
15
+ if (requireAssignee) {
16
+ schedule(checkAssigneeExist)
17
+ }
@@ -0,0 +1,24 @@
1
+ /// <reference types="danger" />
2
+ /* globals danger, fail */
3
+ const { davinciProjectConfig } = require('@toptal/davinci-cli-shared')
4
+
5
+ const {
6
+ master: { requireAssigneeWhiteList = [] },
7
+ } = davinciProjectConfig
8
+
9
+ const WHITELISTED_USERS = requireAssigneeWhiteList
10
+ const checkAssigneeExist = () => {
11
+ const isLocalRun = !danger.github
12
+
13
+ if (isLocalRun || WHITELISTED_USERS.includes(danger.github.pr.user.login)) {
14
+ return
15
+ }
16
+
17
+ if (!danger.github.pr.assignee || danger.github.pr.assignees.length === 0) {
18
+ fail('Please assign someone to this PR before merging.')
19
+ }
20
+ }
21
+
22
+ module.exports = {
23
+ checkAssigneeExist,
24
+ }
@@ -1,7 +1,17 @@
1
1
  const { schedule } = require('danger')
2
+ const { davinciProjectConfig } = require('@toptal/davinci-cli-shared')
2
3
 
3
4
  const { toptalCommits } = require('./plugins/toptal-commits')
4
5
  const { toptalPRTitle } = require('./plugins/toptal-pr-title')
6
+ const { checkAssigneeExist } = require('../plugins/empty-assignee')
5
7
 
6
8
  schedule(toptalCommits)
7
9
  schedule(toptalPRTitle)
10
+
11
+ const {
12
+ master: { requireAssignee },
13
+ } = davinciProjectConfig
14
+
15
+ if (requireAssignee) {
16
+ schedule(checkAssigneeExist)
17
+ }
@@ -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
+ it('commit with title only', () => {
30
+ global.danger.git = prepareCommitsWithMessages(['Hello world'])
31
+ toptalCommits()
32
+
33
+ expect(global.fail).toHaveBeenCalledTimes(0)
34
+ })
35
+
36
+ it('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
+ it('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
+ it('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
+ it('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
+ it('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
+ it('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
+ it('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
+ it('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
+ it('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
+ })
@@ -0,0 +1,68 @@
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: [{ name: 'My Team' }],
18
+ },
19
+ pr: {
20
+ title: '',
21
+ user: {
22
+ login: 'user',
23
+ },
24
+ },
25
+ },
26
+ }
27
+ })
28
+
29
+ afterEach(() => {
30
+ global.fail = undefined
31
+ global.danger = undefined
32
+ })
33
+
34
+ it('should pass valid PR title', () => {
35
+ global.danger.github.pr.title = VALID_PR_TITLE
36
+
37
+ toptalPRTitle()
38
+
39
+ expect(global.fail).toHaveBeenCalledTimes(0)
40
+ })
41
+
42
+ it('should fail PR title with missing ticket code', () => {
43
+ global.danger.github.pr.title = NO_TICKET_CODE_PR_TITLE
44
+
45
+ toptalPRTitle()
46
+
47
+ expect(global.fail).toHaveBeenCalledTimes(1)
48
+ expect(global.fail).toHaveBeenCalledWith(MISSING_TICKET_CODE_ERROR_MESSAGE)
49
+ })
50
+
51
+ it('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
+
57
+ expect(global.fail).toHaveBeenCalledTimes(0)
58
+ })
59
+
60
+ it('should fail invalid PR title', () => {
61
+ global.danger.github.pr.title = INVALID_PR_TITLE
62
+
63
+ toptalPRTitle()
64
+
65
+ expect(global.fail).toHaveBeenCalledTimes(1)
66
+ expect(global.fail).toHaveBeenCalledWith(DEFAULT_PR_TITLE_ERROR_MESSAGE)
67
+ })
68
+ })
@@ -13,7 +13,7 @@ def hasCommandInDavinci(args) {
13
13
  docker run \
14
14
  --rm \
15
15
  -u 469:469 \
16
- gcr.io/toptal-hub/${repoName}:${tag} \
16
+ us-central1-docker.pkg.dev/toptal-hub/containers/${repoName}:${tag} \
17
17
  yarn davinci help
18
18
  """,
19
19
  returnStdout: true
@@ -109,7 +109,7 @@ pipeline {
109
109
  HELM_OPTS='\
110
110
  $set_params_env \
111
111
  --set image.tag=${params.TAG} \
112
- --set image.repository=gcr.io/toptal-hub/${params.REPOSITORY_NAME}-release' \
112
+ --set image.repository=us-central1-docker.pkg.dev/toptal-hub/containers/${params.REPOSITORY_NAME}-release' \
113
113
  make $chart $release dep_build upgrade
114
114
  """
115
115
  }
@@ -137,7 +137,7 @@ pipeline {
137
137
  -e SENTRY_ORG=${sentryOrg} \
138
138
  -e SENTRY_PROJECT=${REPOSITORY_NAME} \
139
139
  -e SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN} \
140
- gcr.io/toptal-hub/${REPOSITORY_NAME}:${TAG} \
140
+ us-central1-docker.pkg.dev/toptal-hub/containers/${REPOSITORY_NAME}:${TAG} \
141
141
  yarn davinci-engine sentry-upload-source-maps
142
142
  """
143
143
  } else {
@@ -91,7 +91,7 @@ def hasParamInDavinciCommand(args) {
91
91
  docker run \
92
92
  --rm \
93
93
  -u 469:469 \
94
- gcr.io/toptal-hub/${repoName}:${tag} \
94
+ us-central1-docker.pkg.dev/toptal-hub/containers/${repoName}:${tag} \
95
95
  yarn davinci help ${command}
96
96
  """,
97
97
  returnStdout: true
@@ -205,7 +205,7 @@ pipeline {
205
205
  -u 469:469 \
206
206
  -v ${jenkinsTestsCoverageDirectory}:/app/${testsCoverageDirectory} \
207
207
  -v ${jenkinsTestsPactContractsDirectory}:/app/${testsPactsDirectory} \
208
- gcr.io/toptal-hub/${repositoryName}:${commitId} \
208
+ us-central1-docker.pkg.dev/toptal-hub/containers/${repositoryName}:${commitId} \
209
209
  yarn test --ci
210
210
  """
211
211
  }
@@ -231,7 +231,7 @@ pipeline {
231
231
  -e GIT_BRANCH=${branch} \
232
232
  -e GIT_СOMMIT=${commitId} \
233
233
  -v ${jenkinsTestsPactContractsDirectory}:/app/${testsPactsDirectory} \
234
- gcr.io/toptal-hub/${repositoryName}:${commitId} \
234
+ us-central1-docker.pkg.dev/toptal-hub/containers/${repositoryName}:${commitId} \
235
235
  yarn publish-pact
236
236
  """
237
237
  }
@@ -316,7 +316,7 @@ pipeline {
316
316
  -v $SSH_AUTH_SOCK:/ssh-agent \
317
317
  -e SSH_AUTH_SOCK=/ssh-agent \
318
318
  -v ${PWD}/.git:/app/.git \
319
- gcr.io/toptal-hub/${repositoryName}:${commitId} \
319
+ us-central1-docker.pkg.dev/toptal-hub/containers/${repositoryName}:${commitId} \
320
320
  ${releasePackageCommand}
321
321
  """
322
322
  }
@@ -380,7 +380,7 @@ pipeline {
380
380
  sh """
381
381
  docker run \
382
382
  --user="root" \
383
- --rm gcr.io/toptal-hub/${repositoryName}:${commitId} /bin/bash -c "apt update && apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb && yarn cypress install > /dev/null && yarn test:$testCommand:ci"
383
+ --rm us-central1-docker.pkg.dev/toptal-hub/containers/${repositoryName}:${commitId} /bin/bash -c "apt update && apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb && yarn cypress install > /dev/null && yarn test:$testCommand:ci"
384
384
  """
385
385
  }
386
386
  } //steps
@@ -124,7 +124,7 @@ pipeline {
124
124
  -v $SSH_AUTH_SOCK:/ssh-agent \
125
125
  -e SSH_AUTH_SOCK=/ssh-agent \
126
126
  -v ${PWD}/.git:/app/.git \
127
- gcr.io/toptal-hub/${repositoryName}:${commitId} \
127
+ us-central1-docker.pkg.dev/toptal-hub/containers/${repositoryName}:${commitId} \
128
128
  /bin/bash -c "yarn ${params.BUILD_PACKAGE_SCRIPT_NAME} && \
129
129
  yarn davinci-engine publish-package \
130
130
  --alpha \