Skip to content

Commit 618279a

Browse files
committed
[TASK] add ciUpload cmd to uload files based on .cihsignore file
1 parent a345987 commit 618279a

File tree

5 files changed

+168
-5
lines changed

5 files changed

+168
-5
lines changed

lib/cmd/ciUpload.exec.js

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { ciUpload } from './ciUpload.js'
2+
ciUpload()

lib/cmd/ciUpload.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import '../utils/check.js'
2+
import { themeName } from '../hubspot/theme.js'
3+
import { loadAuthConfig } from '../hubspot/auth/auth.js'
4+
import { ciUploadTheme } from '../hubspot/upload.js'
5+
import { cleanVendorDestFolder } from '../compile/clean.js'
6+
import { compileScss } from '../compile/sass.js'
7+
import { compileCss } from '../compile/css.js'
8+
import { compileJs } from '../compile/js.js'
9+
import { compileFieldsJs } from '../hubspot/fields.js'
10+
import * as ui from '../utils/ui.js'
11+
import chalk from 'chalk'
12+
13+
/**
14+
* #### CI Upload theme to HUBSPOT cms portall
15+
* @async
16+
* @memberof Commands
17+
* @example
18+
* // run with node
19+
* echo "import '@resultify/hubspot-cms-lib/ciUpload'" > ciUpload.js
20+
* node ciUpload.js
21+
*
22+
*
23+
* // run with npm by adding to package.json scripts:
24+
* "scripts": {
25+
* "ciUpload": "cmslib --ciUpload",
26+
* }
27+
* or
28+
* "scripts": {
29+
* "ciUpload": "node -e 'import(`@resultify/hubspot-cms-lib/ciUpload`)'"
30+
* }
31+
* npm run ciUpload
32+
*/
33+
async function ciUpload () {
34+
const timeStart = ui.startTaskGroup(`Clean upload ${chalk.yellow(themeName)}`)
35+
const hubAuthData = await loadAuthConfig()
36+
await cleanVendorDestFolder()
37+
await compileScss()
38+
await compileCss()
39+
await compileJs()
40+
await compileFieldsJs()
41+
await ciUploadTheme(hubAuthData, themeName)
42+
ui.endTaskGroup({ taskName: `Clean upload ${chalk.yellow(themeName)}`, timeStart })
43+
}
44+
45+
export { ciUpload }

lib/hubspot/upload.js

+117-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/** @module hubspot/upload */
22
/// <reference path="../types/types.js" />
3+
import fsPromises from 'fs/promises'
34
import uploadFolder from '@hubspot/local-dev-lib/cms/uploadFolder'
45
import { deleteFile, getDirectoryContentsByPath } from '@hubspot/local-dev-lib/api/fileMapper'
56
import { setLogLevel, LOG_LEVEL } from '@hubspot/local-dev-lib/logger'
@@ -9,6 +10,7 @@ import { walk } from '@hubspot/local-dev-lib/fs'
910
import * as ui from '../utils/ui.js'
1011
import { getThemeOptions } from '../utils/options.js'
1112
import { throwErrorIfMissingScope } from './auth/scopes.js'
13+
import { isFileDir } from '../utils/fs.js'
1214
import ora from 'ora'
1315
import chalk from 'chalk'
1416

@@ -47,6 +49,59 @@ const getUploadableFileList = async (src) => {
4749
return allowedFiles
4850
}
4951

