pressship 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -52,8 +52,8 @@ npx pressship login
52
52
  # 2. (Optional) Verify the saved session
53
53
  npx pressship whoami
54
54
 
55
- # 3. Validate, package, and check without uploading
56
- npx pressship publish ./my-plugin --dry-run
55
+ # 3. Verify the plugin without packaging or uploading
56
+ npx pressship verify ./my-plugin
57
57
 
58
58
  # 4. Submit for review or release an approved plugin
59
59
  npx pressship publish ./my-plugin
@@ -96,6 +96,7 @@ Playwright Chromium is installed automatically the first time browser automation
96
96
  | `pressship get` | Checkout or update a WordPress.org plugin SVN working copy. |
97
97
  | `pressship status` | Read review state from the logged-in developer dashboard. |
98
98
  | `pressship version <patch\|minor\|major>` | Bump the plugin header version and readme stable tag together. |
99
+ | `pressship verify` | Run readme validation and Plugin Check without creating a zip. |
99
100
  | `pressship pack` | Validate, run Plugin Check, and write an installable zip. |
100
101
  | `pressship publish` | Route to submit or release based on current state. |
101
102
  | `pressship submit` | Upload a zip to WordPress.org review (or reupload). |
@@ -108,6 +109,24 @@ Get help for any command:
108
109
  pressship <command> --help
109
110
  ```
110
111
 
112
+ ## WP-CLI Package
113
+
114
+ Pressship can also be installed as a WP-CLI package:
115
+
116
+ ```bash
117
+ wp package install f/pressship
118
+ ```
119
+
120
+ That adds a `wp ship` command:
121
+
122
+ ```bash
123
+ wp ship verify ./my-plugin
124
+ wp ship pack ./my-plugin
125
+ wp ship publish ./my-plugin --dry-run
126
+ ```
127
+
128
+ The WP-CLI package is intentionally a thin PHP bridge. It forwards arguments to the Node.js Pressship package through `npx`, so the publishing logic stays in one place. Node.js 20+ and npm/npx are still required.
129
+
111
130
  ## Authentication
112
131
 
113
132
  ```bash
@@ -149,6 +168,19 @@ Need fine-grained control? Use the explicit subcommands `submit` and `release`.
149
168
 
150
169
  ## Packaging
151
170
 
171
+ ```bash
172
+ pressship verify ./my-plugin
173
+ ```
174
+
175
+ Runs readme validation and Plugin Check without writing a zip or publishing anything.
176
+
177
+ ```bash
178
+ pressship verify ./my-plugin --ignore "assets/**/*.mp4"
179
+ pressship verify ./my-plugin --skip-readme-validator
180
+ pressship verify ./my-plugin --wp-path /path/to/wordpress
181
+ pressship verify ./my-plugin --json
182
+ ```
183
+
152
184
  ```bash
153
185
  pressship pack ./my-plugin
154
186
  ```
package/composer.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "f/pressship",
3
+ "type": "wp-cli-package",
4
+ "description": "Run Pressship from WP-CLI by forwarding to the Node.js Pressship package.",
5
+ "homepage": "https://pressship.org",
6
+ "license": "MIT",
7
+ "require": {
8
+ "php": ">=7.4",
9
+ "wp-cli/wp-cli": "^2.8"
10
+ },
11
+ "autoload": {
12
+ "classmap": [
13
+ "wp-cli/src/"
14
+ ],
15
+ "files": [
16
+ "wp-cli/pressship-command.php"
17
+ ]
18
+ },
19
+ "extra": {
20
+ "commands": [
21
+ "ship"
22
+ ]
23
+ },
24
+ "support": {
25
+ "issues": "https://github.com/f/pressship/issues",
26
+ "source": "https://github.com/f/pressship"
27
+ }
28
+ }
package/dist/cli.js CHANGED
@@ -4,6 +4,7 @@ import { login } from "./auth/login.js";
4
4
  import { logout } from "./auth/logout.js";
