Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scripts: Add plugin-zip command to create a zip file for a WordPress plugin #37687

Merged
merged 1 commit into from
Jan 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions bin/test-create-block.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@ status "Lintig CSS files..."

status "Linting JavaScript files..."
../node_modules/.bin/wp-scripts lint-js

status "Creating a plugin zip file..."
../node_modules/.bin/wp-scripts plugin-zip
95 changes: 83 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/create-block/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### New Features

- Integrated a new `plugin-zip` command to create a zip file for a WordPress plugin ([#37687](https://github.com/WordPress/gutenberg/pull/37687)).

### Enhancement

- Speed up scaffolding process by omitting WordPress dependencies in the template ([#37639](https://github.com/WordPress/gutenberg/pull/37639)).
Expand Down
3 changes: 2 additions & 1 deletion packages/create-block/lib/init-package-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ module.exports = async ( {
format: 'wp-scripts format',
'lint:css': 'wp-scripts lint-style',
'lint:js': 'wp-scripts lint-js',
start: 'wp-scripts start',
'packages-update': 'wp-scripts packages-update',
'plugin-zip': 'wp-scripts plugin-zip',
start: 'wp-scripts start',
},
},
isEmpty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ node_modules/
# Optional eslint cache
.eslintcache

# Output of 'npm pack'
# Output of `npm pack`
*.tgz

# Output of `wp-scripts plugin-zip`
*.zip

# dotenv environment variables file
.env
1 change: 1 addition & 0 deletions packages/scripts/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

### New Features

- Added a new `plugin-zip` command to create a zip file for a WordPress plugin ([#37687](https://github.com/WordPress/gutenberg/pull/37687)).
- Added optional support for React Fast Refresh in the `start` command. It can be activated with `--hot` CLI argument ([#28273](https://github.com/WordPress/gutenberg/pull/28273)).

### Bug Fixes
Expand Down
29 changes: 29 additions & 0 deletions packages/scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ _Example:_
"lint:md:js": "wp-scripts lint-md-js",
"lint:pkg-json": "wp-scripts lint-pkg-json",
"packages-update": "wp-scripts packages-update",
"plugin-zip": "wp-scripts plugin-zip",
"start": "wp-scripts start",
"test:e2e": "wp-scripts test-e2e",
"test:unit": "wp-scripts test-unit-js"
Expand Down Expand Up @@ -303,6 +304,34 @@ _Example:_

The command checks which packages whose name starts with `@wordpress/` are used in the project by reading the package.json file, and then executes `npm install @wordpress/package1@latest @wordpress/package2@latest ... --save` to change the package versions to the latest one.

### `packages-update`

Creates a zip file for a WordPress plugin.

_Example:_

```json
{
"scripts": {
"plugin-zip": "wp-scripts plugin-zip"
}
}
```

By default, it uses [Plugin Handbook best practices](https://developer.wordpress.org/plugins/plugin-basics/best-practices/#file-organization) to discover files.

#### Advanced information

In the case where the plugin author wants to customize the files included in the zip file, they can provide the `files` field in the `package.json` file as documented in the [`npm-packlist`](https://www.npmjs.com/package/npm-packlist) package, example:

```json
{
"files": [ "dir" ]
}
```

It reuses the same logic as `npm pack` command to create an npm package tarball.

### `start`

Transforms your code according the configuration provided so it’s ready for development. The script will automatically rebuild if you make changes to the code, and you will see the build errors in the console. The entry point for your project’s code should be located in `src/index.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`). The output generated will be written to `build/index.js`. For single builds, better suited for production, see the [build](#build) script.
Expand Down
2 changes: 2 additions & 0 deletions packages/scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@wordpress/postcss-plugins-preset": "file:../postcss-plugins-preset",
"@wordpress/prettier-config": "file:../prettier-config",
"@wordpress/stylelint-config": "file:../stylelint-config",
"adm-zip": "^0.5.9",
"babel-jest": "^26.6.3",
"babel-loader": "^8.2.3",
"browserslist": "^4.17.6",
Expand All @@ -70,6 +71,7 @@
"mini-css-extract-plugin": "^2.1.0",
"minimist": "^1.2.0",
"npm-package-json-lint": "^5.0.0",
"npm-packlist": "^3.0.0",
"postcss": "^8.2.15",
"postcss-loader": "^6.1.1",
"prettier": "npm:wp-prettier@2.2.1-beta-1",
Expand Down
56 changes: 56 additions & 0 deletions packages/scripts/scripts/plugin-zip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* External dependencies
*/
const AdmZip = require( 'adm-zip' );
const { sync: glob } = require( 'fast-glob' );
const { sync: packlist } = require( 'npm-packlist' );
const { dirname } = require( 'path' );
const { stdout } = require( 'process' );

/**
* Internal dependencies
*/
const { hasPackageProp, getPackageProp } = require( '../utils' );

const name = getPackageProp( 'name' );
stdout.write( `Creating archive for \`${ name }\` plugin... 🎁\n\n` );
const zip = new AdmZip();

let files = [];
if ( hasPackageProp( 'files' ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an idea here, but could we have the files entry merge with the existing defaults? This would make it much easier to add a new directory/file without needing to also provide all of the defaults.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to check our existing configs but I remember one of the tools exposing shortcut that brings all the default settings if you want to extend them. This should do the trick.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that exists already? That would be great to add to the docs in the PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not here, but it would be simple to replicate.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an idea here, but could we have the files entry merge with the existing defaults? This would make it much easier to add a new directory/file without needing to also provide all of the defaults.

Let's keep it as is for now. It's a bit tricky to handle with files because it is used also when publishing to npm. The good news is that when you set files then you don't need to list files like readme, changelog, or license because they are always included. I figured out that we can't add any custom items in files because it would break npm publish if someone is using it.

stdout.write(
'Using the `files` field from `package.json` to detect files:\n\n'
);
files = packlist();
} else {
stdout.write(
'Using Plugin Handbook best practices to discover files:\n\n'
);
// See https://developer.wordpress.org/plugins/plugin-basics/best-practices/#file-organization.
files = glob(
[
'admin/**',
'build/**',
'includes/**',
'languages/**',
'public/**',
`${ name }.php`,
'uninstall.php',
'block.json',
'changelog.*',
'license.*',
'readme.*',
],
{
caseSensitiveMatch: false,
}
);
}

files.forEach( ( file ) => {
stdout.write( ` Adding \`${ file }\`.\n` );
zip.addLocalFile( file, dirname( file ) );
} );

zip.writeZip( `./${ name }.zip` );
stdout.write( `\nDone. \`${ name }.zip\` is ready! 🎉\n` );