diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 000000000..3d194eb91 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,29 @@ +name: Lint + +on: + pull_request: + branches: ["main"] + + +jobs: + lint: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: "true" + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: '20.x' + cache: 'yarn' + cache-dependency-path: '**/yarn.lock' + + - name: Install + run: yarn install --frozen-lockfile + + - name: Lint + run: yarn lint diff --git a/package.json b/package.json index 4ba77e2db..55ea5bfe2 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "build": "cross-env SKIP_ENV_VALIDATION=1 yarn workspaces foreach --all --topological run build", "test": "yarn workspaces foreach --all --topological run test", + "lint": "yarn workspaces foreach --all --topological run lint", "dev": "concurrently --kill-others --names \"zoekt,worker,web,schemas\" 'yarn dev:zoekt' 'yarn dev:backend' 'yarn dev:web' 'yarn watch:schemas'", "with-env": "cross-env PATH=\"$PWD/bin:$PATH\" dotenv -e .env.development -c --", "dev:zoekt": "yarn with-env zoekt-webserver -index .sourcebot/index -rpc", diff --git a/packages/web/src/features/agents/review-agent/nodes/githubPrParser.test.ts b/packages/web/src/features/agents/review-agent/nodes/githubPrParser.test.ts index 66175a03e..d06cdd889 100644 --- a/packages/web/src/features/agents/review-agent/nodes/githubPrParser.test.ts +++ b/packages/web/src/features/agents/review-agent/nodes/githubPrParser.test.ts @@ -1,4 +1,5 @@ import { expect, test, vi, describe } from 'vitest'; +import { Octokit } from 'octokit'; import { githubPrParser } from './githubPrParser'; import { GitHubPullRequest } from '../types'; @@ -50,7 +51,7 @@ function makePullRequest(overrides: Partial<{ function makeMockOctokit(diffText: string) { return { request: vi.fn().mockResolvedValue({ data: diffText }), - } as any; + } as unknown as Octokit; } describe('githubPrParser', () => { @@ -80,7 +81,7 @@ describe('githubPrParser', () => { test('fetches diff using the pull request diff_url', async () => { const mockRequest = vi.fn().mockResolvedValue({ data: '' }); - const octokit = { request: mockRequest } as any; + const octokit = { request: mockRequest } as unknown as Octokit; const pr = makePullRequest({ diff_url: 'https://github.com/my-org/my-repo/pull/7.diff' }); await githubPrParser(octokit, pr); @@ -184,7 +185,7 @@ describe('githubPrParser', () => { test('throws when the diff request fails', async () => { const octokit = { request: vi.fn().mockRejectedValue(new Error('Network error')), - } as any; + } as unknown as Octokit; const pr = makePullRequest(); await expect(githubPrParser(octokit, pr)).rejects.toThrow('Network error'); diff --git a/packages/web/src/features/agents/review-agent/nodes/githubPushPrReviews.test.ts b/packages/web/src/features/agents/review-agent/nodes/githubPushPrReviews.test.ts index 9e80d31a9..210fffb44 100644 --- a/packages/web/src/features/agents/review-agent/nodes/githubPushPrReviews.test.ts +++ b/packages/web/src/features/agents/review-agent/nodes/githubPushPrReviews.test.ts @@ -1,4 +1,5 @@ import { expect, test, vi, describe } from 'vitest'; +import { Octokit } from 'octokit'; import { githubPushPrReviews } from './githubPushPrReviews'; import { sourcebot_pr_payload, sourcebot_file_diff_review } from '../types'; @@ -38,7 +39,7 @@ function makeMockOctokit(createReviewCommentResult: 'resolve' | 'reject' = 'reso : vi.fn().mockRejectedValue(new Error('Unprocessable Entity')), }, }, - } as any; + } as unknown as Octokit; } describe('githubPushPrReviews', () => { @@ -123,7 +124,7 @@ describe('githubPushPrReviews', () => { const mockCreate = vi.fn() .mockRejectedValueOnce(new Error('422')) .mockResolvedValueOnce({}); - const octokit = { rest: { pulls: { createReviewComment: mockCreate } } } as any; + const octokit = { rest: { pulls: { createReviewComment: mockCreate } } } as unknown as Octokit; await githubPushPrReviews(octokit, MOCK_PAYLOAD, twoReviews); diff --git a/packages/web/src/features/agents/review-agent/nodes/gitlabMrParser.test.ts b/packages/web/src/features/agents/review-agent/nodes/gitlabMrParser.test.ts index ba9fd3eae..b4f7d560a 100644 --- a/packages/web/src/features/agents/review-agent/nodes/gitlabMrParser.test.ts +++ b/packages/web/src/features/agents/review-agent/nodes/gitlabMrParser.test.ts @@ -1,7 +1,10 @@ import { expect, test, vi, describe } from 'vitest'; +import { Gitlab } from '@gitbeaker/rest'; import { gitlabMrParser } from './gitlabMrParser'; import { GitLabMergeRequestPayload } from '../types'; +type GitlabClient = InstanceType; + vi.mock('@sourcebot/shared', () => ({ createLogger: () => ({ debug: vi.fn(), @@ -51,7 +54,7 @@ function makeMockGitlabClient(allDiffsResult: unknown, mrOverrides: Partial { @@ -100,7 +103,7 @@ describe('gitlabMrParser', () => { test('calls show and allDiffs with the correct project id and MR iid', async () => { const mockShow = vi.fn().mockResolvedValue(MOCK_MR_API_RESPONSE); const mockAllDiffs = vi.fn().mockResolvedValue([]); - const client = { MergeRequests: { show: mockShow, allDiffs: mockAllDiffs } } as any; + const client = { MergeRequests: { show: mockShow, allDiffs: mockAllDiffs } } as unknown as GitlabClient; await gitlabMrParser(client, MOCK_MR_PAYLOAD, 'gitlab.com'); @@ -244,7 +247,7 @@ describe('gitlabMrParser', () => { show: vi.fn().mockResolvedValue(MOCK_MR_API_RESPONSE), allDiffs: vi.fn().mockRejectedValue(new Error('Network error')), }, - } as any; + } as unknown as GitlabClient; await expect(gitlabMrParser(client, MOCK_MR_PAYLOAD, 'gitlab.com')).rejects.toThrow('Network error'); }); diff --git a/packages/web/src/features/agents/review-agent/nodes/gitlabPushMrReviews.test.ts b/packages/web/src/features/agents/review-agent/nodes/gitlabPushMrReviews.test.ts index b26ecc53b..98caad2d9 100644 --- a/packages/web/src/features/agents/review-agent/nodes/gitlabPushMrReviews.test.ts +++ b/packages/web/src/features/agents/review-agent/nodes/gitlabPushMrReviews.test.ts @@ -1,7 +1,10 @@ import { expect, test, vi, describe } from 'vitest'; +import { Gitlab } from '@gitbeaker/rest'; import { gitlabPushMrReviews } from './gitlabPushMrReviews'; import { sourcebot_pr_payload, sourcebot_file_diff_review } from '../types'; +type GitlabClient = InstanceType; + vi.mock('@sourcebot/shared', () => ({ createLogger: () => ({ debug: vi.fn(), @@ -44,7 +47,7 @@ function makeMockClient(discussionResult: 'resolve' | 'reject' = 'resolve') { MergeRequestNotes: { create: vi.fn().mockResolvedValue({}), }, - } as any; + } as unknown as GitlabClient; } describe('gitlabPushMrReviews', () => { @@ -165,7 +168,7 @@ describe('gitlabPushMrReviews', () => { const client = { MergeRequestDiscussions: { create: mockCreate }, MergeRequestNotes: { create: vi.fn().mockResolvedValue({}) }, - } as any; + } as unknown as GitlabClient; await gitlabPushMrReviews(client, 101, MOCK_PAYLOAD, twoReviews); @@ -178,7 +181,7 @@ describe('gitlabPushMrReviews', () => { const client = { MergeRequestDiscussions: { create: vi.fn().mockRejectedValue(new Error('500')) }, MergeRequestNotes: { create: vi.fn().mockRejectedValue(new Error('500')) }, - } as any; + } as unknown as GitlabClient; await expect( gitlabPushMrReviews(client, 101, MOCK_PAYLOAD, SINGLE_REVIEW),