diff --git a/action.yml b/action.yml index cabafabf..9447689e 100644 --- a/action.yml +++ b/action.yml @@ -289,16 +289,20 @@ runs: # Keep track of whether we've failed FAILED=false - # Run Gemini CLI with the provided prompt, streaming responses in debug + # Run Gemini CLI with the provided prompt, using JSON output format if [[ "${DEBUG}" = true ]]; then echo "::warning::Gemini CLI debug logging is enabled. This will stream responses, which could reveal sensitive information if processed with untrusted inputs." - if ! { gemini --yolo --prompt "${PROMPT}" 2> >(tee "${TEMP_STDERR}" >&2) | tee "${TEMP_STDOUT}"; }; then - FAILED=true - fi - else - if ! gemini --yolo --prompt "${PROMPT}" 2> "${TEMP_STDERR}" 1> "${TEMP_STDOUT}"; then - FAILED=true - fi + fi + + # We capture stdout (JSON) to TEMP_STDOUT and stderr to TEMP_STDERR + if ! gemini --yolo --prompt "${PROMPT}" --output-format json 2> "${TEMP_STDERR}" 1> "${TEMP_STDOUT}"; then + FAILED=true + fi + + if [[ "${DEBUG}" = true ]]; then + echo "::: Start Gemini CLI STDOUT :::" + cat "${TEMP_STDOUT}" + echo "::: End Gemini CLI STDOUT :::" fi # Create the artifacts directory and copy full logs @@ -312,20 +316,48 @@ runs: touch gemini-artifacts/telemetry.log fi + # Parse JSON output to extract response and errors + # If output is not valid JSON, RESPONSE will be empty and we'll rely on stderr for errors + RESPONSE="" + ERROR_JSON="" + if jq -e . "${TEMP_STDOUT}" >/dev/null 2>&1; then + RESPONSE=$(jq -r '.response // ""' "${TEMP_STDOUT}") + fi + if jq -e . "${TEMP_STDERR}" >/dev/null 2>&1; then + ERROR_JSON=$(jq -c '.error // empty' "${TEMP_STDERR}") + fi + if ! { jq -e . "${TEMP_STDERR}" >/dev/null 2>&1 && jq -e . "${TEMP_STDOUT}" >/dev/null 2>&1; }; then + echo "::warning::Gemini CLI output was not valid JSON" + fi + + # Set the captured response as a step output, supporting multiline echo "gemini_response<> "${GITHUB_OUTPUT}" - cat "${TEMP_STDOUT}" >> "${GITHUB_OUTPUT}" + if [[ -n "${RESPONSE}" ]]; then + echo "${RESPONSE}" >> "${GITHUB_OUTPUT}" + else + cat "${TEMP_STDOUT}" >> "${GITHUB_OUTPUT}" + fi echo "EOF" >> "${GITHUB_OUTPUT}" # Set the captured errors as a step output, supporting multiline echo "gemini_errors<> "${GITHUB_OUTPUT}" - cat "${TEMP_STDERR}" >> "${GITHUB_OUTPUT}" + if [[ -n "${ERROR_JSON}" ]]; then + echo "${ERROR_JSON}" >> "${GITHUB_OUTPUT}" + else + cat "${TEMP_STDERR}" >> "${GITHUB_OUTPUT}" + fi echo "EOF" >> "${GITHUB_OUTPUT}" if [[ "${FAILED}" = true ]]; then - LAST_LINE="$(tail -n1 "${TEMP_STDERR}")" - echo "::error title=Gemini CLI execution failed::${LAST_LINE}" - echo "See logs for more details" + # If we have a structured error from JSON, use it for the error message + if [[ -n "${ERROR_JSON}" ]]; then + ERROR_MSG=$(jq -r '.message // .' <<< "${ERROR_JSON}") + echo "::error title=Gemini CLI execution failed::${ERROR_MSG}" + fi + echo "::: Start Gemini CLI STDERR :::" + cat "${TEMP_STDERR}" + echo "::: End Gemini CLI STDERR :::" exit 1 fi env: