chore: add deployment test (#874)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Added an npm build script to simplify project compilation.

* **Chores**
  * Simplified CI dependency installation to use standard npm install.
* Added a new deployment test job that runs multi-service integration
checks, build, health checks, and graceful shutdown.
* Introduced an environment-variable gate to allow opting into local
filesystem behavior in production.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
MK (fengmk2)
2025-10-29 23:35:06 +08:00
committed by GitHub
parent 6c29f084b2
commit 0d32146562
3 changed files with 79 additions and 4 deletions

View File

@@ -28,7 +28,7 @@ jobs:
node-version: 22
- name: Install Dependencies
run: npm i -g npminstall && npminstall
run: npm i
- name: Lint
run: npm run lint
@@ -38,6 +38,79 @@ jobs:
- name: Build
run: npm run tsc && npm run tsc:prod
test-deployment:
runs-on: ubuntu-latest
concurrency:
group: test-deployment-${{ github.workflow }}-#${{ github.event.pull_request.number || github.head_ref || github.ref }}
cancel-in-progress: true
services:
mysql:
image: mysql:5.7
env:
MYSQL_ALLOW_EMPTY_PASSWORD: true
MYSQL_DATABASE: cnpmcore
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=5
redis:
# https://docs.github.com/en/actions/using-containerized-services/about-service-containers#example-mapping-redis-ports
image: redis
ports:
# Opens tcp port 6379 on the host and service container
- 6379:6379
steps:
- name: Checkout Git Source
uses: actions/checkout@v5
- name: Use Node.js
uses: actions/setup-node@v6
with:
node-version: 22
- name: Install Dependencies
run: npm i
- name: Test Deployment
run: |
npm run build
echo "Preparing database..."
CNPMCORE_DATABASE_NAME=cnpmcore bash ./prepare-database-mysql.sh
echo "Starting cnpmcore..."
CNPMCORE_FORCE_LOCAL_FS=true npm run start:foreground &
sleep 5
echo "Checking cnpmcore is ready..."
set -Eeuo pipefail
URL="http://127.0.0.1:7001"
PATTERN="instance_start_time"
TIMEOUT=60
TMP="$(mktemp)"
echo "🔎 Health check $URL, expect 200 & body contains: $PATTERN"
deadline=$((SECONDS + TIMEOUT))
last_status=""
while (( SECONDS < deadline )); do
last_status="$(curl -sS -o "$TMP" -w '%{http_code}' "$URL" || true)"
echo "last_status=$last_status"
echo "body=$(cat $TMP)"
if [[ "$last_status" == "200" ]] && grep -q "$PATTERN" "$TMP"; then
echo "✅ OK"
rm -f "$TMP"
npx eggctl stop
exit 0
fi
sleep 1
done
echo "::error::❌ Health check failed: status=$last_status"
echo "---- Response body (last try) ----"
cat "$TMP" || true
rm -f "$TMP"
exit 1
test-postgresql-fs-nfs:
strategy:
@@ -91,7 +164,7 @@ jobs:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: npm i -g npminstall && npminstall
run: npm i
# https://github.com/elastic/elastic-github-actions/blob/master/elasticsearch/README.md
- name: Configure sysctl limits
@@ -178,7 +251,7 @@ jobs:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: npm i -g npminstall && npminstall
run: npm i
- name: Continuous Integration
run: npm run ci

View File

@@ -43,7 +43,8 @@ export class NFSClientAdapter implements NFSClient {
if (this.config.nfs.client) {
this._client = this.config.nfs.client;
} else {
if (this.config.env === 'prod') {
// Please do not set the CNPMCORE_FORCE_LOCAL_FS environment variable unless you know what you are doing.
if (this.config.env === 'prod' && process.env.CNPMCORE_FORCE_LOCAL_FS !== 'true') {
throw new Error(
"[NFSAdapter] Can't use local fs NFS on production env"
);

View File

@@ -58,6 +58,7 @@
"ci": "npm run cov",
"ci:postgresql": "npm run cov:postgresql",
"clean": "tsc -b --clean && rm -rf dist *.tsbuildinfo",
"build": "npm run tsc",
"tsc": "npm run clean && tsc -p ./tsconfig.json",
"tsc:prod": "npm run clean && tsc -p ./tsconfig.prod.json",
"prepublishOnly": "npm run tsc:prod",