Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
name: PR Review

on:
pull_request:
branches: [main, dev]
types: [opened, edited, synchronize, reopened]
pull_request_target:
branches: [main, dev]
types: [opened]

permissions:
pull-requests: write
contents: read

jobs:
# ── 1. Validate PR title follows Conventional Commits ─────────────────────
lint-pr-title:
name: Lint PR Title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
feat
fix
docs
test
refactor
style
chore
ci
perf
requireScope: false
subjectPattern: ^(?![A-Z]).+$
subjectPatternError: |
The PR title "{subject}" should start with a lowercase letter.
Example: "feat: add dark mode" not "feat: Add dark mode"

# ── 2. Check PR description is not empty ──────────────────────────────────
check-pr-description:
name: Check PR Description
runs-on: ubuntu-latest
steps:
- name: Check description is not empty
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const body = context.payload.pull_request.body;
if (!body || body.trim().length < 20) {
core.setFailed(
'PR description is too short or empty. ' +
'Please describe what this PR does and why. ' +
'See CONTRIBUTING.md for guidelines.'
);
}

# ── 3. Auto-label PRs based on conventional commit prefix ─────────────────
auto-label:
name: Auto Label
runs-on: ubuntu-latest
steps:
- name: Apply label based on PR title prefix
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const title = context.payload.pull_request.title || '';
const pr = context.payload.pull_request.number;
const owner = context.repo.owner;
const repo = context.repo.repo;

const labelMap = {
'feat': 'enhancement',
'fix': 'bug',
'docs': 'documentation',
'test': 'testing',
'refactor': 'refactor',
'style': 'style',
'chore': 'chore',
'ci': 'ci/cd',
'perf': 'performance',
};

const match = title.match(/^(\w+)(?:\(.+\))?!?:/);
if (!match) return;

const label = labelMap[match[1]];
if (!label) return;

// Create label if it doesn't exist, then apply it
try {
await github.rest.issues.getLabel({ owner, repo, name: label });
} catch {
const colors = {
'enhancement': '84b6eb',
'bug': 'ee0701',
'documentation':'0075ca',
'testing': 'bfd4f2',
'refactor': 'e4e669',
'style': 'fef2c0',
'chore': 'c2e0c6',
'ci/cd': 'f9d0c4',
'performance': 'cfd3d7',
};
await github.rest.issues.createLabel({
owner, repo, name: label,
color: colors[label] || 'ededed',
});
}

await github.rest.issues.addLabels({
owner, repo, issue_number: pr, labels: [label],
});

# ── 4. Post a helpful checklist comment on first-time PR open ─────────────
welcome-comment:
name: Post Contribution Checklist
runs-on: ubuntu-latest
if: github.event.action == 'opened'
steps:
- name: Post checklist comment
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const author = context.payload.pull_request.user.login;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: `Thanks for the PR, @${author}! πŸŽ‰

Before this gets reviewed, please make sure the following are checked:

- [ ] Tests pass locally (\`npm test\`)
- [ ] Type check passes (\`npm run typecheck\`)
- [ ] Lint passes (\`npm run lint\`)
- [ ] New features include tests
- [ ] Documentation updated if needed
- [ ] PR targets the \`dev\` branch (not \`main\`)

> See [CONTRIBUTING.md](https://github.com/night-slayer18/leetcode-cli/blob/dev/CONTRIBUTING.md) for full guidelines.

The CI pipeline will also run build, test, lint, and typecheck automatically.`
});
202 changes: 202 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
# Contributing to leetcode-cli

Thank you for taking the time to contribute! This guide will help you get started.

---

## Table of Contents

- [Getting Started](#getting-started)
- [Development Setup](#development-setup)
- [Making Changes](#making-changes)
- [Commit Messages](#commit-messages)
- [Pull Request Guidelines](#pull-request-guidelines)
- [Running Tests](#running-tests)
- [Reporting Issues](#reporting-issues)

---

## Getting Started

1. **Fork** the repository on GitHub.
2. **Clone** your fork locally:
```bash
git clone https://github.com/<your-username>/leetcode-cli.git
cd leetcode-cli
```
3. Add the upstream remote so you can keep your fork in sync:
```bash
git remote add upstream https://github.com/night-slayer18/leetcode-cli.git
```

---

## Development Setup

**Requirements**: Node.js β‰₯ 20 and npm.

```bash
# Install dependencies
npm install

# Build the project
npm run build

# Run tests
npm test

# Type check
npm run typecheck

# Lint
npm run lint
```

For a live rebuild during development:
```bash
npm run dev
```

---

## Making Changes

1. **Sync with upstream** before branching:
```bash
git checkout dev
git pull upstream dev
```

2. **Create a branch** from `dev` (not `main`):
```bash
git checkout -b feat/my-feature
```
> All PRs should target the `dev` branch. `main` is release-only.

3. Make your changes, then **verify everything passes**:
```bash
npm run typecheck
npm run lint
npm run build
npm test
```

4. **Push** your branch and open a PR against `dev`.

---

## Commit Messages

We follow the **[Conventional Commits](https://www.conventionalcommits.org/)** specification. This keeps the changelog clean and makes it easy to understand what changed and why.

**Format:**
```
<type>(<optional scope>): <short description>

<optional body>
```

**Types:**

| Type | When to use |
|------|-------------|
| `feat` | A new feature |
| `fix` | A bug fix |
| `docs` | Documentation changes only |
| `test` | Adding or updating tests |
| `refactor` | Code change that is neither a fix nor a feature |
| `style` | Formatting, whitespace (no logic change) |
| `chore` | Build process, tooling, dependency updates |
| `ci` | CI/CD workflow changes |
| `perf` | Performance improvements |

**Examples:**
```bash
feat(tui): add dark mode toggle to config screen
fix(submit): handle null percentile from leetcode API
docs: update installation instructions for Windows
test(star-prompt): add coverage for 30-day reset window
chore: bump got to v14
```

> **Note on signing commits**: We recommend signing commits with GPG (`git commit -s`) as a good practice,
> but it is **not required**. Please don't let that stop you from contributing.

---

## Pull Request Guidelines

### Title

Your PR title must follow the same Conventional Commits format:
```
feat: add random problem filter by topic tag
fix(login): handle expired session gracefully
```

An automated check will validate this and fail if the format is incorrect.

### Description

Please include in your PR description:
- **What** the change does
- **Why** it is needed (link to an issue if applicable)
- **How** to test it manually (if applicable)

Empty PR descriptions are not accepted.

### Checklist

Before submitting, make sure:

- [ ] Tests pass locally (`npm test`)
- [ ] Type check passes (`npm run typecheck`)
- [ ] Lint passes (`npm run lint`)
- [ ] New features include tests
- [ ] Documentation is updated if needed
- [ ] PR targets the `dev` branch (not `main`)

### PR Size

Keep PRs focused. A PR that does one thing well is much easier to review than one that does five.
If your change is large, consider breaking it into smaller PRs.

---

## Running Tests

```bash
# Run all tests
npm test

# Run a specific test file
npx vitest run src/__tests__/commands/submit.test.ts

# Watch mode during development
npm run test:watch
```

When adding a new feature, please add tests. When fixing a bug, add a test that would have caught it.

---

## Reporting Issues

When filing a bug report, please include:

1. **CLI version** (`leetcode --version`)
2. **Operating system and version**
3. **Node.js version** (`node --version`)
4. **Steps to reproduce** the issue
5. **Expected** vs **actual** behaviour
6. Any **error output** from the terminal

For feature requests, describe the use case and what problem it solves for you.

---

## Questions?

Feel free to open a [Discussion](https://github.com/night-slayer18/leetcode-cli/discussions) if you have questions that don't fit an issue.

Thank you for contributing! ⭐
Loading