Skip to content

Commit 6c6a7c1

Browse files
docs: create proper contributing guidelines
1 parent c7bcecd commit 6c6a7c1

File tree

1 file changed

+376
-0
lines changed

1 file changed

+376
-0
lines changed

CONTRIBUTING.md

Lines changed: 376 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,376 @@
1+
# Contributing to @stencil/eslint-plugin
2+
3+
Thank you for your interest in contributing to the Stencil ESLint Plugin! This guide will help you get started with development, testing, and submitting contributions.
4+
5+
## 📋 Table of Contents
6+
7+
- [Development Setup](#development-setup)
8+
- [Project Structure](#project-structure)
9+
- [Creating New Rules](#creating-new-rules)
10+
- [Testing](#testing)
11+
- [Code Standards](#code-standards)
12+
- [Submitting Changes](#submitting-changes)
13+
- [Release Process](#release-process)
14+
15+
## 🚀 Development Setup
16+
17+
### Prerequisites
18+
19+
- **Node.js**: >=22.13.1 (for development)
20+
- **npm**: Latest version recommended
21+
- **TypeScript**: Knowledge of TypeScript is essential
22+
- **ESLint**: Understanding of ESLint rule development
23+
24+
### Getting Started
25+
26+
1. **Fork and Clone**
27+
```bash
28+
git clone https://github.com/YOUR_USERNAME/eslint-plugin.git
29+
cd eslint-plugin
30+
```
31+
32+
2. **Install Dependencies**
33+
```bash
34+
npm ci
35+
```
36+
37+
3. **Build the Project**
38+
```bash
39+
npm run build
40+
```
41+
42+
4. **Run Tests**
43+
```bash
44+
npm test
45+
```
46+
47+
5. **Watch Mode for Development**
48+
```bash
49+
npm run watch
50+
```
51+
52+
## 📁 Project Structure
53+
54+
```
55+
src/
56+
├── configs/ # ESLint configuration presets
57+
│ ├── base.ts
58+
│ ├── recommended.ts
59+
│ └── strict.ts
60+
├── rules/ # ESLint rule implementations
61+
│ ├── async-methods.ts
62+
│ ├── ban-default-true.ts
63+
│ └── ...
64+
├── utils.ts # Shared utilities for rule development
65+
└── index.ts # Main plugin entry point
66+
67+
tests/
68+
├── rules/ # Rule test suites
69+
│ ├── async-methods/
70+
│ │ ├── async-methods.test.ts
71+
│ │ ├── async-methods.good.tsx # Valid code examples
72+
│ │ └── async-methods.wrong.tsx # Invalid code examples
73+
│ └── ...
74+
└── rule-tester.ts # Shared test configuration
75+
76+
docs/ # Rule documentation
77+
├── async-methods.md
78+
├── ban-default-true.md
79+
└── ...
80+
```
81+
82+
## 🛠️ Creating New Rules
83+
84+
### 1. Rule Implementation
85+
86+
Create your rule file in `src/rules/your-rule-name.ts`:
87+
88+
```typescript
89+
import type { Rule } from 'eslint';
90+
import { stencilComponentContext } from '../utils';
91+
92+
const rule: Rule.RuleModule = {
93+
meta: {
94+
docs: {
95+
description: 'Brief description of what this rule does.',
96+
category: 'Possible Errors', // or 'Best Practices', 'Stylistic Issues'
97+
recommended: true // or false
98+
},
99+
schema: [], // JSON schema for rule options
100+
type: 'problem', // 'problem', 'suggestion', or 'layout'
101+
fixable: 'code' // Optional: 'code' or 'whitespace' if rule is auto-fixable
102+
},
103+
104+
create(context): Rule.RuleListener {
105+
const stencil = stencilComponentContext();
106+
107+
return {
108+
...stencil.rules,
109+
// Your rule logic here
110+
'SelectorNode': (node: any) => {
111+
if (!stencil.isComponent()) {
112+
return;
113+
}
114+
115+
// Rule implementation
116+
context.report({
117+
node,
118+
message: 'Your error message here',
119+
fix(fixer) {
120+
// Optional: provide auto-fix
121+
return fixer.replaceText(node, 'corrected code');
122+
}
123+
});
124+
}
125+
};
126+
}
127+
};
128+
129+
export default rule;
130+
```
131+
132+
### 2. Add Rule to Index
133+
134+
Update `src/rules/index.ts`:
135+
136+
```typescript
137+
import yourRuleName from './your-rule-name';
138+
139+
export default {
140+
// ... existing rules
141+
'your-rule-name': yourRuleName,
142+
};
143+
```
144+
145+
### 3. Add to Configurations
146+
147+
Update the appropriate config files in `src/configs/` to include your rule:
148+
149+
- `base.ts` - Essential rules
150+
- `recommended.ts` - Recommended rules
151+
- `strict.ts` - Strict rules
152+
153+
### 4. Create Documentation
154+
155+
Create `docs/your-rule-name.md` with:
156+
157+
````markdown
158+
# your-rule-name
159+
160+
Brief description of the rule.
161+
162+
## Rule Details
163+
164+
Detailed explanation of what the rule checks for.
165+
166+
## Examples
167+
168+
### ❌ Incorrect
169+
170+
```tsx
171+
// Bad code example
172+
```
173+
174+
### ✅ Correct
175+
176+
```tsx
177+
// Good code example
178+
```
179+
180+
## Options
181+
182+
If your rule accepts options, document them here.
183+
184+
## When Not To Use It
185+
186+
Explain scenarios where this rule might not be applicable.
187+
````
188+
189+
### 5. Update README
190+
191+
Add your rule to the "Supported Rules" section in `README.md`.
192+
193+
## 🧪 Testing
194+
195+
### Test Structure
196+
197+
Each rule should have comprehensive tests in `tests/rules/your-rule-name/`:
198+
199+
1. **`your-rule-name.test.ts`** - Main test file
200+
2. **`your-rule-name.good.tsx`** - Valid code examples
201+
3. **`your-rule-name.wrong.tsx`** - Invalid code examples
202+
4. **`your-rule-name.output.tsx`** - Expected output after auto-fix (if applicable)
203+
204+
### Test Implementation
205+
206+
```typescript
207+
import path from 'node:path';
208+
import fs from 'node:fs';
209+
import { test } from 'vitest';
210+
import { ruleTester } from '../rule-tester';
211+
import rule from '../../../src/rules/your-rule-name';
212+
213+
test('your-rule-name', () => {
214+
const files = {
215+
good: path.resolve(__dirname, 'your-rule-name.good.tsx'),
216+
wrong: path.resolve(__dirname, 'your-rule-name.wrong.tsx'),
217+
output: path.resolve(__dirname, 'your-rule-name.output.tsx') // if fixable
218+
};
219+
220+
ruleTester.run('your-rule-name', rule, {
221+
valid: [
222+
{
223+
code: fs.readFileSync(files.good, 'utf8'),
224+
filename: files.good
225+
}
226+
],
227+
invalid: [
228+
{
229+
code: fs.readFileSync(files.wrong, 'utf8'),
230+
filename: files.wrong,
231+
errors: 1, // Expected number of errors
232+
output: fs.readFileSync(files.output, 'utf8') // if fixable
233+
}
234+
]
235+
});
236+
});
237+
```
238+
239+
### Running Tests
240+
241+
```bash
242+
# Run all tests
243+
npm test
244+
245+
# Run tests with coverage
246+
npm test -- --coverage
247+
248+
# Run specific test
249+
npm test -- async-methods
250+
```
251+
252+
The project enforces code coverage thresholds that must be maintained.
253+
254+
## 📝 Code Standards
255+
256+
### TypeScript
257+
258+
- Use strict TypeScript configuration
259+
- Provide proper type annotations
260+
- Use ESLint's type definitions from `@types/eslint`
261+
262+
### Code Style
263+
264+
- Follow existing code patterns in the project
265+
- Use meaningful variable and function names
266+
- Add JSDoc comments for complex logic
267+
- Use the Stencil utilities from `../utils` when possible
268+
269+
### Stencil-Specific Guidelines
270+
271+
- Use `stencilComponentContext()` to ensure rules only apply to Stencil components
272+
- Leverage TypeScript's type checker for accurate analysis
273+
- Consider Stencil decorators: `@Component`, `@Prop`, `@State`, `@Method`, `@Event`, `@Listen`, `@Watch`, `@Element`
274+
275+
## 📤 Submitting Changes
276+
277+
### Pull Request Process
278+
279+
1. **Create a Branch**
280+
```bash
281+
git checkout -b feature/your-rule-name
282+
# or
283+
git checkout -b fix/issue-description
284+
```
285+
286+
2. **Make Your Changes**
287+
- Implement your rule
288+
- Add comprehensive tests
289+
- Update documentation
290+
- Ensure tests pass and coverage meets requirements
291+
292+
3. **Commit Your Changes**
293+
```bash
294+
git add .
295+
git commit -m "feat: add your-rule-name rule"
296+
# or
297+
git commit -m "fix: resolve issue with existing-rule"
298+
```
299+
300+
4. **Push and Create PR**
301+
```bash
302+
git push origin feature/your-rule-name
303+
```
304+
305+
### PR Requirements
306+
307+
**Required for all PRs:**
308+
- [ ] Tests pass (`npm test`)
309+
- [ ] Code builds successfully (`npm run build`)
310+
- [ ] New rules include comprehensive tests
311+
- [ ] Documentation is updated (README.md, docs/, etc.)
312+
- [ ] Code follows existing patterns and style
313+
314+
**For new rules:**
315+
- [ ] Rule implementation in `src/rules/`
316+
- [ ] Tests with good/wrong/output examples
317+
- [ ] Documentation in `docs/`
318+
- [ ] Added to appropriate configs
319+
- [ ] Added to README.md rule list
320+
321+
### CI/CD
322+
323+
The project uses GitHub Actions for:
324+
- **[Build & Test](https://github.com/stenciljs/eslint-plugin/blob/main/.github/workflows/main.yml)**: Runs on Node.js 20, 22, 24 across Ubuntu and Windows
325+
- **Coverage**: Ensures code coverage thresholds are met
326+
- **[Automated Releases](https://github.com/stenciljs/eslint-plugin/blob/main/.github/workflows/release.yml)**: Handles version bumping and npm publishing
327+
328+
## 🚀 Release Process
329+
330+
Releases are handled through GitHub Actions and are restricted to maintainers.
331+
332+
### Release Types
333+
334+
- **Patch** (`1.0.1`): Bug fixes and minor improvements
335+
- **Minor** (`1.1.0`): New features, new rules
336+
- **Major** (`2.0.0`): Breaking changes
337+
338+
### Release Workflow
339+
340+
1. **Prepare Release**
341+
- Ensure all PRs are merged to `main`
342+
- Verify all tests pass
343+
- Review changelog and breaking changes
344+
345+
2. **Trigger Release**
346+
- Go to [GitHub Actions](https://github.com/stenciljs/eslint-plugin/actions)["Release Eslint Stencil"](https://github.com/stenciljs/eslint-plugin/actions/workflows/release.yml)
347+
- Choose release type (patch/minor/major)
348+
- Choose "no" for dev release (unless testing)
349+
- Run workflow
350+
351+
3. **Post-Release**
352+
- Verify npm package is published
353+
- Check GitHub release is created
354+
- Update any dependent projects
355+
356+
### Dev Releases
357+
358+
For testing purposes, maintainers can create dev releases:
359+
- Set "devRelease" to "yes" in the workflow
360+
- Creates a version like `1.1.0-dev.1677185104.7c87e34`
361+
- Published with `dev` tag on npm
362+
363+
## 🆘 Getting Help
364+
365+
- **Issues**: Check existing [GitHub Issues](https://github.com/stenciljs/eslint-plugin/issues)
366+
- **Discord**: Join our [Discord community](https://chat.stenciljs.com) for questions and discussions
367+
- **ESLint Docs**: [ESLint Rule Guidelines](https://eslint.org/docs/developer-guide/working-with-rules)
368+
- **Stencil Docs**: [Stencil Documentation](https://stenciljs.com/docs/introduction)
369+
370+
## 🙏 Thank You
371+
372+
Your contributions help make Stencil development better for everyone. Whether it's a bug fix, new rule, or documentation improvement, every contribution is valued!
373+
374+
---
375+
376+
For questions about this contributing guide, please open an issue or discussion in the repository.

0 commit comments

Comments
 (0)