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

WP Scripts: Add a --root-folder argument to the plugin-zip command #61375

Merged
merged 7 commits into from
Oct 29, 2024

Conversation

nicolasgalvez
Copy link
Contributor

@nicolasgalvez nicolasgalvez commented May 4, 2024

What?

Fixes #60481.

Allows adding a root folder to the zip file generated by plugin-zip

Why?

This allows creating a zip file that can be used to update a plugin via the WP Admin update page, since the plugin updater expects the zip file to contain a folder with the name of the plugin in the root of the zip file.
Please refer to the issue I opened here: #60481

How?

Add an argument to the plugin-zip command that will allow a developer to specify the root folder inside the zip file. Modifies zip creation to use this argument if specified. Defaults to the plugin name if no string was passed along with the argument.

Testing Instructions

Here's what I did to test:

  1. Link local Gutenberg project globally: from inside the gutenberg directory npm link
  2. Go back to my project directory: cd ..
  3. Create a block plugin with wp-scripts: npx @wordpress/create-block test
  4. Go into the block directory cd test
  5. Link the local Gutenberg project npm link gutenberg
  6. Build the block: npm run build
  7. Run the local build script../gutenberg/node_modules/.bin/wp-scripts plugin-zip
  8. View the zip file and ensure the contents are consistent with the default behavior:
    Archive: test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      488  05-03-2024 18:02   build/block.json
      134  05-03-2024 18:02   build/index.asset.php
       51  05-03-2024 18:02   build/index.css
     1363  05-03-2024 18:02   build/index.js
       77  05-03-2024 18:02   build/style-index.css
       84  05-03-2024 18:02   build/view.asset.php
       59  05-03-2024 18:02   build/view.js
     1807  05-03-2024 17:43   readme.txt
      915  05-03-2024 17:43   test.php
---------                     -------
     4978                     9 files

Test --zip-root-folder argument

Expected: should use the name of the plugin as the root folder.

  1. Try using the new argument ../gutenberg/node_modules/.bin/wp-scripts plugin-zip --zip-root-folder
  2. Now running unzip -l test.zip should show you a test folder at the root of the zip:
Archive:  test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      488  05-03-2024 18:02   test/build/block.json
      134  05-03-2024 18:02   test/build/index.asset.php
       51  05-03-2024 18:02   test/build/index.css
     1363  05-03-2024 18:02   test/build/index.js
       77  05-03-2024 18:02   test/build/style-index.css
       84  05-03-2024 18:02   test/build/view.asset.php
       59  05-03-2024 18:02   test/build/view.js
     1807  05-03-2024 17:43   test/readme.txt
      915  05-03-2024 17:43   test/test.php
---------                     -------
     4978                     9 files

Test with --zip-root-folder argument with a value

Expected: should use a custom name for the root folder. Zip file name will remain unchanged.

  1. Try with a value ../gutenberg/node_modules/.bin/wp-scripts plugin-zip --zip-root-folder=foo
  2. Now running unzip -l test.zip should show you a foo folder at the root of the zip:
Archive:  test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      488  05-03-2024 18:02   foo/build/block.json
      134  05-03-2024 18:02   foo/build/index.asset.php
...

Test files array in package.json still works

  1. Add the following to the test block's package.json
	"files": [
		"build",
		".editorconfig"
	],
  1. Run ../gutenberg/node_modules/.bin/wp-scripts plugin-zip --zip-root-folder=foo
  2. Running unzip -l test.zip should show you a foo folder at the root of the zip:, and the additional file(s) you add should be in the archive.
Archive:  test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      369  05-03-2024 17:43   foo/.editorconfig
      488  05-03-2024 18:02   foo/build/block.json
... etc

Thanks for reading! I can't wait to get some feedback. Please let me know if there is anything I can improve on.

Copy link

