Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughTwo new GitHub Actions workflows were added to deploy the Kaapi frontend to EC2: staging (triggers on pushes to Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor GitHubActions as "GitHub Actions"
participant Runner as "Actions Runner\n(ubuntu-latest)"
participant EC2 as "EC2 Host"
participant PM2 as "PM2\n(process manager)"
GitHubActions->>Runner: trigger on push (feat/frontend-cicd-deployment / release)
Runner->>EC2: SSH using secrets (host, user, key)
EC2->>EC2: cd $BUILD_DIRECTORY\ngit pull origin (branch)\nset -e
EC2->>PM2: pm2 stop $PM2_APP_NAME || true
EC2->>EC2: npm ci\nnpm run build
EC2->>PM2: pm2 start $PM2_APP_NAME
PM2-->>Runner: process started / restarted
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
.github/workflows/cd-production.yml (1)
13-45: Extract shared staging/production logic into a reusable workflow.This deployment block is largely duplicated across both workflow files, which increases drift risk and patch latency for fixes.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/cd-production.yml around lines 13 - 45, Deployment steps using the appleboy/ssh-action@v1.0.3 and the SCRIPT_NAME/pm2/npm sequence are duplicated; extract this shared SSH deploy logic (the step named "Deploy via SSH" and its script that uses SCRIPT_NAME, pm2 stop/start, npm ci, npm run build, git pull) into a reusable workflow (e.g., a workflow called "deploy-ssh" that exposes inputs like host, user, key, project_path and SCRIPT_NAME and uses workflow_call), then replace the duplicated blocks in both staging and production workflows with a single call to that reusable workflow (use the workflow_call inputs to pass secrets/values). Ensure the reusable workflow preserves the set -e script behavior and existing environment variable names so pm2/npm/git commands continue to work 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 @.github/workflows/cd-production.yml:
- Around line 41-42: Add a pre-build guard that fails the job if the required
build-time env var NEXT_PUBLIC_BACKEND_URL is missing so the pipeline cannot run
npm run build (next build) with an invalid config; implement this by inserting a
step before the "===== Build Application =====" / npm run build step that checks
for NEXT_PUBLIC_BACKEND_URL (exit non‑zero and echo a clear error if unset or
empty) so the workflow fails fast when the variable is absent.
- Around line 32-33: The current deployment uses a non-deterministic "git pull
origin release" which can create merge commits or leave a dirty working tree;
replace that step with an explicit fetch and hard-reset sequence: run "git fetch
--prune origin release", then "git reset --hard origin/release" and optionally
"git clean -fdx" to remove untracked files, ensuring the script enforces an
exact branch state before continuing (replace the "git pull origin release"
invocation).
In @.github/workflows/cd-staging.yml:
- Around line 9-24: The deploy job is not scoped to staging and uses generic
secret names; update the job definition for the deploy job to include an
environment: staging and switch all generic secrets and env refs to
staging-specific secrets (e.g., replace secrets.EC2_HOST, secrets.EC2_USER,
secrets.EC2_SSH_KEY, and secrets.PM2_APP_NAME with secrets.STAGING_EC2_HOST,
secrets.STAGING_EC2_USER, secrets.STAGING_EC2_SSH_KEY,
secrets.STAGING_PM2_APP_NAME) so the appleboy/ssh-action invocation and
SCRIPT_NAME env use staging-only values and cannot target production.
- Around line 35-45: The script currently stops the PM2 process (pm2 stop
"$SCRIPT_NAME") before running npm ci and npm run build, which can leave the
service down if build fails; move the pm2 stop/restart sequence so that npm ci
and npm run build run first and only after they succeed perform the process
restart, and replace the stop + start sequence with pm2 reload "$SCRIPT_NAME"
(or pm2 reload ecosystem file) to achieve a zero-downtime restart; ensure the
commands referencing SCRIPT_NAME and the pm2 invocation are relocated after the
build steps and that failures in npm ci/npm run build do not stop a currently
running instance.
- Around line 18-25: Add SSH host key fingerprint verification to the
appleboy/ssh-action@v1.0.3 invocation by supplying the fingerprint parameter
(use a repository secret like SSH_HOST_FINGERPRINT) alongside the existing with:
host/username/key entries; update the workflow to read the fingerprint from
secrets and pass it into the action so the action performs host key pinning and
prevents MITM attacks during deployments.
---
Nitpick comments:
In @.github/workflows/cd-production.yml:
- Around line 13-45: Deployment steps using the appleboy/ssh-action@v1.0.3 and
the SCRIPT_NAME/pm2/npm sequence are duplicated; extract this shared SSH deploy
logic (the step named "Deploy via SSH" and its script that uses SCRIPT_NAME, pm2
stop/start, npm ci, npm run build, git pull) into a reusable workflow (e.g., a
workflow called "deploy-ssh" that exposes inputs like host, user, key,
project_path and SCRIPT_NAME and uses workflow_call), then replace the
duplicated blocks in both staging and production workflows with a single call to
that reusable workflow (use the workflow_call inputs to pass secrets/values).
Ensure the reusable workflow preserves the set -e script behavior and existing
environment variable names so pm2/npm/git commands continue to work unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 94bb20bf-62eb-4db7-871b-95ae6154fa90
📒 Files selected for processing (2)
.github/workflows/cd-production.yml.github/workflows/cd-staging.yml
.github/workflows/cd-production.yml
Outdated
| echo "===== Fetch Latest Code =====" | ||
| git pull origin release |
There was a problem hiding this comment.
Use deterministic branch sync instead of git pull.
Line 33 can create merge commits or deploy a dirty local state. Deploy scripts should enforce exact branch state.
Deterministic sync example
echo "===== Fetch Latest Code ====="
- git pull origin release
+ git fetch --prune origin
+ git checkout -B release origin/release
+ git reset --hard origin/release📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| echo "===== Fetch Latest Code =====" | |
| git pull origin release | |
| echo "===== Fetch Latest Code =====" | |
| git fetch --prune origin | |
| git checkout -B release origin/release | |
| git reset --hard origin/release |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/cd-production.yml around lines 32 - 33, The current
deployment uses a non-deterministic "git pull origin release" which can create
merge commits or leave a dirty working tree; replace that step with an explicit
fetch and hard-reset sequence: run "git fetch --prune origin release", then "git
reset --hard origin/release" and optionally "git clean -fdx" to remove untracked
files, ensuring the script enforces an exact branch state before continuing
(replace the "git pull origin release" invocation).
.github/workflows/cd-production.yml
Outdated
| echo "===== Build Application =====" | ||
| npm run build |
There was a problem hiding this comment.
Fail fast when required build-time env vars are missing.
Given next build (from package.json scripts) won’t enforce NEXT_PUBLIC_BACKEND_URL, this pipeline can successfully deploy a broken frontend config.
Guard before build
echo "===== Build Application ====="
+ : "${NEXT_PUBLIC_BACKEND_URL:?NEXT_PUBLIC_BACKEND_URL is required for production build}"
npm run build📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| echo "===== Build Application =====" | |
| npm run build | |
| echo "===== Build Application =====" | |
| : "${NEXT_PUBLIC_BACKEND_URL:?NEXT_PUBLIC_BACKEND_URL is required for production build}" | |
| npm run build |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/cd-production.yml around lines 41 - 42, Add a pre-build
guard that fails the job if the required build-time env var
NEXT_PUBLIC_BACKEND_URL is missing so the pipeline cannot run npm run build
(next build) with an invalid config; implement this by inserting a step before
the "===== Build Application =====" / npm run build step that checks for
NEXT_PUBLIC_BACKEND_URL (exit non‑zero and echo a clear error if unset or empty)
so the workflow fails fast when the variable is absent.
| uses: appleboy/ssh-action@v1.0.3 | ||
| env: | ||
| SCRIPT_NAME: ${{ secrets.PM2_APP_NAME }} | ||
| with: | ||
| host: ${{ secrets.EC2_HOST }} | ||
| username: ${{ secrets.EC2_USER }} | ||
| key: ${{ secrets.EC2_SSH_KEY }} | ||
| script_stop: true |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
appleboy/ssh-action fingerprint parameter support documentation
💡 Result:
appleboy/ssh-action does support a fingerprint input.
- Where it’s documented (official):
- In
action.yml, the input is defined as:fingerprint: “SHA256 fingerprint of the host public key for verification to prevent MITM attacks.” (and it’s passed through asINPUT_FINGERPRINT). [1]- There is also
proxy_fingerprintfor jump/proxy host verification. [1]
- In the README under “Host Fingerprint Verification”, it explains why to verify, shows how to obtain a host key fingerprint, and shows usage:
with: fingerprint: ${{ secrets.FINGERPRINT }}. [2]
- In
Sources
- [1]
appleboy/ssh-action—action.yml(inputs, includingfingerprint/proxy_fingerprint) (github.com) - [2]
appleboy/ssh-action— README “Host Fingerprint Verification” section (github.com)
Citations:
- 1: https://github.com/appleboy/ssh-action/blob/master/action.yml
- 2: https://github.com/appleboy/ssh-action
🏁 Script executed:
#!/bin/bash
# Search for any existing usage of fingerprint in workflows within the repo
rg "fingerprint" .github/workflows/ --type yamlRepository: ProjectTech4DevAI/kaapi-frontend
Length of output: 58
🌐 Web query:
appleboy/ssh-action@v1.0.3 github action supported parameters inputs
💡 Result:
appleboy/ssh-action@v1.0.3 supports these with: inputs (GitHub Actions parameters): [1]
hostport(default:22)passphraseusernamepasswordsyncuse_insecure_cipherciphertimeout(default:30s)command_timeout(default:10m)keykey_pathfingerprintproxy_hostproxy_port(default:22)proxy_usernameproxy_passwordproxy_passphraseproxy_timeout(default:30s)proxy_keyproxy_key_pathproxy_fingerprintproxy_cipherproxy_use_insecure_cipherscriptscript_stopenvsenvs_formatdebugallenvsrequest_pty
Source: action.yml for tag v1.0.3. [1]
References:
[1] (github.com)
Citations:
Add SSH host key fingerprint verification.
The SSH action is configured with key auth, but no host fingerprint pinning. That weakens MITM protection during deployment. The appleboy/ssh-action@v1.0.3 action supports the fingerprint parameter for this purpose.
Suggested hardening
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
+ fingerprint: ${{ secrets.EC2_HOST_FINGERPRINT }}
script_stop: true📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| uses: appleboy/ssh-action@v1.0.3 | |
| env: | |
| SCRIPT_NAME: ${{ secrets.PM2_APP_NAME }} | |
| with: | |
| host: ${{ secrets.EC2_HOST }} | |
| username: ${{ secrets.EC2_USER }} | |
| key: ${{ secrets.EC2_SSH_KEY }} | |
| script_stop: true | |
| uses: appleboy/ssh-action@v1.0.3 | |
| env: | |
| SCRIPT_NAME: ${{ secrets.PM2_APP_NAME }} | |
| with: | |
| host: ${{ secrets.EC2_HOST }} | |
| username: ${{ secrets.EC2_USER }} | |
| key: ${{ secrets.EC2_SSH_KEY }} | |
| fingerprint: ${{ secrets.EC2_HOST_FINGERPRINT }} | |
| script_stop: true |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/cd-staging.yml around lines 18 - 25, Add SSH host key
fingerprint verification to the appleboy/ssh-action@v1.0.3 invocation by
supplying the fingerprint parameter (use a repository secret like
SSH_HOST_FINGERPRINT) alongside the existing with: host/username/key entries;
update the workflow to read the fingerprint from secrets and pass it into the
action so the action performs host key pinning and prevents MITM attacks during
deployments.
.github/workflows/cd-staging.yml
Outdated
| echo "===== Stop Running Application =====" | ||
| pm2 stop "$SCRIPT_NAME" || true | ||
|
|
||
| echo "===== Install Dependencies =====" | ||
| npm ci | ||
|
|
||
| echo "===== Build Application =====" | ||
| npm run build | ||
|
|
||
| echo "===== Start Application =====" | ||
| pm2 start "$SCRIPT_NAME" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n .github/workflows/cd-staging.ymlRepository: ProjectTech4DevAI/kaapi-frontend
Length of output: 1503
Move process stop/reload after a successful build to prevent service downtime on build failures.
The deployment stops the application before running npm ci and npm run build. If either step fails, the set -e on line 27 causes the script to exit before reaching the pm2 start command, leaving the service down.
By moving the stop/reload sequence after the build succeeds, the application continues serving traffic during the build phase. If the build fails, the old version stays running instead of going offline.
Consider using pm2 reload instead of pm2 stop followed by pm2 start for cleaner zero-downtime restarts.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/cd-staging.yml around lines 35 - 45, The script currently
stops the PM2 process (pm2 stop "$SCRIPT_NAME") before running npm ci and npm
run build, which can leave the service down if build fails; move the pm2
stop/restart sequence so that npm ci and npm run build run first and only after
they succeed perform the process restart, and replace the stop + start sequence
with pm2 reload "$SCRIPT_NAME" (or pm2 reload ecosystem file) to achieve a
zero-downtime restart; ensure the commands referencing SCRIPT_NAME and the pm2
invocation are relocated after the build steps and that failures in npm ci/npm
run build do not stop a currently running instance.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
.github/workflows/cd-production.yml (2)
32-33:⚠️ Potential issue | 🟠 MajorReplace
git pullwith deterministic branch sync.Line 33 can deploy a merged/dirty state. Use fetch + hard reset to
origin/releaseinstead.Suggested fix
echo "=== Fetch Latest Code ===" - git pull origin release + git fetch --prune origin release + git reset --hard origin/release + git clean -fdx🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/cd-production.yml around lines 32 - 33, Replace the non-deterministic git pull in the deployment step with an explicit fetch and hard reset to the remote branch: instead of running "git pull origin release" update the workflow to run "git fetch origin release" followed by "git reset --hard origin/release" (optionally add a shallow fetch depth) so the working tree is deterministically synced to origin/release before building or deploying.
41-42:⚠️ Potential issue | 🟠 MajorFail fast when required build-time env vars are missing.
next buildcan succeed with missing runtime-critical config. Add an explicit guard before Line 42.Suggested fix
echo "=== Build Application ===" + : "${NEXT_PUBLIC_BACKEND_URL:?NEXT_PUBLIC_BACKEND_URL is required for production build}" npm run build🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/cd-production.yml around lines 41 - 42, Before running the build step (the npm run build / next build invocation), add a shell guard that checks the required build-time environment variables and exits non-zero if any are missing; implement this by enumerating the required names (e.g., NEXT_PUBLIC_API_URL, NEXTAUTH_URL, etc.) in a list, iterating over them in a small bash snippet that tests each with [ -z "${VAR}" ] and prints which are missing, then exit 1 if any were empty—place this check immediately before the npm run build line so the workflow fails fast on missing build-time env vars.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/cd-production.yml:
- Around line 22-25: Add host key pinning for the appleboy/ssh-action@v1.0.3 SSH
step by providing the `fingerprint` input so the EC2 host identity is verified;
update the SSH action block that currently contains `host`, `username`, `key`,
and `script_stop` to include `fingerprint: "<expected_host_key_fingerprint>"`
(replace with the actual EC2 SSH host key fingerprint) to enforce host key
verification and prevent MITM.
- Around line 35-45: Replace the unreliable pm2 start call with a
restart-or-start flow: attempt pm2 restart "$SCRIPT_NAME" first and if that
fails fall back to starting npm as a named process (e.g., pm2 start npm --name
"$SCRIPT_NAME" -- start) so PM2 treats the process as the previously registered
app; update the block that currently calls pm2 stop "$SCRIPT_NAME" and pm2 start
"$SCRIPT_NAME" to use pm2 restart "$SCRIPT_NAME" || pm2 start npm --name
"$SCRIPT_NAME" -- start (keeping npm ci and npm run build intact).
---
Duplicate comments:
In @.github/workflows/cd-production.yml:
- Around line 32-33: Replace the non-deterministic git pull in the deployment
step with an explicit fetch and hard reset to the remote branch: instead of
running "git pull origin release" update the workflow to run "git fetch origin
release" followed by "git reset --hard origin/release" (optionally add a shallow
fetch depth) so the working tree is deterministically synced to origin/release
before building or deploying.
- Around line 41-42: Before running the build step (the npm run build / next
build invocation), add a shell guard that checks the required build-time
environment variables and exits non-zero if any are missing; implement this by
enumerating the required names (e.g., NEXT_PUBLIC_API_URL, NEXTAUTH_URL, etc.)
in a list, iterating over them in a small bash snippet that tests each with [ -z
"${VAR}" ] and prints which are missing, then exit 1 if any were empty—place
this check immediately before the npm run build line so the workflow fails fast
on missing build-time env vars.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7b6b14c7-3d4b-475f-94d7-3ff376c20f36
📒 Files selected for processing (2)
.github/workflows/cd-production.yml.github/workflows/cd-staging.yml
🚧 Files skipped from review as they are similar to previous changes (1)
- .github/workflows/cd-staging.yml
.github/workflows/cd-production.yml
Outdated
| echo "=== Stop Running Application ===" | ||
| pm2 stop "$SCRIPT_NAME" || true | ||
|
|
||
| echo "=== Install Dependencies ===" | ||
| npm ci | ||
|
|
||
| echo "=== Build Application ===" | ||
| npm run build | ||
|
|
||
| echo "=== Start Application ===" | ||
| pm2 start "$SCRIPT_NAME" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Check for PM2 ecosystem files (if none, app-name-only start is suspicious):"
fd -HI 'ecosystem*.js'
fd -HI 'ecosystem*.cjs'
fd -HI 'ecosystem*.json'
fd -HI 'ecosystem*.yml'
fd -HI 'ecosystem*.yaml'
echo "Inspect package scripts:"
rg -n '"scripts"\s*:\s*\{' -A12 package.json
echo "Inspect PM2 usage in workflows:"
rg -n 'PM2_APP_NAME|pm2 (start|restart|stop|describe)' -C2 .github/workflowsRepository: ProjectTech4DevAI/kaapi-frontend
Length of output: 2308
🏁 Script executed:
#!/bin/bash
# Check if there are any other deployment scripts or PM2 config references
echo "=== Search for PM2 config patterns ==="
rg -i 'pm2.*config|ecosystem' .github/workflows
echo "=== Check full context of pm2 start usage ==="
rg -B5 -A5 'pm2 start.*SCRIPT_NAME' .github/workflows
echo "=== Check if there are any error logs or related issues in repo ==="
find . -name "*.md" -type f | head -20 | xargs grep -l 'pm2\|deployment' 2>/dev/null || trueRepository: ProjectTech4DevAI/kaapi-frontend
Length of output: 967
🌐 Web query:
PM2 start command behavior: when given an app name vs script path file extension
💡 Result:
What pm2 start does depends on what the argument resolves to
PM2 documents start as accepting either a file path or an existing app name / PM2 id: start [options] <file|json|stdin|app_name|pm_id…>.[2]
1) If you pass a script/path (e.g., app.js, dist/server.js)
- PM2 registers a new process in its process list and starts it in the background.[1]
- The default PM2 process name becomes the script filename without its extension (e.g.,
app.js→ nameapp) unless you override with--name/-n.[1][2]
2) If you pass an existing PM2 app name (e.g., pm2 start app)
- In the normal “routine” workflow, once a process is already in the process list, you manage it by name;
pm2 start appis used to start that process again (after a stop) using its registered entry.[1]
3) If you pass something without an extension and it’s treated as a file
- PM2 maps interpreters by extension (e.g.,
.js→node,.py→python, etc.). If there is no extension, PM2 documents that the app is started as a binary file.[1]
Ecosystem file case (config vs “just a .js script”)
- An ecosystem file is typically
ecosystem.config.js;pm2 start(with no args) will run allappsfrom that file, andpm2 start /path/to/ecosystem.config.jsloads it explicitly.[3] - You can target a single app from the ecosystem with
pm2 start --only <app_name>.[3] (This relies on app names defined inside the ecosystem file, not script extensions.)
Sources: PM2 Process Management guide[1], PM2 CLI reference[2], PM2 Ecosystem File guide[3].
Use restart-or-start PM2 flow; current start target is unreliable.
pm2 start "$SCRIPT_NAME" with a plain app name (no file extension) is unreliable. PM2 may fail to start the stopped app because it will attempt to treat the name as a file path first. After stopping, the app remains registered; use pm2 restart if it exists, otherwise start npm explicitly as a named process.
Suggested fix
- echo "=== Stop Running Application ==="
- pm2 stop "$SCRIPT_NAME" || true
@@
- echo "=== Start Application ==="
- pm2 start "$SCRIPT_NAME"
+ echo "=== Start/Restart Application ==="
+ if pm2 describe "$SCRIPT_NAME" >/dev/null 2>&1; then
+ pm2 restart "$SCRIPT_NAME" --update-env
+ else
+ pm2 start npm --name "$SCRIPT_NAME" -- start
+ fi
+ pm2 save📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| echo "=== Stop Running Application ===" | |
| pm2 stop "$SCRIPT_NAME" || true | |
| echo "=== Install Dependencies ===" | |
| npm ci | |
| echo "=== Build Application ===" | |
| npm run build | |
| echo "=== Start Application ===" | |
| pm2 start "$SCRIPT_NAME" | |
| echo "=== Install Dependencies ===" | |
| npm ci | |
| echo "=== Build Application ===" | |
| npm run build | |
| echo "=== Start/Restart Application ===" | |
| if pm2 describe "$SCRIPT_NAME" >/dev/null 2>&1; then | |
| pm2 restart "$SCRIPT_NAME" --update-env | |
| else | |
| pm2 start npm --name "$SCRIPT_NAME" -- start | |
| fi | |
| pm2 save |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/cd-production.yml around lines 35 - 45, Replace the
unreliable pm2 start call with a restart-or-start flow: attempt pm2 restart
"$SCRIPT_NAME" first and if that fails fall back to starting npm as a named
process (e.g., pm2 start npm --name "$SCRIPT_NAME" -- start) so PM2 treats the
process as the previously registered app; update the block that currently calls
pm2 stop "$SCRIPT_NAME" and pm2 start "$SCRIPT_NAME" to use pm2 restart
"$SCRIPT_NAME" || pm2 start npm --name "$SCRIPT_NAME" -- start (keeping npm ci
and npm run build intact).
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/cd-staging.yml:
- Around line 20-22: The CI sets SCRIPT_NAME but does not forward it into the
remote ssh steps; update the appleboy/ssh-action steps to pass SCRIPT_NAME via
the with.envs map so the remote shell sees the app name (use the existing
secrets.PM2_APP_NAME value). Specifically, add SCRIPT_NAME: ${{
secrets.PM2_APP_NAME }} to the with.envs of the appleboy/ssh-action invocations
(both the deploy step around the first ssh-action and the later one referenced
at lines 37–46) so commands run remotely with a populated app name.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 846964fd-bb85-4d73-95d7-089eed4fb331
📒 Files selected for processing (2)
.github/workflows/cd-production.yml.github/workflows/cd-staging.yml
🚧 Files skipped from review as they are similar to previous changes (1)
- .github/workflows/cd-production.yml
| env: | ||
| SCRIPT_NAME: ${{ secrets.PM2_APP_NAME }} | ||
| with: |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
appleboy/ssh-action v1.0.3 envs input required to pass step env variables to remote script
💡 Result:
Yes. In appleboy/ssh-action@v1.0.3, step/job env: variables exist only inside the GitHub Actions runner/container; they are not automatically available in the remote SSH session. To make them available to your remote script, you must (1) define them in env: and (2) whitelist their names via with: envs:. [1]
- name: Deploy
uses: appleboy/ssh-action@v1.0.3
env:
APP_ENV: production
API_URL: ${{ vars.API_URL }}
SECRET: ${{ secrets.SECRET }}
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
envs: APP_ENV,API_URL,SECRET
script: |
echo "APP_ENV=$APP_ENV"
./deploy.shNotes:
envsis a comma-separated allowlist of variable names to forward. [1]- If you omit
envs, your remote script won’t see those variables (common “why is$SECRETempty?” symptom). [2] allenvsonly forwards variables withGITHUB_andINPUT_prefixes, not your custom names. [1]
Sources: [1] appleboy/ssh-action README (inputs + “Pass environment variables” example), [2] appleboy/ssh-action issue discussion about env vars not being available remotely.
Pass SCRIPT_NAME into the remote shell explicitly.
Line 21 sets SCRIPT_NAME, but it is not forwarded to the remote session. In appleboy/ssh-action, custom env vars must be listed in with.envs; otherwise Lines 37 and 46 will execute with an empty app name.
Proposed fix
- name: Deploy via SSH
uses: appleboy/ssh-action@v1.0.3
env:
SCRIPT_NAME: ${{ secrets.PM2_APP_NAME }}
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
+ envs: SCRIPT_NAME
script_stop: true
script: |Also applies to: 37-46
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/cd-staging.yml around lines 20 - 22, The CI sets
SCRIPT_NAME but does not forward it into the remote ssh steps; update the
appleboy/ssh-action steps to pass SCRIPT_NAME via the with.envs map so the
remote shell sees the app name (use the existing secrets.PM2_APP_NAME value).
Specifically, add SCRIPT_NAME: ${{ secrets.PM2_APP_NAME }} to the with.envs of
the appleboy/ssh-action invocations (both the deploy step around the first
ssh-action and the later one referenced at lines 37–46) so commands run remotely
with a populated app name.
| on: | ||
| push: | ||
| branches: | ||
| - release |
There was a problem hiding this comment.
Production uses the release branch, as discussed in the GitHub issue.
For reference, you can check it here: #22 (comment)
There was a problem hiding this comment.
♻️ Duplicate comments (4)
.github/workflows/cd-production.yml (4)
37-47:⚠️ Potential issue | 🟠 MajorReplace stop/start with restart-or-start PM2 flow.
Line 47 still depends on
pm2 start "$PM2_APP_NAME"path; first deploys or registration drift can fail startup.Suggested fix
- echo "=== Stop Running Application ===" - pm2 stop "$PM2_APP_NAME" || true @@ - echo "=== Start Application ===" - pm2 start "$PM2_APP_NAME" + echo "=== Start/Restart Application ===" + if pm2 describe "$PM2_APP_NAME" >/dev/null 2>&1; then + pm2 restart "$PM2_APP_NAME" --update-env + else + pm2 start npm --name "$PM2_APP_NAME" -- start + fi + pm2 save🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/cd-production.yml around lines 37 - 47, The workflow currently uses "pm2 stop \"$PM2_APP_NAME\"" and then "pm2 start \"$PM2_APP_NAME\"" which can fail when the app isn't registered; replace that stop/start sequence with a restart-or-start flow so deployments work whether the process exists or not: use pm2 restart "$PM2_APP_NAME" (or pm2 restart "$PM2_APP_NAME" --update-env) and fall back to pm2 start "$PM2_APP_NAME" if restart fails, keeping the same PM2_APP_NAME variable and ensuring the commands run after build.
34-35:⚠️ Potential issue | 🟠 MajorUse deterministic branch sync instead of
git pull.Line 35 can merge or keep drifted state on the server; deployment should force exact
origin/release.Suggested fix
echo "=== Fetch Latest Code ===" - git pull origin release + git fetch --prune origin + git checkout -B release origin/release + git reset --hard origin/release🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/cd-production.yml around lines 34 - 35, Replace the non-deterministic "git pull origin release" with an explicit fetch and hard-reset to the remote branch so the deployment always matches origin/release; update the workflow to run a deterministic sequence such as fetching from origin (e.g., "git fetch --prune origin") and then resetting or recreating the local branch to exactly match origin/release (e.g., "git reset --hard origin/release" or "git checkout -B release origin/release") instead of using "git pull origin release".
24-27:⚠️ Potential issue | 🟠 MajorPin the EC2 SSH host key fingerprint.
Line 24-Line 27 still omit host key pinning, so SSH target identity is not enforced during deploy.
Suggested fix
with: host: ${{ secrets.EC2_HOST }} username: ${{ secrets.EC2_USER }} key: ${{ secrets.EC2_SSH_KEY }} + fingerprint: ${{ secrets.EC2_HOST_FINGERPRINT }} script_stop: true🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/cd-production.yml around lines 24 - 27, The workflow currently sets host/username/key but doesn’t pin the EC2 SSH host key; update the step that uses host/username/key (the SSH/deploy action) to enforce host key verification by adding a pinned host key/known_hosts entry (e.g., a host_key or known_hosts parameter referencing a secret containing the EC2 server's public key or fingerprint) so the action verifies the target identity instead of accepting any host; ensure the secret value is created from the EC2 instance's SSH host public key or its fingerprint and referenced in the step alongside host, username, and key.
20-23:⚠️ Potential issue | 🟠 MajorFail fast when required build-time env var is missing.
npm run buildcan succeed with an invalid runtime config if required public env vars are absent.Suggested fix
env: PM2_APP_NAME: ${{ secrets.PM2_APP_NAME }} BUILD_DIRECTORY: ${{ secrets.BUILD_DIRECTORY }} + NEXT_PUBLIC_BACKEND_URL: ${{ secrets.NEXT_PUBLIC_BACKEND_URL }} @@ echo "=== Build Application ===" + : "${NEXT_PUBLIC_BACKEND_URL:?NEXT_PUBLIC_BACKEND_URL is required for production build}" npm run buildAlso applies to: 43-44
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/cd-production.yml around lines 20 - 23, Add a pre-build check step in the GitHub Actions job that verifies required build-time env vars (PM2_APP_NAME and BUILD_DIRECTORY) are set and exits non-zero if any are missing so the workflow fails fast before running npm run build; place this check before the build step and mirror it for the other job that also uses those vars (the block referenced by the second occurrence), referencing the env keys PM2_APP_NAME and BUILD_DIRECTORY in the validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In @.github/workflows/cd-production.yml:
- Around line 37-47: The workflow currently uses "pm2 stop \"$PM2_APP_NAME\""
and then "pm2 start \"$PM2_APP_NAME\"" which can fail when the app isn't
registered; replace that stop/start sequence with a restart-or-start flow so
deployments work whether the process exists or not: use pm2 restart
"$PM2_APP_NAME" (or pm2 restart "$PM2_APP_NAME" --update-env) and fall back to
pm2 start "$PM2_APP_NAME" if restart fails, keeping the same PM2_APP_NAME
variable and ensuring the commands run after build.
- Around line 34-35: Replace the non-deterministic "git pull origin release"
with an explicit fetch and hard-reset to the remote branch so the deployment
always matches origin/release; update the workflow to run a deterministic
sequence such as fetching from origin (e.g., "git fetch --prune origin") and
then resetting or recreating the local branch to exactly match origin/release
(e.g., "git reset --hard origin/release" or "git checkout -B release
origin/release") instead of using "git pull origin release".
- Around line 24-27: The workflow currently sets host/username/key but doesn’t
pin the EC2 SSH host key; update the step that uses host/username/key (the
SSH/deploy action) to enforce host key verification by adding a pinned host
key/known_hosts entry (e.g., a host_key or known_hosts parameter referencing a
secret containing the EC2 server's public key or fingerprint) so the action
verifies the target identity instead of accepting any host; ensure the secret
value is created from the EC2 instance's SSH host public key or its fingerprint
and referenced in the step alongside host, username, and key.
- Around line 20-23: Add a pre-build check step in the GitHub Actions job that
verifies required build-time env vars (PM2_APP_NAME and BUILD_DIRECTORY) are set
and exits non-zero if any are missing so the workflow fails fast before running
npm run build; place this check before the build step and mirror it for the
other job that also uses those vars (the block referenced by the second
occurrence), referencing the env keys PM2_APP_NAME and BUILD_DIRECTORY in the
validation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 28e9a87d-11c4-41cd-ad33-00f71346b91b
📒 Files selected for processing (2)
.github/workflows/cd-production.yml.github/workflows/cd-staging.yml
🚧 Files skipped from review as they are similar to previous changes (1)
- .github/workflows/cd-staging.yml
Issue: #22
Summary:
mainandreleasebranch.Summary by CodeRabbit