Remove definition wrapper to test performance #902
Workflow file for this run
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: Vale Linting | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| jobs: | |
| vale: | |
| name: Run Vale | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| checks: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '24' | |
| - name: Install dependencies | |
| run: | | |
| corepack enable | |
| corepack install | |
| pnpm install | |
| - name: Setup PATH for mdx2vast | |
| run: | | |
| echo "PATH=${{ github.workspace }}/node_modules/.bin:$PATH" >> $GITHUB_ENV | |
| - name: Get changed files | |
| id: changed-files | |
| run: | | |
| # Get changed markdown files, excluding specific directories and files | |
| git diff --name-only --diff-filter=ACMR \ | |
| ${{ github.event.pull_request.base.sha }} ${{ github.sha }} \ | |
| | grep -E '\.(mdx|md)$' \ | |
| | grep -v '^snippets/' \ | |
| | grep -v '^errors/' \ | |
| | grep -v '^\.skills/' \ | |
| | grep -v '^agent/cli-api.mdx$' \ | |
| | grep -v '^agent/cli.mdx$' \ | |
| | grep -v '^style-guide.mdx$' \ | |
| > changed_files.txt || true | |
| if [ -s changed_files.txt ]; then | |
| # Build JSON array of files using jq | |
| FILES_JSON=$(jq -R -s -c 'split("\n") | map(select(length > 0))' changed_files.txt) | |
| echo "vale_files=$FILES_JSON" >> $GITHUB_OUTPUT | |
| else | |
| echo "vale_files=" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Install Vale | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VALE_URL=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ | |
| "https://api.github.com/repos/errata-ai/vale/releases/latest" \ | |
| | jq -r '.assets[] | select(.name | contains("Linux_64-bit")) | .browser_download_url') | |
| wget -q "$VALE_URL" -O vale.tar.gz | |
| tar -xzf vale.tar.gz -C /usr/local/bin | |
| vale --version | |
| - name: Install jq and curl | |
| run: | | |
| sudo apt-get update && sudo apt-get install -y jq curl | |
| - name: Clean up outdated Vale comments | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| VALE_FILES: ${{ steps.changed-files.outputs.vale_files }} | |
| run: | | |
| PAGE=1 | |
| PER_PAGE=100 | |
| while true; do | |
| COMMENTS_PAGE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments?page=$PAGE&per_page=$PER_PAGE") | |
| if ! echo "$COMMENTS_PAGE" | jq -e 'type == "array"' > /dev/null 2>&1; then | |
| break | |
| fi | |
| PAGE_COUNT=$(echo "$COMMENTS_PAGE" | jq 'length') | |
| if [ "$PAGE_COUNT" -eq 0 ]; then | |
| break | |
| fi | |
| echo "$COMMENTS_PAGE" | jq -r '.[] | select((.body | contains("❌") or contains("⚠️")) and (.body | contains("**") and contains("(") and contains("):")) and (.user.login | test("github-actions"))) | .id' 2>/dev/null | while read -r comment_id; do | |
| if [ -n "$comment_id" ] && [ "$comment_id" != "null" ] && [ "$comment_id" != "" ]; then | |
| curl -s -w "%{http_code}" -o /dev/null -X DELETE \ | |
| -H "Authorization: token $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| "https://api.github.com/repos/${{ github.repository }}/pulls/comments/$comment_id" | |
| fi | |
| done | |
| PAGE=$((PAGE + 1)) | |
| done | |
| # When no markdown files changed, update the Style summary comment so it's not stale | |
| if [ -z "$VALE_FILES" ] || [ "$VALE_FILES" = "" ]; then | |
| SUMMARY_COMMENT_ID="" | |
| PAGE=1 | |
| while true; do | |
| ISSUE_COMMENTS_PAGE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments?page=$PAGE&per_page=100") | |
| if ! echo "$ISSUE_COMMENTS_PAGE" | jq -e 'type == "array"' > /dev/null 2>&1; then | |
| break | |
| fi | |
| PAGE_COUNT=$(echo "$ISSUE_COMMENTS_PAGE" | jq 'length') | |
| if [ "$PAGE_COUNT" -eq 0 ]; then | |
| break | |
| fi | |
| FOUND_ID=$(echo "$ISSUE_COMMENTS_PAGE" | jq -r '.[] | select(.body | contains("# Style linting summary")) | .id' 2>/dev/null | head -n1) | |
| if [ -n "$FOUND_ID" ] && [ "$FOUND_ID" != "null" ] && [ "$FOUND_ID" != "" ]; then | |
| SUMMARY_COMMENT_ID="$FOUND_ID" | |
| break | |
| fi | |
| PAGE=$((PAGE + 1)) | |
| done | |
| if [ -n "$SUMMARY_COMMENT_ID" ] && [ "$SUMMARY_COMMENT_ID" != "" ]; then | |
| SUMMARY_BODY=$(printf '# Style linting summary\n\nVale found no style issues in this PR. Great job!') | |
| curl -s -X PATCH \ | |
| -H "Authorization: token $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| -H "Content-Type: application/json" \ | |
| "https://api.github.com/repos/${{ github.repository }}/issues/comments/$SUMMARY_COMMENT_ID" \ | |
| -d "$(jq -n --arg body "$SUMMARY_BODY" '{body: $body}')" > /dev/null | |
| fi | |
| fi | |
| - name: Post individual Vale comments on PR lines | |
| if: steps.changed-files.outputs.vale_files != '' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Read files into space-separated string for Vale | |
| FILES=$(tr '\n' ' ' < changed_files.txt) | |
| # Verify we have files to check | |
| if [ -z "$FILES" ] || [ "$FILES" = " " ]; then | |
| exit 0 | |
| fi | |
| # Run Vale and save JSON output (MinAlertLevel is set in .vale.ini) | |
| vale --config=.vale.ini --output=JSON $FILES > vale_results.json || true | |
| # Filter Vale results to only include files that are actually in our changed files list | |
| # This prevents processing violations from files that Vale might have checked but aren't in the PR | |
| # Read changed files into a jq-friendly format | |
| jq -R -s 'split("\n") | map(select(length > 0))' changed_files.txt > changed_files_array.json | |
| # Filter Vale results to only include files in the changed files list | |
| jq --slurpfile changed changed_files_array.json ' | |
| . as $all | | |
| $changed[0] as $changed_files | | |
| ($all | keys | map(select(. as $file | ($changed_files | index($file) != null)))) as $valid_files | | |
| ($valid_files | map({key: ., value: $all[.]}) | from_entries) | |
| ' vale_results.json > vale_results_filtered.json | |
| # Use the filtered results | |
| mv vale_results_filtered.json vale_results.json | |
| # Check if there are any results | |
| TOTAL_ISSUES=$(jq '[.[] | length] | add // 0' vale_results.json 2>/dev/null || echo "0") | |
| # Get PR head SHA (needed for both posting comments and cleanup) | |
| PR_HEAD_SHA=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ | |
| "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}" \ | |
| | jq -r '.head.sha') | |
| # Initialize counters | |
| COMMENT_COUNT=0 | |
| SKIP_COUNT=0 | |
| ERROR_COUNT=0 | |
| WARNING_COUNT=0 | |
| # Find existing summary comment (don't delete it - we'll update it later) | |
| SUMMARY_COMMENT_ID="" | |
| PAGE=1 | |
| PER_PAGE=100 | |
| while true; do | |
| ISSUE_COMMENTS_PAGE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments?page=$PAGE&per_page=$PER_PAGE") | |
| if ! echo "$ISSUE_COMMENTS_PAGE" | jq -e 'type == "array"' > /dev/null 2>&1; then | |
| break | |
| fi | |
| PAGE_COUNT=$(echo "$ISSUE_COMMENTS_PAGE" | jq 'length') | |
| if [ "$PAGE_COUNT" -eq 0 ]; then | |
| break | |
| fi | |
| # Find summary comment (those with "# Style linting summary" in the body) | |
| FOUND_ID=$(echo "$ISSUE_COMMENTS_PAGE" | jq -r '.[] | select(.body | contains("# Style linting summary")) | .id' 2>/dev/null | head -n1) | |
| if [ -n "$FOUND_ID" ] && [ "$FOUND_ID" != "null" ] && [ "$FOUND_ID" != "" ]; then | |
| SUMMARY_COMMENT_ID="$FOUND_ID" | |
| break | |
| fi | |
| PAGE=$((PAGE + 1)) | |
| done | |
| # Get PR files to check which lines are actually changed | |
| curl -s -H "Authorization: token $GITHUB_TOKEN" \ | |
| "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" > pr_files.json | |
| # Function to check if a line is actually changed (added/modified) in the diff | |
| is_line_changed() { | |
| local file="$1" | |
| local target_line="$2" | |
| # Get the diff for this file | |
| local file_diff=$(jq -r --arg file "$file" '.[] | select(.filename == $file) | .patch // ""' pr_files.json) | |
| if [ -z "$file_diff" ] || [ "$file_diff" = "null" ] || [ "$file_diff" = "" ]; then | |
| return 1 | |
| fi | |
| local current_line=0 | |
| local line_changed=0 | |
| while IFS= read -r diff_line || [ -n "$diff_line" ]; do | |
| # Skip diff headers | |
| if [[ "$diff_line" =~ ^(@@|diff|index|---|\+\+\+) ]]; then | |
| if [[ "$diff_line" =~ ^@@ ]]; then | |
| # Extract starting line number from @@ -old_start,old_count +new_start,new_count @@ | |
| if [[ "$diff_line" =~ \+([0-9]+) ]]; then | |
| current_line="${BASH_REMATCH[1]}" | |
| current_line=$((current_line - 1)) | |
| fi | |
| fi | |
| continue | |
| fi | |
| # Check if this is an added/modified line (starts with +) | |
| if [[ "$diff_line" =~ ^\+ ]]; then | |
| current_line=$((current_line + 1)) | |
| if [ "$current_line" -eq "$target_line" ]; then | |
| line_changed=1 | |
| break | |
| fi | |
| # Count unchanged lines (context) but don't mark as changed | |
| elif [[ "$diff_line" =~ ^[[:space:]] ]]; then | |
| current_line=$((current_line + 1)) | |
| if [ "$current_line" -eq "$target_line" ]; then | |
| # This line is in the diff but not actually changed | |
| return 1 | |
| fi | |
| fi | |
| done <<< "$file_diff" | |
| return $((1 - line_changed)) | |
| } | |
| # Only process violations if there are any | |
| if [ -n "$TOTAL_ISSUES" ] && [ "$TOTAL_ISSUES" != "null" ] && [ "$TOTAL_ISSUES" -gt 0 ]; then | |
| # Process violations and group by file+line to combine multiple violations on same line | |
| jq -c --arg commit "$PR_HEAD_SHA" ' | |
| def severity_emoji(s): | |
| if s == "error" then "❌ " | |
| elif s == "warning" then "⚠️ " | |
| else "" end; | |
| # Group violations by file and line | |
| [to_entries[] | .key as $file | .value[] | { | |
| file: $file, | |
| line: (.Line | tonumber), | |
| rule: .Check, | |
| severity: .Severity, | |
| message: .Message, | |
| body: (severity_emoji(.Severity) + "**" + .Check + "** (" + .Severity + "): " + .Message), | |
| commit: $commit | |
| }] | | |
| group_by(.file + "|" + (.line | tostring)) | | |
| .[] | | |
| { | |
| file: .[0].file, | |
| line: .[0].line, | |
| commit: .[0].commit, | |
| violations: [.[] | {rule: .rule, severity: .severity, message: .message, body: .body}], | |
| combined_body: ([.[] | .body] | join("\n\n")) | |
| } | |
| ' vale_results.json > violations_to_post.json | |
| # Process each violation group (file+line combination) | |
| while read -r violation_group; do | |
| if [ -z "$violation_group" ]; then | |
| continue | |
| fi | |
| FILE=$(echo "$violation_group" | jq -r '.file') | |
| LINE=$(echo "$violation_group" | jq -r '.line') | |
| COMMIT=$(echo "$violation_group" | jq -r '.commit') | |
| COMBINED_BODY=$(echo "$violation_group" | jq -r '.combined_body') | |
| VIOLATION_COUNT=$(echo "$violation_group" | jq '.violations | length') | |
| # Check if this line is actually changed in the diff | |
| if ! is_line_changed "$FILE" "$LINE"; then | |
| SKIP_COUNT=$((SKIP_COUNT + VIOLATION_COUNT)) | |
| continue | |
| fi | |
| # Count errors and warnings for this violation group (on changed lines) | |
| VIOLATION_ERRORS=$(echo "$violation_group" | jq '[.violations[] | select(.severity == "error")] | length') | |
| VIOLATION_WARNINGS=$(echo "$violation_group" | jq '[.violations[] | select(.severity == "warning")] | length') | |
| ERROR_COUNT=$((ERROR_COUNT + VIOLATION_ERRORS)) | |
| WARNING_COUNT=$((WARNING_COUNT + VIOLATION_WARNINGS)) | |
| COMMENT_JSON=$(jq -n \ | |
| --arg path "$FILE" \ | |
| --argjson line "$LINE" \ | |
| --arg body "$COMBINED_BODY" \ | |
| --arg commit "$COMMIT" \ | |
| '{ | |
| path: $path, | |
| line: $line, | |
| side: "RIGHT", | |
| body: $body, | |
| commit_id: $commit | |
| }') | |
| RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \ | |
| -H "Authorization: token $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| -H "Content-Type: application/json" \ | |
| "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments" \ | |
| -d "$COMMENT_JSON") | |
| HTTP_CODE=$(echo "$RESPONSE" | tail -n1) | |
| if [ "$HTTP_CODE" = "201" ]; then | |
| COMMENT_COUNT=$((COMMENT_COUNT + VIOLATION_COUNT)) | |
| elif [ "$HTTP_CODE" = "422" ]; then | |
| SKIP_COUNT=$((SKIP_COUNT + VIOLATION_COUNT)) | |
| fi | |
| done < violations_to_post.json | |
| fi | |
| # Post or update summary comment (ERROR_COUNT and WARNING_COUNT were counted above from changed lines only) | |
| if [ "$ERROR_COUNT" -eq 0 ] && [ "$WARNING_COUNT" -eq 0 ]; then | |
| SUMMARY_BODY=$(printf "# Style linting summary\n\nVale found no style issues in this PR. Great job!") | |
| else | |
| SUMMARY_BODY=$(printf "# Style linting summary\n\nVale found ❌ %s error(s) and ⚠️ %s warning(s) in this PR. Please resolve all errors and review all warnings before merging.\n\nSee the [ngrok docs style guide](https://ngrok.com/docs/style-guide) for more information about style rules and best practices." "$ERROR_COUNT" "$WARNING_COUNT") | |
| fi | |
| SUMMARY_JSON=$(jq -n \ | |
| --arg body "$SUMMARY_BODY" \ | |
| '{body: $body}') | |
| # Update existing comment or create new one | |
| if [ -n "$SUMMARY_COMMENT_ID" ] && [ "$SUMMARY_COMMENT_ID" != "" ]; then | |
| # Update existing comment (this will show live update without refresh) | |
| curl -s -X PATCH \ | |
| -H "Authorization: token $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| -H "Content-Type: application/json" \ | |
| "https://api.github.com/repos/${{ github.repository }}/issues/comments/$SUMMARY_COMMENT_ID" \ | |
| -d "$SUMMARY_JSON" > /dev/null | |
| else | |
| # Create new comment | |
| curl -s -X POST \ | |
| -H "Authorization: token $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| -H "Content-Type: application/json" \ | |
| "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" \ | |
| -d "$SUMMARY_JSON" > /dev/null | |
| fi |