feat: add one-command environment setup script#781
feat: add one-command environment setup script#781alexsuperpremium-collab wants to merge 5 commits intoSolFoundry:mainfrom
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a new executable Bash script Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/setup.sh`:
- Around line 123-126: The script currently treats `npm install` failures as
non-fatal but still calls `print_success "SDK checked."`, which misreports
success; update the `npm install` logic so the success message is only printed
when the install actually succeeds (for example, check the exit status of `npm
install` or set a local flag), and on failure either exit with a non-zero status
or call the existing warning helper before skipping further success output;
target the `npm install` invocation and the subsequent `print_success "SDK
checked."` call to implement this conditional behavior.
- Line 7: The global "set -e" causes docker-compose failures to hard-fail the
script; keep "set -e" but make Docker invocations resilient by wrapping the
docker commands ("docker-compose" and "docker compose") so their failures do not
exit the script—e.g., run them only if Docker is present and append a
non-failing fallback (similar to the SDK install's "|| echo" pattern), or
replace the direct calls with a conditional that logs a warning on failure and
continues; update the docker invocation sites referenced by the
"docker-compose"/"docker compose" symbols accordingly.
- Around line 36-70: The script only checks for presence of tools but not
minimum versions; update the checks around NODE_VERSION, PYTHON_VERSION and
RUST_VERSION (and optionally ANCHOR_VERSION) to parse the installed version
strings (from node -v, python3 --version, rustc --version, anchor --version) and
compare them against the required minimums (Node >= 18, Python >= 3.10, Rust as
desired); if a version is lower than the minimum, call print_error and exit
non‑zero. Implement a small shell version-compare helper (or use dpkg
--compare-versions / sort -V if available) and use it where NODE_VERSION,
PYTHON_VERSION and RUST_VERSION are assigned to enforce the constraints before
printing success.
- Around line 106-108: The script calls "python3 -m venv venv" without
confirming the venv module is present, so add a preflight check (similar to the
existing Python/pip3/Node/Rust checks) that verifies venv is available before
attempting to create the virtualenv; implement this by running a quick import
test (e.g., attempt "python3 -c 'import venv'") or equivalent, and if it fails
print a clear error instructing the user to install the python3-venv package and
exit non-zero so the one-command setup fails early instead of mid-run.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: e25128da-4be0-4446-92ce-487e7b8a953c
📒 Files selected for processing (1)
scripts/setup.sh
- Added automated tests using Bats (scripts/setup_test.bats) - Implemented robust minimum version checking for Node.js (18+) and Python (3.10+) - Added pre-flight check for python3-venv before creating virtual environments - Fixed SDK npm install error handling to not incorrectly report success on failure - Replaced hardcded directory assumptions with robust `[ -d ... ]` checks for backend, frontend, and SDK - Captured docker-compose failures to prevent the script from hard-crashing if Docker daemon is not running - Enabled strict error handling with `set -euo pipefail`
- Refactored to use a mode helper () so tests can execute deterministically without system side effects or network hangs - Stopped relying on in the script; now calls directly to ensure POSIX portability - Added explicit checks for before trying to spin up Docker - Separated global state: script will now print a 'Warnings' banner if optional SDK or Docker setup fails, rather than a blanket misleading success - Enhanced to use DRY_RUN and assert exact text outputs and file conditions for success, missing frontend, missing backend, missing docker, and venv creation
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/setup_test.bats`:
- Around line 3-10: The setup() function in scripts/setup_test.bats assumes the
test is run from the repo root by using a relative path cp ./scripts/setup.sh;
change it to locate the repo script relative to the test file (use the test's
directory via BATS_TEST_DIRNAME or dirname "${BATS_TEST_FILENAME}") when copying
into TEST_DIR, and make TEST_DIR creation and chmod logic unchanged; also ensure
external command availability by sanitizing PATH inside setup() or by
stubbing/mocking required commands (node, python3, etc.) via wrapper scripts
placed into TEST_DIR and prepending TEST_DIR to PATH so tests run
deterministically even when executed from other working directories.
- Around line 30-39: The test "creates .env from .env.example" in
scripts/setup_test.bats fails on CI because it invokes run ./setup.sh which
performs real dependency checks (Node/Python/Rust) before the .env creation
logic; modify the test to isolate those checks by either exporting a feature
flag or environment variable that skips dependency verification in setup.sh
(e.g., SKIP_DEP_CHECKS=1) or by stubbing the required tools into PATH (create
fake node/python/rust executables in a temp bin and prepend to PATH) so setup.sh
reaches the .env creation branch, and add an explicit assertion on the exit
status (e.g., [ "$status" -eq 0 ]) immediately after run ./setup.sh before
asserting [ -f .env ] and [ -f backend/.env ] so failures report the process
exit code.
- Around line 16-28: The test "script runs and exits 0 on valid environment" is
currently accepting both exit codes 0 and 1 which masks failures; change it so
the test only asserts success when prerequisites are present and otherwise skips
the test: detect required tools (e.g., using command -v node python3 rustc
docker) at the top of the test and call bats' skip if any are missing, or
alternatively mock/override external commands before running ./setup.sh so the
script runs deterministically, then assert [ "$status" -eq 0 ] to verify
successful execution; ensure the test separates a lightweight "syntax/flow"
check (which can run without dependencies) from the full execution test by
adding a distinct test name or conditional logic within the "script runs and
exits 0 on valid environment" test to avoid false positives.
- Around line 41-59: The tests "handles missing backend gracefully" and "handles
missing frontend gracefully" in scripts/setup_test.bats fail to reach the
directory-handling logic because setup.sh aborts earlier during dependency
checks; fix by having the tests bypass dependency validation before invoking
setup.sh (e.g., export a flag or env var that setup.sh honors such as
SKIP_DEP_CHECKS=1, or invoke setup.sh with a --skip-deps option if implemented)
so the call to setup.sh in those `@test` blocks executes the directory logic and
the grep assertions can succeed; update the two `@test` blocks to set
SKIP_DEP_CHECKS=1 (or otherwise stub dependency checks) before running setup.sh.
In `@scripts/setup.sh`:
- Around line 174-188: The failure messages in the docker-compose branches (the
if blocks that call "docker-compose up -d db redis" and "docker compose up -d db
redis") incorrectly only suggest "Is Docker daemon running?"; update the logic
in the docker-compose branch(s) to first check for a compose file (look for
common filenames like docker-compose.yml, docker-compose.yaml,
docker/compose.yml, docker/compose.yaml or compose.yaml) before attempting to
start services, and if missing either skip start with print_warning mentioning
"compose file not found" or augment the existing print_warning to list both
possible causes (missing compose file OR Docker daemon not running); reference
these checks around the existing docker-compose and docker compose invocation
blocks and use the same print_warning/print_success helpers for messaging.
- Line 37: The version_gt function uses GNU sort -V which isn't available on
macOS; update version_gt to first test if "sort -V" works, then fall back to
"gsort -V" if present, and if neither is available replace the implementation
with a POSIX-safe comparator (e.g., an awk-based numeric segment compare) or
call a small Python one-liner; ensure you update the existing version_gt
function and its callers (the Node.js and Python version checks that invoke
version_gt) so they use the detected/gfallback comparator so the script runs on
macOS without requiring coreutils.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 38e08fe7-c897-4bf2-bcc8-a5dc44b269a3
📒 Files selected for processing (2)
scripts/setup.shscripts/setup_test.bats
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (4)
scripts/setup_test.bats (2)
9-13:⚠️ Potential issue | 🟠 Major
DRY_RUN=1does not make this suite deterministic; hard dependency checks still execute.The script’s Node/Python/pip/Rust presence/version checks run before install commands, so these tests still depend on host toolchain availability despite DRY_RUN. This undermines reproducibility and can fail unrelated assertions across environments.
Also applies to: 20-81
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/setup_test.bats` around lines 9 - 13, The dependency/version checks in scripts/setup_test.bats still run even when DRY_RUN=1, causing nondeterministic failures; modify the script so that all hard tool checks (the blocks that verify node/python/pip/rust under the dependency-check section — the checks spanning the current 20-81 range) are skipped when DRY_RUN is set: add a guard that returns/continues early if DRY_RUN=1 (or wrap each check in if [ -n "$DRY_RUN" ]; then ... skip ... fi), or set a mock-safe path/flag used by the check functions to bypass actual host tool probing, ensuring no host tool versions are invoked when DRY_RUN is enabled.
3-7:⚠️ Potential issue | 🟠 MajorTest setup assumes repository-root execution path.
Line 6 copies
./scripts/setup.sh, which breaks when Bats is invoked from outside repo root. This makes the suite fragile in CI wrappers and local developer workflows.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/setup_test.bats` around lines 3 - 7, The setup() function currently uses a relative path (cp ./scripts/setup.sh) which fails when Bats is run outside the repo root; change the copy source to an absolute path resolved at runtime (e.g., determine the test script's directory or the repository root) instead of relying on cwd. In practice, inside setup() compute the directory of the current test file (or call git rev-parse --show-toplevel) and use that resolved path as the source for copying setup.sh into TEST_DIR so the cp command always finds the correct scripts/setup.sh regardless of invocation location.scripts/setup.sh (2)
194-217:⚠️ Potential issue | 🟠 MajorCompose detection + final status reporting can misstate setup completeness.
Two issues combine here:
- Line 194 gates only on
docker-compose.yml(ignores other common compose filenames/locations).- Lines 215–217 warn on missing compose file but do not set
SETUP_FAILED, so lines 220–224 can still print “All components successfully installed” even when services were skipped.This is misleading for a one-command “running dev environment” flow.
Also applies to: 220-224
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/setup.sh` around lines 194 - 217, The compose detection currently only checks "docker-compose.yml" and, when missing, prints a warning without setting SETUP_FAILED which can allow the final "All components successfully installed" message to be incorrect; update the detection logic in the block that uses run_cmd/docker-compose/docker compose to instead look for common compose filenames (e.g., docker-compose.yml, docker-compose.yaml, docker/compose.yml, docker/compose.yaml, and compose.yaml) before attempting docker commands, and ensure that when no compose file is found you set SETUP_FAILED=1 (and leave DOCKER_SUCCESS unset/0) so the final status reporting correctly reflects that services were skipped or failed; keep using the existing helpers run_cmd, print_warning, print_success, and the DOCKER_SUCCESS/SETUP_FAILED flags so the rest of the script's final checks behave correctly.
37-37:⚠️ Potential issue | 🟠 Major
version_gtis GNU-specific and breaks macOS compatibility claims.Line 37 depends on
sort -V, which is not available in default BSDsorton macOS. This can fail dependency validation before setup even starts, conflicting with the stated macOS compatibility objective.#!/bin/bash set -euo pipefail echo "Inspect version comparator implementation:" nl -ba scripts/setup.sh | sed -n '34,40p' echo echo "Check whether current environment sort supports -V (GNU extension):" if sort --help 2>&1 | rg -q '\-V'; then echo "sort -V supported" else echo "sort -V NOT supported (typical on BSD/macOS)" fi echo echo "Check for macOS fallback comparator references in script:" rg -n "gsort|Darwin|OSTYPE|awk.*version|python.*version" scripts/setup.sh || true🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/setup.sh` at line 37, The current version_gt function relies on GNU sort -V which breaks on macOS; replace it with a POSIX-compatible comparator (e.g., an awk-based numeric component-wise semver comparator) inside the version_gt function so it works without GNU extensions. Locate the version_gt() definition and implement a short awk (or pure-sh) routine that splits the two version strings on dots, compares each numeric field in order, and returns success if the first is greater; keep the function signature version_gt() { ... } so all callers remain unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/setup_test.bats`:
- Around line 62-71: The test "@test \"reports global success when all
components are present and mock execution succeeds\"" is flaky because it
depends on real docker-compose/docker availability when invoking ./setup.sh;
modify the test to stub/override the compose check before running ./setup.sh
(for example export a variable or mock the docker-compose/docker command that
setup.sh uses) so the success path is forced, then assert that ./setup.sh exits
0 and prints "Setup Complete! All components successfully installed."; target
the test block and the invocation of ./setup.sh to insert the mock setup rather
than relying on real compose tooling.
- Around line 34-41: Update the Bats tests to assert the command exit status in
addition to grepping output: after the existing run ./setup.sh line in each
`@test` block (including the blocks at 34-41, 43-50, 52-60, and 73-81), add an
explicit assertion on $status (e.g., test "$status" -eq 0 or the expected
non-zero value) so failures distinguish branch mismatches from early
termination; reference the existing use of run and $output in these `@test` blocks
and ensure the $status assertion appears before or alongside the echo "$output"
| grep checks.
In `@scripts/setup.sh`:
- Around line 86-97: The script currently only checks presence of rustc and
anchor and prints their versions (RUST_VERSION, ANCHOR_VERSION) but does not
enforce minimums; update the rust and anchor checks to use the existing
version_gt() helper to validate RUST_VERSION >= 1.76 and ANCHOR_VERSION >= 0.30,
calling print_error and exiting (like the Node/Python checks) when version_gt
indicates the installed version is too old, otherwise call print_success as now;
keep the existing command -v presence checks and print_warning behavior for
Anchor only if you prefer non-fatal, otherwise make Anchor failure fatal per
CONTRIBUTING.md.
---
Duplicate comments:
In `@scripts/setup_test.bats`:
- Around line 9-13: The dependency/version checks in scripts/setup_test.bats
still run even when DRY_RUN=1, causing nondeterministic failures; modify the
script so that all hard tool checks (the blocks that verify node/python/pip/rust
under the dependency-check section — the checks spanning the current 20-81
range) are skipped when DRY_RUN is set: add a guard that returns/continues early
if DRY_RUN=1 (or wrap each check in if [ -n "$DRY_RUN" ]; then ... skip ... fi),
or set a mock-safe path/flag used by the check functions to bypass actual host
tool probing, ensuring no host tool versions are invoked when DRY_RUN is
enabled.
- Around line 3-7: The setup() function currently uses a relative path (cp
./scripts/setup.sh) which fails when Bats is run outside the repo root; change
the copy source to an absolute path resolved at runtime (e.g., determine the
test script's directory or the repository root) instead of relying on cwd. In
practice, inside setup() compute the directory of the current test file (or call
git rev-parse --show-toplevel) and use that resolved path as the source for
copying setup.sh into TEST_DIR so the cp command always finds the correct
scripts/setup.sh regardless of invocation location.
In `@scripts/setup.sh`:
- Around line 194-217: The compose detection currently only checks
"docker-compose.yml" and, when missing, prints a warning without setting
SETUP_FAILED which can allow the final "All components successfully installed"
message to be incorrect; update the detection logic in the block that uses
run_cmd/docker-compose/docker compose to instead look for common compose
filenames (e.g., docker-compose.yml, docker-compose.yaml, docker/compose.yml,
docker/compose.yaml, and compose.yaml) before attempting docker commands, and
ensure that when no compose file is found you set SETUP_FAILED=1 (and leave
DOCKER_SUCCESS unset/0) so the final status reporting correctly reflects that
services were skipped or failed; keep using the existing helpers run_cmd,
print_warning, print_success, and the DOCKER_SUCCESS/SETUP_FAILED flags so the
rest of the script's final checks behave correctly.
- Line 37: The current version_gt function relies on GNU sort -V which breaks on
macOS; replace it with a POSIX-compatible comparator (e.g., an awk-based numeric
component-wise semver comparator) inside the version_gt function so it works
without GNU extensions. Locate the version_gt() definition and implement a short
awk (or pure-sh) routine that splits the two version strings on dots, compares
each numeric field in order, and returns success if the first is greater; keep
the function signature version_gt() { ... } so all callers remain unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6c99d02b-e98c-481d-b7ed-73a685a8b83d
📒 Files selected for processing (2)
scripts/setup.shscripts/setup_test.bats
|
Closing test/invalid PR. Apologies for the noise. |
Summary
Added
scripts/setup.shto automate the local development environment setup from git clone to running services.Changes
.env.exampleto.envfor both root and backend directories safely (idempotent).venv.npm install.Testing
Tested script execution locally, confirms idempotent behavior across multiple runs without failure.
Fixes #491
Wallet: 7y4cEfLgX5m7ymTHdmwybBJoD6TYWgfWhcXG3yaXXniv