Add CI auto-deploy with selective app restarts - #73
Conversation
Deploy on merge to main via SSH (matching API/Discord), always rebuild tools, and only rebuild/restart hermes, atlas, or zeus when changed files touch their Go dependency closure. Co-authored-by: Cursor <cursoragent@cursor.com>
| branch_ref="${{ github.ref }}" | ||
| branch_name="${branch_ref#refs/heads/}" | ||
| ssh -o ProxyCommand="cloudflared access ssh --hostname %h" root@ssh.raidhub.io \ | ||
| "cd /RaidHub/Services && DEPLOY_FORCE_APPS=1 bash ./.github/scripts/deploy-services.sh \"$branch_name\"" |
There was a problem hiding this comment.
Bug: The branch_name variable, derived from github.ref, is used unsafely in a run block, creating a command injection vulnerability if the branch name contains shell metacharacters.
Severity: HIGH
Suggested Fix
Pass the branch name to the script via an environment variable instead of direct string interpolation. Set branch_name in the env context of the step, and then reference it as $BRANCH_NAME within the script. This prevents the shell from interpreting metacharacters in the branch name during expansion. For example: env: { BRANCH_NAME: ${{ github.ref_name }} } and then use $BRANCH_NAME in the run script. Using github.ref_name is also safer as it only contains the branch/tag name.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: .github/workflows/deploy-manual.yml#L51-L54
Potential issue: The `branch_name` variable is derived from `${{ github.ref }}` and is
directly substituted into a bash `run` block. If a branch name contains shell
metacharacters like `$()` or backticks, it can lead to arbitrary command execution on
the GitHub Actions runner. The `run` block on line 54 executes an SSH command where
`$branch_name` is expanded by the local shell. A malicious branch name like
`feature/fix-$(evil_command)` would cause `evil_command` to run on the runner. While an
admin check mitigates direct exploitation, an admin could unknowingly trigger the
workflow on a malicious branch created by another user with push access.
Did we get this right? 👍 / 👎 to inform future reviews.
Co-authored-by: Cursor <cursoragent@cursor.com>
| go build -o /dev/null ./apps/atlas/ | ||
| go build -o /dev/null ./apps/hermes/ | ||
| go build -o /dev/null ./apps/zeus/ | ||
|
|
There was a problem hiding this comment.
Bug: The deploy workflow will fail because actions/checkout creates a shallow clone, but a later step requires more git history to run git diff.
Severity: CRITICAL
Suggested Fix
In the deploy.yml workflow, configure the actions/checkout@v4 step with fetch-depth: 0 to ensure the full git history is available. This will allow the git diff command to access the previous commit and execute successfully.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: .github/workflows/deploy.yml#L25-L28
Potential issue: The `deploy.yml` workflow uses `actions/checkout@v4` without specifying
`fetch-depth`, which defaults to a shallow clone of depth 1. A subsequent step in the
workflow attempts to run `git diff` using the previous commit SHA
(`github.event.before`). Because this previous commit is not available in the shallow
clone, the `git diff` command fails with a `fatal: bad object` error. This failure halts
the entire workflow, preventing any deployments from running on pushes to the `main`
branch.
Summary
mainvia SSH through Cloudflare Access (same pattern as API and Discord).determine-deploy-targets.shusesgit diff+go list -depsto decide which long-running apps need a rebuild — tools always, hermes/atlas/zeus only when their dependency closure changed.deploy-services.shon the VPS pulls, builds selectively, and restarts only the affected systemd units.deploy-manual.yml) forces all apps for branch deploys.Deploy logic
tools/**apps/hermes/**or importedlib/**go.mod/go.sum/Makefile.github/**,docs/**,infrastructure/**Secrets required
These should already exist from API/Discord deploys — confirm they're available on the Services repo (or org-level):
VPS_SSH_PRIVATE_KEYVPS_SSH_KNOWN_HOSTSCF_GHA_CLIENT_IDCF_GHA_CLIENT_SECRETTest plan
Deploy to Prodworkflow succeeds on mergegit log -1matchesmainapps=(none), no hermes/atlas/zeus restartlib/change affecting hermes: workflow logs showhermesrebuilt + restartedstrings bin/hermes | grep <version-tag>or equivalent smoke checkMade with Cursor