Skip to content

PR automation testing#7

Closed
chanwoo7 wants to merge 6 commits intomainfrom
ci/pr-ai-description
Closed

PR automation testing#7
chanwoo7 wants to merge 6 commits intomainfrom
ci/pr-ai-description

Conversation

@chanwoo7
Copy link
Member

@chanwoo7 chanwoo7 commented Mar 4, 2026

Summary by CodeRabbit

  • New Features

    • Automated AI-powered PR descriptions with diff-aware summaries, masked sensitive content, and conditional title/assignee/label updates.
    • Optional LangSmith tracing integration for run-level telemetry with resilient error handling and run-scoped helpers.
  • Tests

    • Comprehensive test suites for PR summary generation, diff handling, label/filter logic, truncation, JSON schema validation, and tracing behaviors.
  • Chores

    • CI workflow to run tests and generate AI PR descriptions; package updates to support tracing.

AI PR 요약

제목 제안

PR AI Description 기능 추가 및 LangSmith 트레이싱 통합

요약

이 PR은 PR AI 요약 생성 기능을 새로 도입하고, LangSmith 트레이싱 기능을 통합하여 PR 변경사항을 자동으로 분석하고 요약하는 기능을 구현합니다. GitHub Actions 워크플로우를 통해 PR 이벤트 발생 시 AI 기반 요약을 생성하고, PR 본문과 라벨, 담당자를 자동으로 업데이트합니다.

변경사항

  • [high] CI/CD: GitHub Actions 워크플로우(.github/workflows/pr-ai-description.yml) 추가로 PR AI 요약 자동 생성 프로세스 구현
  • [high] 스크립트: .github/scripts/pr-ai-description.mjs 및 관련 라이브러리(.github/scripts/pr-ai-description-lib.mjs, .github/scripts/langsmith-tracer.mjs) 추가로 AI 요약 생성 및 LangSmith 트레이싱 기능 구현
  • [medium] 테스트: .github/scripts/tests 디렉터리에 pr-ai-description 및 langsmith-tracer 관련 단위 테스트 추가
  • [low] 패키지: package.json에 langsmith 라이브러리 의존성 추가

영향도

  • API: medium
  • DB: low
  • Security: low
  • Performance: medium
  • Operations: medium
  • Tests: medium

체크리스트

  • GitHub Actions 워크플로우 정상 동작 확인
  • AI 요약 JSON 스키마 검증 통과
  • LangSmith 트레이싱 로그 정상 기록
  • PR 본문 및 라벨 자동 업데이트 기능 검증

리스크

  • OpenAI API 호출 실패 시 워크플로우 실패 가능성
  • GitHub 권한 부족 시 라벨 및 담당자 업데이트 실패 가능성
  • Diff 크기 제한 초과 시 요약 정확도 저하 가능성

메타

  • Diff Source: compare
  • Diff Bytes: 63072
  • Excluded Files: 1
  • Truncated: false
  • Assignees Added: chanwoo7
  • Labels Added: ⚙️ Setting, ⭐️ Feature, ✅ Test
  • Unknown Labels Ignored: 0

@coderabbitai
Copy link

coderabbitai bot commented Mar 4, 2026

📝 Walkthrough

Walkthrough

Adds a new AI-driven PR description system: a reusable PR description library, an orchestrating script that calls OpenAI and updates PRs, optional LangSmith tracing utilities, unit tests, a GitHub Actions workflow, and package.json additions for LangSmith.

Changes

Cohort / File(s) Summary
LangSmith Tracing
.github/scripts/langsmith-tracer.mjs, .github/scripts/__tests__/langsmith-tracer.spec.mjs
New trace config resolver and tracer factory with lifecycle helpers (startRun, endRun, failRun, withRun), SDK call wrapper, helpers (KV mapping, error formatting), and comprehensive tests covering enablement, endpoints, project/workspace propagation, success/failure flows, and logging.
PR Description Library
src/.github/scripts/pr-ai-description-lib.mjs, .github/scripts/pr-ai-description-lib.mjs, .github/scripts/__tests__/pr-ai-description-lib.spec.mjs
New full-featured utility library exporting markers, glob/path helpers, diff filtering/normalization, UTF‑8-safe truncation, masking, schema validation, summary rendering/upsertion, label/title helpers, and tests validating filtering, truncation/meta, schema rules, marker upsert, fallback logic, and label filtering.
PR Description Orchestrator
.github/scripts/pr-ai-description.mjs, .github/workflows/pr-ai-description.yml
New orchestrator script that fetches PR and labels, computes/filters diffs (compare API with git fallback), masks/truncates content, builds OpenAI prompt with a strict JSON schema, validates AI output, updates PR body/title/labels, writes step summary, and emits LangSmith sub-runs; workflow runs tests then executes the script on PR events.
Tests
.github/scripts/__tests__/*.spec.mjs
Added comprehensive unit tests for LangSmith tracer and PR AI description library covering enablement, endpoints, run lifecycle, config resolution, filtering, truncation, schema validation, upsert behavior, fallback logic, and label handling.
Dependencies
package.json
Adds langsmith@^0.5.7 to both dependencies and devDependencies.

Sequence Diagrams

sequenceDiagram
    participant GitHub as GitHub (Events & API)
    participant Script as PR AI Script
    participant OpenAI as OpenAI Chat API
    participant LangSmith as LangSmith (Optional)
    participant GH_Client as GitHub API Client

    GitHub->>Script: PR opened/reopened/updated
    Script->>Script: Init config, logging, tracing
    Script->>GH_Client: Fetch PR details & repo labels
    GH_Client-->>Script: Labels & PR metadata
    Script->>Script: Compute diff (compare API or git)
    Script->>Script: Filter files, mask secrets, truncate
    Script->>OpenAI: Send chat request with schema & diff
    alt AI Success
        OpenAI-->>Script: JSON summary
        Script->>Script: Validate & extract title/labels/summary
    else AI Failure
        OpenAI-->>Script: Error/timeout
        Script->>Script: Log & handle gracefully
    end
    Script->>GH_Client: Apply labels, update PR body/title
    GH_Client-->>Script: ACK
    opt LangSmith enabled
        Script->>LangSmith: create/update trace runs
        LangSmith-->>Script: Trace responses
    end
    Script->>GitHub: Write step summary
Loading
sequenceDiagram
    participant Caller as Caller
    participant Config as resolveLangSmithTraceConfig()
    participant Tracer as createLangSmithTracer()
    participant LangSmithClient as LangSmith SDK

    Caller->>Config: Read env
    Config-->>Caller: {enabled, reason, apiKey, endpoint, projectName, workspaceId}
    Caller->>Tracer: Initialize with env/logger/clientFactory
    alt Tracing enabled
        Tracer->>LangSmithClient: Create or use provided client
        LangSmithClient-->>Tracer: Client instance
    else Tracing disabled
        Tracer-->>Caller: No-op tracer
    end
    Caller->>Tracer: withRun({name,...}, executeFn)
    Tracer->>LangSmithClient: createRun(startPayload)
    LangSmithClient-->>Tracer: Run ID
    Tracer->>Caller: Execute function
    alt Success
        Caller-->>Tracer: Result
        Tracer->>LangSmithClient: updateRun(outputs, end_time)
    else Failure
        Caller-->>Tracer: Error
        Tracer->>LangSmithClient: updateRun(error, end_time)
    end
    LangSmithClient-->>Tracer: Ack
    Tracer-->>Caller: Return result or rethrow error
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 I hopped through diffs and trimmed each line,
Masked the secrets, kept the gist fine.
Traces now hum for every run,
AI summaries stitched, one by one.
Cheers — a rabbit’s job is done! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately describes the main changes: adding PR AI Description functionality and integrating LangSmith tracing, which aligns with the comprehensive changes across workflow, scripts, and test files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ci/pr-ai-description

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/scripts/pr-ai-description-lib.mjs:
- Around line 6-14: DEFAULT_EXCLUDE_GLOBS is missing common secret-bearing
filename patterns; update the array to include sensitive file globs (e.g.,
'.env*', '*.pem', '*.key', '*.p12', '*.crt', '*.asc', 'id_rsa', 'id_dsa',
'.aws/**', '.gnupg/**', '.ssh/**', '.docker/**', 'secrets/**', 'private*') so
any PR diff scanned for AI description generation (see pr-ai-description.mjs
usage surrounding DEFAULT_EXCLUDE_GLOBS) will skip these files; add the patterns
to the DEFAULT_EXCLUDE_GLOBS constant and ensure they are normalized as globs
consistent with existing entries.
- Around line 402-417: The maskSensitiveContent function's regexes are too
narrow; expand them to cover common key names (api_key, api-key, client_secret,
access_token, refresh_token, private_key, client_id, etc.) in
snake_case/kebab-case and mixed case by adding case-insensitive patterns (e.g.,
/(?:"?(?:password|secret|token|apiKey|api_key|api-key|client_secret|access_token|private_key|refresh_token|client_id)"?\s*[:=]\s*).../gim)
and add a dedicated multiline PEM/block masker that matches -----BEGIN [A-Z
]+-----[\s\S]*?-----END [A-Z ]+-----/gim to replace the entire block with
[REDACTED PEM]. Also widen the Bearer/Authorization rules to catch variants like
"authorization: bearer ..." and ensure all regexes use global and multiline
flags so replaceAll removes single- and multi-line credentials consistently;
update the existing replaceAll calls in maskSensitiveContent accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e17050c9-2fd4-4455-afdd-6045ddf061af

📥 Commits

Reviewing files that changed from the base of the PR and between a2f091f and a5d628f.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (7)
  • .github/scripts/__tests__/langsmith-tracer.spec.mjs
  • .github/scripts/__tests__/pr-ai-description-lib.spec.mjs
  • .github/scripts/langsmith-tracer.mjs
  • .github/scripts/pr-ai-description-lib.mjs
  • .github/scripts/pr-ai-description.mjs
  • .github/workflows/pr-ai-description.yml
  • package.json

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/scripts/pr-ai-description.mjs:
- Line 143: The file .github/scripts/pr-ai-description.mjs has Prettier
formatting violations (e.g., the line creating `const error = new
Error(\`github-api-error:${response.status}:${routePath}\`)` and other ranges
listed); run the project's formatter (prettier --write) or your editor's format
command on this file to fix all `prettier/prettier` errors, re-save the file,
and re-run lint/CI to ensure ranges (319-324, 350, 378-382, etc.) are cleared;
no code logic changes are needed—only apply Prettier formatting to the file
containing symbols like `error`, `response`, and `routePath`.
- Around line 459-465: AI_RESPONSE_JSON_SCHEMA's required array is missing the
'labels' entry which conflicts with the schema's declared properties and causes
OpenAI strict json_schema errors; update the AI_RESPONSE_JSON_SCHEMA definition
to include 'labels' in its required array (ensure the 'labels' property already
defined in the schema remains unchanged) so the schema's required list matches
declared properties used by the json_schema call in response_format.
- Line 22: Replace the hardcoded TARGET_ASSIGNEE constant with a configurable
value (read from process.env.TARGET_ASSIGNEE with a sensible default) so
assignee can be set per-environment, and update the assignee handling logic in
addAssignee to treat GitHub 422 responses as non-fatal: either extend
isPermissionError to consider status 422 or catch the 422 error in addAssignee,
log a warning including the error details, and continue without failing the
workflow (leave existing behavior for 401/403 intact). Ensure references to
TARGET_ASSIGNEE and addAssignee/isPermissionError are updated consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3de7286b-e5c7-4df9-854a-ffa5ddf47c87

📥 Commits

Reviewing files that changed from the base of the PR and between a5d628f and 3538147.

📒 Files selected for processing (1)
  • .github/scripts/pr-ai-description.mjs

@github-actions github-actions bot added ⚙️ Setting 개발환경 세팅 ✅ Test 테스트 관련 ⭐️ Feature 기능 개발 labels Mar 4, 2026
@github-actions github-actions bot changed the title Ci/pr ai description PR AI Description 기능 추가 및 LangSmith 트레이싱 통합 Mar 4, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
.github/scripts/pr-ai-description-lib.mjs (2)

6-14: ⚠️ Potential issue | 🟠 Major

Harden default exclusions to prevent accidental secret exfiltration.

This still omits common secret-bearing files at Line 6-Line 14, so sensitive diffs can be sent to external AI processing.

🔐 Proposed hardening
 export const DEFAULT_EXCLUDE_GLOBS = [
   'yarn.lock',
   'package-lock.json',
   'pnpm-lock.yaml',
   '**/*.snap',
   'dist/**',
   'coverage/**',
   '**/*.map',
+  '.env',
+  '.env.*',
+  '**/*.pem',
+  '**/*.key',
+  '**/*.p12',
+  '**/*.jks',
+  '**/*id_rsa*',
+  '**/*id_ed25519*',
+  '**/.aws/**',
+  '**/.ssh/**',
+  '**/secrets/**',
 ];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/scripts/pr-ai-description-lib.mjs around lines 6 - 14,
DEFAULT_EXCLUDE_GLOBS is too permissive and may allow secret-bearing files to be
sent; update the array to include common secret and credential patterns such as
.env and .env.* files, .npmrc, .netrc, .git-credentials, .docker/config.json,
AWS and cloud credentials (e.g., **/aws/credentials, **/gcloud/**), SSH keys and
known_hosts (e.g., **/.ssh/**, **/*.pem, **/*.key, **/*.crt), kube configs and
Helm secrets, and any secrets.* or *.secret.* patterns so these are never
included in AI-processing diffs. Modify the DEFAULT_EXCLUDE_GLOBS constant
accordingly and ensure patterns are broad (globstar) and account for dotfiles
and nested paths to prevent accidental exfiltration.

402-417: ⚠️ Potential issue | 🟠 Major

Broaden masking rules for common credential formats and PEM blocks.

maskSensitiveContent at Line 402-Line 417 remains too narrow and can miss frequent key variants and multiline private key blocks.