5
5
  import { whoami } from "./auth/whoami.js";
6
6
  import { pack } from "./package/pack.js";
7
+ import { verify } from "./package/verify.js";
7
8
  import { publish } from "./wordpress-org/publish.js";
8
9
  import { submit } from "./wordpress-org/submit.js";
9
10
  import { status } from "./wordpress-org/state.js";
@@ -85,6 +86,15 @@ program
85
86
  .option("--ignore <glob>", "Ignore files in the package; repeat for multiple globs", collectValues, [])
86
87
  .option("-y, --yes", "Continue without interactive confirmations where possible")
87
88
  .action((pluginPath, options) => run(() => publish(pluginPath, options))());
89
+ program
90
+ .command("verify")
91
+ .description("Run readme validation and Plugin Check without packaging or publishing.")
92
+ .argument("[plugin-path]", "Path to the WordPress plugin directory")
93
+ .option("--ignore <glob>", "Ignore files while staging Plugin Check; repeat for multiple globs", collectValues, [])
94
+ .option("--skip-readme-validator", "Skip the remote WordPress.org readme validator")
95
+ .option("--wp-path <path>", "WordPress installation path for `wp plugin check`")
96
+ .option("--json", "Print verification details as JSON")
97
+ .action((pluginPath, options) => run(() => verify(pluginPath, options))());
88
98
  program
89
99
  .command("pack")
90
100
  .description("Create a WordPress-installable plugin zip, similar to npm pack.")
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { z } from "zod";
2
+ import type { PluginProject } from "../types.js";
3
+ import { type PackValidationResult } from "./pack.js";
4
+ declare const verifyOptionsSchema: z.ZodObject<{
5
+ ignore: z.ZodDefault<z.ZodArray<z.ZodString>>;
6
+ skipReadmeValidator: z.ZodDefault<z.ZodBoolean>;
7
+ wpPath: z.ZodOptional<z.ZodString>;
8
+ json: z.ZodDefault<z.ZodBoolean>;
9
+ }, z.core.$strip>;
10
+ export type VerifyOptions = z.input<typeof verifyOptionsSchema>;
11
+ export type VerifySummary = {
12
+ ok: boolean;
13
+ plugin: {
14
+ rootDir: string;
15
+ mainFile: string;
16
+ name: string;
17
+ slug: string;
18
+ version?: string;
19
+ readmePath?: string;
20
+ };
21
+ validation: PackValidationResult;
22
+ };
23
+ export declare function verify(pluginPath: string | undefined, rawOptions: VerifyOptions): Promise<void>;
24
+ export declare function summarizeVerifyResult(project: PluginProject, validation: PackValidationResult): VerifySummary;
25
+ export {};
@@ -0,0 +1,54 @@
1
+ import path from "node:path";
2
+ import { z } from "zod";
3
+ import { hasBlockingFindings, printFindings } from "../checks/summary.js";
4
+ import { discoverPluginProject } from "../plugin/discover.js";
5
+ import { ui } from "../ui.js";
6
+ import { validatePluginPack } from "./pack.js";
7
+ const verifyOptionsSchema = z.object({
8
+ ignore: z.array(z.string()).default([]),
9
+ skipReadmeValidator: z.boolean().default(false),
10
+ wpPath: z.string().optional(),
11
+ json: z.boolean().default(false)
12
+ });
13
+ export async function verify(pluginPath, rawOptions) {
14
+ const options = verifyOptionsSchema.parse(rawOptions);
15
+ if (!options.json) {
16
+ ui.intro("Verify WordPress plugin");
17
+ }
18
+ const rootDir = path.resolve(pluginPath ?? process.cwd());
19
+ const project = options.json
20
+ ? await discoverPluginProject(rootDir)
21
+ : await ui.task("Discovering WordPress plugin", () => discoverPluginProject(rootDir), (value) => `Discovered ${value.headers.pluginName}`);
22
+ const validation = options.json
23
+ ? await validatePluginPack(project, options)
24
+ : await ui.task("Verifying plugin", () => validatePluginPack(project, options));
25
+ const summary = summarizeVerifyResult(project, validation);
26
+ if (options.json) {
27
+ console.log(JSON.stringify(summary, null, 2));
28
+ if (!summary.ok) {
29
+ process.exitCode = 1;
30
+ }
31
+ return;
32
+ }
33
+ printFindings("Readme validation", validation.readmeFindings);
34
+ printFindings("Plugin Check", validation.pluginCheckFindings);
35
+ if (!summary.ok) {
36
+ throw new Error("Verification reported blocking findings.");
37
+ }
38
+ ui.success("Verification passed.");
39
+ }
40
+ export function summarizeVerifyResult(project, validation) {
41
+ return {
42
+ ok: !hasBlockingFindings(validation.readmeFindings) && !hasBlockingFindings(validation.pluginCheckFindings),
43
+ plugin: {
44
+ rootDir: project.rootDir,
45
+ mainFile: project.mainFile,
46
+ name: project.headers.pluginName,
47
+ slug: project.slug,
48
+ version: project.version,
49
+ readmePath: project.readmePath
50
+ },
51
+ validation
52
+ };
53
+ }
54
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/package/verify.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pressship",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Submit and release WordPress.org plugins from the command line.",
5
5
  "homepage": "https://pressship.org",
