@gravityforms/gulp-tasks
Version:
Configurable Gulp tasks for use in Gravity Forms projects.
436 lines (347 loc) • 18.3 kB
JavaScript
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 );
} );
} );
}