🛡️ Proposed masking expansion
   return text
     .replaceAll(/(Authorization\s*[:=]\s*)([^\n\r]+)/gi, '$1[REDACTED]')
     .replaceAll(/Bearer\s+[A-Za-z0-9\-._~+/]+=*/gi, 'Bearer [REDACTED]')
+    .replaceAll(
+      /-----BEGIN [A-Z0-9 ]+-----[\s\S]*?-----END [A-Z0-9 ]+-----/g,
+      '[REDACTED_PEM]',
+    )
     .replaceAll(
-      /(\"?(?:password|secret|token|apiKey)\"?\s*[:=]\s*)\"([^\"\n\r]*)\"/gi,
+      /(\"?(?:password|secret|token|api[_-]?key|client[_-]?secret|access[_-]?token|refresh[_-]?token|private[_-]?key|client[_-]?id)\"?\s*[:=]\s*)\"([^\"\n\r]*)\"/gi,
       '$1"[REDACTED]"',
     )
     .replaceAll(
-      /(\"?(?:password|secret|token|apiKey)\"?\s*[:=]\s*)([^\s,\n\r]+)/gi,
+      /(\"?(?:password|secret|token|api[_-]?key|client[_-]?secret|access[_-]?token|refresh[_-]?token|private[_-]?key|client[_-]?id)\"?\s*[:=]\s*)([^\s,\n\r]+)/gi,
       '$1[REDACTED]',
     );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/scripts/pr-ai-description-lib.mjs around lines 402 - 417, The
maskSensitiveContent function currently misses many credential name variants and
multiline PEM blocks; update its replacement rules to (1) expand the key-name
patterns in the existing regexes used in maskSensitiveContent to include common
variants like api_key, api-key, client_secret, clientId, access_token,
refresh_token (case-insensitive, with optional quotes and separators), (2) add a
dedicated regex to detect and redact PEM/private-key blocks between "-----BEGIN
(RSA|PRIVATE|ENCRYPTED|OPENSSH) KEY-----" and the matching "-----END ...
KEY-----" using a multiline/dotall-aware pattern, and (3) ensure regex flags
include global and dotAll (or [\s\S] as needed) so multiline secrets are
captured; apply these changes within maskSensitiveContent so existing replaceAll
calls are extended/replaced to cover these variants and PEM blocks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/scripts/pr-ai-description-lib.mjs:
- Around line 30-706: Prettier/formatting errors are failing CI; run the
repository formatter (Prettier) on this file and re-save so formatting matches
project rules (fixes around declarations like IMPACT_KEYS, functions
globToRegExp, parseAdditionalExcludeGlobs, renderTruncationNotice/composeDiff,
buildLimitedDiff, maskSensitiveContent, renderSummaryBlock, upsertSummaryBlock,
filterKnownLabels and shouldApplyTitle), then commit the formatted file so
ESLint/Prettier violations (reported on lines near the functions above) are
resolved.
- Around line 645-697: The function filterKnownLabels currently assumes aiLabels
and repoLabelNames are iterable arrays and will throw if either is
null/undefined or not an array; update filterKnownLabels to defensively
normalize inputs by treating non-array values as empty arrays (e.g., if
!Array.isArray(repoLabelNames) set repoLabelNames = [] and likewise for
aiLabels) before the for...of loops, so the canonicalLabelMap and
label-processing loops never iterate over invalid values and the function
returns the existing shape ({ applicableLabels, unknownLabelsIgnoredCount })
safely.
- Around line 700-707: The function shouldApplyTitle calls labelNames.some and
can throw if labelNames is null/undefined; guard by normalizing labelNames to an
array (e.g., treat missing or non-array labelNames as [] ) before calling .some,
or add an early return when labelNames is falsy; update shouldApplyTitle to
reference the normalized array when checking for the 'ai-title-lock' label so
.some is never invoked on undefined.

---

Duplicate comments:
In @.github/scripts/pr-ai-description-lib.mjs:
- Around line 6-14: DEFAULT_EXCLUDE_GLOBS is too permissive and may allow
secret-bearing files to be sent; update the array to include common secret and
credential patterns such as .env and .env.* files, .npmrc, .netrc,
.git-credentials, .docker/config.json, AWS and cloud credentials (e.g.,
**/aws/credentials, **/gcloud/**), SSH keys and known_hosts (e.g., **/.ssh/**,
**/*.pem, **/*.key, **/*.crt), kube configs and Helm secrets, and any secrets.*
or *.secret.* patterns so these are never included in AI-processing diffs.
Modify the DEFAULT_EXCLUDE_GLOBS constant accordingly and ensure patterns are
broad (globstar) and account for dotfiles and nested paths to prevent accidental
exfiltration.
- Around line 402-417: The maskSensitiveContent function currently misses many
credential name variants and multiline PEM blocks; update its replacement rules
to (1) expand the key-name patterns in the existing regexes used in
maskSensitiveContent to include common variants like api_key, api-key,
client_secret, clientId, access_token, refresh_token (case-insensitive, with
optional quotes and separators), (2) add a dedicated regex to detect and redact
PEM/private-key blocks between "-----BEGIN (RSA|PRIVATE|ENCRYPTED|OPENSSH)
KEY-----" and the matching "-----END ... KEY-----" using a
multiline/dotall-aware pattern, and (3) ensure regex flags include global and
dotAll (or [\s\S] as needed) so multiline secrets are captured; apply these
changes within maskSensitiveContent so existing replaceAll calls are
extended/replaced to cover these variants and PEM blocks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 62d100fe-e4da-453d-ada6-3baf87d1c041

📥 Commits

Reviewing files that changed from the base of the PR and between 3538147 and f7cf032.

📒 Files selected for processing (1)
  • .github/scripts/pr-ai-description-lib.mjs

@chanwoo7 chanwoo7 closed this Mar 5, 2026
@chanwoo7 chanwoo7 changed the title PR AI Description 기능 추가 및 LangSmith 트레이싱 통합 PR automation testing Mar 5, 2026
@CaQuick CaQuick deleted a comment from coderabbitai bot Mar 5, 2026
@CaQuick CaQuick deleted a comment from coderabbitai bot Mar 5, 2026
@CaQuick CaQuick deleted a comment from coderabbitai bot Mar 5, 2026
@CaQuick CaQuick deleted a comment from coderabbitai bot Mar 5, 2026
@CaQuick CaQuick deleted a comment from coderabbitai bot Mar 5, 2026
@CaQuick CaQuick deleted a comment from coderabbitai bot Mar 5, 2026
@CaQuick CaQuick deleted a comment from coderabbitai bot Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⭐️ Feature 기능 개발 ⚙️ Setting 개발환경 세팅 ✅ Test 테스트 관련

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant