diff --git a/automation/ci-issue-reporter.sh b/automation/ci-issue-reporter.sh deleted file mode 100644 index 65c47ba..0000000 --- a/automation/ci-issue-reporter.sh +++ /dev/null @@ -1,237 +0,0 @@ -#!/usr/bin/env bash -# ============================================================================ -# Copyright (C) 2026 Moko Consulting -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# FILE INFORMATION -# DEFGROUP: Automation.CI -# INGROUP: moko-platform.Automation -# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform -# PATH: /automation/ci-issue-reporter.sh -# VERSION: 09.23.00 -# BRIEF: Creates or updates a Gitea issue when a CI gate fails. -# Deduplicates by searching open issues with the "ci-auto" label -# whose title matches the gate. If a matching issue exists, a comment -# is appended instead of opening a duplicate. -# ============================================================================ - -set -euo pipefail - -# ── Defaults ──────────────────────────────────────────────────────────────── -GITEA_URL="${GITEA_URL:-https://git.mokoconsulting.tech}" -GITEA_TOKEN="${GITEA_TOKEN:-}" -REPO="${GITHUB_REPOSITORY:-}" -RUN_URL="${GITHUB_SERVER_URL:-${GITEA_URL}}/${REPO}/actions/runs/${GITHUB_RUN_ID:-0}" -LABEL_NAME="ci-auto" -LABEL_COLOR="#e11d48" - -GATE="" -DETAILS="" -SEVERITY="error" -WORKFLOW="" - -# ── Parse arguments ───────────────────────────────────────────────────────── -usage() { - cat </dev/null || echo "000") - - if [[ "$exists" == "200" ]]; then - # Check if label already exists - local found - found=$(curl -sf \ - -H "Authorization: token ${GITEA_TOKEN}" \ - "${API}/labels" 2>/dev/null \ - | grep -o "\"name\":\"${LABEL_NAME}\"" || true) - - if [[ -z "$found" ]]; then - curl -sf -X POST \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - "${API}/labels" \ - -d "{\"name\":\"${LABEL_NAME}\",\"color\":\"${LABEL_COLOR}\",\"description\":\"Auto-created by CI issue reporter\"}" \ - > /dev/null 2>&1 || true - fi - fi -} - -# ── Search for existing open issue ────────────────────────────────────────── -find_existing_issue() { - # URL-encode the gate name for the query - local query - query=$(printf '%s' "[CI] ${GATE}" | sed 's/ /%20/g; s/\[/%5B/g; s/\]/%5D/g') - - local response - response=$(curl -sf \ - -H "Authorization: token ${GITEA_TOKEN}" \ - "${API}/issues?type=issues&state=open&labels=${LABEL_NAME}&q=${query}&limit=5" \ - 2>/dev/null || echo "[]") - - # Extract the first matching issue number - echo "$response" \ - | grep -oP '"number":\s*\K[0-9]+' \ - | head -1 -} - -# ── Build issue body ──────────────────────────────────────────────────────── -build_body() { - local severity_badge - if [[ "$SEVERITY" == "error" ]]; then - severity_badge="**Severity:** Error" - else - severity_badge="**Severity:** Warning" - fi - - cat </dev/null) - - HTTP=$(curl -sf -o /dev/null -w '%{http_code}' -X POST \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - "${API}/issues/${EXISTING}/comments" \ - -d "${COMMENT_JSON}" 2>/dev/null || echo "000") - - if [[ "$HTTP" == "201" ]]; then - echo "Commented on existing issue #${EXISTING}" - else - echo "WARNING: Failed to comment on issue #${EXISTING} (HTTP ${HTTP})" - fi -else - # Create new issue - ISSUE_BODY=$(build_body) - ISSUE_JSON=$(python3 -c " -import sys, json -body = sys.stdin.read() -print(json.dumps({ - 'title': sys.argv[1], - 'body': body, - 'labels': [] -}))" "$TITLE" <<< "$ISSUE_BODY" 2>/dev/null) - - # Create the issue - RESPONSE=$(curl -sf -X POST \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - "${API}/issues" \ - -d "${ISSUE_JSON}" 2>/dev/null || echo "{}") - - ISSUE_NUM=$(echo "$RESPONSE" | grep -oP '"number":\s*\K[0-9]+' | head -1) - - if [[ -n "$ISSUE_NUM" ]]; then - # Apply label (separate call — more reliable across Gitea versions) - LABEL_ID=$(curl -sf \ - -H "Authorization: token ${GITEA_TOKEN}" \ - "${API}/labels" 2>/dev/null \ - | grep -oP "\"id\":\s*\K[0-9]+(?=[^}]*\"name\":\s*\"${LABEL_NAME}\")" \ - | head -1 || true) - - if [[ -n "$LABEL_ID" ]]; then - curl -sf -X POST \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - "${API}/issues/${ISSUE_NUM}/labels" \ - -d "{\"labels\":[${LABEL_ID}]}" \ - > /dev/null 2>&1 || true - fi - - echo "Created issue #${ISSUE_NUM}: ${TITLE}" - else - echo "WARNING: Failed to create issue" - echo "Response: ${RESPONSE}" - fi -fi diff --git a/scripts/!.gitkeep b/scripts/!.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/scripts/setup.mjs b/scripts/setup.mjs deleted file mode 100644 index c1e6a40..0000000 --- a/scripts/setup.mjs +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env node -/* Copyright (C) 2026 Moko Consulting - * - * This file is part of a Moko Consulting project. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - * FILE INFORMATION - * DEFGROUP: dolibarr-api-mcp.Scripts - * INGROUP: dolibarr-api-mcp - * REPO: https://git.mokoconsulting.tech/MokoConsulting/dolibarr-api-mcp - * PATH: /scripts/setup.mjs - * VERSION: 01.00.00 - * BRIEF: Interactive setup — prompts for Dolibarr API connection details and writes config - */ - -import { createInterface } from 'node:readline/promises'; -import { readFile, writeFile } from 'node:fs/promises'; -import { resolve } from 'node:path'; -import { homedir } from 'node:os'; - -const CONFIG_PATH = resolve(homedir(), '.dolibarr-api-mcp.json'); - -const rl = createInterface({ input: process.stdin, output: process.stdout }); - -async function prompt(question, defaultValue) { - const suffix = defaultValue ? ` [${defaultValue}]` : ''; - const answer = await rl.question(`${question}${suffix}: `); - return answer.trim() || defaultValue || ''; -} - -async function promptRequired(question) { - let answer = ''; - while (!answer) { - answer = (await rl.question(`${question}: `)).trim(); - if (!answer) { - console.log(' This field is required.'); - } - } - return answer; -} - -async function main() { - console.log(''); - console.log('=== dolibarr-api-mcp Setup ==='); - console.log(''); - console.log('This will create your configuration file at:'); - console.log(` ${CONFIG_PATH}`); - console.log(''); - - // Check for existing config - let existing = null; - try { - const raw = await readFile(CONFIG_PATH, 'utf-8'); - existing = JSON.parse(raw); - console.log('Existing config found. You can add a new connection or overwrite.'); - console.log(` Current connections: ${Object.keys(existing.connections).join(', ')}`); - console.log(''); - } catch { - // No existing config - } - - const connectionName = await prompt('Connection name', 'production'); - const baseUrl = await promptRequired('Dolibarr URL (e.g. https://erp.example.com)'); - const apiKey = await promptRequired('Dolibarr API key (from user settings or Setup > Security)'); - - const cleanUrl = baseUrl.replace(/\/+$/, ''); - - const insecureAnswer = await prompt('Skip TLS verification for self-signed certs? (y/N)', 'N'); - const insecure = insecureAnswer.toLowerCase() === 'y'; - - const connection = { baseUrl: cleanUrl, apiKey }; - if (insecure) { - connection.insecure = true; - } - - let config; - if (existing) { - config = existing; - config.connections[connectionName] = connection; - const setDefault = await prompt(`Set "${connectionName}" as default connection? (y/N)`, 'N'); - if (setDefault.toLowerCase() === 'y') { - config.defaultConnection = connectionName; - } - } else { - config = { - defaultConnection: connectionName, - connections: { - [connectionName]: connection, - }, - }; - } - - await writeFile(CONFIG_PATH, JSON.stringify(config, null, '\t') + '\n', 'utf-8'); - - console.log(''); - console.log(`Config written to ${CONFIG_PATH}`); - console.log(` Connection "${connectionName}" configured for ${cleanUrl}`); - console.log(''); - - const addAnother = await prompt('Add another connection? (y/N)', 'N'); - if (addAnother.toLowerCase() === 'y') { - rl.close(); - // Re-run to add another - const { execFileSync } = await import('node:child_process'); - execFileSync('node', [new URL(import.meta.url).pathname], { stdio: 'inherit' }); - return; - } - - console.log('Setup complete. You can now use the MCP server.'); - console.log(''); - rl.close(); -} - -main().catch((err) => { - console.error(`Setup failed: ${err.message}`); - rl.close(); - process.exit(1); -});