Skip to content

feat: add one-command environment setup script#781

Closed
alexsuperpremium-collab wants to merge 5 commits intoSolFoundry:mainfrom
alexsuperpremium-collab:fix/issue-491
Closed

feat: add one-command environment setup script#781
alexsuperpremium-collab wants to merge 5 commits intoSolFoundry:mainfrom
alexsuperpremium-collab:fix/issue-491

Conversation

@alexsuperpremium-collab
Copy link
Copy Markdown

Summary

Added scripts/setup.sh to automate the local development environment setup from git clone to running services.

Changes

  • Checks for required dependencies: Node.js, Python, Rust, and optionally Anchor & Docker.
  • Copies .env.example to .env for both root and backend directories safely (idempotent).
  • Installs Python backend dependencies inside a local venv.
  • Installs Node.js frontend (and SDK) dependencies via npm install.
  • Starts the database and Redis using Docker Compose if available.
  • Prints clear success messages with the URLs needed to start developing.

Testing

Tested script execution locally, confirms idempotent behavior across multiple runs without failure.

Fixes #491

Wallet: 7y4cEfLgX5m7ymTHdmwybBJoD6TYWgfWhcXG3yaXXniv

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0faf4fac-241a-4789-8b87-28bf581d743a

📥 Commits

Reviewing files that changed from the base of the PR and between e4f5605 and bcb7c1b.

📒 Files selected for processing (2)
  • scripts/setup.sh
  • scripts/setup_test.bats

📝 Walkthrough

Walkthrough

Adds a new executable Bash script scripts/setup.sh that bootstraps a local dev environment: enables strict error handling, provides colored logging and command wrappers, checks required tools (Node.js, npm, Python 3.10+, venv, pip3, Rust) with version comparisons, emits warnings for optional tools (Anchor CLI, Docker), copies .env.example to .env and backend/.env.example to backend/.env when missing, installs backend Python deps into backend/venv, runs npm install in frontend/ and optionally sdk/, and attempts to start DB/Redis via Docker Compose. Adds Bats tests scripts/setup_test.bats covering dry-run behavior, env file creation, missing directories, and compose handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

approved, paid

Suggested reviewers

  • chronoeth-creator
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive The PR implements most core requirements (setup script, dependency checks, env file creation, installation of deps, service startup, success messaging), but reviewer feedback and commit messages indicate unresolved robustness, testing quality, and error-handling gaps that may not fully satisfy the bounty criteria. Address identified issues: strengthen automated test coverage and robustness, enforce minimum tool versions with clear validation, improve error handling and final status reporting to distinguish success from partial failures, and add preflight directory/file checks before attempting operations.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add one-command environment setup script' accurately describes the main change—a new automation script for environment setup.
Description check ✅ Passed The description clearly relates to the changeset, detailing the setup script functionality, dependency checks, environment configuration, service startup, and testing.
Out of Scope Changes check ✅ Passed All changes (setup.sh and setup_test.bats) are directly scoped to the bounty requirements for a one-command environment setup script and its test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5a3017b and 237cc19.

📒 Files selected for processing (1)
  • scripts/setup.sh

Xinyan0906 added 2 commits March 23, 2026 10:47
- 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
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 237cc19 and 82d428c.

📒 Files selected for processing (2)
  • scripts/setup.sh
  • scripts/setup_test.bats

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (4)
scripts/setup_test.bats (2)

9-13: ⚠️ Potential issue | 🟠 Major

DRY_RUN=1 does 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 | 🟠 Major

Test 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 | 🟠 Major

Compose 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_gt is GNU-specific and breaks macOS compatibility claims.

Line 37 depends on sort -V, which is not available in default BSD sort on 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

📥 Commits

Reviewing files that changed from the base of the PR and between 82d428c and e4f5605.

📒 Files selected for processing (2)
  • scripts/setup.sh
  • scripts/setup_test.bats

@alexsuperpremium-collab
Copy link
Copy Markdown
Author

Closing test/invalid PR. Apologies for the noise.

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.

2 participants