Skip to content

Commit 398e951

Browse files
authored
Merge pull request #167 from Neziahtech/issue-78-server-ci
Add CI pipeline with lint, test, and build gates
2 parents 6651c66 + 2279100 commit 398e951

5 files changed

Lines changed: 120 additions & 1 deletion

File tree

.github/workflows/server-ci.yml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
name: Server CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
concurrency:
10+
group: server-ci-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
server:
15+
name: Server quality gates
16+
runs-on: ubuntu-latest
17+
defaults:
18+
run:
19+
working-directory: server
20+
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v4
24+
25+
- name: Set up pnpm
26+
uses: pnpm/action-setup@v4
27+
with:
28+
version: 10.28.0
29+
30+
- name: Set up Node.js
31+
uses: actions/setup-node@v4
32+
with:
33+
node-version: 20
34+
cache: pnpm
35+
cache-dependency-path: pnpm-lock.yaml
36+
37+
- name: Cache server dependencies and TypeScript build cache
38+
uses: actions/cache@v4
39+
with:
40+
path: |
41+
server/node_modules
42+
server/tsconfig.tsbuildinfo
43+
key: server-ci-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'server/tsconfig.json') }}
44+
restore-keys: |
45+
server-ci-${{ runner.os }}-
46+
47+
- name: Install dependencies
48+
working-directory: .
49+
run: pnpm install --frozen-lockfile
50+
51+
- name: Prepare test environment
52+
run: cp .env.test .env
53+
54+
- name: Lint
55+
run: pnpm lint
56+
57+
- name: Type-check
58+
run: pnpm tsc --noEmit
59+
60+
- name: Test
61+
id: tests
62+
continue-on-error: true
63+
env:
64+
NODE_ENV: test
65+
DOTENV_CONFIG_PATH: .env.test
66+
NODE_OPTIONS: --require=dotenv/config
67+
run: pnpm test -- --run --json --outputFile=test-results.json
68+
69+
- name: Convert Jest results to JUnit XML
70+
if: always()
71+
run: |
72+
node - <<'NODE'
73+
const fs = require('fs');
74+
const results = JSON.parse(fs.readFileSync('test-results.json', 'utf8'));
75+
const escape = (value) => String(value)
76+
.replaceAll('&', '&amp;')
77+
.replaceAll('<', '&lt;')
78+
.replaceAll('>', '&gt;')
79+
.replaceAll('"', '&quot;');
80+
const cases = (results.testResults || []).map((test) => {
81+
const duration = test.endTime && test.startTime ? test.endTime - test.startTime : 0;
82+
const failure = test.status === 'failed'
83+
? `<failure message="${escape((test.message || '').split('\n')[0])}">${escape(test.message || '')}</failure>`
84+
: '';
85+
return `<testcase classname="${escape(test.testFilePath || 'server')}" name="${escape(test.testFilePath || 'test')}" time="${(duration / 1000).toFixed(3)}">${failure}</testcase>`;
86+
}).join('');
87+
const failures = results.numFailedTestSuites || 0;
88+
const tests = results.numTotalTestSuites || cases.length;
89+
fs.writeFileSync('test-results.xml', `<testsuites tests="${tests}" failures="${failures}">${cases}</testsuites>`);
90+
NODE
91+
92+
- name: Upload JUnit test results
93+
if: always()
94+
uses: actions/upload-artifact@v4
95+
with:
96+
name: server-junit-results
97+
path: server/test-results.xml
98+
if-no-files-found: error
99+
100+
- name: Build
101+
run: pnpm build
102+
103+
- name: Fail when tests fail
104+
if: steps.tests.outcome == 'failure'
105+
run: exit 1

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ web_modules/
6969
.env
7070
.env.*
7171
!.env.example
72+
!server/.env.test
7273

7374
# parcel-bundler cache (https://parceljs.org/)
7475
.cache

server/.env.test

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
NODE_ENV=test
2+
PORT=3999
3+
DATABASE_URL=postgresql://test:test@localhost:5432/airflex_test
4+
JWT_SECRET=test-only-jwt-secret
5+
ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000
6+
ESCROW_CONTRACT_ADDRESS=CCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
7+
STELLAR_SERVER_SECRET=SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
8+
PLATFORM_TREASURY_USER_ID=00000000-0000-0000-0000-000000000001
9+
PLATFORM_FEE_PERCENT=1.5

server/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
"scripts": {
77
"dev": "ts-node-dev --respawn --transpile-only src/index.ts",
88
"build": "tsc",
9+
"lint": "tsc --noEmit",
10+
"tsc": "tsc",
911
"start": "node dist/index.js",
1012
"test": "jest --runInBand --forceExit",
1113
"test:watch": "jest --watch"

server/tsconfig.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
"resolveJsonModule": true,
1313
"declaration": true,
1414
"declarationMap": true,
15-
"sourceMap": true
15+
"sourceMap": true,
16+
"incremental": true,
17+
"tsBuildInfoFile": "tsconfig.tsbuildinfo"
1618
},
1719
"include": ["src/**/*"],
1820
"exclude": ["node_modules", "dist"]

0 commit comments

Comments
 (0)