Update codacy.yml #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Sync Codacy Issues | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: "Run without creating GitHub issues" | |
| required: false | |
| default: "false" | |
| push: | |
| branches: | |
| - master | |
| - main | |
| jobs: | |
| sync-codacy-issues: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| issues: write | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install jq and gh | |
| run: | | |
| sudo apt-get update -y | |
| sudo apt-get install -y jq gh | |
| # 🔹 STEP 1: Fetch Codacy Issues | |
| - name: Fetch Codacy Issues | |
| env: | |
| CODACY_API_TOKEN: ${{ secrets.CODACY_API_TOKEN }} | |
| run: | | |
| curl --request POST \ | |
| --url "https://app.codacy.com/api/v3/analysis/organizations/gh/${{ github.repository_owner }}/repositories/${{ github.event.repository.name }}/issues/search" \ | |
| --header "api-token: $CODACY_API_TOKEN" \ | |
| --header "content-type: application/json" \ | |
| --data '{"levels":["Error","Warning","High"]}' \ | |
| --silent \ | |
| --fail \ | |
| -o codacy_issues.json | |
| # 🔹 STEP 2: Ensure standard labels exist with your colors | |
| - name: Ensure standard labels exist | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| declare -A LABELS=( | |
| ["task"]="Tasks and work items|#aefcde" | |
| ["refactor"]="Code cleanup and best practices|#eb69a2" | |
| ["bug"]="Bugs and error-prone code|#b60205" | |
| ["security"]="Security-related issues|#d93f0b" | |
| ["performance"]="Performance optimization issues|#e57504" | |
| ) | |
| for label in "${!LABELS[@]}"; do | |
| desc=${LABELS[$label]%%|*} | |
| color=${LABELS[$label]##*|} | |
| echo "Creating/updating label '$label'" | |
| gh label create "$label" --description "$desc" --color "$color" --repo ${{ github.repository }} --force | |
| done | |
| # 🔹 STEP 3: Sync Codacy Issues (create/update) | |
| - name: Sync Codacy Issues | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| dry_run="${{ github.event.inputs.dry_run }}" | |
| current_issues=$(gh issue list --repo ${{ github.repository }} --state open --json number,title,body,labels) | |
| jq -c '.data[]' codacy_issues.json | while read -r issue; do | |
| id=$(echo "$issue" | jq -r '.issueId') | |
| file=$(echo "$issue" | jq -r '.filePath') | |
| line=$(echo "$issue" | jq -r '.lineNumber') | |
| message=$(echo "$issue" | jq -r '.message') | |
| line_text=$(echo "$issue" | jq -r '.lineText // empty') | |
| category=$(echo "$issue" | jq -r '.patternInfo.category') | |
| severity=$(echo "$issue" | jq -r '.patternInfo.severityLevel') | |
| sha=$(echo "$issue" | jq -r '.commitInfo.sha') | |
| title="[$category] $message" | |
| # Prepare the code snippet inline | |
| if [ -n "$line_text" ]; then | |
| # Replace literal \n from JSON and real newlines with space | |
| clean_line_text=$(echo "$line_text" | tr -d '\r' | tr '\n' ' ' | sed 's/\\n/ /g') | |
| code_snippet="\`\`\` | |
| $clean_line_text | |
| \`\`\`" | |
| else | |
| code_snippet="" | |
| fi | |
| # Build the full body with Codacy ID at the top | |
| body="**Codacy ID:** \`$id\` | |
| **File:** \`$file\` | |
| **Line:** $line | |
| **Rule:** $category ($severity) | |
| **Commit:** \`$sha\`" | |
| # Append code snippet if present | |
| if [ -n "$code_snippet" ]; then | |
| body+=" | |
| **Code Snippet:** | |
| $code_snippet" | |
| fi | |
| # Determine labels based on message/category | |
| labels=() | |
| if echo "$message" | grep -iq "todo"; then | |
| labels+=("task") | |
| elif echo "$category" | grep -Eiq "best[_ ]?practice|code[_ ]?style|complexity"; then | |
| labels+=("refactor") | |
| elif echo "$message" | grep -iq "security"; then | |
| labels+=("task" "security") | |
| elif echo "$category" | grep -iq "performance"; then | |
| labels+=("task" "performance") | |
| elif echo "$message" | grep -Eiq "error[_ ]?prone"; then | |
| labels+=("bug") | |
| fi | |
| label_string=$(IFS=,; echo "${labels[*]}") | |
| # Check if issue exists | |
| existing_number=$(echo "$current_issues" | jq -r --arg id "$id" '.[] | select(.body | contains($id)) | .number') | |
| if [ -n "$existing_number" ]; then | |
| echo "Updating existing issue #$existing_number ($id)" | |
| if [ "$dry_run" != "true" ]; then | |
| gh issue edit "$existing_number" \ | |
| --body "$body" \ | |
| --add-label "$label_string" \ | |
| --repo ${{ github.repository }} | |
| else | |
| echo "[DRY RUN] Would update issue #$existing_number with labels: $label_string" | |
| fi | |
| else | |
| echo "Creating new issue for Codacy ID $id" | |
| if [ "$dry_run" != "true" ]; then | |
| gh issue create \ | |
| --title "$title" \ | |
| --body "$body" \ | |
| --label "$label_string" \ | |
| --repo ${{ github.repository }} | |
| else | |
| echo "[DRY RUN] Would create issue '$title' with labels: $label_string" | |
| fi | |
| fi | |
| done | |
| # 🔹 STEP 4: Close resolved issues | |
| - name: Close resolved issues | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| current_ids=$(jq -r '.data[].issueId' codacy_issues.json) | |
| gh issue list --repo ${{ github.repository }} --state open --label codacy --json number,body | jq -c '.[]' | while read -r issue; do | |
| number=$(echo "$issue" | jq -r '.number') | |
| body=$(echo "$issue" | jq -r '.body') | |
| id=$(echo "$body" | grep -oE 'Codacy ID: [a-f0-9]+' | awk '{print $3}') | |
| if [ -n "$id" ] && ! echo "$current_ids" | grep -q "$id"; then | |
| echo "Closing stale Codacy issue #$number ($id)" | |
| if [ "$dry_run" != "true" ]; then | |
| gh issue close "$number" --comment "This issue no longer appears in Codacy reports and has been auto-closed." --repo ${{ github.repository }} | |
| else | |
| echo "[DRY RUN] Would close issue #$number" | |
| fi | |
| fi | |
| done |