Skip to content

Add host-tools/setup.sh to create .env with prompts - #348

Merged
jazzsequence merged 5 commits into
WordPress:masterfrom
iarif4u:add/host-tools-setup
Nov 4, 2026
Merged

jazzsequence merged 5 commits into
WordPress:masterfrom
iarif4u:add/host-tools-setup

Conversation

@iarif4u

@iarif4u iarif4u commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Part of #257 (the first idea: set up .env with prompts instead of vim). The one-step run script is in #346 for #260.

Purpose

Hosts say that the runner install is tedious. Today, they clone the repo, copy .env.default, edit it in vim, and find out on the first run whether the database credentials work. This script does those steps and checks them.

What host-tools/setup.sh does

  1. Checks the software: php git rsync wget unzip node npm. composer is optional. It prints the Node.js and npm versions and stops with a list if something is missing.
  2. Asks for the values: database name, user, password, host, PHP executable, checkout directory, and the report API key. Passwords and the API key are not shown when you type them. Press Enter to keep the current value.
  3. Tests the database connection with the runner's own wpt_runner_parse_db_host() and mysqli, using WPT_PHP_EXECUTABLE. If the connection fails, .env is not changed.
  4. Writes .env from .env.default. It changes only the lines it asks about. It quotes each value safely, sets the file mode to 600, and saves the old .env as .env.bak-<timestamp>.

Also:

  • Sets WPT_TEST_DIR to WPT_PREPARE_DIR. With .env.default as it is, the two are different (wp-test-runner and /tmp/wp-test-runner), so a local run stops in check_required_env() with "WPT_TEST_DIR must be the same as WPT_PREPARE_DIR".
  • --non-interactive takes the values from the environment, for provisioning tools. --skip-checks and --skip-db-check skip those steps.
  • Warns when run as root.
  • It does not install software, create the database, or set up cron. Those are different for each host.

The README "Configuring the Runner" section now mentions the script first, before the manual steps.

Testing

Tested against a real MySQL 9.6 server with PHP 8.4:

Case Result
--non-interactive, correct credentials Connects, writes .env (mode 600), exit 0
source .env, then check_required_env() Passes
Wrong password "Access denied", .env unchanged, exit 1
Invalid WPT_DB_HOST "WPT_DB_HOST is not valid", .env unchanged
Interactive, values with ', #, $ and spaces Values are the same after source .env
Run again, Enter for every value Keeps the values, saves a backup
Environment value set Environment value wins over the current .env
node, npm or wget missing Lists the missing software, exit 1

Contributed at WordCamp Contributor Day.

Checks the required software, asks for the database credentials and the
report API key, tests the database connection with mysqli, and writes
.env from .env.default. WPT_TEST_DIR is set to WPT_PREPARE_DIR, which a
local run requires. --non-interactive takes the values from the
environment.

Part of WordPress#257.
@github-actions

github-actions Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @iarif4u.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

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

Unlinked contributors: iarif4u.

Co-authored-by: ekamran <ekamran@git.wordpress.org>
Co-authored-by: kittenkamala <amykamala@git.wordpress.org>
Co-authored-by: mindctrl <mindctrl@git.wordpress.org>

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


Props Bot commands

You can trigger Props Bot actions by commenting on this PR:

  • @propsbot add <username> to give props to a GitHub user. Requires write access.
  • @propsbot remove <username> to leave a user out of the props. Requires write access.
  • @propsbot refresh to refresh this list. Adding the props-bot label works too.

@ekamran ekamran left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @iarif4u, this will save hosts a lot of time. I ran it on macOS (bash 3.2) and Linux (bash 5.2) against MariaDB 12.3. Correct and wrong credentials, a password with ', ", $, # and a space, an invalid host, PHP without mysqli, and missing software all work as described. The values come back the same after source .env.

The one change I think should be fixed before merge is about running the script again. It rebuilds .env from .env.default, so the settings it does not ask about go back to the defaults, and SSH hosts lose their SSH settings. Details and suggestions are inline. With all of them applied, a re-run with Enter at every prompt changes nothing, on a local host and on an SSH host.

Not blocking: the ${WPT_PHP_EXECUTABLE-php} line becomes 'php', so a cron entry that sets WPT_PHP_EXECUTABLE no longer wins. That is fine if no host relies on it.

Comment thread host-tools/setup.sh Resolved
Comment thread host-tools/setup.sh Resolved
Comment thread host-tools/setup.sh Resolved
Comment thread host-tools/setup.sh Resolved
Comment thread host-tools/setup.sh Resolved
- Build .env from the current .env, not .env.default, so the settings
  the script does not ask about (SSH, report URL, debug, ...) are kept,
  and append any asked-about variable the file does not have yet.
- Set WPT_TEST_DIR to WPT_PREPARE_DIR after the prompts, so it also
  applies to --non-interactive, and keep it when WPT_SSH_CONNECT is set.
- Skip the database check in SSH mode: the tests connect from the
  remote server.
- Make the .env backup readable only by its owner.
- Allow .env lines that use an unset variable.
SC2016 flags the single-quoted PHP code. The quotes are intentional.
@iarif4u

iarif4u commented Oct 10, 2026

Copy link
Copy Markdown
Contributor Author

@ekamran Thanks for the careful review. All suggestions on #346, #348 and #349 are applied: #348 e7efa2d (+ 41d62ea), #346 28be5d0, #349 4996e28.

I ran both scripts through 36 checks, on macOS (bash 3.2.57, MySQL 9.6) and on Ubuntu 24.04 (bash 5.2.21, PHP 8.3, MySQL 8.0). Your cases are included: a re-run keeps the 8 custom settings and the SSH settings, --non-interactive after cp .env.default .env, the SSH database skip, a 644 .env gets a 600 backup, and a .env with an unset variable. The original cases are included too: special characters, real and wrong database credentials, and the testrunner.sh step order. All 36 pass on both systems. The same harness against the previous heads (9ab31b9 and 41575c3) fails 18 checks, exactly the cases you found. shellcheck 0.9.0 is clean on both scripts. 41d62ea only adds a disable=SC2016 directive for the single-quoted PHP code.

On the non-blocking note: I left WPT_PHP_EXECUTABLE as a written value. The prompt shows the current value, so a host can keep it or change it there.

@ekamran ekamran left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @iarif4u. I re-checked 41d62ea as a whole on macOS and Linux. All 14 earlier cases now behave as intended, and so do a runner path with a space, a .env with a missing or non-exported variable, and repeated backups.

One case is left, details inline: a .env this user cannot read, or a runner folder it cannot write to. Happy to approve once that is in.

Comment thread host-tools/setup.sh Resolved
An unreadable .env (for example root-owned after a first run with sudo)
was replaced without a backup, losing the settings the script does not ask
about, and a read-only runner directory was reported as saved.

@ekamran ekamran left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @iarif4u. I re-checked 5c1a235: an unreadable .env and a read-only runner folder now both stop before anything is asked, on macOS and on Linux, and the 14 earlier cases behave the same.

@iarif4u

iarif4u commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @ekamran for the approval, and for testing the last two cases on macOS and Linux!

Comment thread host-tools/setup.sh Resolved
Comment thread host-tools/setup.sh Resolved
read without IFS= strips them before -r gets the line, so a password
or report API key typed with a leading or trailing space loses it
silently.
@kittenkamala

kittenkamala commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Can merge with #349 and #346 once 346 is approved

@jazzsequence
jazzsequence merged commit cf2b138 into WordPress:master Nov 4, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants