From 8d6ca07aa749b5a96e84115e48acd19f0e1d82f8 Mon Sep 17 00:00:00 2001 From: manufacturist <15235526+manufacturist@users.noreply.github.com> Date: Thu, 25 Jun 2026 15:58:16 +0300 Subject: [PATCH] feat: add gemini server support OD-118 --- docker/Dockerfile | 2 ++ docker/entrypoint.sh | 5 ----- docker/local-pipeline.sh | 39 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index e22a7f9..5d977df 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -25,6 +25,8 @@ RUN apt-get update && apt-get upgrade -y && apt-get install -y --no-install-reco default-jdk-headless \ # shellcheck — adapter finds it on PATH, skips the GitHub release download shellcheck \ + # ripgrep — gemini-cli prefers rg over the fallback GrepTool + ripgrep \ # Ruby runtime — rubocop, reek, brakeman, sqlint ruby \ ruby-dev \ diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 2831809..e231ac7 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -10,9 +10,4 @@ fi # Fix ownership of the tool-cache volume (mounted as root by Docker) sudo chown -R node:node /home/node/.codacy 2>/dev/null || true -# Install Gemini extension from pre-baked local clone (--consent skips the prompt) -if [ -n "${GEMINI_API_KEY:-}" ]; then - gemini extensions install /opt/codacy-skills --consent 2>/dev/null || true -fi - exec "$@" diff --git a/docker/local-pipeline.sh b/docker/local-pipeline.sh index a788d74..c0f2650 100644 --- a/docker/local-pipeline.sh +++ b/docker/local-pipeline.sh @@ -50,9 +50,42 @@ if [ -n "${ANTHROPIC_API_KEY:-}" ]; then elif [ -n "${GEMINI_API_KEY:-}" ]; then echo "==> Running configure-codacy-cloud with Gemini..." - echo "/configure-codacy-cloud" | gemini - SKILL_EXIT=$? - RUN_META="" + SKILL_MD="/opt/codacy-skills/skills/configure-codacy-cloud/SKILL.md" + if [[ ! -f "${SKILL_MD}" ]]; then + echo "ERROR: ${SKILL_MD} not found in the container" >&2 + exit 1 + fi + GEMINI_STREAM_FILE=$(mktemp) + RUN_STARTED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ) + + gemini -y --skip-trust -m "${GEMINI_MODEL:-gemini-3-flash-preview}" -o stream-json \ + -p "Execute the skill instructions provided above." < "${SKILL_MD}" \ + | tee "${GEMINI_STREAM_FILE}" \ + | jq --unbuffered -rj 'select(.type == "message" and .role == "assistant") | .content' + SKILL_EXIT=${PIPESTATUS[0]} + RUN_FINISHED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ) + echo + + RUN_META=$(jq -rsc \ + --arg startedAt "${RUN_STARTED_AT}" \ + --arg finishedAt "${RUN_FINISHED_AT}" ' + . as $events | + ($events | map(select(.type == "init")) | first | .session_id // "") as $sessionId | + ($events | map(select(.type == "init")) | first | .model // "unknown") as $model | + ($events | map(select(.type == "result")) | last) as $result | + { + llm: "gemini", + model: $model, + startedAt: $startedAt, + finishedAt: $finishedAt, + tokensIn: ($result.stats.input_tokens // 0), + tokensOut: ($result.stats.output_tokens // 0), + durationMs: ($result.stats.duration_ms // 0), + costUsd: ((($result.stats.input_tokens // 0) * 0.50 + ($result.stats.output_tokens // 0) * 3.00) / 1000000), + sessionId: $sessionId + } + ' "${GEMINI_STREAM_FILE}") + rm -f "${GEMINI_STREAM_FILE}" else echo "Error: neither ANTHROPIC_API_KEY nor GEMINI_API_KEY is set." >&2