|
1 | 1 | # .github/workflows/issue_explainer.yml |
2 | 2 | name: Codex CLI Explain Issue |
3 | 3 |
|
4 | | -# Trigger when an issue is labeled with 'ask-cstudio-explain' |
5 | 4 | on: |
6 | 5 | issues: |
7 | 6 | types: [labeled] |
8 | 7 |
|
9 | | -# Permissions needed by the workflow |
10 | 8 | permissions: |
11 | | - issues: write # Allows writing comments to issues |
12 | | - contents: read # Allows checking out the repository code (needed for setup-python cache) |
| 9 | + issues: write |
| 10 | + contents: read # Keep read permission just in case checkout needs it explicitly |
13 | 11 |
|
14 | 12 | jobs: |
15 | 13 | explain_code_in_issue: |
16 | | - # Run job only if the triggering label name matches |
17 | 14 | if: github.event.label.name == 'ask-cstudio-explain' |
18 | | - # Use the latest Ubuntu runner environment |
19 | 15 | runs-on: ubuntu-latest |
20 | 16 |
|
21 | 17 | steps: |
22 | | - # Step 1: Check out the repository code |
23 | | - # Needed for setup-python to find pyproject.toml for caching |
24 | 18 | - name: Check out repository code |
25 | 19 | uses: actions/checkout@v4 |
26 | 20 |
|
27 | | - # Step 2: Set up Python environment |
| 21 | + # --- FIX: Completely remove cache parameters --- |
28 | 22 | - name: Set up Python |
29 | 23 | uses: actions/setup-python@v5 |
30 | 24 | with: |
31 | | - python-version: '3.13' # Specify Python version |
32 | | - cache: 'pip' # Enable pip caching |
33 | | - cache-dependency-path: 'pyproject.toml' # Explicitly point to the dependency file |
| 25 | + python-version: '3.13' # Or your preferred version (3.12, 3.13) |
| 26 | + # No 'cache' or 'cache-dependency-path' here |
34 | 27 |
|
35 | | - # Step 3: Install the CLI tool from PyPI |
36 | 28 | - name: Install Codex CLI Studio |
37 | 29 | run: | |
38 | 30 | python -m pip install --upgrade pip |
39 | | - pip install codex-cli-studio # Install the latest published version |
| 31 | + # Install directly from PyPI, no local build needed here |
| 32 | + pip install codex-cli-studio |
40 | 33 |
|
41 | | - # Step 4: Extract code snippet from the issue body |
| 34 | + # ... (Rest of the steps remain the same) ... |
42 | 35 | - name: Extract Code Snippet from Issue Body |
43 | | - id: extract_code # Assign an ID to reference outputs later |
| 36 | + id: extract_code |
44 | 37 | run: | |
45 | | - # Get issue body, remove potential carriage returns |
46 | 38 | ISSUE_BODY=$(echo "${{ github.event.issue.body }}" | sed 's/\\r//g') |
47 | | - # Extract content between the first pair of ``` fences using awk |
48 | 39 | CODE_SNIPPET=$(echo "$ISSUE_BODY" | awk '/^```(\w*)/{f=1;next} /^```/{f=0; exit} f{print}') |
49 | | - # Check if code snippet is empty |
50 | 40 | if [[ -z "$CODE_SNIPPET" ]]; then |
51 | 41 | echo "No code block found in issue body. Setting error message." |
52 | | - # Set an output variable to indicate the error |
53 | 42 | echo "error_message=No fenced code block (\`\`\` ... \`\`\`) found in the issue body." >> $GITHUB_OUTPUT |
54 | | - # Exit step gracefully (job continues based on 'if' conditions later) |
55 | | - exit 0 |
| 43 | + exit 0 # Gracefully exit step |
56 | 44 | else |
57 | | - echo "Code snippet extracted successfully." |
58 | | - # Save the multiline code snippet to a step output variable safely |
| 45 | + echo "Code snippet extracted." |
59 | 46 | echo "code_snippet<<EOF" >> $GITHUB_OUTPUT |
60 | 47 | echo "$CODE_SNIPPET" >> $GITHUB_OUTPUT |
61 | 48 | echo "EOF" >> $GITHUB_OUTPUT |
62 | 49 | fi |
63 | 50 |
|
64 | | - # Step 5: Run 'cstudio explain' command if code was extracted |
65 | 51 | - name: Run cstudio explain |
66 | | - id: cstudio # Assign an ID |
67 | | - # Only run if the previous step did not set an error message |
| 52 | + id: cstudio |
68 | 53 | if: steps.extract_code.outputs.error_message == null |
69 | 54 | env: |
70 | | - # Provide the OpenAI API key from repository secrets |
71 | 55 | OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} |
72 | | - # Set environment variables to potentially simplify terminal output for parsing |
73 | 56 | TERM: dumb |
74 | 57 | NO_COLOR: 1 |
75 | 58 | run: | |
76 | | - # Execute the command using process substitution for multiline input |
77 | | - # Capture the full output (stdout and potentially stderr if redirected) |
78 | 59 | EXPLANATION=$(cstudio explain <(echo "${{ steps.extract_code.outputs.code_snippet }}") 2>&1) |
79 | | - # Check the exit code of the command |
80 | 60 | EXIT_CODE=$? |
81 | 61 | if [ $EXIT_CODE -ne 0 ]; then |
82 | 62 | echo "cstudio explain command failed with exit code $EXIT_CODE." |
83 | | - # Save the error output |
84 | 63 | echo "output<<EOF" >> $GITHUB_OUTPUT |
85 | 64 | echo "Error running cstudio explain. Output:" >> $GITHUB_OUTPUT |
86 | | - echo "$EXPLANATION" >> $GITHUB_OUTPUT # Include the command's output/error |
| 65 | + echo "$EXPLANATION" >> $GITHUB_OUTPUT |
87 | 66 | echo "EOF" >> $GITHUB_OUTPUT |
88 | | - exit 0 # Exit step gracefully to allow comment posting |
| 67 | + exit 0 |
89 | 68 | fi |
90 | 69 | echo "Explanation generated." |
91 | | - # Save the successful explanation output |
92 | 70 | echo "output<<EOF" >> $GITHUB_OUTPUT |
93 | 71 | echo "$EXPLANATION" >> $GITHUB_OUTPUT |
94 | 72 | echo "EOF" >> $GITHUB_OUTPUT |
95 | 73 |
|
96 | | - # Step 6: Post the result (explanation or error) as a comment on the issue |
97 | 74 | - name: Create Comment on Issue |
98 | | - # Use the official GitHub Script action for API interactions |
99 | 75 | uses: actions/github-script@v7 |
100 | 76 | with: |
101 | | - # Use the default GITHUB_TOKEN which has necessary permissions |
102 | 77 | github-token: ${{ secrets.GITHUB_TOKEN }} |
103 | | - # The JavaScript code to run |
104 | 78 | script: | |
105 | | - // Get context for the issue and repository |
| 79 | + // ... (JavaScript code remains the same) ... |
106 | 80 | const issue_number = context.issue.number; |
107 | 81 | const repo = context.repo.repo; |
108 | 82 | const owner = context.repo.owner; |
109 | | - let body; // Variable to hold the comment body |
110 | | -
|
111 | | - // Get outputs from previous steps |
| 83 | + let body; |
112 | 84 | const extraction_error = `${{ steps.extract_code.outputs.error_message }}`; |
113 | | - const raw_output = `${{ steps.cstudio.outputs.output }}`; // Use raw_output for clarity |
114 | | -
|
115 | | - // Attempt basic cleanup of potential status lines from the CLI output |
| 85 | + const raw_output = `${{ steps.cstudio.outputs.output }}`; |
116 | 86 | const output_lines = raw_output.split('\n'); |
117 | 87 | const first_line = output_lines[0] || ''; |
118 | | - // Remove known status/debug lines if present |
119 | 88 | const explanation_content = (first_line.includes('Analyzing') || first_line.includes('Generating')) |
120 | 89 | ? output_lines.slice(1).join('\n') |
121 | 90 | : raw_output; |
122 | 91 |
|
123 | | - // Construct the comment body based on step outcomes |
124 | 92 | if (extraction_error) { |
125 | | - // If code extraction failed |
126 | 93 | body = `🤖 **Codex CLI Studio:**\n\n${extraction_error}`; |
127 | 94 | } else if (explanation_content && !explanation_content.includes('Error running cstudio explain')) { |
128 | | - // If explanation seems successful |
129 | 95 | const formatted_explanation = explanation_content |
130 | | - // Standardize headers potentially added by the explain module |
131 | 96 | .replace(/^✨ Configuration File Explanation:/gm, '**Explanation:**') |
132 | 97 | .replace(/^✨ Explanation:/gm, '**Explanation:**') |
133 | | - .trim(); // Remove leading/trailing whitespace |
| 98 | + .trim(); |
134 | 99 | body = `🤖 **Codex CLI Studio Explanation:**\n\n---\n\n${formatted_explanation || "_(AI generated an empty explanation)_"}`; |
135 | 100 | } else { |
136 | | - // If cstudio command failed or returned empty/error output |
137 | 101 | body = `🤖 **Codex CLI Studio:**\n\nSorry, I couldn't generate an explanation. There might have been an API issue or an internal error executing the command.`; |
138 | | - // Log the raw output for debugging purposes in the Actions console |
139 | 102 | console.log("Raw output from cstudio step:", raw_output); |
140 | 103 | } |
141 | | -
|
142 | | - // Use GitHub REST API client provided by github-script to create the comment |
143 | 104 | await github.rest.issues.createComment({ |
144 | 105 | owner: owner, |
145 | 106 | repo: repo, |
|
0 commit comments