Skip to content

Conversation

@ulrikandersen
Copy link
Contributor

@ulrikandersen ulrikandersen commented Dec 10, 2025

Description

Show a visual indicator (orange dot with tooltip) on specs that have been modified in the current PR. Only specs whose filenames appear in the PR's changed files list will display the indicator.

Motivation and Context

Users needed a way to quickly identify which specs in a branch have changes compared to the base branch. This feature adds a subtle visual indicator that helps users focus on the modified specs.

Screenshots (if appropriate):

Skærmbillede 2025-12-10 kl  18 49 20

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Show a visual indicator (orange dot with tooltip) on specs that have
been modified in the current PR. Only specs whose filenames appear in
the PR's changed files list will display the indicator.

- Fetch changed files from PR via GraphQL
- Add changedFiles to GitHubRepositoryRef type
- Only set diffURL on specs in changedFiles
- Display subtle orange dot with "Has changes" tooltip
Copilot AI review requested due to automatic review settings December 10, 2025 17:49
@github-actions
Copy link

⚠️ It looks like .env.example has changed. Remember to update the Setting Environment Variables article accordingly.

@ulrikandersen ulrikandersen changed the base branch from main to develop December 10, 2025 17:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a comprehensive diff sidebar feature that displays changes between PR branches and their base branch. The feature includes visual indicators on specs that have changes, a dedicated sidebar showing the list of changes with severity levels, and integration with the oasdiff CLI tool for OpenAPI spec comparison.

Key Changes

  • New diff sidebar UI: Adds a right-side drawer with components to display, filter, and view detailed diff changes
  • PR data integration: Fetches open PR information via GitHub GraphQL API to identify changed files in each branch
  • Diff calculation: Implements OasDiffCalculator using the external oasdiff CLI tool with URL validation for security
  • Visual indicators: Shows orange dot badges on specs with changes in the version selector

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/features/sidebar/view/internal/tertiary/RightContainer.tsx New right sidebar container with responsive drawer (temporary/persistent variants)
src/features/sidebar/view/internal/secondary/Container.tsx Updates secondary container to support offsetting content for diff sidebar
src/features/sidebar/view/internal/diffbar/* New diff sidebar components for displaying change list, dialogs, and level indicators
src/features/sidebar/data/useDiff.ts New hook to fetch and manage diff data from API
src/features/sidebar/data/useDiffbarOpen.ts New hook for diff sidebar open/close state
src/features/projects/data/GitHubRepositoryDataSource.ts Fetches PR data for all repositories to identify changed files per branch
src/features/projects/data/GitHubProjectDataSource.ts Maps PR changed files to specifications and generates diff URLs
src/features/diff/data/OasDiffCalculator.ts Implements diff calculation with URL validation and oasdiff CLI integration
src/app/api/diff/[owner]/[repository]/[...path]/route.ts New API endpoint to calculate and return diffs for a given spec
src/common/github/IGitHubClient.ts Adds compareCommitsWithBasehead method interface
src/common/github/GitHubClient.ts Implements GitHub API call to find merge base between commits
src/features/projects/view/toolbar/Selector.tsx Adds visual "has changes" indicator (orange dot) to selector items
src/features/projects/domain/ProjectNavigator.ts Adds per-segment URL encoding for navigation paths
Dockerfile Adds oasdiff CLI tool installation in Docker image
package.json & package-lock.json Dependency reordering (no functional changes)
.env.example Adds NEXT_PUBLIC_ENABLE_DIFF_SIDEBAR feature flag
README.md Documents oasdiff installation requirement
__test__/diff/OasDiffCalculator.test.ts Adds comprehensive tests for URL validation security
Comments suppressed due to low confidence (1)

src/features/projects/data/GitHubRepositoryDataSource.ts:189

  • The GraphQL query is vulnerable to injection attacks. The owner and name variables are directly interpolated into the query string without sanitization. An attacker could potentially inject malicious GraphQL code through repository names.

Consider using GraphQL variables instead of string interpolation:

const request = {
  query: `
    query PullRequests($repos: [RepositoryInput!]!) {
      # Use variables instead of string interpolation
    }
  `,
  variables: {
    repos: repositories.map(repo => ({ owner: repo.owner, name: repo.name }))
  }
}

Or at minimum, escape special characters in the owner and name values.

    const repoQueries = repositories
      .map((repo, index) => {
        return `
        repo${index}: repository(owner: "${repo.owner}", name: "${repo.name}") {
          pullRequests(first: 100, states: [OPEN]) {
            edges {
              node {
                number
                headRefName
                baseRefName
                baseRefOid
                files(first: 100) {
                  nodes {
                    path
                  }
                }
              }
            }
          }
        }`
      })
      .join("\n")

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

path: file.name,
ref: ref.id
}),
editURL: `https://github.com/${ownerName}/${repositoryName}/edit/${ref.name}/${encodeURIComponent(file.name)}`,
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

The editURL constructs a GitHub URL but only encodes the filename. The branch name (ref.name) should also be encoded in case it contains special characters like / or #.

Change to:

editURL: `https://github.com/${ownerName}/${repositoryName}/edit/${encodeURIComponent(ref.name)}/${encodeURIComponent(file.name)}`
Suggested change
editURL: `https://github.com/${ownerName}/${repositoryName}/edit/${ref.name}/${encodeURIComponent(file.name)}`,
editURL: `https://github.com/${ownerName}/${repositoryName}/edit/${encodeURIComponent(ref.name)}/${encodeURIComponent(file.name)}`,

Copilot uses AI. Check for mistakes.
}) : undefined,
diffBaseBranch: isFileChanged ? ref.baseRef : undefined,
diffBaseOid: isFileChanged ? ref.baseRefOid : undefined,
diffPrUrl: isFileChanged && ref.prNumber ? `https://github.com/${ownerName}/${repositoryName}/pull/${ref.prNumber}` : undefined,
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

Similarly, the PR URL should encode the owner and repository names to handle special characters properly.

Change to:

diffPrUrl: isFileChanged && ref.prNumber ? `https://github.com/${encodeURIComponent(ownerName)}/${encodeURIComponent(repositoryName)}/pull/${ref.prNumber}` : undefined
Suggested change
diffPrUrl: isFileChanged && ref.prNumber ? `https://github.com/${ownerName}/${repositoryName}/pull/${ref.prNumber}` : undefined,
diffPrUrl: isFileChanged && ref.prNumber ? `https://github.com/${encodeURIComponent(ownerName)}/${encodeURIComponent(repositoryName)}/pull/${ref.prNumber}` : undefined,

Copilot uses AI. Check for mistakes.
@ulrikandersen ulrikandersen added the enhancement New feature or request label Dec 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants