From 5a83627c47e9cb62b7c9149dd53c122457ae7e20 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 07:22:25 +0000 Subject: [PATCH 1/2] Initial plan From 4f3ccb213c507922621fed95b25ffebe666b5b33 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 07:36:20 +0000 Subject: [PATCH 2/2] Fix SC2295: Quote variable inside parameter expansion in ci-doctor workflow Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ci-doctor.lock.yml | 4 ++-- .github/workflows/ci-doctor.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index b16f8ef6ea1..e0577dda36e 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -25,7 +25,7 @@ # # Source: githubnext/agentics/workflows/ci-doctor.md@ea350161ad5dcc9624cf510f134c6a9e39a6f94d # -# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"a021e9ae8508f6bf47f91b524cc2c91532db36f08303096c2dcfdf1319271bc4","stop_time":"2026-03-03 16:27:58"} +# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"4f6c689a557bac05e4396f51747ef414be67fb802404e0b79dd1aaf8364f6754","stop_time":"2026-03-03 16:27:58"} # # Effective stop-time: 2026-03-03 16:27:58 @@ -302,7 +302,7 @@ jobs: REPO: ${{ github.repository }} RUN_ID: ${{ github.event.workflow_run.id }} name: Pre-download CI failure logs and artifacts, apply heuristics - run: "set -e\nLOG_DIR=\"/tmp/ci-doctor/logs\"\nARTIFACT_DIR=\"/tmp/ci-doctor/artifacts\"\nFILTERED_DIR=\"/tmp/ci-doctor/filtered\"\nmkdir -p \"$LOG_DIR\" \"$ARTIFACT_DIR\" \"$FILTERED_DIR\"\n\necho \"=== CI Doctor: Pre-downloading logs and artifacts for run $RUN_ID ===\"\n\n# Get failed jobs and their failed steps\ngh api \"repos/$REPO/actions/runs/$RUN_ID/jobs\" \\\n --jq '[.jobs[] | select(.conclusion == \"failed\" or .conclusion == \"cancelled\") | {id:.id, name:.name, failed_steps:[.steps[]? | select(.conclusion==\"failed\") | .name]}]' \\\n > \"$LOG_DIR/failed-jobs.json\"\n\nFAILED_COUNT=$(jq 'length' \"$LOG_DIR/failed-jobs.json\")\necho \"Found $FAILED_COUNT failed job(s)\"\n\nif [ \"$FAILED_COUNT\" -eq 0 ]; then\n echo \"No failed jobs found, skipping log download\"\n exit 0\nfi\n\necho \"Failed jobs:\"\ncat \"$LOG_DIR/failed-jobs.json\"\n\n# Download logs for each failed job and apply generic error heuristics\njq -r '.[].id' \"$LOG_DIR/failed-jobs.json\" | while read -r JOB_ID; do\n LOG_FILE=\"$LOG_DIR/job-${JOB_ID}.log\"\n echo \"Downloading log for job $JOB_ID...\"\n gh api \"repos/$REPO/actions/jobs/$JOB_ID/logs\" > \"$LOG_FILE\" 2>/dev/null \\\n || echo \"(log download failed)\" > \"$LOG_FILE\"\n echo \" -> Saved $(wc -l < \"$LOG_FILE\") lines to $LOG_FILE\"\n\n # Apply generic heuristics: find lines with common error indicators\n HINTS_FILE=\"$FILTERED_DIR/job-${JOB_ID}-hints.txt\"\n grep -n -iE \"(error[: ]|ERROR|FAIL|panic:|fatal[: ]|undefined[: ]|exception|exit status [^0])\" \\\n \"$LOG_FILE\" | head -30 > \"$HINTS_FILE\" 2>/dev/null || true\n\n if [ -s \"$HINTS_FILE\" ]; then\n echo \" -> Pre-located $(wc -l < \"$HINTS_FILE\") hint line(s) in $HINTS_FILE\"\n else\n echo \" -> No error hints found in $LOG_FILE\"\n fi\ndone\n\n# Download and unpack all artifacts from the failed run\necho \"\"\necho \"=== Downloading artifacts for run $RUN_ID ===\"\ngh run download \"$RUN_ID\" --repo \"$REPO\" --dir \"$ARTIFACT_DIR\" 2>/dev/null \\\n || echo \"No artifacts available or download failed\"\n\n# Apply heuristics to artifact text files\nfind \"$ARTIFACT_DIR\" -type f \\( \\\n -name \"*.txt\" -o -name \"*.log\" -o -name \"*.json\" \\\n -o -name \"*.xml\" -o -name \"*.out\" -o -name \"*.err\" \\\n\\) | while read -r ARTIFACT_FILE; do\n REL_PATH=\"${ARTIFACT_FILE#$ARTIFACT_DIR/}\"\n SAFE_NAME=$(echo \"$REL_PATH\" | tr '/' '_')\n HINTS_FILE=\"$FILTERED_DIR/artifact-${SAFE_NAME}-hints.txt\"\n grep -n -iE \"(error[: ]|ERROR|FAIL|panic:|fatal[: ]|undefined[: ]|exception|exit status [^0])\" \\\n \"$ARTIFACT_FILE\" | head -30 > \"$HINTS_FILE\" 2>/dev/null || true\n if [ -s \"$HINTS_FILE\" ]; then\n echo \" -> Artifact hints: $HINTS_FILE ($(wc -l < \"$HINTS_FILE\") lines from $ARTIFACT_FILE)\"\n fi\ndone\n\n# Write summary for the agent\nSUMMARY_FILE=\"/tmp/ci-doctor/summary.txt\"\n{\n echo \"=== CI Doctor Pre-Analysis ===\"\n echo \"Run ID: $RUN_ID\"\n echo \"\"\n echo \"Failed jobs (details in $LOG_DIR/failed-jobs.json):\"\n jq -r '.[] | \" Job \\(.id): \\(.name)\\n Failed steps: \\(.failed_steps | join(\", \"))\"' \\\n \"$LOG_DIR/failed-jobs.json\"\n echo \"\"\n echo \"Downloaded log files ($LOG_DIR):\"\n for LOG_FILE in \"$LOG_DIR\"/job-*.log; do\n [ -f \"$LOG_FILE\" ] || continue\n echo \" $LOG_FILE ($(wc -l < \"$LOG_FILE\") lines)\"\n done\n echo \"\"\n echo \"Downloaded artifact files ($ARTIFACT_DIR):\"\n find \"$ARTIFACT_DIR\" -type f | while read -r f; do\n echo \" $f\"\n done\n echo \"\"\n echo \"Filtered hint files ($FILTERED_DIR):\"\n for HINTS_FILE in \"$FILTERED_DIR\"/*-hints.txt; do\n [ -s \"$HINTS_FILE\" ] || continue\n echo \" $HINTS_FILE ($(wc -l < \"$HINTS_FILE\") matches)\"\n head -3 \"$HINTS_FILE\" | sed 's/^/ /'\n done\n} | tee \"$SUMMARY_FILE\"\n\necho \"\"\necho \"✅ Pre-analysis complete. Agent should start with $SUMMARY_FILE\"\n" + run: "set -e\nLOG_DIR=\"/tmp/ci-doctor/logs\"\nARTIFACT_DIR=\"/tmp/ci-doctor/artifacts\"\nFILTERED_DIR=\"/tmp/ci-doctor/filtered\"\nmkdir -p \"$LOG_DIR\" \"$ARTIFACT_DIR\" \"$FILTERED_DIR\"\n\necho \"=== CI Doctor: Pre-downloading logs and artifacts for run $RUN_ID ===\"\n\n# Get failed jobs and their failed steps\ngh api \"repos/$REPO/actions/runs/$RUN_ID/jobs\" \\\n --jq '[.jobs[] | select(.conclusion == \"failed\" or .conclusion == \"cancelled\") | {id:.id, name:.name, failed_steps:[.steps[]? | select(.conclusion==\"failed\") | .name]}]' \\\n > \"$LOG_DIR/failed-jobs.json\"\n\nFAILED_COUNT=$(jq 'length' \"$LOG_DIR/failed-jobs.json\")\necho \"Found $FAILED_COUNT failed job(s)\"\n\nif [ \"$FAILED_COUNT\" -eq 0 ]; then\n echo \"No failed jobs found, skipping log download\"\n exit 0\nfi\n\necho \"Failed jobs:\"\ncat \"$LOG_DIR/failed-jobs.json\"\n\n# Download logs for each failed job and apply generic error heuristics\njq -r '.[].id' \"$LOG_DIR/failed-jobs.json\" | while read -r JOB_ID; do\n LOG_FILE=\"$LOG_DIR/job-${JOB_ID}.log\"\n echo \"Downloading log for job $JOB_ID...\"\n gh api \"repos/$REPO/actions/jobs/$JOB_ID/logs\" > \"$LOG_FILE\" 2>/dev/null \\\n || echo \"(log download failed)\" > \"$LOG_FILE\"\n echo \" -> Saved $(wc -l < \"$LOG_FILE\") lines to $LOG_FILE\"\n\n # Apply generic heuristics: find lines with common error indicators\n HINTS_FILE=\"$FILTERED_DIR/job-${JOB_ID}-hints.txt\"\n grep -n -iE \"(error[: ]|ERROR|FAIL|panic:|fatal[: ]|undefined[: ]|exception|exit status [^0])\" \\\n \"$LOG_FILE\" | head -30 > \"$HINTS_FILE\" 2>/dev/null || true\n\n if [ -s \"$HINTS_FILE\" ]; then\n echo \" -> Pre-located $(wc -l < \"$HINTS_FILE\") hint line(s) in $HINTS_FILE\"\n else\n echo \" -> No error hints found in $LOG_FILE\"\n fi\ndone\n\n# Download and unpack all artifacts from the failed run\necho \"\"\necho \"=== Downloading artifacts for run $RUN_ID ===\"\ngh run download \"$RUN_ID\" --repo \"$REPO\" --dir \"$ARTIFACT_DIR\" 2>/dev/null \\\n || echo \"No artifacts available or download failed\"\n\n# Apply heuristics to artifact text files\nfind \"$ARTIFACT_DIR\" -type f \\( \\\n -name \"*.txt\" -o -name \"*.log\" -o -name \"*.json\" \\\n -o -name \"*.xml\" -o -name \"*.out\" -o -name \"*.err\" \\\n\\) | while read -r ARTIFACT_FILE; do\n REL_PATH=\"${ARTIFACT_FILE#\"$ARTIFACT_DIR/\"}\"\n SAFE_NAME=$(echo \"$REL_PATH\" | tr '/' '_')\n HINTS_FILE=\"$FILTERED_DIR/artifact-${SAFE_NAME}-hints.txt\"\n grep -n -iE \"(error[: ]|ERROR|FAIL|panic:|fatal[: ]|undefined[: ]|exception|exit status [^0])\" \\\n \"$ARTIFACT_FILE\" | head -30 > \"$HINTS_FILE\" 2>/dev/null || true\n if [ -s \"$HINTS_FILE\" ]; then\n echo \" -> Artifact hints: $HINTS_FILE ($(wc -l < \"$HINTS_FILE\") lines from $ARTIFACT_FILE)\"\n fi\ndone\n\n# Write summary for the agent\nSUMMARY_FILE=\"/tmp/ci-doctor/summary.txt\"\n{\n echo \"=== CI Doctor Pre-Analysis ===\"\n echo \"Run ID: $RUN_ID\"\n echo \"\"\n echo \"Failed jobs (details in $LOG_DIR/failed-jobs.json):\"\n jq -r '.[] | \" Job \\(.id): \\(.name)\\n Failed steps: \\(.failed_steps | join(\", \"))\"' \\\n \"$LOG_DIR/failed-jobs.json\"\n echo \"\"\n echo \"Downloaded log files ($LOG_DIR):\"\n for LOG_FILE in \"$LOG_DIR\"/job-*.log; do\n [ -f \"$LOG_FILE\" ] || continue\n echo \" $LOG_FILE ($(wc -l < \"$LOG_FILE\") lines)\"\n done\n echo \"\"\n echo \"Downloaded artifact files ($ARTIFACT_DIR):\"\n find \"$ARTIFACT_DIR\" -type f | while read -r f; do\n echo \" $f\"\n done\n echo \"\"\n echo \"Filtered hint files ($FILTERED_DIR):\"\n for HINTS_FILE in \"$FILTERED_DIR\"/*-hints.txt; do\n [ -s \"$HINTS_FILE\" ] || continue\n echo \" $HINTS_FILE ($(wc -l < \"$HINTS_FILE\") matches)\"\n head -3 \"$HINTS_FILE\" | sed 's/^/ /'\n done\n} | tee \"$SUMMARY_FILE\"\n\necho \"\"\necho \"✅ Pre-analysis complete. Agent should start with $SUMMARY_FILE\"\n" # Cache memory file share configuration from frontmatter processed below - name: Create cache-memory directory diff --git a/.github/workflows/ci-doctor.md b/.github/workflows/ci-doctor.md index 07beccafdfb..db95ff69e4a 100644 --- a/.github/workflows/ci-doctor.md +++ b/.github/workflows/ci-doctor.md @@ -112,7 +112,7 @@ steps: -name "*.txt" -o -name "*.log" -o -name "*.json" \ -o -name "*.xml" -o -name "*.out" -o -name "*.err" \ \) | while read -r ARTIFACT_FILE; do - REL_PATH="${ARTIFACT_FILE#$ARTIFACT_DIR/}" + REL_PATH="${ARTIFACT_FILE#"$ARTIFACT_DIR/"}" SAFE_NAME=$(echo "$REL_PATH" | tr '/' '_') HINTS_FILE="$FILTERED_DIR/artifact-${SAFE_NAME}-hints.txt" grep -n -iE "(error[: ]|ERROR|FAIL|panic:|fatal[: ]|undefined[: ]|exception|exit status [^0])" \