From ab2197e02112110c206def17971a9c46405235ed Mon Sep 17 00:00:00 2001 From: Dmitry Mayorov Date: Mon, 22 Apr 2024 15:19:05 -0400 Subject: [PATCH 01/17] Add logic for block style entry points --- packages/toolkit/config/paths.config.js | 7 +++--- packages/toolkit/config/webpack/entry.js | 30 ++++++++++++++++++++++-- packages/toolkit/utils/config.js | 1 + 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/packages/toolkit/config/paths.config.js b/packages/toolkit/config/paths.config.js index a22f3eef..21879748 100644 --- a/packages/toolkit/config/paths.config.js +++ b/packages/toolkit/config/paths.config.js @@ -1,6 +1,7 @@ module.exports = { - srcDir: './assets/', - cssLoaderPaths: ['./assets/css', './includes/blocks'], - copyAssetsDir: './assets/', blocksDir: './includes/blocks/', + blocksStyles: './assets/css/blocks/', + copyAssetsDir: './assets/', + cssLoaderPaths: ['./assets/css', './includes/blocks'], + srcDir: './assets/', }; diff --git a/packages/toolkit/config/webpack/entry.js b/packages/toolkit/config/webpack/entry.js index 5f66b3af..dd2ffbca 100644 --- a/packages/toolkit/config/webpack/entry.js +++ b/packages/toolkit/config/webpack/entry.js @@ -9,11 +9,12 @@ const removeDistFolder = (file) => { module.exports = ({ buildType = 'script', isPackage, - projectConfig: { devServer, paths, useBlockAssets, filenames }, + projectConfig: { devServer, paths, useBlockAssets, filenames, loadBlockSpecificStyles }, packageConfig: { packageType, source, main, umd, libraryName }, buildFiles, }) => { let additionalEntrypoints = {}; + if (useBlockAssets) { // override default block filenames filenames.block = 'blocks/[name].js'; @@ -104,12 +105,37 @@ module.exports = ({ }, {}); } + const blockStyleEntryPoints = {}; + + // Logic for loading CSS files per block. + if (loadBlockSpecificStyles) { + // get all stylesheets located in the assets/css/blocks directory and subdirectories + const blockStylesheetDirectory = resolve(process.cwd(), paths.blocksStyles); + + // get all stylesheets in the blocks directory + const stylesheets = glob( + // glob only accepts forward-slashes this is required to make things work on Windows + `${blockStylesheetDirectory.replace(/\\/g, '/')}/**/*.css`, + { + absolute: true, + }, + ); + + stylesheets.forEach((filePath) => { + const blockName = filePath + .replace(`${blockStylesheetDirectory}/`, '') + .replace(extname(filePath), ''); + + blockStyleEntryPoints[`autoenqueue/${blockName}`] = resolve(filePath); + }); + } + if (buildType === 'module') { return additionalEntrypoints; } // merge the new entrypoints with the existing ones - Object.assign(buildFiles, additionalEntrypoints); + Object.assign(buildFiles, additionalEntrypoints, blockStyleEntryPoints); if (isPackage) { const config = {}; diff --git a/packages/toolkit/utils/config.js b/packages/toolkit/utils/config.js index ca8554ad..c9cebb46 100644 --- a/packages/toolkit/utils/config.js +++ b/packages/toolkit/utils/config.js @@ -139,6 +139,7 @@ const getDefaultConfig = () => { !process.env.TENUP_NO_EXTERNALS, publicPath: process.env.ASSET_PATH || undefined, useBlockAssets: true, + loadBlockSpecificStyles: false, useBlockModules, include, }; From 2ad198680524363c13ea1477315b4aa2a3780079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 9 Jul 2024 17:45:33 +0200 Subject: [PATCH 02/17] fix transform file extension for .ts and .tsx assets inside block.json files --- packages/toolkit/config/webpack/plugins.js | 4 +-- packages/toolkit/utils/__tests__/blocks.js | 16 ++++++------ packages/toolkit/utils/blocks.js | 29 ++++++++++++++++++++-- packages/toolkit/utils/index.js | 4 +-- 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/packages/toolkit/config/webpack/plugins.js b/packages/toolkit/config/webpack/plugins.js index 1d00c6ee..4ea7c0cd 100644 --- a/packages/toolkit/config/webpack/plugins.js +++ b/packages/toolkit/config/webpack/plugins.js @@ -19,7 +19,7 @@ const { fromConfigRoot, hasProjectFile, getArgFromCLI, - maybeInsertStyleVersionHash, + transformBlockJson, } = require('../../utils'); const { isPackageInstalled } = require('../../utils/package'); @@ -164,7 +164,7 @@ module.exports = ({ noErrorOnMissing: true, to: 'blocks/[path][name][ext]', transform: (content, absoluteFilename) => { - return maybeInsertStyleVersionHash(content, absoluteFilename); + return transformBlockJson(content, absoluteFilename); }, }, useBlockAssets && { diff --git a/packages/toolkit/utils/__tests__/blocks.js b/packages/toolkit/utils/__tests__/blocks.js index 9399f8fd..4703cb5b 100644 --- a/packages/toolkit/utils/__tests__/blocks.js +++ b/packages/toolkit/utils/__tests__/blocks.js @@ -1,5 +1,5 @@ import path from 'path'; -import { maybeInsertStyleVersionHash } from '../blocks'; +import { transformBlockJson } from '../blocks'; import { getFileContentHash as getFileContentHashMock } from '../file'; jest.mock('../file', () => { @@ -10,12 +10,12 @@ jest.mock('../file', () => { return module; }); -describe('maybeInsertStyleVersionHash', () => { +describe('transformBlockJson', () => { const absoluteteFileName = path.join('dist', 'blocks', 'block.json'); it('does nothing if version is set', () => { expect( - maybeInsertStyleVersionHash( + transformBlockJson( JSON.stringify({ version: 1, style: 'file:./style.css', @@ -27,7 +27,7 @@ describe('maybeInsertStyleVersionHash', () => { it('does nothing if style is not set', () => { expect( - maybeInsertStyleVersionHash( + transformBlockJson( JSON.stringify({ script: 'file:./script.js', }), @@ -42,7 +42,7 @@ describe('maybeInsertStyleVersionHash', () => { it('does nothing if style does not start with file:', () => { expect( - maybeInsertStyleVersionHash( + transformBlockJson( JSON.stringify({ style: 'style.css', }), @@ -51,7 +51,7 @@ describe('maybeInsertStyleVersionHash', () => { ).toEqual(JSON.stringify({ style: 'style.css' })); expect( - maybeInsertStyleVersionHash( + transformBlockJson( JSON.stringify({ style: ['another-css', 'style.css'], }), @@ -64,7 +64,7 @@ describe('maybeInsertStyleVersionHash', () => { getFileContentHashMock.mockReturnValue('12345678'); expect( - maybeInsertStyleVersionHash( + transformBlockJson( JSON.stringify({ style: 'file:./style.css', }), @@ -86,7 +86,7 @@ describe('maybeInsertStyleVersionHash', () => { ); expect( - maybeInsertStyleVersionHash( + transformBlockJson( JSON.stringify({ style: ['another-style', 'file:./style2.css'], }), diff --git a/packages/toolkit/utils/blocks.js b/packages/toolkit/utils/blocks.js index 6a35677a..9c42864b 100644 --- a/packages/toolkit/utils/blocks.js +++ b/packages/toolkit/utils/blocks.js @@ -1,7 +1,7 @@ const path = require('path'); const { getFileContentHash } = require('./file'); -const maybeInsertStyleVersionHash = (content, absoluteFilename) => { +const transformBlockJson = (content, absoluteFilename) => { const rawMetadata = content.toString(); if (rawMetadata === '') { return content; @@ -32,14 +32,39 @@ const maybeInsertStyleVersionHash = (content, absoluteFilename) => { styleFileContentHash += getFileContentHash(absoluteStylePath); }); + const { script, editorScript, viewScript, viewScriptModule, scriptModule } = metadata; + + const jsAssets = [script, editorScript, viewScript, viewScriptModule, scriptModule].filter( + Boolean, + ); + + const transformedJsAssets = jsAssets.map((asset) => { + const assetArray = Array.isArray(asset) ? asset : [asset]; + + return assetArray.map((rawJsPath) => { + if (!rawJsPath.startsWith('file:')) { + return rawJsPath; + } + const isFilePath = rawJsPath.startsWith('file:'); + if (!isFilePath) { + return rawJsPath; + } + + // replace the `.ts or .tsx` extension with `.js` + const jsPath = rawJsPath.replace(/\.tsx?$/, '.js'); + return jsPath; + }); + }); + return JSON.stringify( { ...metadata, version: styleFileContentHash, + ...transformedJsAssets, }, null, 2, ); }; -module.exports = { maybeInsertStyleVersionHash }; +module.exports = { transformBlockJson }; diff --git a/packages/toolkit/utils/index.js b/packages/toolkit/utils/index.js index ca7245bf..391e388e 100644 --- a/packages/toolkit/utils/index.js +++ b/packages/toolkit/utils/index.js @@ -32,7 +32,7 @@ const { hasPackageProp, getPackagePath, getPackage, getPackageVersion } = requir const { displayWebpackStats } = require('./webpack'); -const { maybeInsertStyleVersionHash } = require('./blocks'); +const { transformBlockJson } = require('./blocks'); const { getProjectRoot, @@ -78,5 +78,5 @@ module.exports = { getTenUpScriptsPackageBuildConfig, hasWebpackConfig, displayWebpackStats, - maybeInsertStyleVersionHash, + transformBlockJson, }; From bb94bf5a9213f453173c6fd5e28a62f59133da84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 9 Jul 2024 17:48:52 +0200 Subject: [PATCH 03/17] add test cases --- packages/toolkit/utils/__tests__/blocks.js | 51 ++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/packages/toolkit/utils/__tests__/blocks.js b/packages/toolkit/utils/__tests__/blocks.js index 4703cb5b..86d3f265 100644 --- a/packages/toolkit/utils/__tests__/blocks.js +++ b/packages/toolkit/utils/__tests__/blocks.js @@ -107,4 +107,55 @@ describe('transformBlockJson', () => { path.join('dist', 'blocks', 'style2.css'), ); }); + + it('transforms ts and tsx to js', () => { + expect( + transformBlockJson( + JSON.stringify({ + script: 'file:./script.ts', + editorScript: 'file:./editor.tsx', + viewScript: 'file:./view.ts', + viewScriptModule: 'file:./view.tsx', + scriptModule: 'file:./script.tsx', + }), + absoluteteFileName, + ), + ).toEqual( + JSON.stringify( + { + script: 'file:./script.js', + editorScript: 'file:./editor.js', + viewScript: 'file:./view.js', + viewScriptModule: 'file:./view.js', + scriptModule: 'file:./script.js', + }, + null, + 2, + ), + ); + expect( + transformBlockJson( + JSON.stringify({ + script: ['file:./script.ts', 'file:./script.tsx'], + editorScript: ['file:./editor.ts', 'file:./editor.tsx'], + viewScript: ['file:./view.ts', 'file:./view.tsx'], + viewScriptModule: ['file:./view.tsx', 'file:./view.ts'], + scriptModule: ['file:./script.ts', 'file:./script.tsx'], + }), + absoluteteFileName, + ), + ).toEqual( + JSON.stringify( + { + script: ['file:./script.js', 'file:./script.js'], + editorScript: ['file:./editor.js', 'file:./editor.js'], + viewScript: ['file:./view.js', 'file:./view.js'], + viewScriptModule: ['file:./view.js', 'file:./view.js'], + scriptModule: ['file:./script.js', 'file:./script.js'], + }, + null, + 2, + ), + ); + }); }); From 7ce09d9a413f8bba3cf5d0d217a465dbb54c4955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20K=C3=A4gy?= Date: Tue, 9 Jul 2024 17:50:54 +0200 Subject: [PATCH 04/17] Create young-guests-deliver.md --- .changeset/young-guests-deliver.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/young-guests-deliver.md diff --git a/.changeset/young-guests-deliver.md b/.changeset/young-guests-deliver.md new file mode 100644 index 00000000..8576d4b6 --- /dev/null +++ b/.changeset/young-guests-deliver.md @@ -0,0 +1,5 @@ +--- +"10up-toolkit": patch +--- + +Fix: transform file extension for .ts and .tsx assets inside block.json files From 3a5b540f84cb3aa5ab00e22b0d1051cf202065e6 Mon Sep 17 00:00:00 2001 From: Dmitry Mayorov Date: Fri, 2 Aug 2024 15:20:56 +0200 Subject: [PATCH 05/17] Add changeset --- .changeset/lemon-owls-invent.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/lemon-owls-invent.md diff --git a/.changeset/lemon-owls-invent.md b/.changeset/lemon-owls-invent.md new file mode 100644 index 00000000..45794b01 --- /dev/null +++ b/.changeset/lemon-owls-invent.md @@ -0,0 +1,5 @@ +--- +"10up-toolkit": patch +--- + +Allow block-specific CSS entry points From 8b74e5a02bdedc2e62b03d338c119629be2afd14 Mon Sep 17 00:00:00 2001 From: Dustin Rue Date: Wed, 21 Aug 2024 14:36:32 -0500 Subject: [PATCH 06/17] Feature/add more flexibility (#413) Co-authored-by: Taylor Lovett --- .changeset/eight-pumpkins-provide.md | 5 + packages/toolkit/PROJECTS.md | 24 +- .../toolkit/project/default-variables.json | 3 - .../toolkit/project/gitlab/.gitlab-ci.tmpl | 2 +- .../deploy-configs/pantheon-production.tmpl | 2 +- .../deploy-configs/pantheon-staging.tmpl | 2 +- .../deploy-configs/rsync-production.tmpl | 2 +- .../gitlab/deploy-configs/rsync-staging.tmpl | 2 +- packages/toolkit/project/local/.gitignore | 26 ++ .../toolkit/project/local/scripts/build.sh | 21 +- ...deploy-excludes.txt => rsync-excludes.txt} | 0 .../toolkit/scripts/project/bash/Dockerfile | 7 + .../scripts/project/bash/build-setup.sh | 13 - .../scripts/project/bash/create-payload.sh | 20 -- .../toolkit/scripts/project/bash/scripts.sh | 239 ++++++++++++++++++ packages/toolkit/scripts/project/build.js | 28 +- .../toolkit/scripts/project/create-payload.js | 62 ----- packages/toolkit/scripts/project/init.js | 169 +++++++------ packages/toolkit/scripts/project/package.js | 35 +++ .../scripts/project/update-composer.js | 35 +++ packages/toolkit/utils/index.js | 2 + packages/toolkit/utils/project.js | 90 +++++-- 22 files changed, 548 insertions(+), 241 deletions(-) create mode 100644 .changeset/eight-pumpkins-provide.md create mode 100644 packages/toolkit/project/local/.gitignore rename packages/toolkit/project/local/scripts/{deploy-excludes.txt => rsync-excludes.txt} (100%) create mode 100644 packages/toolkit/scripts/project/bash/Dockerfile delete mode 100644 packages/toolkit/scripts/project/bash/build-setup.sh delete mode 100644 packages/toolkit/scripts/project/bash/create-payload.sh create mode 100644 packages/toolkit/scripts/project/bash/scripts.sh delete mode 100644 packages/toolkit/scripts/project/create-payload.js mode change 100644 => 100755 packages/toolkit/scripts/project/init.js create mode 100644 packages/toolkit/scripts/project/package.js create mode 100644 packages/toolkit/scripts/project/update-composer.js diff --git a/.changeset/eight-pumpkins-provide.md b/.changeset/eight-pumpkins-provide.md new file mode 100644 index 00000000..81296755 --- /dev/null +++ b/.changeset/eight-pumpkins-provide.md @@ -0,0 +1,5 @@ +--- +"10up-toolkit": patch +--- + +Simple enhancements to toolkit project command to align with devops needs. diff --git a/packages/toolkit/PROJECTS.md b/packages/toolkit/PROJECTS.md index e1f8e2cf..5dcd94fe 100644 --- a/packages/toolkit/PROJECTS.md +++ b/packages/toolkit/PROJECTS.md @@ -58,14 +58,6 @@ In this scenario, `deploy_from` would be set to `wp` and `deploy_to_subdir` woul `deploy_type` currently supports `rsync`, `wpe` (WP Engine), and `pantheon`. It defaults to `rsync`. If WPE or Pantheon is choosen, `deploy_to` should contain a Git URL. More deploy types will be added in the future. -The following are additional optional variables that allow you to use custom scripts different than the ones provided by 10up Toolkit. You shouldn't need to use these unless you are doing something super custom. All these paths are relative from the root of your project. - -```yaml -deploy_script_path: "" # Custom deploy script -build_script_path: "" # For using a build script in a different location -create_payload_script_path: "" # Custom create payload script -``` - ## Commands The project subcommand provides a variety of utlities for creating, building, and deploying 10up-specific projects. @@ -73,27 +65,27 @@ The project subcommand provides a variety of utlities for creating, building, an List of commands: ```bash -10up-toolkit project init [] [--template=] [--name=] [--confirm] [--skip-composer] +10up-toolkit project init [--path=] [--layout=] [--template=] [--name=] [--confirm] [--skip-composer] [--skip-ci] ``` -`init` creates a project. You can optionally provide it a number of parameters or answer the prompts. If no path is provided, it will initialize the project in the current directory. You will be prompted to choose a template e.g. [WP Scaffold](https://github.com/10up/wp-scaffold). Init will automatically search and replace prefixes using the project name you provide. +`init` creates a project. You can optionally provide it a number of parameters or answer the prompts. If no path is provided, it will initialize the project in the current directory. If no layout is provided, it will default to `wpcontent` which means the project is rooted in `wp-content` (The other option is `wpparent` where the root of the project is one directory above WordPress). You will be prompted to choose a template e.g. [WP Scaffold](https://github.com/10up/wp-scaffold). Init will automatically search and replace prefixes using the project name you provide. ```bash -10up-toolkit project build +10up-toolkit project build [--type=] ``` -`build` simply executes your `scripts/build.sh` file (or other path you specify). `build` will be executed before deploying files. +`build` will build your project e.g. `composer install`, `npm install`, and `npm run build`. It will execute all the `.sh` files in your `scripts/` directory where you can add custom build logic for your particular project. `--type` defaults to local e.g. build for your local environment. In CI, type will be set to `full`. ```bash -10up-toolkit project create-payload +10up-toolkit project generate-ci [--confirm] [--path=] ``` -This command creates a payload directory of the built project (including WordPress) for deployment. Engineers likely won't need to run this command themselves as GitLab does it automatically. You must provide a branch that corresponds to an environment in `.tenup.yml`. +This command generates necessary CI files. For GitLab, this would be `.gitlab-ci.yml`. Right now this only supports GitLab but we will add support for GitHub in the future. ```bash -10up-toolkit project generate-ci [--confirm] [--path=] +10up-toolkit project update-composer ``` -This command generates necessary CI files. For GitLab, this would be `.gitlab-ci.yml`. Right now this only supports GitLab but we will add support for GitHub in the future. +Convenience function to update all dependencies in all found composer.json files. Also generates updated lock files. **Note that generating CI files is currently in alpha and may require manual editing to fix issues.** diff --git a/packages/toolkit/project/default-variables.json b/packages/toolkit/project/default-variables.json index b1b1a4a7..f15098cb 100644 --- a/packages/toolkit/project/default-variables.json +++ b/packages/toolkit/project/default-variables.json @@ -1,9 +1,6 @@ { "project_name": "10up Project", "php_version": "8.2", - "build_script_path": "", "wordpress_version": "", - "deploy_script_path": "", - "create_payload_script_path": "", "environments": [] } diff --git a/packages/toolkit/project/gitlab/.gitlab-ci.tmpl b/packages/toolkit/project/gitlab/.gitlab-ci.tmpl index 81fc5b15..2f8bc3e1 100644 --- a/packages/toolkit/project/gitlab/.gitlab-ci.tmpl +++ b/packages/toolkit/project/gitlab/.gitlab-ci.tmpl @@ -25,7 +25,7 @@ build_plugins_and_themes: stage: build script: - nvm install 18 - - npx 10up-toolkit project create-payload $CI_COMMIT_REF_NAME + - npx 10up-toolkit project build --type=full artifacts: paths: - payload diff --git a/packages/toolkit/project/gitlab/deploy-configs/pantheon-production.tmpl b/packages/toolkit/project/gitlab/deploy-configs/pantheon-production.tmpl index a3b01e80..a89db894 100644 --- a/packages/toolkit/project/gitlab/deploy-configs/pantheon-production.tmpl +++ b/packages/toolkit/project/gitlab/deploy-configs/pantheon-production.tmpl @@ -7,7 +7,7 @@ deploy_production: MULTI_DEV_ENVIRONMENT: "{{branch}}" WORDPRESS_VERSION: {{wordpress_version}} GIT_URL: {{deploy_to}} - EXCLUDES: {{deploy_file_excludes}} + EXCLUDES: {{rsync_file_excludes}} allow_failure: false only: refs: diff --git a/packages/toolkit/project/gitlab/deploy-configs/pantheon-staging.tmpl b/packages/toolkit/project/gitlab/deploy-configs/pantheon-staging.tmpl index a4bc4a2f..24b2bbf3 100644 --- a/packages/toolkit/project/gitlab/deploy-configs/pantheon-staging.tmpl +++ b/packages/toolkit/project/gitlab/deploy-configs/pantheon-staging.tmpl @@ -7,7 +7,7 @@ deploy_{{branch}}: MULTI_DEV_ENVIRONMENT: "{{branch}}" WORDPRESS_VERSION: {{wordpress_version}} GIT_URL: {{deploy_to}} - EXCLUDES: {{deploy_file_excludes}} + EXCLUDES: {{rsync_file_excludes}} allow_failure: false only: refs: diff --git a/packages/toolkit/project/gitlab/deploy-configs/rsync-production.tmpl b/packages/toolkit/project/gitlab/deploy-configs/rsync-production.tmpl index 36820df4..5862fe35 100644 --- a/packages/toolkit/project/gitlab/deploy-configs/rsync-production.tmpl +++ b/packages/toolkit/project/gitlab/deploy-configs/rsync-production.tmpl @@ -7,7 +7,7 @@ deploy_production: variables: DESTINATION: {{deploy_to}} SUBDIR: {{deploy_to_subdir}} - EXCLUDES: {{deploy_file_excludes}} + EXCLUDES: {{rsync_file_excludes}} only: refs: - {{branch}} diff --git a/packages/toolkit/project/gitlab/deploy-configs/rsync-staging.tmpl b/packages/toolkit/project/gitlab/deploy-configs/rsync-staging.tmpl index 5f47a7f5..0a6ffe71 100644 --- a/packages/toolkit/project/gitlab/deploy-configs/rsync-staging.tmpl +++ b/packages/toolkit/project/gitlab/deploy-configs/rsync-staging.tmpl @@ -7,7 +7,7 @@ deploy_{{branch}}: variables: DESTINATION: {{deploy_to}} SUBDIR: {{deploy_to_subdir}} - EXCLUDES: {{deploy_file_excludes}} + EXCLUDES: {{rsync_file_excludes}} only: refs: - {{branch}} diff --git a/packages/toolkit/project/local/.gitignore b/packages/toolkit/project/local/.gitignore new file mode 100644 index 00000000..14fb7d13 --- /dev/null +++ b/packages/toolkit/project/local/.gitignore @@ -0,0 +1,26 @@ +payload +build/vendor +build/composer.lock +build/composer.json +/vendor +wordpress/.env +wordpress/*php +wordpress/wp-content/uploads +wordpress/wp-includes +wordpress/wp-admin +wordpress/license.txt +wordpress/readme.html +!wordpress/wp-config.php +docker-compose.override.yml +.config.json +wordpress/wp-content/advanced-cache.php +wordpress/wp-content/mu-plugins/10up-experience.php +wordpress/wp-content/mu-plugins/10up-experience/ +wordpress/wp-content/mu-plugins/batcache.php +wordpress/wp-content/mu-plugins/batcache/ +wordpress/wp-content/mu-plugins/redis-cache.php +wordpress/wp-content/mu-plugins/redis-cache/ +wordpress/wp-content/mu-plugins/s3-uploads.php +wordpress/wp-content/mu-plugins/s3-uploads/ +wordpress/wp-content/object-cache.php +.lock diff --git a/packages/toolkit/project/local/scripts/build.sh b/packages/toolkit/project/local/scripts/build.sh index 888d0435..1c372aed 100644 --- a/packages/toolkit/project/local/scripts/build.sh +++ b/packages/toolkit/project/local/scripts/build.sh @@ -1,5 +1,18 @@ -# Add builds scripts here. This script will be run from the root of your project (same directory as .tenup.yml). +#!/usr/bin/env bash -l +# NOTE: you should keep the above line, at line 1. Only modify if you know what you are doing. -nvm install -node -v -npm install +# You should use npx 10up-toolkit build to build your project. When you do, there are a number of things +# you get "for free" including nvm handling and the basics of building are handled automatically. You +# only need to provide additional build routines if the default build system doesn't quite get things +# right. Adding build scripts is easy. Create as many .sh files as you need in this scripts directory. + +# Here is an example script you can use to get you started It assumes you are using a "modern" layout. + +# change directories to your theme or plugin +pushd . + +# run your build commands +echo "Hello World!" + +# return to where we were so the next build script starts off from the same place +popd diff --git a/packages/toolkit/project/local/scripts/deploy-excludes.txt b/packages/toolkit/project/local/scripts/rsync-excludes.txt similarity index 100% rename from packages/toolkit/project/local/scripts/deploy-excludes.txt rename to packages/toolkit/project/local/scripts/rsync-excludes.txt diff --git a/packages/toolkit/scripts/project/bash/Dockerfile b/packages/toolkit/scripts/project/bash/Dockerfile new file mode 100644 index 00000000..666890b4 --- /dev/null +++ b/packages/toolkit/scripts/project/bash/Dockerfile @@ -0,0 +1,7 @@ +FROM alpine:latest + +USER root +WORKDIR /var/www/html +COPY payload . +RUN mkdir wp-content/uploads && \ + chown 33:33 wp-content/uploads diff --git a/packages/toolkit/scripts/project/bash/build-setup.sh b/packages/toolkit/scripts/project/bash/build-setup.sh deleted file mode 100644 index a6c5eb7b..00000000 --- a/packages/toolkit/scripts/project/bash/build-setup.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -maybe_init_nvm() { - - if [ $(find . -name .nvmrc | wc -l) -gt 0 ] && [ ! -f $NVM_DIR/nvm.sh ]; then - echo "This project requires nvm. Please install nvm and try again" - exit 1 - fi - - . $NVM_DIR/nvm.sh -} - -maybe_init_nvm diff --git a/packages/toolkit/scripts/project/bash/create-payload.sh b/packages/toolkit/scripts/project/bash/create-payload.sh deleted file mode 100644 index 91309781..00000000 --- a/packages/toolkit/scripts/project/bash/create-payload.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -download() { - if [ `which curl` ]; then - curl -s "$1" > "$2"; - elif [ `which wget` ]; then - wget -nv -O "$2" "$1" - fi -} - -rm -rf payload -mkdir payload -cd payload - -echo "Downloading WordPress $WORDPRESS_VERSION..." -download https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz wordpress.tar.gz -tar --strip-components=1 -zxmf wordpress.tar.gz -C . -rm wordpress.tar.gz - -rsync -avz --exclude-from=$deploy_file_excludes_absolute $project_root/$deploy_from $deploy_to_subdir diff --git a/packages/toolkit/scripts/project/bash/scripts.sh b/packages/toolkit/scripts/project/bash/scripts.sh new file mode 100644 index 00000000..1874770d --- /dev/null +++ b/packages/toolkit/scripts/project/bash/scripts.sh @@ -0,0 +1,239 @@ +#!/usr/bin/env bash -l + +SHARE_DIR="$(dirname "$(realpath "$0")")" +# Various tasks to determine some things like what kind of project is this +# such as wpparent, wp-content rooted...something else? +function build:preflight { + + # load nvm if it exists + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + + PROJECT_TYPE="wpparent" + # Check for a parent layout that has a wordpress directory + if [ -d wordpress ] && [ -d build ]; then # this is probably a wpparent setup + echo "Detected wpparent WordPress repository layout" + + WORDPRESS_BUILD_ROOT="wordpress/wp-content" + return + fi + + # Check for a wp-content rooted style repository + if [ -d plugins ] || [ -d themes ]; then # this is probably a wp-root repo + echo "Detected wp-content rooted WordPress repository layout" + PROJECT_TYPE="wpcontent" + WORDPRESS_BUILD_ROOT="." + return + fi + +} + + +# Routine to determine what version of WordPress to install +function build:version { + + # If the WORDPRESS_VERSION is not set, set to "latest" + if [[ -z ${WORDPRESS_VERSION} ]]; then + WORDPRESS_VERSION="latest" + fi + + if [[ "${WORDPRESS_VERSION}" == "latest" ]]; then + WORDPRESS_VERSION=$(curl -s https://api.wordpress.org/core/version-check/1.7/ | jq '.offers[0].current' | tr -d '"') + fi + + echo ${WORDPRESS_VERSION} +} + +function build:install { + build:preflight + + # we use command in case wp-cli is installed as an alias + if [[ -z $(command -v wp) ]]; then + echo "wp-cli is not installed or in your path but it is required" + exit 1 + fi + + local WORDPRESS_VERSION=$(build:version) + echo "Installing WordPress version: ${WORDPRESS_VERSION}" + + if [ ${PROJECT_TYPE} = "wpparent" ]; then + mkdir -p wordpress/wp-content + pushd wordpress + else + mkdir -p payload/wp-content + pushd payload + fi + wp core download --version=${WORDPRESS_VERSION} --skip-content --force + popd + +} + +function build:main { + set -eo pipefail + + build:preflight + + # This is your "main" build file. By default, it builds a 10up/wp-scaffold style project + # but you are free to modify it as required for your project. Remember, you can also + # drop in any number of scripts and they will be run in alphabetical order AFTER main.sh + + # detect if this is a wpparent layout or not + if [[ ${PROJECT_TYPE} == "wpparent" ]]; then + pushd wordpress/wp-content + elif [ -d plugins ]; then + pushd . # go no where, we are already in the right spot + fi + + if [[ ! -z $(command -v nvm) ]]; then + # Ensure we have the correct node version installed + nvm install + nvm use + fi + + if [[ "${CI:-false}" = "true" ]] && [[ -f composer.json ]]; then + if [ ! -f composer.lock ] && [ -f composer.json ]; then + echo "No composer.lock file detected. You should create/commit an up to date composer.lock file!" + exit 1 + else + composer install --no-dev + fi + elif [[ -f composer.json ]]; then + composer install + fi + + + if [[ -f package.json ]]; then + if [[ "${CI:-false}" = "true" ]] && [[ -f package.json ]]; then + if [[ -f package-lock.json ]]; then + npm ci + else + echo "No package-lock.json file detected. You should create/commit an up to date package-lock.json file!" + exit 1 + fi + else + npm install + fi + + npm run build + fi + + if [[ ${PROJECT_TYPE} == "wpparent" ]]; then + popd + fi +} + +function build:local { + set -eo pipefail + # Create additional build scripts in the build directory with a .sh + # extension. They should do their work inside the wordpress directory. + + # We always call main.sh first + build:preflight + build:main + + # Then call any other drop in scripts next + for I in $(ls scripts/*sh) + do + . $I + done +} + +# Perform a CI like build +function build:full { + set -eo pipefail + + build:preflight + build:install + build:local + + # This rsync will typically work but if you have integrated the CI Library + # into a non project template based project you should adjust it + + # First determine if we are using a project rsync-exclude or the included one + if [[ -f scripts/rsync-excludes.txt ]]; then + RSYNC_EXCLUDES="scripts/rsync-excludes.txt" + fi + + if [[ ${PROJECT_TYPE} == "wpparent" ]]; then + rsync -a --exclude-from=${RSYNC_EXCLUDES} wordpress/ payload/ + else + for I in themes mu-plugins plugins + do + if [ -d $I ]; then + rsync -a --exclude-from=${RSYNC_EXCLUDES} $I/ payload/wp-content/$I + fi + done + fi + +} + +function build:update-composer { + + build:preflight + + if [[ ${PROJECT_TYPE} == "wpparent" ]]; then + pushd wordpress/wp-content + else + pushd . + fi + + if [[ ! composer.json ]]; then + echo "No composer.json file found. Run this from the root of a project and try again." + exit 1 + fi + + for I in $(find . -maxdepth 1 -name composer.json) + do + composer update --no-install + done + + pushd themes + for I in $(find . -maxdepth 2 -name composer.json) + do + pushd $(dirname $I) + composer update --no-install + popd + done + + popd + popd +} + +function build:initialize-git { + git init . + echo + echo + echo 'Git has been initialized. Please run "git remote add origin " to set the remote repository location.' +} + +function build:package { + + if [[ -z $(which docker) ]]; then + echo "You don't seem to have Docker installed but it is required for this to work." + exit 1 + fi + + if [[ ! -d payload ]]; then + echo "No payload directory found. Please run 10up-toolkit project build --type=full first." + exit 1 + fi + + # First determine if we are using a project Dockerfile or the included one + if [[ -f Dockerfile ]]; then + DOCKERFILE="Dockerfile" + else + DOCKERFILE="${SHARE_DIR:?}/Dockerfile" + fi + # FIXME: This should be updated to use variables from .tenup-ci.yml + docker buildx build --load -f ${DOCKERFILE} . -t tenup-project:latest +} + + +# Converts a git branch to a gitlab compatible slug +function utilities:create-gitlab-slug { + local VALUE=$(echo $1 | sed 's/[^a-zA-Z0-9]/-/g' | awk '{print tolower($0)}') + + echo ${VALUE} +} + +eval build:$@ diff --git a/packages/toolkit/scripts/project/build.js b/packages/toolkit/scripts/project/build.js index 92e789af..f71d8a41 100644 --- a/packages/toolkit/scripts/project/build.js +++ b/packages/toolkit/scripts/project/build.js @@ -3,10 +3,18 @@ const chalk = require('chalk'); const { log } = console; -const fs = require('fs'); -const { getProjectRoot, getProjectVariables, setEnvVariables } = require('../../utils'); +const { + getProjectRoot, + getProjectVariables, + setEnvVariables, + hasArgInCLI, + getArgFromCLI, +} = require('../../utils'); -const description = '10up-toolkit project build'; +const buildType = hasArgInCLI('--type') ? getArgFromCLI('--type') : 'local'; +const buildEnvironment = hasArgInCLI('--environment') ? getArgFromCLI('--environment') : null; + +const description = '10up-toolkit project build [--type=] [--environment=]'; const run = async () => { const root = getProjectRoot(); @@ -16,7 +24,8 @@ const run = async () => { process.exit(1); } - const variables = getProjectVariables(); + // combine project variables with actual environment variables + const variables = { ...getProjectVariables(buildEnvironment), ...process.env }; if (!variables) { log(chalk.red('No .tenup.yml found.')); @@ -25,14 +34,9 @@ const run = async () => { setEnvVariables(variables); - if (fs.existsSync(variables.build_script_path)) { - execSync(`. ${__dirname}/bash/build-setup.sh; . ${variables.build_script_path}`, { - stdio: 'inherit', - }); - } else { - log(chalk.red('No build script found.')); - process.exit(1); - } + execSync(`${process.env.SHELL} ${__dirname}/bash/scripts.sh ${buildType}`, { + stdio: 'inherit', + }); log(chalk.green('Build complete.')); }; diff --git a/packages/toolkit/scripts/project/create-payload.js b/packages/toolkit/scripts/project/create-payload.js deleted file mode 100644 index 81134707..00000000 --- a/packages/toolkit/scripts/project/create-payload.js +++ /dev/null @@ -1,62 +0,0 @@ -const { execSync } = require('child_process'); -const chalk = require('chalk'); - -const { log } = console; - -const fs = require('fs'); -const { - getProjectRoot, - getProjectVariables, - setEnvVariables, - getEnvironmentFromBranch, -} = require('../../utils'); - -const description = '10up-toolkit project create-payload '; - -const run = async () => { - const branch = process.argv.slice(3)[0]; - - if (!branch || branch.match(/--/)) { - log(description); - log(chalk.red('No branch specified.')); - process.exit(1); - } - - const root = getProjectRoot(); - - if (!root) { - log(chalk.red('This is not a project.')); - process.exit(1); - } - - let variables = getProjectVariables(); - - if (!variables) { - log(chalk.red('No .tenup.yml found.')); - process.exit(1); - } - - const matchedEnvironment = getEnvironmentFromBranch(branch, variables.environments); - - if (!matchedEnvironment) { - log(chalk.red(`No environment found matching branch \`${branch}\`.`)); - process.exit(0); - } - - variables = { ...variables, ...matchedEnvironment }; - - log(`Creating payload for environment ${matchedEnvironment.environment}.`); - - setEnvVariables(variables); - - // First run build - await require('./build').run(); - - if (fs.existsSync(variables.create_payload_script_path)) { - execSync(`bash ${variables.create_payload_script_path}`, { stdio: 'inherit' }); - } - - log(chalk.green('Payload created.')); -}; - -module.exports = { run, description }; diff --git a/packages/toolkit/scripts/project/init.js b/packages/toolkit/scripts/project/init.js old mode 100644 new mode 100755 index d8d815e6..3123ca86 --- a/packages/toolkit/scripts/project/init.js +++ b/packages/toolkit/scripts/project/init.js @@ -14,18 +14,22 @@ const { getArgFromCLI, hasArgInCLI } = require('../../utils'); const cliPath = hasArgInCLI('--path') ? getArgFromCLI('--path') : '.'; +const projectLayout = hasArgInCLI('--layout') ? getArgFromCLI('--layout') : 'wpcontent'; + const name = hasArgInCLI('--name') ? getArgFromCLI('--name') : ''; const confirm = !!hasArgInCLI('--confirm'); const skipComposer = !!hasArgInCLI('--skip-composer'); +const skipCI = !!hasArgInCLI('--skip-ci'); + let template = hasArgInCLI('--template') ? getArgFromCLI('--template') : ''; const variables = require(`../../project/default-variables.json`); const description = - '10up-toolkit project init [--path=] [--name=] [--template=