github-actions bot commented May 4, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: nicolasgalvez <[email protected]>
Co-authored-by: gziolo <[email protected]>
Co-authored-by: t-hamano <[email protected]>
Co-authored-by: justlevine <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions github-actions bot added the First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository label May 4, 2024
Copy link

github-actions bot commented May 4, 2024

👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @nicolasgalvez! In case you missed it, we'd love to have you join us in our Slack community.

If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information.

@gziolo gziolo added [Tool] WP Scripts /packages/scripts [Type] Enhancement A suggestion for improvement. labels May 6, 2024
@aaronjorbin aaronjorbin added the props-bot Adding this label triggers the Props Bot workflow for a PR. label May 8, 2024
@github-actions github-actions bot removed the props-bot Adding this label triggers the Props Bot workflow for a PR. label May 8, 2024
@justlevine
Copy link

Tested and working locally (WSL2 + PHP 8.2.x + WP 6.6 + Node 20 )

One suggestion:

In its current form, this is an additive enhancement, that requires --zip-root-folder to wrap the files in a parent dir.

However, since the docs currently say By default, it uses [Plugin Handbook best practices](https://developer.wordpress.org/plugins/plugin-basics/best-practices/#file-organization) to discover files., I'd recommend:

  1. Changing the default behavior to wrap the zip in the plugin-name folder, as expected by WordPress best practices
  2. Changing the flag from --zip-root-folder to just --root-folder and allowing either
  • Using a different base name (--root-folder="foo")
  • Using no root folder ( --root-folder="" )

@gziolo
Copy link
Member

gziolo commented Oct 10, 2024

I like the suggestions shared by @justlevine. That would be the ideal scenario as the default would better align with the best practices. At the same time there would be an easy migration path to include in the changelog entry in the case someone has some workflow that depends on the fact that there is no folder included. They would only need the following change:

- wp-scripts plugin-zip
+ wp-scripts plugin-zip --root-folder=""

@nicolasgalvez, are you available to apply the necessary changes?

@nicolasgalvez
Copy link
Contributor Author

@gziolo @justlevine I'm sorry for the delayed response. Thanks for the help and the great suggestion!

I agree it would be great if it was the default behavior and I'll make the change today.

@nicolasgalvez
Copy link
Contributor Author

New manual tests

Default
wp-scripts plugin-zip - results in a file with the plugin name as a root folder. Default action.
zipinfo test.zip shows ...test/build/block.json...

Archive:  test.zip
Zip file size: 3539 bytes, number of entries: 7
-rw-r--r--  2.0 unx      515 b- defN 24-Oct-23 11:51 test/build/block.json
-rw-r--r--  2.0 unx      134 b- defN 24-Oct-23 11:51 test/build/index.asset.php
-rw-r--r--  2.0 unx       51 b- defN 24-Oct-23 11:51 test/build/index.css
-rw-r--r--  2.0 unx     1378 b- defN 24-Oct-23 11:51 test/build/index.js
-rw-r--r--  2.0 unx       77 b- defN 24-Oct-23 11:51 test/build/style-index.css
-rw-r--r--  2.0 unx     1807 b- defN 24-Aug-13 13:34 test/readme.txt
-rw-r--r--  2.0 unx      915 b- defN 24-Aug-13 13:37 test/test.php

No Root Folder
plugin-zip --root-folder or plugin-zip --root-folder='' or plugin-zip --root-folder=' '
zipinfo test.zip shows:

Archive:  test.zip
Zip file size: 3469 bytes, number of entries: 7
-rw-r--r--  2.0 unx      515 b- defN 24-Oct-23 11:51 build/block.json
-rw-r--r--  2.0 unx      134 b- defN 24-Oct-23 11:51 build/index.asset.php
-rw-r--r--  2.0 unx       51 b- defN 24-Oct-23 11:51 build/index.css
-rw-r--r--  2.0 unx     1378 b- defN 24-Oct-23 11:51 build/index.js
-rw-r--r--  2.0 unx       77 b- defN 24-Oct-23 11:51 build/style-index.css
-rw-r--r--  2.0 unx     1807 b- defN 24-Aug-13 13:34 readme.txt
-rw-r--r--  2.0 unx      915 b- defN 24-Aug-13 13:37 test.php

Custom root folder
plugin-zip --root-folder='foo'

Archive:  test.zip
Zip file size: 3525 bytes, number of entries: 7
-rw-r--r--  2.0 unx      515 b- defN 24-Oct-23 11:51 foo/build/block.json
-rw-r--r--  2.0 unx      134 b- defN 24-Oct-23 11:51 foo/build/index.asset.php
-rw-r--r--  2.0 unx       51 b- defN 24-Oct-23 11:51 foo/build/index.css
-rw-r--r--  2.0 unx     1378 b- defN 24-Oct-23 11:51 foo/build/index.js
-rw-r--r--  2.0 unx       77 b- defN 24-Oct-23 11:51 foo/build/style-index.css
-rw-r--r--  2.0 unx     1807 b- defN 24-Aug-13 13:34 foo/readme.txt
-rw-r--r--  2.0 unx      915 b- defN 24-Aug-13 13:37 foo/test.php

…zip file by default

1. The plugin-zip command will now create a root folder in the zip file matching the name of the plugin. This aligns with the documentation stating that "By default, it uses Plugin Handbook best practices to discover files."
2. `--zip-root-folder` argument from my previous commit is now named `--root-folder`
3. The --root-folder argument will allow specifying a custom folder, or no folder for backwards compatibility.

Example usage:

{{{
npm run plugin-zip --root-folder='foo'
}}}

Follow-up to [61375], [60481].

Props justlevine, gziolo.
@t-hamano
Copy link
Contributor

I have confirmed that it works correctly on a Windows host OS (not WSL).

When I first saw the plugin-zip --root-folder command, I expected the root folder to be included. However, this was not the case, so I was a little confused.

I think it would be good to use the following three patterns, but what do you think?

  • wp-scripts plugin-zip: Create the root folder
  • wp-scripts plugin-zip -- no-root-folder: Don't create the root folder
  • wp-scripts plugin-zip --root-folder="foo": Create the custom root folder

@justlevine
Copy link

justlevine commented Oct 24, 2024

When I first saw the plugin-zip --root-folder command, I expected the root folder to be included. However, this was not the case, so I was a little confused.

I think it would be good to use the following three patterns, but what do you think?

  • wp-scripts plugin-zip: Create the root folder
  • wp-scripts plugin-zip -- no-root-folder: Don't create the root folder
  • wp-scripts plugin-zip --root-folder="foo": Create the custom root folder

@t-hamano what are your thoughts about just requiring a =value to be passed with the --root-folder flag? The error output could then include a usage instruction to use --root-folder='' if they don't want their files wrapped in a dir.

Personally, I find semantic-only aliases to offer a worse DX than guardrails (here, needing to learn 2 flags and how they interrelate), and adds tech debt (e.g. need to deconflict both flags being passed in the same command), but I'm not sure if there's a WP-specific design convention here.

@nicolasgalvez
Copy link
Contributor Author

@t-hamano I agree, it seems weird but I couldn't put my finger on why when working on it. Thanks for pointing that out and thank you thank you for testing on Windows! I think I agree with the points @justlevine makes and I would like to implement the solution outlined below if that's cool with everyone:

@t-hamano what are your thoughts about just requiring a =value to be passed with the --root-folder flag? The error output could then include a usage instruction to use --root-folder='' if they don't want their files wrapped in a dir.

Thanks for the help!

@t-hamano
Copy link
Contributor

what are your thoughts about just requiring a =value to be passed with the --root-folder flag? The error output could then include a usage instruction to use --root-folder='' if they don't want their files wrapped in a dir.

Yes, this looks like a good approach to me 👍

@gziolo
Copy link
Member

gziolo commented Oct 25, 2024

I added a commit f720100 with the CHANGELOG entry explaining the changes applied and a note on how to replicate the old behavior. Is there anything left to land this enhancement?

@gziolo gziolo changed the title Scripts: Add a --zip-root-folder argument to the plugin-zip command #60481 Scripts: Add a --root-folder argument to the plugin-zip command #60481 Oct 25, 2024
@nicolasgalvez
Copy link
Contributor Author

nicolasgalvez commented Oct 26, 2024

@t-hamano @justlevine Well, I discovered the zipRootFolderArg automatically converts falsy values to null, so there isn't a way to differentiate between and empty string '' and null. Given this, I'll go with @t-hamano's suggestion after all.

@gziolo Thank you very much for adding the change message, I will update the message to match the behavior @t-hamano suggested:

wp-scripts plugin-zip: Create the root folder
wp-scripts plugin-zip --no-root-folder: Don't create the root folder
wp-scripts plugin-zip --root-folder="foo": Create the custom root folder

Testing on macos:

Default
wp-scripts plugin-zip - results in a file with the plugin name as a root folder. Default action.
zipinfo test.zip shows:

Archive:  test.zip
Zip file size: 3539 bytes, number of entries: 7
-rw-r--r--  2.0 unx      515 b- defN 24-Oct-23 11:51 test/build/block.json
-rw-r--r--  2.0 unx      134 b- defN 24-Oct-23 11:51 test/build/index.asset.php
-rw-r--r--  2.0 unx       51 b- defN 24-Oct-23 11:51 test/build/index.css
-rw-r--r--  2.0 unx     1378 b- defN 24-Oct-23 11:51 test/build/index.js
-rw-r--r--  2.0 unx       77 b- defN 24-Oct-23 11:51 test/build/style-index.css
-rw-r--r--  2.0 unx     1807 b- defN 24-Aug-13 13:34 test/readme.txt
-rw-r--r--  2.0 unx      915 b- defN 24-Aug-13 13:37 test/test.php

No Root Folder
plugin-zip --no-root-folder
zipinfo test.zip shows:

Archive:  test.zip
Zip file size: 3469 bytes, number of entries: 7
-rw-r--r--  2.0 unx      515 b- defN 24-Oct-23 11:51 build/block.json
-rw-r--r--  2.0 unx      134 b- defN 24-Oct-23 11:51 build/index.asset.php
-rw-r--r--  2.0 unx       51 b- defN 24-Oct-23 11:51 build/index.css
-rw-r--r--  2.0 unx     1378 b- defN 24-Oct-23 11:51 build/index.js
-rw-r--r--  2.0 unx       77 b- defN 24-Oct-23 11:51 build/style-index.css
-rw-r--r--  2.0 unx     1807 b- defN 24-Aug-13 13:34 readme.txt
-rw-r--r--  2.0 unx      915 b- defN 24-Aug-13 13:37 test.php

Custom root folder
plugin-zip --root-folder='bar'

Archive:  test.zip
Zip file size: 3525 bytes, number of entries: 7
-rw-r--r--  2.0 unx      515 b- defN 24-Oct-23 11:51 bar/build/block.json
-rw-r--r--  2.0 unx      134 b- defN 24-Oct-23 11:51 bar/build/index.asset.php
-rw-r--r--  2.0 unx       51 b- defN 24-Oct-23 11:51 bar/build/index.css
-rw-r--r--  2.0 unx     1378 b- defN 24-Oct-23 11:51 bar/build/index.js
-rw-r--r--  2.0 unx       77 b- defN 24-Oct-23 11:51 bar/build/style-index.css
-rw-r--r--  2.0 unx     1807 b- defN 24-Aug-13 13:34 bar/readme.txt
-rw-r--r--  2.0 unx      915 b- defN 24-Aug-13 13:37 bar/test.php

I'll keep an eye out for any other comments on here, thanks again everyone!

Require an argument for root-folder.
Add option no-root-folder to zip files without a root folder for backwards compatibility.
Update documentation, and changelog.
(WordPress#60481)
Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

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

Everything works as expected. I tested all the variations of the command as documented and tested whether it successfully installs and activates depending on how the zip file is structured.

const trimmedZipRootFolderArg =
typeof zipRootFolderArg === 'string' ? zipRootFolderArg.trim() : null;
if ( trimmedZipRootFolderArg === null ) {
stdout.write(
Copy link
Member

Choose a reason for hiding this comment

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

Nit: this could use some formatting to better indicate that the param was misconfigured and the zip wasn't created.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I updated the message to Unable to create zip package: please provide a --root-folder name or use `--no-root-folder.

@gziolo gziolo changed the title Scripts: Add a --root-folder argument to the plugin-zip command #60481 WP Scripts: Add a --root-folder argument to the plugin-zip command Oct 28, 2024
Apply suggestions from code review. props: @gziolo

Co-authored-by: Greg Ziółkowski <[email protected]>
Copy link
Contributor Author

@nicolasgalvez nicolasgalvez left a comment

Choose a reason for hiding this comment

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

Added messaging suggestions. Thanks for the review!

Copy link
Contributor

@t-hamano t-hamano left a comment

Choose a reason for hiding this comment

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

Thanks for the update! I have tested the contents of this comment on a Windows host OS and everything works correctly.

packages/scripts/README.md Outdated Show resolved Hide resolved
@gziolo gziolo enabled auto-merge (squash) October 29, 2024 08:27
@gziolo
Copy link
Member

gziolo commented Oct 29, 2024

@nicolasgalvez, awesome work! I accepted the suggestion from @t-hamano regarding the documentation. I also set the PR to auto-merge 🚀

@gziolo gziolo merged commit 0da9f62 into WordPress:trunk Oct 29, 2024
61 checks passed
@github-actions github-actions bot added this to the Gutenberg 19.6 milestone Oct 29, 2024
karthick-murugan pushed a commit to karthick-murugan/gutenberg that referenced this pull request Nov 13, 2024
WordPress#61375)

* Scripts: Add a --zip-root-folder argument to the plugin-zip command (WordPress#60481)

* Scripts: Change the plugin-zip command to add a folder in the plugin zip file by default

1. The plugin-zip command will now create a root folder in the zip file matching the name of the plugin. This aligns with the documentation stating that "By default, it uses Plugin Handbook best practices to discover files."
2. `--zip-root-folder` argument from my previous commit is now named `--root-folder`
3. The --root-folder argument will allow specifying a custom folder, or no folder for backwards compatibility.

Example usage:

{{{
npm run plugin-zip --root-folder='foo'
}}}

Follow-up to [61375], [60481].

Props justlevine, gziolo.

* Add CHANGELOG entry

* Update CHANGELOG.md

* Scripts: Modify plugin-zip to add no-root-folder and root-folder options
Require an argument for root-folder.
Add option no-root-folder to zip files without a root folder for backwards compatibility.
Update documentation, and changelog.
(WordPress#60481)

* Scripts: adjust message for plugin-zip command

Apply suggestions from code review. props: @gziolo

Co-authored-by: Greg Ziółkowski <[email protected]>

* Update packages/scripts/README.md

Co-authored-by: Aki Hamano <[email protected]>

---------

Co-authored-by: Greg Ziółkowski <[email protected]>
Co-authored-by: Aki Hamano <[email protected]>

Co-authored-by: nicolasgalvez <[email protected]>
Co-authored-by: gziolo <[email protected]>
Co-authored-by: justlevine <[email protected]>
Co-authored-by: t-hamano <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository [Tool] WP Scripts /packages/scripts [Type] Enhancement A suggestion for improvement.
Projects
None yet
5 participants