Skip to content

Commit be94da3

Browse files
Add GitHub Actions workflows and testing infrastructure
- Added CI workflow with Node.js matrix testing (18.x, 20.x, 22.x) - Added release workflow for automated npm publishing - Added Dependabot configuration for dependency updates - Added Dependabot auto-merge workflow for minor/patch updates - Created Jest configuration and basic test suite - Added comprehensive npm scripts for development workflow - Updated package.json with additional dev dependencies Co-authored-by: openhands <openhands@all-hands.dev>
1 parent 8c1110a commit be94da3

File tree

7 files changed

+304
-3
lines changed

7 files changed

+304
-3
lines changed

.github/dependabot.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "npm"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
day: "monday"
8+
time: "09:00"
9+
open-pull-requests-limit: 10
10+
reviewers:
11+
- "All-Hands-AI/core-team"
12+
assignees:
13+
- "All-Hands-AI/core-team"
14+
commit-message:
15+
prefix: "deps"
16+
include: "scope"
17+
groups:
18+
typescript:
19+
patterns:
20+
- "typescript"
21+
- "@typescript-eslint/*"
22+
testing:
23+
patterns:
24+
- "jest"
25+
- "@types/jest"
26+
- "@jest/*"
27+
linting:
28+
patterns:
29+
- "eslint"
30+
- "prettier"
31+
- "@typescript-eslint/*"

.github/workflows/ci.yml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main, develop ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
matrix:
15+
node-version: [18.x, 20.x, 22.x]
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Use Node.js ${{ matrix.node-version }}
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: ${{ matrix.node-version }}
25+
cache: 'npm'
26+
27+
- name: Install dependencies
28+
run: npm ci
29+
30+
- name: Run linter
31+
run: npm run lint
32+
33+
- name: Run type check
34+
run: npm run build
35+
36+
- name: Run tests
37+
run: npm test
38+
39+
- name: Check formatting
40+
run: npm run format:check
41+
42+
build:
43+
runs-on: ubuntu-latest
44+
needs: test
45+
46+
steps:
47+
- name: Checkout code
48+
uses: actions/checkout@v4
49+
50+
- name: Use Node.js 20.x
51+
uses: actions/setup-node@v4
52+
with:
53+
node-version: 20.x
54+
cache: 'npm'
55+
56+
- name: Install dependencies
57+
run: npm ci
58+
59+
- name: Build package
60+
run: npm run build
61+
62+
- name: Upload build artifacts
63+
uses: actions/upload-artifact@v4
64+
with:
65+
name: dist
66+
path: dist/
67+
retention-days: 7
68+
69+
security:
70+
runs-on: ubuntu-latest
71+
72+
steps:
73+
- name: Checkout code
74+
uses: actions/checkout@v4
75+
76+
- name: Use Node.js 20.x
77+
uses: actions/setup-node@v4
78+
with:
79+
node-version: 20.x
80+
cache: 'npm'
81+
82+
- name: Install dependencies
83+
run: npm ci
84+
85+
- name: Run security audit
86+
run: npm audit --audit-level=moderate
87+
88+
- name: Check for vulnerabilities
89+
run: npm audit --audit-level=high --production
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Dependabot Auto-merge
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
7+
jobs:
8+
auto-merge:
9+
runs-on: ubuntu-latest
10+
if: github.actor == 'dependabot[bot]'
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v4
15+
16+
- name: Use Node.js 20.x
17+
uses: actions/setup-node@v4
18+
with:
19+
node-version: 20.x
20+
cache: 'npm'
21+
22+
- name: Install dependencies
23+
run: npm ci
24+
25+
- name: Run tests
26+
run: npm test
27+
28+
- name: Run build
29+
run: npm run build
30+
31+
- name: Auto-merge minor and patch updates
32+
uses: pascalgn/merge-action@v0.15.6
33+
with:
34+
github_token: ${{ secrets.GITHUB_TOKEN }}
35+
merge_method: squash
36+
env:
37+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
jobs:
9+
release:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v4
15+
16+
- name: Use Node.js 20.x
17+
uses: actions/setup-node@v4
18+
with:
19+
node-version: 20.x
20+
cache: 'npm'
21+
registry-url: 'https://registry.npmjs.org'
22+
23+
- name: Install dependencies
24+
run: npm ci
25+
26+
- name: Run tests
27+
run: npm test
28+
29+
- name: Build package
30+
run: npm run build
31+
32+
- name: Publish to npm
33+
run: npm publish --access public
34+
env:
35+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
36+
37+
- name: Create GitHub Release
38+
uses: actions/create-release@v1
39+
env:
40+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41+
with:
42+
tag_name: ${{ github.ref }}
43+
release_name: Release ${{ github.ref }}
44+
draft: false
45+
prerelease: false
46+
body: |
47+
## Changes
48+
49+
See [CHANGELOG.md](CHANGELOG.md) for details.
50+
51+
## Installation
52+
53+
```bash
54+
npm install @openhands/agent-server-typescript-client@${{ github.ref_name }}
55+
```

