@toptal/davinci-workflow 1.8.1-alpha-chore-upgrade-babel-core.3 → 1.8.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/CHANGELOG.md +9 -0
- package/dist-package/package.json +40 -0
- package/package.json +6 -7
- package/src/commands/new-workflow.js +51 -37
- package/src/constants.js +25 -1
- package/src/post-build/alpha-package.js +17 -13
- package/src/post-build/deploy-temploy.js +14 -11
- package/src/post-build/deploy.js +17 -33
- package/src/post-build/integration-tests.js +16 -14
- package/src/utils/generate-command-message.js +38 -0
- package/src/utils/read-secrets.js +42 -0
- package/src/utils/skeleton.js +10 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @toptal/davinci-workflow
|
|
2
2
|
|
|
3
|
+
## 1.8.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1309](https://github.com/toptal/davinci/pull/1309) [`e3aac3fc`](https://github.com/toptal/davinci/commit/e3aac3fc5603664e5b2a49fca96d794e229cf498) Thanks [@dmaklygin](https://github.com/dmaklygin)! - - set up proper secrets to deployment GH Workflows
|
|
8
|
+
- autogenerate secrets from yaml file
|
|
9
|
+
- Updated dependencies [[`e3aac3fc`](https://github.com/toptal/davinci/commit/e3aac3fc5603664e5b2a49fca96d794e229cf498)]:
|
|
10
|
+
- @toptal/davinci-skeleton@6.2.1
|
|
11
|
+
|
|
3
12
|
## 1.8.0
|
|
4
13
|
|
|
5
14
|
### Minor Changes
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@toptal/davinci-workflow",
|
|
3
|
+
"version": "1.8.1",
|
|
4
|
+
"description": "GH Workflow generator package for frontend applications",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"Github Actions",
|
|
10
|
+
"GH Workflows",
|
|
11
|
+
"generator"
|
|
12
|
+
],
|
|
13
|
+
"author": "Toptal",
|
|
14
|
+
"homepage": "https://github.com/toptal/davinci/tree/master/packages/workflow#readme",
|
|
15
|
+
"license": "ISC",
|
|
16
|
+
"bin": {
|
|
17
|
+
"davinci-workflow": "./bin/davinci-workflow.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
|
+
"@toptal/davinci-cli-shared": "1.5.1",
|
|
34
|
+
"@toptal/davinci-skeleton": "6.2.1",
|
|
35
|
+
"fs-extra": "^9.0.1",
|
|
36
|
+
"lodash.kebabcase": "^4.1.1",
|
|
37
|
+
"ora": "^5.4.1",
|
|
38
|
+
"chalk": "^4.1.2"
|
|
39
|
+
}
|
|
40
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toptal/davinci-workflow",
|
|
3
|
-
"version": "1.8.1
|
|
3
|
+
"version": "1.8.1",
|
|
4
4
|
"description": "GH Workflow generator package for frontend applications",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -30,12 +30,11 @@
|
|
|
30
30
|
"url": "https://github.com/toptal/davinci/issues"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@toptal/davinci-cli-shared": "1.5.
|
|
34
|
-
"@toptal/davinci-skeleton": "6.2.1
|
|
35
|
-
"chalk": "^4.1.2",
|
|
33
|
+
"@toptal/davinci-cli-shared": "1.5.1",
|
|
34
|
+
"@toptal/davinci-skeleton": "6.2.1",
|
|
36
35
|
"fs-extra": "^9.0.1",
|
|
37
36
|
"lodash.kebabcase": "^4.1.1",
|
|
38
|
-
"ora": "^5.4.1"
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
"ora": "^5.4.1",
|
|
38
|
+
"chalk": "^4.1.2"
|
|
39
|
+
}
|
|
41
40
|
}
|
|
@@ -3,15 +3,21 @@ const path = require('path')
|
|
|
3
3
|
const fs = require('fs-extra')
|
|
4
4
|
const ora = require('ora')
|
|
5
5
|
const kebabCase = require('lodash.kebabcase')
|
|
6
|
-
|
|
7
|
-
const {
|
|
6
|
+
|
|
7
|
+
const { WORKFLOWS_DIR, GITHUB_DIR } = require('../constants')
|
|
8
|
+
const {
|
|
9
|
+
copyWorkflowFromSkeleton,
|
|
10
|
+
getWorkflowSourceFilepath
|
|
11
|
+
} = require('../utils/skeleton')
|
|
12
|
+
const { readYMLSecrets } = require('../utils/read-secrets')
|
|
13
|
+
const generateMessageFromSecrets = require('../utils/generate-command-message')
|
|
8
14
|
|
|
9
15
|
/**
|
|
10
16
|
* Check whether github directory exists
|
|
11
17
|
* @param rootDir
|
|
12
18
|
* @returns {Promise<void>}
|
|
13
19
|
*/
|
|
14
|
-
const checkGithubDirectory = async
|
|
20
|
+
const checkGithubDirectory = async rootDir => {
|
|
15
21
|
const spinner = ora(`Searching for ${GITHUB_DIR} directory...`).start()
|
|
16
22
|
const githubDir = path.join(rootDir, GITHUB_DIR)
|
|
17
23
|
|
|
@@ -19,7 +25,9 @@ const checkGithubDirectory = async (rootDir) => {
|
|
|
19
25
|
const doesGithubDirExist = await fs.stat(githubDir)
|
|
20
26
|
|
|
21
27
|
if (!doesGithubDirExist) {
|
|
22
|
-
throw new Error(
|
|
28
|
+
throw new Error(
|
|
29
|
+
'It looks like you run Davinci command not in a root of the project.'
|
|
30
|
+
)
|
|
23
31
|
}
|
|
24
32
|
|
|
25
33
|
spinner.succeed('Github directory exists!')
|
|
@@ -35,7 +43,7 @@ const checkGithubDirectory = async (rootDir) => {
|
|
|
35
43
|
* Returns workflows directory. If the directory structure does not exist, it is created.
|
|
36
44
|
* @param githubDir
|
|
37
45
|
*/
|
|
38
|
-
const getWorkflowsDirectory = async
|
|
46
|
+
const getWorkflowsDirectory = async githubDir => {
|
|
39
47
|
const spinner = ora('Searching for workflows directory...').start()
|
|
40
48
|
|
|
41
49
|
const workflowsDir = path.join(githubDir, WORKFLOWS_DIR)
|
|
@@ -57,48 +65,48 @@ const getWorkflowsDirectory = async (githubDir) => {
|
|
|
57
65
|
* @param workflowName
|
|
58
66
|
* @returns {*}
|
|
59
67
|
*/
|
|
60
|
-
const getWorkflowFilename =
|
|
68
|
+
const getWorkflowFilename = workflowName => {
|
|
61
69
|
return kebabCase(`davinci-${workflowName}`) + '.yml'
|
|
62
70
|
}
|
|
63
71
|
|
|
64
|
-
const getWorkflowPostBuildFilename =
|
|
72
|
+
const getWorkflowPostBuildFilename = workflowName => {
|
|
65
73
|
return kebabCase(workflowName) + '.js'
|
|
66
74
|
}
|
|
67
75
|
|
|
68
76
|
const performPostBuildProcedure = async (filename, destDir) => {
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return
|
|
77
|
-
}
|
|
77
|
+
const postBuildFilePathname = path.join(
|
|
78
|
+
require.resolve('@toptal/davinci-workflow'),
|
|
79
|
+
'../',
|
|
80
|
+
'post-build',
|
|
81
|
+
filename
|
|
82
|
+
)
|
|
83
|
+
const doesFileExist = await fs.exists(postBuildFilePathname)
|
|
78
84
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
85
|
+
if (!doesFileExist) {
|
|
86
|
+
return
|
|
87
|
+
}
|
|
83
88
|
|
|
84
|
-
|
|
85
|
-
print,
|
|
86
|
-
destDir
|
|
87
|
-
})
|
|
89
|
+
const executePostBuild = require(postBuildFilePathname)
|
|
88
90
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
spinner.fail()
|
|
92
|
-
throw err
|
|
91
|
+
if (typeof executePostBuild !== 'function') {
|
|
92
|
+
throw new Error('post build file must export a function')
|
|
93
93
|
}
|
|
94
|
+
|
|
95
|
+
await executePostBuild({
|
|
96
|
+
print,
|
|
97
|
+
destDir
|
|
98
|
+
})
|
|
94
99
|
}
|
|
95
100
|
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
const printMandatorySecretsList = async fileName => {
|
|
102
|
+
const workflowFilepath = getWorkflowSourceFilepath(fileName)
|
|
103
|
+
const secrets = readYMLSecrets(workflowFilepath)
|
|
104
|
+
|
|
105
|
+
print.grey(generateMessageFromSecrets(secrets))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const createCommand = async workflowName => {
|
|
109
|
+
print.green('Creating', workflowName, '...')
|
|
102
110
|
|
|
103
111
|
const rootDir = process.cwd()
|
|
104
112
|
|
|
@@ -109,12 +117,18 @@ const createCommand = async (workflowName) => {
|
|
|
109
117
|
const workflowsDir = await getWorkflowsDirectory(githubDir)
|
|
110
118
|
// get filename
|
|
111
119
|
const fileName = getWorkflowFilename(workflowName)
|
|
120
|
+
|
|
112
121
|
// copy workflow to an appropriate directory
|
|
113
122
|
await copyWorkflowFromSkeleton(fileName, workflowsDir)
|
|
123
|
+
// print successfull result
|
|
124
|
+
print.green('Workflow has been created.\n')
|
|
114
125
|
// execute a possible post-build procedure
|
|
115
|
-
await performPostBuildProcedure(
|
|
116
|
-
|
|
117
|
-
|
|
126
|
+
await performPostBuildProcedure(
|
|
127
|
+
getWorkflowPostBuildFilename(workflowName),
|
|
128
|
+
workflowsDir
|
|
129
|
+
)
|
|
130
|
+
// read and print mandatory ENV secrets that must be installed beforehand
|
|
131
|
+
await printMandatorySecretsList(fileName)
|
|
118
132
|
} catch (err) {
|
|
119
133
|
print.red(err)
|
|
120
134
|
process.exit(1)
|
package/src/constants.js
CHANGED
|
@@ -1,7 +1,31 @@
|
|
|
1
1
|
const GITHUB_DIR = '.github'
|
|
2
2
|
const WORKFLOWS_DIR = 'workflows'
|
|
3
3
|
|
|
4
|
+
const SECRET_DEFINITION = {
|
|
5
|
+
// common
|
|
6
|
+
TOPTAL_DEVBOT_TOKEN:
|
|
7
|
+
'GH access token to checkout and publish comments/reactions in PRs',
|
|
8
|
+
GCR_ACCOUNT_KEY: 'Google Cloud Account Key. Necessary to upload Docker image',
|
|
9
|
+
SENTRY_SOURCEMAP_UPLOAD_TOKEN:
|
|
10
|
+
'Sentry Token. Necessary to upload source files to Sentry',
|
|
11
|
+
// production
|
|
12
|
+
TOPTAL_BOT_JENKINS_DEPLOYMENT_TOKEN:
|
|
13
|
+
'Jenkins Deploy Token. Necessary to execute deploy to PRODUCTION Jenkins job',
|
|
14
|
+
HTTP_PROXY:
|
|
15
|
+
'Jenkins Proxy. Necessary to execute deploy to production Jenkins job',
|
|
16
|
+
// staging
|
|
17
|
+
TOPTAL_BOT_JENKINS_API_TOKEN:
|
|
18
|
+
'Jenkins Deploy Token. Necessary to execute deploy to STAGING Jenkins job',
|
|
19
|
+
// temploy
|
|
20
|
+
TOPTAL_JENKINS_BUILD_TOKEN:
|
|
21
|
+
'Jenkins Build Token. Necessary to execute Jenkins job',
|
|
22
|
+
// alpha-package
|
|
23
|
+
NPM_TOKEN_PUBLISH: 'NPM publish access token',
|
|
24
|
+
NPM_TOKEN_READ_ONLY: 'NPM read token'
|
|
25
|
+
}
|
|
26
|
+
|
|
4
27
|
module.exports = {
|
|
5
28
|
GITHUB_DIR,
|
|
6
|
-
WORKFLOWS_DIR
|
|
29
|
+
WORKFLOWS_DIR,
|
|
30
|
+
SECRET_DEFINITION
|
|
7
31
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
const chalk = require('chalk')
|
|
2
|
-
const skeleton = require('../utils/skeleton')
|
|
3
2
|
const path = require('path')
|
|
4
3
|
|
|
5
|
-
const
|
|
6
|
-
|
|
4
|
+
const skeleton = require('../utils/skeleton')
|
|
5
|
+
const yellowBoldText = chalk.yellow.bold
|
|
6
|
+
const logText = chalk.red.bold
|
|
7
|
+
|
|
8
|
+
const executePostBuild = ({ destDir }) => {
|
|
7
9
|
let isScriptExist = false
|
|
8
10
|
|
|
9
11
|
try {
|
|
@@ -13,7 +15,8 @@ const executePostBuild = ({destDir}) => {
|
|
|
13
15
|
const config = skeleton.readPackageJson(rootDir)
|
|
14
16
|
|
|
15
17
|
if (!config.scripts['build:package']) {
|
|
16
|
-
config.scripts['build:package'] =
|
|
18
|
+
config.scripts['build:package'] =
|
|
19
|
+
'lerna run build:package --stream --parallel'
|
|
17
20
|
} else {
|
|
18
21
|
isScriptExist = true
|
|
19
22
|
}
|
|
@@ -24,15 +27,16 @@ const executePostBuild = ({destDir}) => {
|
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
console.log(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
[
|
|
31
|
+
chalk.green(
|
|
32
|
+
'\nPublish Alpha Package (alpha-package) GH Workflow has been generated! \n\n'
|
|
33
|
+
),
|
|
34
|
+
yellowBoldText('@toptal-bot run package:alpha-release'),
|
|
35
|
+
' — it performs build&release of a new alpha package \n',
|
|
36
|
+
!isScriptExist
|
|
37
|
+
? logText('New "build:package" script was added in package.json! \n')
|
|
38
|
+
: ''
|
|
39
|
+
].join('')
|
|
36
40
|
)
|
|
37
41
|
}
|
|
38
42
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
const chalk = require('chalk')
|
|
2
|
-
const skeleton = require('../utils/skeleton')
|
|
3
2
|
const path = require('path')
|
|
4
3
|
|
|
5
|
-
const
|
|
4
|
+
const skeleton = require('../utils/skeleton')
|
|
5
|
+
const yellowBoldText = chalk.yellow.bold
|
|
6
|
+
|
|
7
|
+
const executePostBuild = ({ destDir }) => {
|
|
6
8
|
const logText = chalk.red.bold
|
|
7
9
|
let isScriptExist = false
|
|
8
10
|
|
|
@@ -24,15 +26,16 @@ const executePostBuild = ({destDir}) => {
|
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
console.log(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
[
|
|
30
|
+
chalk.green(
|
|
31
|
+
'\r\nDeploy Temploy (deploy-temploy) GH Workflow has been generated! \n\n'
|
|
32
|
+
),
|
|
33
|
+
yellowBoldText('@toptal-bot run temploy'),
|
|
34
|
+
' — it performs build & deploy a new temploy \n',
|
|
35
|
+
!isScriptExist
|
|
36
|
+
? logText('New "build" script was added in package.json! \n')
|
|
37
|
+
: ''
|
|
38
|
+
].join('')
|
|
36
39
|
)
|
|
37
40
|
}
|
|
38
41
|
|
package/src/post-build/deploy.js
CHANGED
|
@@ -2,14 +2,14 @@ const chalk = require('chalk')
|
|
|
2
2
|
const path = require('path')
|
|
3
3
|
|
|
4
4
|
const skeleton = require('../utils/skeleton')
|
|
5
|
-
|
|
5
|
+
const logText = chalk.red.bold
|
|
6
|
+
const yellowBoldText = chalk.yellow.bold
|
|
6
7
|
const deployWorkflows = [
|
|
7
8
|
'davinci-deploy-production.yml',
|
|
8
9
|
'davinci-deploy-staging.yml'
|
|
9
10
|
]
|
|
10
11
|
|
|
11
12
|
const executePostBuild = async ({ destDir }) => {
|
|
12
|
-
const logText = chalk.red.bold
|
|
13
13
|
let isScriptExist = false
|
|
14
14
|
|
|
15
15
|
const rootDir = path.resolve(destDir, '../../')
|
|
@@ -40,37 +40,21 @@ const executePostBuild = async ({ destDir }) => {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
console.log(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
logText('TOPTAL_DEVBOT_TOKEN'),
|
|
59
|
-
' — GH access token to checkout and publish comments/reactions in PRs\n',
|
|
60
|
-
logText('TOPTAL_JENKINS_BUILD_TOKEN'),
|
|
61
|
-
' — Jenkins Build Token. Necessary to execute Jenkins jobs\n',
|
|
62
|
-
logText('TOPTAL_BOT_JENKINS_DEPLOYMENT_TOKEN'),
|
|
63
|
-
' — Jenkins Deploy Token. Necessary to execute deploy to production Jenkins job\n',
|
|
64
|
-
logText('TOPTAL_BOT_USERNAME'),
|
|
65
|
-
' — Jenkins User Name. Necessary to execute deploy to production Jenkins job\n',
|
|
66
|
-
logText('HTTP_PROXY'),
|
|
67
|
-
' — Jenkins Proxy. Necessary to execute deploy to production Jenkins job\n',
|
|
68
|
-
logText('NPM_TOKEN'),
|
|
69
|
-
' — NPM Token. Necessary to load private NPM packages\n',
|
|
70
|
-
'———————————————————————————————————————————————————————————————————————————————————————————————— \n',
|
|
71
|
-
isScriptExist
|
|
72
|
-
? logText('Script "build" already exists in package.json! \n')
|
|
73
|
-
: logText('New "build" script was added in package.json! \n')
|
|
43
|
+
[
|
|
44
|
+
chalk.green('\nDeploy GH Workflow has been generated!\n\n'),
|
|
45
|
+
'Three workflows have been created — ',
|
|
46
|
+
chalk.green(
|
|
47
|
+
'davinci-deploy.yml, davinci-deploy-staging.yml and davinci-deploy-production.yml'
|
|
48
|
+
),
|
|
49
|
+
'\n\n',
|
|
50
|
+
chalk.green('davinci-deploy.yml'),
|
|
51
|
+
' GH Workflow builds&pushes Docker image and according to settings in davinci.yml it triggers deploy to staging and/or production\n\n',
|
|
52
|
+
yellowBoldText('@toptal-bot run deploy-staging'),
|
|
53
|
+
' — it performs build & deploy to staging for the latest commit in the PR branch \n',
|
|
54
|
+
!isScriptExist
|
|
55
|
+
? logText('New "build" script was added in package.json! \n')
|
|
56
|
+
: ''
|
|
57
|
+
].join('')
|
|
74
58
|
)
|
|
75
59
|
}
|
|
76
60
|
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
const chalk = require('chalk')
|
|
2
2
|
|
|
3
|
-
const CONFLUENCE_PAGE =
|
|
4
|
-
|
|
5
|
-
const redBoldText = chalk.red.bold
|
|
3
|
+
const CONFLUENCE_PAGE =
|
|
4
|
+
'https://toptal-core.atlassian.net/l/c/qtXKBzvs#Generated-IT-Workflow'
|
|
6
5
|
const yellowBoldText = chalk.yellow.bold
|
|
7
6
|
|
|
8
7
|
const executePostBuild = () => {
|
|
9
8
|
console.log(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
[
|
|
10
|
+
chalk.green(
|
|
11
|
+
'\nIntegration tests (integration-tests) GH Workflow has been generated! \n\n'
|
|
12
|
+
),
|
|
13
|
+
'Workflow is located in ',
|
|
14
|
+
chalk.green.bold('.github/workflows/davinci-integration-tests.yml'),
|
|
15
|
+
'\n',
|
|
16
|
+
"But it likely won't work out of the box and will ",
|
|
17
|
+
yellowBoldText('require little bit of adjusting'),
|
|
18
|
+
' to make it work in your CI\n',
|
|
19
|
+
'Read more about customization here ',
|
|
20
|
+
chalk.grey.bold(CONFLUENCE_PAGE),
|
|
21
|
+
'\n'
|
|
22
|
+
].join('')
|
|
21
23
|
)
|
|
22
24
|
}
|
|
23
25
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const chalk = require('chalk')
|
|
2
|
+
|
|
3
|
+
const { SECRET_DEFINITION } = require('../constants')
|
|
4
|
+
const logText = chalk.red.bold
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Function gather necessary secrets to a command message
|
|
8
|
+
* @type {Array} list of secrets
|
|
9
|
+
*/
|
|
10
|
+
const generateMessageFromSecrets = secretsList => {
|
|
11
|
+
if (secretsList.length === 0) {
|
|
12
|
+
return ''
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let message = [
|
|
16
|
+
'————————————————————————————————————————————————————————————————————————————————————————————————\n',
|
|
17
|
+
'The following GH secrets',
|
|
18
|
+
logText('must'),
|
|
19
|
+
'be specified in the repo to properly execute the command: \n\n'
|
|
20
|
+
].join(' ')
|
|
21
|
+
|
|
22
|
+
message += secretsList.reduce((message, secret) => {
|
|
23
|
+
if (!SECRET_DEFINITION[secret]) {
|
|
24
|
+
throw new Error(`the definition for the secret: ${secret} is not found`)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
message += ' ' + logText(secret) + ' — ' + SECRET_DEFINITION[secret] + '\n'
|
|
28
|
+
|
|
29
|
+
return message
|
|
30
|
+
}, '')
|
|
31
|
+
|
|
32
|
+
message +=
|
|
33
|
+
'————————————————————————————————————————————————————————————————————————————————————————————————\n'
|
|
34
|
+
|
|
35
|
+
return message
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = generateMessageFromSecrets
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
|
|
3
|
+
const reg = /\$\{\{\s*secrets\.([A-Za-z_\-0-9]+)\s*\}\}/g
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Pick up secrets from string
|
|
7
|
+
* @param document
|
|
8
|
+
* @returns {String[]}
|
|
9
|
+
*/
|
|
10
|
+
const readSecrets = document => {
|
|
11
|
+
let match
|
|
12
|
+
|
|
13
|
+
const secrets = []
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line no-cond-assign
|
|
16
|
+
while ((match = reg.exec(document))) {
|
|
17
|
+
secrets.push(match[1])
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return secrets
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Read YML file's secrets and return a list of them
|
|
25
|
+
* @param pathname
|
|
26
|
+
* @returns {String[]}
|
|
27
|
+
*/
|
|
28
|
+
const readYMLSecrets = pathname => {
|
|
29
|
+
try {
|
|
30
|
+
const file = fs.readFileSync(pathname, 'utf8')
|
|
31
|
+
|
|
32
|
+
return readSecrets(file)
|
|
33
|
+
} catch (e) {
|
|
34
|
+
console.log('readYMLSecrets Error: ', e)
|
|
35
|
+
throw e
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = {
|
|
40
|
+
readSecrets,
|
|
41
|
+
readYMLSecrets
|
|
42
|
+
}
|
package/src/utils/skeleton.js
CHANGED
|
@@ -19,17 +19,22 @@ const writePackageJson = (folder, config) => {
|
|
|
19
19
|
fs.writeFileSync(packageJsonFile, modifiedConfigData)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
const getWorkflowSourceFilepath = fileName => {
|
|
23
|
+
const skeletonPath = require.resolve('@toptal/davinci-skeleton')
|
|
24
|
+
|
|
25
|
+
return path.join(skeletonPath, '../..', GITHUB_DIR, WORKFLOWS_DIR, fileName)
|
|
26
|
+
}
|
|
27
|
+
|
|
22
28
|
const copyWorkflowFromSkeleton = async (fileName, destDir) => {
|
|
23
29
|
const spinner = ora('Copying workflow...').start()
|
|
24
30
|
|
|
25
|
-
const
|
|
26
|
-
const srcFilepath = path.join(skeletonPath, '../..', GITHUB_DIR, WORKFLOWS_DIR, fileName)
|
|
31
|
+
const srcFilepath = getWorkflowSourceFilepath(fileName)
|
|
27
32
|
const destFilepath = path.join(destDir, fileName)
|
|
28
33
|
|
|
29
34
|
try {
|
|
30
35
|
await fs.copy(srcFilepath, destFilepath)
|
|
31
36
|
|
|
32
|
-
spinner.succeed('Workflow copied!')
|
|
37
|
+
spinner.succeed('Workflow has been copied!')
|
|
33
38
|
} catch (err) {
|
|
34
39
|
spinner.fail()
|
|
35
40
|
throw err
|
|
@@ -39,5 +44,6 @@ const copyWorkflowFromSkeleton = async (fileName, destDir) => {
|
|
|
39
44
|
module.exports = {
|
|
40
45
|
readPackageJson,
|
|
41
46
|
writePackageJson,
|
|
42
|
-
|
|
47
|
+
getWorkflowSourceFilepath,
|
|
48
|
+
copyWorkflowFromSkeleton
|
|
43
49
|
}
|