Skip to content

fix(installer): drop RETURN-trap leak and guard ctl deploy on template config#33

Merged
chr1syy merged 1 commit into
mainfrom
fix/installer-followups
May 7, 2026
Merged

fix(installer): drop RETURN-trap leak and guard ctl deploy on template config#33
chr1syy merged 1 commit into
mainfrom
fix/installer-followups

Conversation

@chr1syy
Copy link
Copy Markdown
Collaborator

@chr1syy chr1syy commented May 7, 2026

Summary

Two follow-ups discovered during a fresh-install dry run of v0.1.0 in a sandboxed \$HOME.

  • install.sh — drop the RETURN trap on \$staging cleanup, replace with explicit rm -rf at the end of install_release(). Bash's RETURN trap is process-wide, not function-local, so it kept firing on later function returns where \$staging had gone out of scope and printed line 516: staging: unbound variable after install completed.
  • bin/maestro-relay-ctl.sh — `cmd_deploy` now mirrors `install.sh`'s `config_complete` check, refusing with a friendly error when the `.env` is empty or still has `your_*` template values. Previously it surfaced a Node stack trace (Missing required env var: DISCORD_BOT_TOKEN) to the user.

Bumps to `0.1.1` (patch).

Test plan

  • `npm test` — 169/169 pass
  • Smoke-tested patched ctl deploy against the v0.1.0 install in `/tmp/relay-fresh`: now exits 1 with `✗ Config at .../.env is incomplete or contains template values. Edit it before running deploy.`
  • After merge: tag `v0.1.1`, verify `maestro-relay-v0.1.1.tar.gz` published, re-run fresh-install dry run and confirm no `unbound variable` warning.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced deployment process with configuration validation to ensure all required Discord settings are present and properly configured. Users receive clear error messages if configuration is incomplete.
  • Chores

    • Updated version to 0.1.1.

…e config

Two follow-up fixes uncovered by the v0.1.0 fresh-install dry run:

- install.sh: remove the RETURN trap that referenced a function-local
  `staging` variable. Bash's RETURN trap is process-wide, so it kept
  firing on later function returns where `$staging` no longer existed
  and printed "line 516: staging: unbound variable" after install
  completed. Replace with explicit cleanup at end of install_release().

- bin/maestro-relay-ctl.sh: cmd_deploy now mirrors install.sh's
  config_complete check, refusing with a friendly error when the .env
  is empty or still has `your_*` template values. Previously it
  invoked the deploy script directly and surfaced a Node stack trace
  ("Missing required env var: DISCORD_BOT_TOKEN") to the user.

Bump to 0.1.1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

Configuration validation is added to enforce complete Discord settings before deployment. The config_complete helper ensures DISCORD_BOT_TOKEN, DISCORD_CLIENT_ID, and DISCORD_GUILD_ID are present and not template placeholders. The installer's staging cleanup is refactored to use explicit removal after environment migration. Version bumped to 0.1.1.

Changes

Deployment Validation & Installation Refinement

Layer / File(s) Summary
Configuration Validation Helper
bin/maestro-relay-ctl.sh
New config_complete function reads Discord configuration keys and rejects files with missing, empty, or placeholder-template values (starting with your_).
Deploy Command Integration
bin/maestro-relay-ctl.sh
cmd_deploy calls config_complete after verifying the .env file exists; aborts with descriptive error if configuration is incomplete or contains templates. Preserved existing logic for deriving ENABLED_PROVIDERS and dispatching to Discord provider.
Installer Staging Cleanup
install.sh
Changed install_release to remove automatic trap-based cleanup of staging directory; now explicitly calls rm -rf "$staging" after environment file migration instead.
Version Update
package.json
Version field updated from 0.1.0 to 0.1.1.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A config check before we go,
No more rushing with template woe,
Staging cleaned with explicit care,
Version bumped, now passing fair! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures both main changes: dropping a RETURN-trap bug and adding config validation to ctl deploy, matching the changeset exactly.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/installer-followups

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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.

🧹 Nitpick comments (3)
bin/maestro-relay-ctl.sh (2)

158-174: 💤 Low value

cmd_deploy guard is correct and matches the PR's stated behavior.

The validation correctly short-circuits with a user-friendly die before attempting Node deployment. One small point: the error message at line 163 names $INSTALL_DIR/.env (the symlink), while install.sh's deploy_commands names $CONFIG_DIR/.env (the canonical file). Both paths resolve to the same file, so this is transparent to the user, but pointing directly at $CONFIG_DIR (which is available in scope) would be slightly more consistent and avoid any confusion for users who inspect the path and find a symlink:

-  if ! config_complete "$env_file"; then
-    die "Config at $env_file is incomplete or contains template values. Edit it before running deploy."
-  fi
+  if ! config_complete "$env_file"; then
+    die "Config at $CONFIG_DIR/.env is incomplete or contains template values. Edit it before running deploy."
+  fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bin/maestro-relay-ctl.sh` around lines 158 - 174, The error message in
cmd_deploy uses $INSTALL_DIR/.env which may be a symlink and differs from
install.sh's messaging; update the die call in function cmd_deploy to reference
the canonical $CONFIG_DIR/.env instead (use the existing env_file logic or
replace $INSTALL_DIR with $CONFIG_DIR in the message) so that cmd_deploy, the
require_install check, and the deployment validation consistently report the
same canonical config path; ensure you still check the same file existence and
keep the surrounding logic in cmd_deploy (enabled_providers parsing and dispatch
to dist/providers/discord/deploy.js) unchanged.

145-156: 💤 Low value

config_complete implementation is correct.

The sed pattern correctly handles inline comments, empty values, and template placeholders. The head -n1 guard for duplicate keys is a nice touch.

Minor observation: this function is byte-for-byte identical to config_complete in install.sh. Since both scripts are standalone executables that cannot reliably source each other at runtime, the duplication is acceptable — but worth a comment noting that any future change to the validation logic (e.g., adding a new required key) must be applied to both files.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bin/maestro-relay-ctl.sh` around lines 145 - 156, The function
config_complete is duplicated in another script (install.sh); add a short inline
comment above the config_complete function noting that this duplication is
intentional because the scripts are standalone and reminding maintainers to
apply any future validation changes (e.g., adding required keys) to both copies;
reference the function name config_complete and the other script install.sh in
the comment so reviewers know where the twin implementation lives.
install.sh (1)

146-184: 💤 Low value

LGTM — correct fix for the process-wide RETURN-trap bug.

The explicit rm -rf "$staging" at line 183 cleanly replaces the misfiring trap. One minor tradeoff worth acknowledging: if an earlier statement in install_release (e.g., the tar at line 150 or the cp at line 163) fails under set -Eeuo pipefail, control jumps to the ERR trap in main (rollback_install) without passing through line 183, leaving the mktemp -d directory behind. In practice this is harmless — /tmp is volatile — but if you want airtight cleanup a local EXIT/ERR handler scoped to the function body is the idiomatic approach:

 install_release() {
   local tag="$1" tarball="$2"
   local staging
   staging="$(mktemp -d)"
+  trap 'rm -rf "$staging"; trap - RETURN' RETURN
   tar -xzf "$tarball" -C "$staging"
   ...
-  rm -rf "$staging"
   ok "Extracted release to $INSTALL_DIR"
 }

Note: Bash's RETURN trap fires once per function return (including error exits), so clearing it (trap - RETURN) immediately inside the trap body prevents the re-firing issue that motivated this PR in the first place. This is entirely optional — the explicit rm is already a net improvement.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@install.sh` around lines 146 - 184, install_release currently creates a
staging dir with staging="$(mktemp -d)" but may leak it if the function exits
early under set -Eeuo pipefail; add a local EXIT (or ERR) trap at the top of
install_release that removes "$staging" (e.g., trap 'rm -rf "$staging"' EXIT)
and clears itself before normal return to avoid RETURN-trap re-firing; ensure
the trap references the staging variable and that the final explicit rm -rf
"$staging" still runs or is made idempotent so cleanup always occurs even on
error.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@bin/maestro-relay-ctl.sh`:
- Around line 158-174: The error message in cmd_deploy uses $INSTALL_DIR/.env
which may be a symlink and differs from install.sh's messaging; update the die
call in function cmd_deploy to reference the canonical $CONFIG_DIR/.env instead
(use the existing env_file logic or replace $INSTALL_DIR with $CONFIG_DIR in the
message) so that cmd_deploy, the require_install check, and the deployment
validation consistently report the same canonical config path; ensure you still
check the same file existence and keep the surrounding logic in cmd_deploy
(enabled_providers parsing and dispatch to dist/providers/discord/deploy.js)
unchanged.
- Around line 145-156: The function config_complete is duplicated in another
script (install.sh); add a short inline comment above the config_complete
function noting that this duplication is intentional because the scripts are
standalone and reminding maintainers to apply any future validation changes
(e.g., adding required keys) to both copies; reference the function name
config_complete and the other script install.sh in the comment so reviewers know
where the twin implementation lives.

In `@install.sh`:
- Around line 146-184: install_release currently creates a staging dir with
staging="$(mktemp -d)" but may leak it if the function exits early under set
-Eeuo pipefail; add a local EXIT (or ERR) trap at the top of install_release
that removes "$staging" (e.g., trap 'rm -rf "$staging"' EXIT) and clears itself
before normal return to avoid RETURN-trap re-firing; ensure the trap references
the staging variable and that the final explicit rm -rf "$staging" still runs or
is made idempotent so cleanup always occurs even on error.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 53dcedd8-15a8-46bd-9c2a-9e4a119a9b29

📥 Commits

Reviewing files that changed from the base of the PR and between ddc6c54 and b64e709.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • bin/maestro-relay-ctl.sh
  • install.sh
  • package.json

@chr1syy chr1syy merged commit 8f5331e into main May 7, 2026
3 checks passed
@chr1syy chr1syy deleted the fix/installer-followups branch May 7, 2026 05:39
chr1syy added a commit that referenced this pull request May 10, 2026
Brings in installer bugfixes (PRs #33-#35), .maestro/ untrack (#36),
and the docs split (#37) that landed on main after rc was branched.

Conflict resolutions:
- Kept rc's queue error-hiding (PR #39) and per-message logger.error.
- Kept rc's WAL-checkpoint shutdown alongside main's split DB import.
- Combined main's docs split with rc's Slack provider additions in
  README.md, AGENTS.md, .env.example, install.sh, providers.ts,
  migrations.ts.
- Extended config_complete in maestro-relay-ctl.sh to cover the
  Slack key set when ENABLED_PROVIDERS=slack.
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.

1 participant