Setup wizard, config validation, and SEO metadata#10
Conversation
| const crypto = await import("node:crypto"); | ||
| const signature = crypto | ||
| .createHmac("sha256", Buffer.from(secret, "hex")) | ||
| .update(`${header}.${payload}`) |
|
|
||
| for (const [key, value] of [...map.entries()].sort(([a], [b]) => a.localeCompare(b))) { | ||
| const escaped = | ||
| value.includes(" ") || value.includes("#") ? `"${value.replace(/"/gu, '\\"')}"` : value; |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9537867e79
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| export function validateConfig(options: ValidateConfigOptions = {}): ValidationReport { | ||
| const cwd = options.cwd ?? process.cwd(); | ||
| const env = envRecordFromProcess(options.env); |
There was a problem hiding this comment.
Load the project .env during validation
When pnpm validate:config is run from the documented CLI path, validateConfigAsync() is called without an env override, so this line only reads process.env and never parses the .env file that the setup wizard just wrote. In a normal local setup where credentials live only in .env, validation reports required variables like GITHUB_TOKEN/GITHUB_OWNER as missing even though envPath exists, making the new validation command and Studio compatibility check misleading unless the user manually exports every value in their shell.
Useful? React with 👍 / 👎.
| label: "WordPress site URL", | ||
| help: "Your site root, e.g. https://blog.example.com — no trailing slash.", | ||
| required: true, |
There was a problem hiding this comment.
Ask for the WordPress REST base URL
For WordPress setups, this prompt tells the wizard user to save the site root, but the existing WordPress publisher treats WORDPRESS_API_URL as the REST base and appends paths like /wp/v2/posts to it. If a user follows this new setup text and enters https://blog.example.com, publishing calls https://blog.example.com/wp/v2/posts instead of https://blog.example.com/wp-json/wp/v2/posts; conversely, an existing correct /wp-json value makes the new connection check append /wp-json a second time.
Useful? React with 👍 / 👎.
| headers: { | ||
| Authorization: `Bearer ${token}`, | ||
| Accept: "application/json", |
There was a problem hiding this comment.
Honor Bitbucket app-password auth in connection checks
This connection check always sends the token as a bearer token, but the runtime Bitbucket publisher switches to Basic auth when BITBUCKET_USERNAME is set for app passwords. In the common setup path where users provide an app password plus username (which the setup prompts allow), publishing can work while the new --connections validation reports Bitbucket as unreachable, so the setup wizard fails a valid configuration.
Useful? React with 👍 / 👎.
| if ( | ||
| socialImage && | ||
| /^https?:\/\//iu.test(socialImage) && | ||
| socialImage !== featureImage | ||
| ) { | ||
| post.og_image = socialImage; |
There was a problem hiding this comment.
Use the social image for Ghost og_image
When a Ghost post has both an absolute heroImage and a different absolute socialImage, this new branch still does not send og_image: featureImage is computed via resolveFeatureImageUrl(article), which picks article.socialImage before heroImage, so socialImage !== featureImage is false for exactly the case the new SEO mapping documents. The result is that users cannot publish a distinct Open Graph image to Ghost even though the field is accepted in Studio.
Useful? React with 👍 / 👎.
| if (options.checkConnections) { | ||
| report.connection = await checkPublisherConnection(publisher, env); |
There was a problem hiding this comment.
Report connection failures instead of throwing
When --connections is enabled and a fetch rejects (offline machine, DNS/TLS error, corporate proxy, etc.), this await propagates the exception instead of returning a validation report with a connection issue. The CLI/wizard then exits with a generic fetch error after the wizard may already have written files, so users do not get the promised validation summary or actionable per-publisher failure detail.
Useful? React with 👍 / 👎.
| if (publisher === "github" && defaultBranch) { | ||
| envUpdates.set("GITHUB_BRANCH", defaultBranch); | ||
| } |
There was a problem hiding this comment.
Preserve existing GitHub branch choices
If .env already contains GITHUB_BRANCH and the user keeps that existing value when prompted, the wizard still unconditionally adds the newly entered default branch to envUpdates here, so the final merge overwrites the existing branch without confirmation. This can redirect future publishes to main (the default wizard answer) even for projects intentionally configured to publish from another branch.
Useful? React with 👍 / 👎.
|
Closing retroactive split-stack review PR. Continuing from protected main with scoped feature PRs. |
PR 9 of 11. Interactive setup wizard, config validation CLI, SEO metadata.