52+
/**
53+
* #### Reads the .cihsignore file and returns the list of files to ignore.
54+
* @private
55+
* @async
56+
* @returns {Promise<string[]>} List of files to ignore.
57+
*/
58+
async function readCihsIgnore () {
59+
try {
60+
if (await isFileDir(`${process.cwd()}/.cihsignore`)) {
61+
const ignoreContent = await fsPromises.readFile(`${process.cwd()}/.cihsignore`, 'utf8')
62+
return ignoreContent.split('\n').map(line => line.trim()).filter(line => line && !line.startsWith('#'))
63+
} else {
64+
return []
65+
}
66+
} catch (error) {
67+
console.error('Error reading .cihsignore file:', error)
68+
return []
69+
}
70+
}
71+
72+
/**
73+
* #### Walks the src folder for files, filters them based on ignore filter and CI .cihsignore file.
74+
* @async
75+
* @private
76+
* @param {string} src - src folder
77+
* @returns {Promise<Array<string>>} src file list
78+
*/
79+
const getCiUploadableFileList = async (src) => {
80+
/**
81+
* @type {Array<string>}
82+
*/
83+
let filePaths = []
84+
try {
85+
filePaths = await walk(src)
86+
} catch (error) {
87+
console.error(error)
88+
}
89+
let allowedFiles = filePaths.filter((/** @type {any} */ file) => {
90+
if (!isAllowedExtension(file)) {
91+
return false
92+
}
93+
return true
94+
// @ts-ignore
95+
}).filter(createIgnoreFilter())
96+
97+
async function filterFiles (/** @type {any} */ files) {
98+
const ignoredPaths = await readCihsIgnore()
99+
return files.filter((/** @type {any} */ file) => !ignoredPaths.some(ignoredPath => file.includes(ignoredPath)))
100+
}
101+
allowedFiles = await filterFiles(allowedFiles)
102+
return allowedFiles
103+
}
104+
50105
/**
51106
* #### upload all HubSpot theme files
52107
* @async
@@ -111,8 +166,8 @@ async function cleanUploadThemeTemplates (config, themeName) {
111166
setLogLevel(LOG_LEVEL.NONE)
112167
const uploadableFileList = await getUploadableFileList(src)
113168
const filesToDelete = await getDirectoryContentsByPath(portalId, dest)
114-
if (filesToDelete !== undefined && filesToDelete.children.length > 0) {
115-
for await (const file of filesToDelete.children) {
169+
if (filesToDelete !== undefined && filesToDelete.data.children.length > 0) {
170+
for await (const file of filesToDelete.data.children) {
116171
// @ts-ignore
117172
if (file.includes('.html')) {
118173
await deleteFile(portalId, `${dest}/${file}`)
@@ -168,8 +223,8 @@ async function cleanUploadTheme (config, themeName) {
168223
const uploadableFileList = await getUploadableFileList(src)
169224
spinner.start()
170225
const filesToDelete = await getDirectoryContentsByPath(portalId, '/')
171-
if (filesToDelete !== undefined && filesToDelete.children.length > 0) {
172-
for await (const file of filesToDelete.children) {
226+
if (filesToDelete !== undefined && filesToDelete.data.children.length > 0) {
227+
for await (const file of filesToDelete.data.children) {
173228
// @ts-ignore
174229
if (file === dest) {
175230
await deleteFile(portalId, file)
@@ -204,4 +259,61 @@ async function cleanUploadTheme (config, themeName) {
204259
}
205260
}
206261

207-
export { uploadTheme, cleanUploadThemeTemplates, cleanUploadTheme }
262+
/**
263+
* #### CI clean theme upload
264+
* @async
265+
* @param {HUBSPOT_AUTH_CONFIG} config - hubspot authentication config
266+
* @param {string} themeName - theme name
267+
* @returns undefined
268+
*/
269+
async function ciUploadTheme (config, themeName) {
270+
const timeStart = ui.startTask('ciUpload')
271+
const dest = themeName
272+
const spinner = ora(`Clean ${dest} folder before upload`)
273+
try {
274+
const cmslibOptions = getThemeOptions()
275+
const src = `${process.cwd()}/${cmslibOptions.themeFolder}`
276+
const portalId = config.portals[0].portalId
277+
278+
throwErrorIfMissingScope(config, 'design_manager')
279+
setLogLevel(LOG_LEVEL.LOG)
280+
const uploadableFileList = await getCiUploadableFileList(src)
281+
spinner.start()
282+
const filesToDelete = await getDirectoryContentsByPath(portalId, '/')
283+
if (filesToDelete !== undefined && filesToDelete.data.children.length > 0) {
284+
for await (const file of filesToDelete.data.children) {
285+
// @ts-ignore
286+
if (file === dest) {
287+
await deleteFile(portalId, file)
288+
}
289+
}
290+
}
291+
spinner.succeed()
292+
await uploadFolder.uploadFolder(
293+
portalId,
294+
src,
295+
dest,
296+
{ overwrite: false },
297+
{ saveOutput: true, convertFields: false },
298+
uploadableFileList,
299+
cmsMode
300+
)
301+
ui.endTask({ taskName: 'ciUpload', timeStart })
302+
} catch (error) {
303+
spinner.fail()
304+
if (error.cause.response.data.errorType === 'TEMPLATE_VALIDATION_FAILED') {
305+
console.error(chalk.red(error.cause.response.data.errorType))
306+
console.error(error.message)
307+
process.exitCode = 1
308+
} else {
309+
console.error(error.message)
310+
process.exitCode = 1
311+
}
312+
if (process.env.DEBUG_MODE === 'debug') {
313+
console.error(error)
314+
process.exitCode = 1
315+
}
316+
}
317+
}
318+
319+
export { uploadTheme, cleanUploadThemeTemplates, cleanUploadTheme, ciUploadTheme }

lib/init.js

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { watch } from './cmd/watch.js'
44
import { hubspotFetchAll } from './cmd/fetch.js'
55
import { hubspotFetchModules } from './cmd/fetchModules.js'
66
import { upload } from './cmd/upload.js'
7+
import { ciUpload } from './cmd/ciUpload.js'
78
import { cleanUpload } from './cmd/cleanUpload.js'
89
import { validate } from './cmd/validate.js'
910
import { lighthouse } from './cmd/lighthouse.js'
@@ -23,6 +24,8 @@ function init () {
2324
hubspotFetchModules()
2425
} else if (args.upload) {
2526
upload()
27+
} else if (args.ciUpload) {
28+
ciUpload()
2629
} else if (args.cleanUpload) {
2730
cleanUpload()
2831
} else if (args.validate) {

lib/utils/arg.js

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const argOptions = {
1010
'fetch',
1111
'fetchModules',
1212
'upload',
13+
'ciUpload',
1314
'cleanUpload',
1415
'validate',
1516
'lighthouse',

0 commit comments

Comments
 (0)