jest.config.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
testEnvironment: 'node',
4+
roots: ['<rootDir>/src'],
5+
testMatch: [
6+
'**/__tests__/**/*.ts',
7+
'**/?(*.)+(spec|test).ts'
8+
],
9+
transform: {
10+
'^.+\\.ts$': 'ts-jest'
11+
},
12+
collectCoverageFrom: [
13+
'src/**/*.ts',
14+
'!src/**/*.d.ts',
15+
'!src/__tests__/**/*'
16+
],
17+
coverageDirectory: 'coverage',
18+
coverageReporters: [
19+
'text',
20+
'lcov',
21+
'html'
22+
],
23+
moduleFileExtensions: [
24+
'ts',
25+
'js',
26+
'json'
27+
],
28+
testTimeout: 10000
29+
};

package.json

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@
66
"types": "dist/index.d.ts",
77
"scripts": {
88
"build": "tsc",
9-
"dev": "tsc --watch",
10-
"test": "jest",
119
"lint": "eslint src/**/*.ts",
12-
"format": "prettier --write src/**/*.ts"
10+
"lint:fix": "eslint src/**/*.ts --fix",
11+
"format": "prettier --write \"src/**/*.ts\" \"examples/**/*.ts\"",
12+
"format:check": "prettier --check \"src/**/*.ts\" \"examples/**/*.ts\"",
13+
"test": "jest",
14+
"test:watch": "jest --watch",
15+
"test:coverage": "jest --coverage",
16+
"dev": "tsc --watch",
17+
"clean": "rm -rf dist",
18+
"prepublishOnly": "npm run clean && npm run build && npm test"
1319
},
1420
"keywords": [
1521
"openhands",
@@ -25,6 +31,7 @@
2531
"ws": "^8.14.2"
2632
},
2733
"devDependencies": {
34+
"@types/jest": "^29.0.0",
2835
"@types/node": "^20.0.0",
2936
"@types/uuid": "^9.0.6",
3037
"@types/ws": "^8.5.8",
@@ -33,6 +40,7 @@
3340
"eslint": "^8.0.0",
3441
"jest": "^29.0.0",
3542
"prettier": "^3.0.0",
43+
"ts-jest": "^29.0.0",
3644
"typescript": "^5.0.0"
3745
},
3846
"files": [

src/__tests__/index.test.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { RemoteConversation, RemoteWorkspace } from '../index';
2+
3+
describe('OpenHands Agent Server TypeScript Client', () => {
4+
describe('Exports', () => {
5+
it('should export RemoteConversation', () => {
6+
expect(RemoteConversation).toBeDefined();
7+
expect(typeof RemoteConversation).toBe('function');
8+
});
9+
10+
it('should export RemoteWorkspace', () => {
11+
expect(RemoteWorkspace).toBeDefined();
12+
expect(typeof RemoteWorkspace).toBe('function');
13+
});
14+
});
15+
16+
describe('RemoteConversation', () => {
17+
it('should create instance with config', () => {
18+
const config = {
19+
baseUrl: 'http://localhost:8000',
20+
apiKey: 'test-key'
21+
};
22+
23+
const conversation = new RemoteConversation(config);
24+
expect(conversation).toBeInstanceOf(RemoteConversation);
25+
});
26+
27+
it('should have workspace property', () => {
28+
const config = {
29+
baseUrl: 'http://localhost:8000',
30+
apiKey: 'test-key'
31+
};
32+
33+
const conversation = new RemoteConversation(config);
34+
expect(conversation.workspace).toBeDefined();
35+
expect(conversation.workspace).toBeInstanceOf(RemoteWorkspace);
36+
});
37+
});
38+
39+
describe('RemoteWorkspace', () => {
40+
it('should create instance with http client', () => {
41+
const mockHttpClient = {
42+
get: jest.fn(),
43+
post: jest.fn(),
44+
put: jest.fn(),
45+
delete: jest.fn()
46+
};
47+
48+
const workspace = new RemoteWorkspace(mockHttpClient as any);
49+
expect(workspace).toBeInstanceOf(RemoteWorkspace);
50+
});
51+
});
52+
});

0 commit comments

Comments
 (0)