6
6
  "bin": {
@@ -9,7 +9,9 @@
9
9
  "files": [
10
10
  ".claude",
11
11
  "assets",
12
+ "composer.json",
12
13
  "dist",
14
+ "wp-cli",
13
15
  "README.md",
14
16
  "LICENSE"
15
17
  ],
@@ -0,0 +1,24 @@
1
+ <?php
2
+ /**
3
+ * Registers the Pressship WP-CLI bridge command.
4
+ *
5
+ * The implementation intentionally delegates to the Node.js Pressship package
6
+ * instead of duplicating publishing logic in PHP.
7
+ */
8
+
9
+ if ( ! class_exists( 'WP_CLI' ) ) {
10
+ return;
11
+ }
12
+
13
+ if ( ! class_exists( 'Pressship_WP_CLI_Command' ) ) {
14
+ require_once __DIR__ . '/src/Pressship_WP_CLI_Command.php';
15
+ }
16
+
17
+ WP_CLI::add_command(
18
+ 'ship',
19
+ 'Pressship_WP_CLI_Command',
20
+ array(
21
+ 'shortdesc' => 'Run the Pressship WordPress.org plugin publishing CLI.',
22
+ 'when' => 'before_wp_load',
23
+ )
24
+ );
@@ -0,0 +1,157 @@
1
+ <?php
2
+ /**
3
+ * WP-CLI command bridge for Pressship.
4
+ */
5
+
6
+ /**
7
+ * Run Pressship through WP-CLI.
8
+ */
9
+ class Pressship_WP_CLI_Command {
10
+ /**
11
+ * Invoke Pressship.
12
+ *
13
+ * This command forwards all arguments to the Node.js Pressship CLI through npx.
14
+ *
15
+ * ## OPTIONS
16
+ *
17
+ * [<args>...]
18
+ * : Arguments passed through to Pressship.
19
+ *
20
+ * [--<field>=<value>]
21
+ * : Options passed through to Pressship.
22
+ *
23
+ * ## EXAMPLES
24
+ *
25
+ * wp ship verify ./my-plugin
26
+ * wp ship pack ./my-plugin --json
27
+ * wp ship publish ./my-plugin --dry-run
28
+ *
29
+ * @when before_wp_load
30
+ *
31
+ * @param array<int, string> $args Positional arguments.
32
+ * @param array<string, mixed> $assoc_args Associative arguments.
33
+ * @return void
34
+ */
35
+ public function __invoke( $args, $assoc_args ) {
36
+ $command = self::build_command( $args, $assoc_args );
37
+
38
+ $descriptors = array( STDIN, STDOUT, STDERR );
39
+ $process = proc_open( $command, $descriptors, $pipes );
40
+ if ( ! is_resource( $process ) ) {
41
+ WP_CLI::error( 'Could not start Pressship through npx.' );
42
+ }
43
+
44
+ exit( proc_close( $process ) );
45
+ }
46
+
47
+ /**
48
+ * Build the npx command.
49
+ *
50
+ * @param array<int, string> $args Positional arguments.
51
+ * @param array<string, mixed> $assoc_args Associative arguments.
52
+ * @return string
53
+ */
54
+ public static function build_command( $args, $assoc_args ) {
55
+ $npx = getenv( 'PRESSSHIP_NPX' ) ?: self::default_npx_binary();
56
+ $package = getenv( 'PRESSSHIP_NPX_PACKAGE' ) ?: self::default_npx_package();
57
+ $argv = array_merge(
58
+ array( $npx, '--yes', $package ),
59
+ array_values( $args ),
60
+ self::assoc_args_to_argv( $assoc_args )
61
+ );
62
+
63
+ return self::escape_command( $argv );
64
+ }
65
+
66
+ /**
67
+ * Convert WP-CLI associative arguments to Pressship argv flags.
68
+ *
69
+ * @param array<string, mixed> $assoc_args Associative arguments.
70
+ * @return array<int, string>
71
+ */
72
+ public static function assoc_args_to_argv( $assoc_args ) {
73
+ $argv = array();
74
+
75
+ foreach ( $assoc_args as $name => $value ) {
76
+ if ( 'format' === $name && 'json' === $value ) {
77
+ $argv[] = '--json';
78
+ continue;
79
+ }
80
+
81
+ if ( is_array( $value ) ) {
82
+ foreach ( $value as $item ) {
83
+ $argv[] = self::format_assoc_arg( $name, $item );
84
+ }
85
+ continue;
86
+ }
87
+
88
+ $argv[] = self::format_assoc_arg( $name, $value );
89
+ }
90
+
91
+ return $argv;
92
+ }
93
+
94
+ /**
95
+ * Format one WP-CLI associative argument.
96
+ *
97
+ * @param string $name Argument name.
98
+ * @param mixed $value Argument value.
99
+ * @return string
100
+ */
101
+ private static function format_assoc_arg( $name, $value ) {
102
+ if ( false === $value ) {
103
+ return '--no-' . $name;
104
+ }
105
+
106
+ if ( true === $value ) {
107
+ return '--' . $name;
108
+ }
109
+
110
+ return '--' . $name . '=' . (string) $value;
111
+ }
112
+
113
+ /**
114
+ * Escape argv as a shell command.
115
+ *
116
+ * @param array<int, string> $argv Command argv.
117
+ * @return string
118
+ */
119
+ private static function escape_command( $argv ) {
120
+ return implode( ' ', array_map( 'escapeshellarg', $argv ) );
121
+ }
122
+
123
+ /**
124
+ * Default npx binary.
125
+ *
126
+ * @return string
127
+ */
128
+ private static function default_npx_binary() {
129
+ return self::is_windows() ? 'npx.cmd' : 'npx';
130
+ }
131
+
132
+ /**
133
+ * Default npm package spec.
134
+ *
135
+ * @return string
136
+ */
137
+ private static function default_npx_package() {
138
+ $package_json = dirname( __DIR__, 2 ) . '/package.json';
139
+ if ( file_exists( $package_json ) ) {
140
+ $package = json_decode( file_get_contents( $package_json ), true );
141
+ if ( is_array( $package ) && ! empty( $package['version'] ) ) {
142
+ return 'pressship@' . $package['version'];
143
+ }
144
+ }
145
+
146
+ return 'pressship';
147
+ }
148
+
149
+ /**
150
+ * Detect Windows without depending on WP-CLI utils.
151
+ *
152
+ * @return bool
153
+ */
154
+ private static function is_windows() {
155
+ return '\\' === DIRECTORY_SEPARATOR;
156
+ }
157
+ }