mlgym-deploy 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +106 -13
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -17,7 +17,7 @@ import crypto from 'crypto';
17
17
  const execAsync = promisify(exec);
18
18
 
19
19
  // Current version of this MCP server - INCREMENT FOR WORKFLOW FIXES
20
- const CURRENT_VERSION = '2.7.0';
20
+ const CURRENT_VERSION = '2.8.0'; // Fixed to match CLI workflow: nested API payload, git push, deployment monitoring
21
21
  const PACKAGE_NAME = 'mlgym-deploy';
22
22
 
23
23
  // Version check state
@@ -945,15 +945,26 @@ async function initProject(args) {
945
945
 
946
946
  console.error(`Creating project: ${name}`);
947
947
 
948
- // Create project via backend API
948
+ // Create project via backend API with CORRECT nested structure (matching CLI)
949
949
  const projectData = {
950
950
  name: name,
951
- description: description,
952
- enable_deployment: enable_deployment
951
+ description: description
953
952
  };
954
953
 
955
- if (enable_deployment && hostname) {
956
- projectData.hostname = hostname;
954
+ if (enable_deployment) {
955
+ // Generate a secure webhook secret for deployments
956
+ const webhookSecret = Array.from(
957
+ crypto.getRandomValues(new Uint8Array(32)),
958
+ byte => byte.toString(16).padStart(2, '0')
959
+ ).join('');
960
+
961
+ // Use nested deployment_info structure like CLI does
962
+ projectData.deployment_info = {
963
+ type: 'dockerfile',
964
+ enabled: true,
965
+ webhook_secret: webhookSecret,
966
+ hostname: hostname
967
+ };
957
968
  }
958
969
 
959
970
  const result = await apiRequest('POST', '/api/v1/projects', projectData, true);
@@ -992,12 +1003,92 @@ async function initProject(args) {
992
1003
 
993
1004
  await execAsync(`git remote add mlgym ${gitUrl}`, { cwd: absolutePath });
994
1005
 
1006
+ // Create initial commit and push (like CLI does)
1007
+ const gitSteps = [];
1008
+
1009
+ try {
1010
+ // Check if there are any files to commit
1011
+ const { stdout: statusOutput } = await execAsync('git status --porcelain', { cwd: absolutePath });
1012
+
1013
+ if (statusOutput.trim()) {
1014
+ // There are uncommitted changes
1015
+ gitSteps.push('Adding files to git');
1016
+ await execAsync('git add .', { cwd: absolutePath });
1017
+
1018
+ gitSteps.push('Creating initial commit');
1019
+ await execAsync('git commit -m "Initial MLGym deployment"', { cwd: absolutePath });
1020
+ } else {
1021
+ // Check if there are any commits at all
1022
+ try {
1023
+ await execAsync('git rev-parse HEAD', { cwd: absolutePath });
1024
+ gitSteps.push('Repository already has commits');
1025
+ } catch {
1026
+ // No commits yet, create an initial one
1027
+ gitSteps.push('Creating README for initial commit');
1028
+ const readmePath = path.join(absolutePath, 'README.md');
1029
+ if (!await fs.access(readmePath).then(() => true).catch(() => false)) {
1030
+ await fs.writeFile(readmePath, `# ${name}\n\n${description}\n\nDeployed with MLGym\n`);
1031
+ }
1032
+ await execAsync('git add .', { cwd: absolutePath });
1033
+ await execAsync('git commit -m "Initial MLGym deployment"', { cwd: absolutePath });
1034
+ }
1035
+ }
1036
+
1037
+ // Push to trigger webhook and deployment
1038
+ gitSteps.push('Pushing to GitLab to trigger deployment');
1039
+ await execAsync('git push -u mlgym main', { cwd: absolutePath });
1040
+
1041
+ } catch (pushError) {
1042
+ console.error('Git operations warning:', pushError.message);
1043
+ gitSteps.push(`Warning: ${pushError.message}`);
1044
+ }
1045
+
1046
+ // Monitor deployment if enabled (like CLI does)
1047
+ let deploymentStatus = null;
1048
+ if (enable_deployment) {
1049
+ console.error('Monitoring deployment status...');
1050
+
1051
+ // Poll for deployment status (up to 60 seconds)
1052
+ for (let i = 0; i < 12; i++) {
1053
+ await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
1054
+
1055
+ const statusResult = await apiRequest('GET', `/api/v1/projects/${project.id}/deployment`, null, true);
1056
+ if (statusResult.success && statusResult.data) {
1057
+ const status = statusResult.data.status;
1058
+ console.error(`Deployment status: ${status}`);
1059
+
1060
+ if (status === 'deployed' || status === 'running') {
1061
+ deploymentStatus = {
1062
+ status: 'deployed',
1063
+ url: statusResult.data.url || `https://${hostname}.ezb.net`,
1064
+ message: 'Application successfully deployed'
1065
+ };
1066
+ break;
1067
+ } else if (status === 'failed') {
1068
+ deploymentStatus = {
1069
+ status: 'failed',
1070
+ message: 'Deployment failed. Check Coolify logs for details.'
1071
+ };
1072
+ break;
1073
+ }
1074
+ }
1075
+ }
1076
+
1077
+ if (!deploymentStatus) {
1078
+ deploymentStatus = {
1079
+ status: 'pending',
1080
+ message: 'Deployment is still in progress. Check status later.',
1081
+ expected_url: `https://${hostname}.ezb.net`
1082
+ };
1083
+ }
1084
+ }
1085
+
995
1086
  return {
996
1087
  content: [{
997
1088
  type: 'text',
998
1089
  text: JSON.stringify({
999
1090
  status: 'success',
1000
- message: 'Project created successfully',
1091
+ message: 'Project created and pushed successfully',
1001
1092
  project: {
1002
1093
  id: project.id,
1003
1094
  name: project.name,
@@ -1006,12 +1097,14 @@ async function initProject(args) {
1006
1097
  deployment_enabled: enable_deployment,
1007
1098
  deployment_url: hostname ? `https://${hostname}.ezb.net` : null
1008
1099
  },
1009
- next_steps: [
1010
- 'Add your code files',
1011
- 'git add .',
1012
- `git commit -m "Initial commit"`,
1013
- 'git push mlgym main',
1014
- enable_deployment ? 'Your app will be automatically deployed after push' : null
1100
+ git_operations: gitSteps,
1101
+ deployment: deploymentStatus,
1102
+ next_steps: enable_deployment && deploymentStatus?.status === 'deployed' ? [
1103
+ `✅ Your application is live at: ${deploymentStatus.url}`,
1104
+ 'Future updates: git push mlgym main'
1105
+ ] : [
1106
+ 'To update: git push mlgym main',
1107
+ enable_deployment ? 'Deployment will trigger automatically' : null
1015
1108
  ].filter(Boolean)
1016
1109
  }, null, 2)
1017
1110
  }]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mlgym-deploy",
3
- "version": "2.7.0",
3
+ "version": "2.8.0",
4
4
  "description": "MCP server for GitLab Backend - User creation and project deployment",
5
5
  "main": "index.js",
6
6
  "type": "module",