UNPKG

@gravityforms/gulp-tasks

Version:
436 lines (347 loc) 18.3 kB
const fs = require( 'fs' ); const gulp = require( 'gulp' ); const getConfig = require( './config' ); const { config } = getConfig(); const simpleGit = require( 'simple-git' ); const getPluginVersion = require( './src/utils/get-plugin-version' ); const { loadEnv } = require( './src/utils/tools' ); const prePackage = require( './src/scripts/pre-package' ); const sendSlackMessage = require( './src/utils/send-slack-message' ); process.env.GRAVITY_PLUGIN_VERSION = ( config?.paths?.root && config?.settings?.rootPluginFile ) ? getPluginVersion( config.paths.root, config.settings.rootPluginFile ) : ''; loadEnv( config.paths.root ); const publishDocs = require( './src/publish/docs' ); const requireDir = require( 'require-dir' ); const findConfig = require( 'find-config' ); const tasks = requireDir( './src/tasks' ); const browserSync = require( 'browser-sync' ).create( config?.browserSync?.serverName || 'gravity-dev' ); const localConfig = findConfig.require( 'local-config.json' ); const bsConfig = localConfig || { proxy: config?.browserSync?.defaultUrl || '', certs_path: '', }; const git = simpleGit( config.paths.root ); /** * List out your tasks as defined in the gulp_tasks directory * require-dir module will bring those in here as an object * Each task type object will be named by its filename * So: 'postcss:admin' means a file named 'postcss' in the gulp-tasks dir, * and the method admin inside that modules export. * You must follow this approach, or modify the registerTasks function below. * * @type {string[]} */ const customBuiltInTasks = config?.tasks?.builtinsTasks || []; let gulpTasks = [ /* AWS tasks */ 'awspublish:publishReleaseZip', // publish release zip to AWS 'awspublish:publishReleaseChangelog', // publish release changelog to AWS 'awspublish:publishReleaseChecksums', // publish release checksums to AWS, 'awspublish:publishReleasePotFile', // publish release pot file to AWS /* Checksum tasks */ 'checksum:release', // create a checksum file for the release /* Clean CSS Tasks */ 'clean-css:minifyAssetFiles', // minify asset files 'clean-css:minifyFiles', // minify css files in passed directory 'clean-css:minifyDistFiles', // minify css dist directory files /* Copy tasks */ 'copy:iconsFonts', // copy fonts for icons from dev folder to fonts directory 'copy:iconsStyles', // copy styles for icons to pcss shared dir 'copy:iconsVariables', // copy variables for icons to theme pcss variables dir 'copy:packagesDistJS', // copy dist js files from packages to js dist of project 'copy:tokensCss', // copy tokens css to the project /* Clean tasks */ 'clean:css', // clean all css 'clean:gravityForms', // clean all min css and js in gravity forms 'clean:iconsEnd', // delete all files related to target icons in pcss, in prep for reinjection 'clean:iconsStart', // delete all files related to target icons in pcss, in prep for reinjection 'clean:js', // clean chunks javascript 'clean:nonMinAssetCss', // clean non minified css in assets directory /* Decompress tasks */ 'decompress:icons', // extract icomoon kit to dev directory /* Eslint tasks */ 'eslint:admin', // lints and fixes the admin js 'eslint:common', // lints and fixes the common js 'eslint:theme', // lints and fixes the theme js /* Footer tasks */ 'footer:iconsVariables', // just adds a closing } to the icons variables file during the icons import transform tasks /* Header tasks */ 'header:iconsStyle', // sets the header for the icons style file in base during the icons import transform tasks 'header:iconsVariables', // sets the header for the icons style file in vars during the icons import transform tasks /* Postcss tasks */ 'postcss:adminComponentsCss', // the postcss task that transforms admin component css 'postcss:adminCss', // the postcss task that transforms admin css 'postcss:adminThemeCss', // the postcss task that transforms the front end theme components used in the admin 'postcss:commonComponentsCss', // the postcss task that transforms common components css 'postcss:commonCss', // the postcss task that transforms common css 'postcss:themeComponentsCss', // the postcss task that transforms theme component css 'postcss:themeCss', // the postcss task that transforms theme css 'postcss:themeFrameworkCss', // the postcss task that transforms theme framework css 'postcss:componentsAdminDistCss', // the postcss task that transforms admin components css for publish 'postcss:componentsCommonDistCss', // the postcss task that transforms common components css for publish 'postcss:componentsThemeDistCss', // the postcss task that transforms theme components css for publish /* Replace tasks */ 'replace:adminComponentsWrapperPrefix', // replaces the gform-admin wrapper css prefix in our admin components css if one is passed in the config 'replace:commonComponentsWrapperPrefix', // replaces the gform-common wrapper css prefix in our common components css if one is passed in the config 'replace:themeComponentsWrapperPrefix', // replaces the gform-theme wrapper css prefix in our theme components css if one is passed in the config 'replace:adminComponentsIconFontName', // replaces the icon font name in the admin components css 'replace:iconsStyle', // runs regex to replace and convert scss to pcss compatible with our systems in the icons task 'replace:iconsVariables', // runs regex to replace and convert scss to pcss compatible with our systems in the icons task 'replace:templateStrings', // replaces template strings in specified files. /* Shell tasks */ 'shell:composerInstall', // runs composer install 'shell:test', // runs jests tests 'shell:processJsHashes', // creates a php manifest file with hashes for our javascript files 'shell:exportComponents', // exports components from storybooks to components library 'shell:exportComponentsNoClean', // exports components from storybooks to components library without cleaning files 'shell:generateDesignTokenProps', // generates design token props 'shell:generatePot', // generates pot files 'shell:gitTagRelease', // tags the release in git 'shell:gitUploadRelease', // uploads the release to the github repo 'shell:linkMonorepo', // links the monorepo 'shell:packageWpCom', // packages the release for wpcom 'shell:restoreState', // restores the state of the release 'shell:scriptsThemeDev', // runs webpack for the theme dev build 'shell:scriptsThemeDevRelease', // runs webpack for the theme dev build with no dev tools 'shell:scriptsThemeProd', // runs webpack for the theme prod build 'shell:scriptsThemeProdRelease', // runs webpack for the theme prod build with no dev tools 'shell:scriptsAdminDev', // runs webpack for the admin dev build 'shell:scriptsAdminDevRelease', // runs webpack for the admin dev build with no dev tools 'shell:scriptsAdminProd', // runs webpack for the admin prod build 'shell:scriptsAdminProdRelease', // runs webpack for the admin prod build with no dev tools 'shell:scriptsAdminSettingsDev', // runs webpack for the admin settings legacy dev build 'shell:scriptsAdminSettingsDevRelease', // runs webpack for the admin settings legacy dev build with no dev tools 'shell:scriptsAdminSettingsProd', // runs webpack for the admin settings legacy prod build 'shell:scriptsAdminSettingsProdRelease', // runs webpack for the admin settings legacy prod build with no dev tools 'shell:scriptsAdminBlocksDev', // runs webpack for the admin settings legacy dev build 'shell:scriptsAdminBlocksDevRelease', // runs webpack for the admin settings legacy dev build with no dev tools 'shell:scriptsAdminBlocksProd', // runs webpack for the admin settings legacy prod build 'shell:scriptsAdminBlocksProdRelease', // runs webpack for the admin settings legacy prod build with no dev tools 'shell:scriptsAdminComponentsDev', // runs webpack for the components dev build 'shell:scriptsAdminComponentsDevRelease', // runs webpack for the components dev build with no dev tools 'shell:scriptsAdminComponentsProd', // runs webpack for the components prod build 'shell:scriptsAdminComponentsProdRelease', // runs webpack for the components prod build with no dev tools 'shell:scriptsLegacyDev', // runs webpack for the legacy dev build 'shell:scriptsLegacyDevRelease', // runs webpack for the legacy dev build with no dev tools 'shell:scriptsLegacyProd', // runs webpack for the legacy prod build 'shell:scriptsLegacyProdRelease', // runs webpack for the legacy prod build with no dev tools 'shell:scriptsLibrariesDev', // runs webpack for the libraries dev build 'shell:scriptsLibrariesDevRelease', // runs webpack for the libraries dev build with no dev tools 'shell:scriptsLibrariesProd', // runs webpack for the libraries prod build 'shell:scriptsLibrariesProdRelease', // runs webpack for the libraries prod build with no dev tools 'shell:scriptsReactUtilsDev', // runs webpack for the utils dev build 'shell:scriptsReactUtilsDevRelease', // runs webpack for the React utils dev build with no dev tools 'shell:scriptsReactUtilsProd', // runs webpack for the React utils prod build 'shell:scriptsReactUtilsProdRelease', // runs webpack for the React utils prod build with no dev tools 'shell:updateManagerVersion', // updates the manager version for the release to latest 'shell:updateSlackPackage', // updates the slack channel with the package details 'shell:updateSlackPublish', // updates the slack channel with the publish details 'shell:uploadToDrive', // uploads the release to google drive 'shell:scriptsUtilsDev', // runs webpack for the React utils dev build 'shell:scriptsUtilsDevRelease', // runs webpack for the utils dev build with no dev tools 'shell:scriptsUtilsProd', // runs webpack for the utils prod build 'shell:scriptsUtilsProdRelease', // runs webpack for the utils prod build with no dev tools 'shell:webpackAddOns', // runs webpack for the add ons build when using legacy approach /* Stylelint tasks */ 'stylelint:admin', // lints and fixes the admin pcss 'stylelint:common', // lints and fixes the common pcss 'stylelint:theme', // lints and fixes the theme pcss /* Uglify tasks */ 'uglify:minifyFiles', // minifies the legacy js /* Zip tasks */ 'zip:package', // create a zip ready of the release in the root directory 'zip:packageWpCom', // create a zip ready of the release in the root directory for wpcom ]; gulpTasks = gulpTasks.concat( customBuiltInTasks ); gulpTasks = gulpTasks.concat( [ 'watch:main', // watch all fe assets and run appropriate routines 'watch:watchAdminJS', // watch admin js and run appropriate webpack tasks 'watch:watchAdminSettingsJS', // watch admin settings legacy js and run appropriate webpack tasks 'watch:watchThemeJS', // watch theme js and run appropriate webpack tasks ] ); /** * Iterate over the above array. Split on the colon to access the imported tasks array's * corresponding function for the current task in the loop */ function registerTasks( tasksArray, taskModules ) { tasksArray.forEach( ( task ) => { const parts = task.split( ':' ); gulp.task( task, taskModules[ parts[ 0 ] ][ parts[ 1 ] ] ); } ); } /** * Sets variables in the process environment. */ function setupRunningTask( taskName ) { return async function setEnv( done ) { await sendSlackMessage( `Your build results will be shared in #gravitybuilds, and you can monitor the build live <${ process.env.GHA_URL }|here>!`, 'success', [], process.env.SLACK_CHAT_ID ); process.env.GRAVITY_GULP_TASK = taskName; try { const status = await git.status(); process.env.GRAVITY_CURRENT_BRANCH = status.current; if ( taskName === 'package' || taskName === 'publish' ) { await prePackage(); process.env.GRAVITY_PLUGIN_VERSION = ( config?.paths?.root && config?.settings?.rootPluginFile ) ? getPluginVersion( config.paths.root, config.settings.rootPluginFile ) : ''; } } catch ( error ) { console.error( 'Failed to set current branch name:', error ); } done(); }; } /** * Register all tasks in the src directory */ registerTasks( gulpTasks, tasks ); /** * Register external tasks */ if ( config?.tasks?.custom && config?.tasks?.customDir && fs.existsSync( config.tasks.customDir ) ) { const externalTaskModules = requireDir( config.tasks.customDir ); registerTasks( config.tasks.custom, externalTaskModules ); } const watchTasks = config?.watchTasks ? config.watchTasks : [ 'watch:main', 'watch:watchAdminJS', 'watch:watchThemeJS' ]; gulp.task( 'watch', gulp.parallel( watchTasks ) ); /** * Watches all css and js for bundle, runs tasks and reloads browser using browsersync. */ gulp.task( 'dev', gulp.parallel( watchTasks, async function() { browserSync.init( { watchTask: true, debugInfo: true, logConnections: true, notify: true, open: 'external', host: bsConfig.proxy, proxy: `https://${ bsConfig.proxy }`, https: { key: `${ bsConfig.certs_path }/${ bsConfig.proxy }.key`, cert: `${ bsConfig.certs_path }/${ bsConfig.proxy }.crt`, }, ghostMode: { scroll: true, links: true, forms: true, }, } ); } ) ); // lint config const lintRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'lint' )[ 0 ]; if ( lintRunner ) { let lintTasks = []; if ( lintRunner?.tasks ) { lintTasks = lintRunner.tasks.map( ( task ) => gulp.parallel( task ) ); } gulp.task( 'lint', gulp.series( setupRunningTask( 'lint' ), ...lintTasks ) ); } /** * Takes a zip file from icomoon and injects it into the postcss, modifying the scss to pcss and handling all conversions/cleanup. */ const iconsRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'icons' )[ 0 ]; if ( iconsRunner ) { gulp.task( 'icons', gulp.series( setupRunningTask( 'icons' ), iconsRunner.tasks ) ); } const componentsExportRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'export:components' )[ 0 ]; if ( componentsExportRunner ) { gulp.task( 'export:components', gulp.series( setupRunningTask( 'export:components' ), componentsExportRunner.tasks ) ); } const adminComponentsRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'components:admin' )[ 0 ]; if ( adminComponentsRunner ) { gulp.task( 'components:admin', gulp.series( setupRunningTask( 'components:admin' ), adminComponentsRunner.tasks ) ); } const commonComponentsRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'components:common' )[ 0 ]; if ( commonComponentsRunner ) { gulp.task( 'components:common', gulp.series( setupRunningTask( 'components:common' ), commonComponentsRunner.tasks ) ); } const themeComponentsRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'components:theme' )[ 0 ]; if ( themeComponentsRunner ) { gulp.task( 'components:theme', gulp.series( themeComponentsRunner.tasks ) ); } /** * Builds the npm packages dist files, use before publishing components, libraries, react-utils, utils. */ const packagesRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'packages' )[ 0 ]; if ( packagesRunner ) { let packagesTasks = []; if ( packagesRunner?.tasks ) { packagesTasks = packagesRunner.tasks.map( ( task ) => gulp.parallel( task ) ); } gulp.task( 'packages', gulp.series( setupRunningTask( 'packages' ), ...packagesTasks ) ); } /* * Minifies the legacy css files for production release */ const cleanMinRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'clean:min' )[ 0 ]; if ( cleanMinRunner ) { let cleanMinTasks = []; if ( cleanMinRunner?.tasks ) { cleanMinTasks = cleanMinRunner.tasks.map( ( task ) => gulp.parallel( task ) ); } gulp.task( 'clean:min', gulp.series( setupRunningTask( 'clean:min' ), ...cleanMinTasks ) ); } /** * Minifies the legacy js files for production release */ const minifyRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'minify' )[ 0 ]; if ( minifyRunner ) { let minifyTasks = []; if ( minifyRunner?.tasks ) { minifyTasks = minifyRunner.tasks.map( ( task ) => gulp.parallel( task ) ); } gulp.task( 'minify', gulp.series( setupRunningTask( 'minify' ), ...minifyTasks ) ); } /** * Builds the js and css files for local dev */ const distRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'dist' )[ 0 ]; if ( distRunner ) { let distTasks = []; if ( distRunner?.tasks ) { distTasks = distRunner.tasks.map( ( task ) => gulp.parallel( task ) ); } gulp.task( 'dist', gulp.series( setupRunningTask( 'dist' ), ...distTasks ) ); gulp.task( 'default', gulp.series( 'dist' ) ); } /** * Builds the js and css files for production release */ const releaseRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'release' )[ 0 ]; if ( releaseRunner ) { let releaseTasks = []; if ( releaseRunner?.tasks ) { releaseTasks = releaseRunner.tasks.map( ( task ) => gulp.parallel( task ) ); } gulp.task( 'release', gulp.series( setupRunningTask( 'release' ), ...releaseTasks ) ); } /** * Builds the zip file and uploads it google drive and notifies slack */ const packageRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'package' )[ 0 ]; if ( packageRunner ) { let packageTasks = []; if ( packageRunner?.tasks ) { packageTasks = packageRunner.tasks.map( ( task ) => gulp.parallel( task ) ); } gulp.task( 'package', gulp.series( setupRunningTask( 'package' ), ...packageTasks ) ); } /** * Packages the release and publishes as per the config (git tag, aws, etc.) */ const publishRunner = config?.tasks?.runners.filter( ( entry ) => entry.name === 'publish' )[ 0 ]; if ( publishRunner ) { let publishTasks = []; if ( publishRunner?.tasks ) { publishTasks = publishRunner.tasks.map( ( task ) => gulp.parallel( task ) ); } gulp.task( 'publish', gulp.series( setupRunningTask( 'publish' ), ...publishTasks ) ); } /** * Document publishing tasks, run by packages monorepo mainly. */ const publishDocsRunners = config?.tasks?.runners.filter( ( entry ) => entry.name === 'publishDocs' )[ 0 ]; if ( publishDocsRunners ) { publishDocsRunners.tasks.forEach( ( publishDocsTask ) => { gulp.task( publishDocsTask.name, async function() { return publishDocs.sync( publishDocsTask.path, publishDocsTask.params ); } ); } ); }