Skip to content

Commit 0510414

Browse files
committed
Convert GitHub Workflow healthService to HealthService Neo.mjs Class #7556
1 parent 33ee24b commit 0510414

4 files changed

Lines changed: 133 additions & 94 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
title: "Convert GitHub Workflow healthService to HealthService Neo.mjs Class"
3+
labels: enhancement, AI, refactoring
4+
---
5+
6+
GH ticket id: #7556
7+
8+
**Epic:** #7536
9+
**Phase:** 2
10+
**Assignee:** tobiu
11+
**Status:** Done
12+
13+
## Description
14+
15+
This ticket covers refactoring `ai/mcp/server/github-workflow/services/healthService.mjs` into a singleton `HealthService` class that extends `Neo.core.Base`. This is the first step in migrating the GitHub Workflow server to the consistent Neo.mjs service architecture used by the other MCP servers.
16+
17+
## Acceptance Criteria
18+
19+
1. The file `ai/mcp/server/github-workflow/services/healthService.mjs` is renamed to `HealthService.mjs`.
20+
2. The content is replaced with a `HealthService` class that extends `Neo.core.Base` and is configured as a singleton.
21+
3. The existing `healthcheck` function is converted into a class method.
22+
4. The `ai/mcp/server/github-workflow/services/toolService.mjs` is updated to use the new `HealthService` class.
23+
5. The `healthcheck` tool continues to function correctly after the refactoring.
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import {exec} from 'child_process';
2+
import {promisify} from 'util';
3+
import Base from '../../../../../src/core/Base.mjs';
4+
5+
const execAsync = promisify(exec);
6+
const MIN_GH_VERSION = '2.0.0';
7+
8+
/**
9+
* Service for providing the health status of the GitHub workflow server.
10+
* Its primary purpose is to verify the server's critical dependency: the GitHub CLI (`gh`).
11+
* It performs a series of checks for installation, authentication, and version compatibility,
12+
* then consolidates these checks into a single, comprehensive health status object.
13+
* @class Neo.ai.mcp.server.github.HealthService
14+
* @extends Neo.core.Base
15+
* @singleton
16+
*/
17+
class HealthService extends Base {
18+
static config = {
19+
/**
20+
* @member {String} className='Neo.ai.mcp.server.github.HealthService'
21+
* @protected
22+
*/
23+
className: 'Neo.ai.mcp.server.github.HealthService',
24+
/**
25+
* @member {Boolean} singleton=true
26+
* @protected
27+
*/
28+
singleton: true
29+
}
30+
31+
/**
32+
* Checks if the GitHub CLI is installed and if its version meets the minimum requirement.
33+
* This single check is more efficient than performing two separate commands.
34+
* @returns {Promise<{installed: boolean, versionOk: boolean, version: string|null, error?: string}>}
35+
* @private
36+
*/
37+
async #checkGhVersion() {
38+
try {
39+
const {stdout} = await execAsync('gh --version');
40+
const versionMatch = stdout.match(/gh version ([\d.]+)/);
41+
if (versionMatch) {
42+
const currentVersion = versionMatch[1];
43+
if (currentVersion >= MIN_GH_VERSION) {
44+
return {installed: true, versionOk: true, version: currentVersion};
45+
} else {
46+
return {
47+
installed: true,
48+
versionOk: false,
49+
version : currentVersion,
50+
error : `gh version (${currentVersion}) is outdated. Please upgrade to at least ${MIN_GH_VERSION}.`
51+
};
52+
}
53+
}
54+
return {installed: true, versionOk: false, error: 'Could not parse gh version.'};
55+
} catch (e) {
56+
return {installed: false, versionOk: false, error: 'GitHub CLI is not installed. Please install it.'};
57+
}
58+
}
59+
60+
/**
61+
* Checks the status of the GitHub CLI integration.
62+
* @returns {Promise<object>} A promise that resolves to the health check payload.
63+
*/
64+
async healthcheck() {
65+
const payload = {
66+
status : 'healthy',
67+
timestamp: new Date().toISOString(),
68+
githubCli: {
69+
installed : false,
70+
authenticated: false,
71+
versionOk : false,
72+
version : null,
73+
details : []
74+
}
75+
};
76+
77+
const versionCheck = await this.#checkGhVersion();
78+
payload.githubCli.installed = versionCheck.installed;
79+
payload.githubCli.versionOk = versionCheck.versionOk;
80+
payload.githubCli.version = versionCheck.version;
81+
82+
if (!versionCheck.installed) {
83+
payload.status = 'unhealthy';
84+
payload.githubCli.details.push(versionCheck.error);
85+
return payload;
86+
}
87+
88+
if (!versionCheck.versionOk) {
89+
payload.status = 'unhealthy';
90+
payload.githubCli.details.push(versionCheck.error);
91+
}
92+
93+
const authCheck = await this.#checkGhAuth();
94+
payload.githubCli.authenticated = authCheck.authenticated;
95+
if (!authCheck.authenticated) {
96+
payload.status = 'unhealthy';
97+
payload.githubCli.details.push(authCheck.error);
98+
}
99+
100+
if (payload.status === 'healthy') {
101+
payload.githubCli.details.push('GitHub CLI is installed, authenticated, and up to date.');
102+
}
103+
104+
return payload;
105+
}
106+
}
107+
108+
export default Neo.setupClass(HealthService);

ai/mcp/server/github-workflow/services/healthService.mjs

Lines changed: 0 additions & 92 deletions
This file was deleted.

ai/mcp/server/github-workflow/services/toolService.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import path from 'path';
22
import { fileURLToPath } from 'url';
3-
import * as healthService from './healthService.mjs';
3+
import HealthService from './HealthService.mjs';
44
import * as issueService from './issueService.mjs';
55
import * as labelService from './labelService.mjs';
66
import * as pullRequestService from './pullRequestService.mjs';
@@ -16,7 +16,7 @@ const serviceMapping = {
1616
create_comment : pullRequestService.createComment,
1717
get_conversation : pullRequestService.getConversation,
1818
get_pull_request_diff: pullRequestService.getPullRequestDiff,
19-
health_service : healthService.buildHealthResponse(),
19+
healthcheck : HealthService.healthcheck,
2020
list_labels : labelService.listLabels,
2121
list_pull_requests : pullRequestService.listPullRequests,
2222
remove_labels : issueService.removeLabels

0 commit comments

Comments
 (0)