Skip to content
Open
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
54 changes: 35 additions & 19 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,47 @@ Always reference these instructions first and fallback to search or bash command
## Working Effectively

### Bootstrap and Setup

- Clone the repository
- `npm install` -- takes 1-30 seconds depending on npm cache state. Works with Node.js 20.x but shows engine warnings (expects Node.js 22.x)
- Create `.env` file for local development:
```bash
echo 'APP_ID=12345
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
[valid PEM private key content]
-----END RSA PRIVATE KEY-----"
WEBHOOK_SECRET=test_webhook_secret_123
PORT=3000' > .env
```
```bash
echo 'APP_ID=12345
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
[valid PEM private key content]
-----END RSA PRIVATE KEY-----"
WEBHOOK_SECRET=test_webhook_secret_123
PORT=3000' > .env
```

### Build and Test

- `npm run lint` -- takes ~1.5 seconds. NEVER CANCEL. Uses ESLint with eslint-config-eslint
- `npm test` -- takes ~3 seconds. NEVER CANCEL. Runs Jest with 284 tests achieving 98.31% coverage
- Run the web server: `npm start` -- starts immediately on port 3000
- Health check: `curl http://localhost:3000/ping` returns "PONG" in ~1.6ms

### Environment Requirements

- Node.js 22.x preferred (works on 20.x with warnings)
- npm 10.x
- Environment variables for server operation:
- `APP_ID`: GitHub app ID (can be dummy value like 12345 for local testing)
- `PRIVATE_KEY`: Valid PEM private key (required format, can be test key for local development)
- `WEBHOOK_SECRET`: Webhook secret (can be dummy value for local testing)
- `PORT`: Server port (optional, defaults to 3000)
- `APP_ID`: GitHub app ID (can be dummy value like 12345 for local testing)
- `PRIVATE_KEY`: Valid PEM private key (required format, can be test key for local development)
- `WEBHOOK_SECRET`: Webhook secret (can be dummy value for local testing)
- `PORT`: Server port (optional, defaults to 3000)

## Validation

### Manual Testing Requirements

- ALWAYS run the full test suite after making changes: `npm test`
- ALWAYS run linting before committing: `npm run lint`
- Test server startup: `npm start` and verify health check responds: `curl http://localhost:3000/ping`
- For plugin changes, run relevant test files: `npm test tests/plugins/[plugin-name]/index.js`

### Critical Timing Requirements

- **NEVER CANCEL** any commands - all operations complete quickly
- npm install: 1-30 seconds (set timeout to 60+ seconds)
- npm test: ~3 seconds (set timeout to 30+ seconds)
Expand All @@ -52,6 +57,7 @@ Always reference these instructions first and fallback to search or bash command
## Common Tasks

### Plugin Development

The bot uses a plugin architecture with 6 core plugins in `src/plugins/`:

1. **auto-assign** (`src/plugins/auto-assign/index.js`): Auto-assigns issues to users who indicate willingness to submit PRs
Expand All @@ -62,13 +68,15 @@ The bot uses a plugin architecture with 6 core plugins in `src/plugins/`:
6. **wip** (`src/plugins/wip/index.js`): Handles work-in-progress PR status based on title/labels

### Adding New Plugins

1. Create plugin file in `src/plugins/[plugin-name]/index.js`
2. Add plugin to exports in `src/plugins/index.js`
3. Add plugin to enabled list in `src/app.js`
4. Create tests in `tests/plugins/[plugin-name]/index.js`
5. Follow existing plugin patterns using Probot event handlers

### File Structure Reference

```
src/
├── app.js # Main application entry point
Expand Down Expand Up @@ -98,15 +106,17 @@ docs/
```

### Key Configuration Files

- `package.json`: Dependencies, scripts, Jest config
- `eslint.config.js`: ESLint configuration using eslint-config-eslint
- `.editorconfig`: Code formatting rules
- `Procfile`: Production deployment config for Dokku
- `.gitignore`: Excludes node_modules, coverage, .env, *.pem files
- `.gitignore`: Excludes node_modules, coverage, .env, \*.pem files

### Common Command Outputs

#### Repository Root Files

```bash
$ ls -la
.editorconfig
Expand All @@ -127,18 +137,20 @@ tests/
```

#### Package.json Scripts

```json
{
"scripts": {
"lint": "eslint .",
"lint:fix": "npm run lint -- --fix",
"start": "node ./src/app.js",
"test": "jest --colors --verbose --coverage"
}
"scripts": {
"lint": "eslint .",
"lint:fix": "npm run lint -- --fix",
"start": "node ./src/app.js",
"test": "jest --colors --verbose --coverage"
}
}
```

#### Test Coverage Summary

```
All files | 98.31 | 93.1 | 98.36 | 98.21 |
Test Suites: 6 passed, 6 total
Expand All @@ -149,21 +161,25 @@ Time: ~3 seconds
## Troubleshooting

### Node.js Version Warnings

- Repository expects Node.js 22.x but works on 20.x with warnings
- Engine warnings are normal and do not prevent functionality
- All commands and tests work correctly despite version mismatch

### Server Won't Start

- Ensure `.env` file exists with required environment variables
- `PRIVATE_KEY` must be valid PEM format (can be test key for local development)
- Server defaults to port 3000, check for port conflicts

### Test Failures

- Run `npm install` to ensure dependencies are current
- Check that changes don't break existing plugin functionality
- Verify new tests follow existing patterns in `tests/plugins/` structure

### Deployment Notes

- Production deployment uses Dokku to github-bot.eslint.org
- Health check endpoint: https://github-bot.eslint.org/ping
- Webhook URL: /api/github/webhooks (Probot default)
Expand Down
85 changes: 50 additions & 35 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,38 +1,53 @@
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
push:
branches:
- main
pull_request:
branches:
- main
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22.x
- name: Install dependencies
run: npm install
- name: Lint files
run: npm run lint
test:
name: Test
strategy:
matrix:
os: [ubuntu-latest]
node: [22.x]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node }}
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22.x
- name: Install dependencies
run: npm install
- name: Lint files
run: npm run lint

format:
name: File Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Node.js
uses: actions/setup-node@v6
with:
node-version: 22.x
- name: Install dependencies
run: npm install
- name: Prettier Check
run: npm run fmt:check

test:
name: Test
strategy:
matrix:
os: [ubuntu-latest]
node: [22.x]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node }}
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
32 changes: 16 additions & 16 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
name: deploy

on:
push:
branches:
- main
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Cloning repo
uses: actions/checkout@v6
with:
fetch-depth: 0
deploy:
runs-on: ubuntu-latest
steps:
- name: Cloning repo
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Push to dokku
uses: dokku/github-action@master
with:
branch: main
git_remote_url: 'ssh://dokku@github-bot.eslint.org/eslint-github-bot'
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Push to dokku
uses: dokku/github-action@master
with:
branch: main
git_remote_url: "ssh://dokku@github-bot.eslint.org/eslint-github-bot"
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
coverage/
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ This project adheres to the [JS Foundation Code of Conduct](https://js.foundatio

## Filing Issues

* To report a security vulnerability in `eslint-github-bot`, please use our [HackerOne program](https://hackerone.com/eslint).
* To report an issue that does not have security impact, please [create an issue on GitHub](https://github.com/eslint/eslint-github-bot/issues/new).
* To create a feature request, [create an issue on GitHub](https://github.com/eslint/eslint-github-bot/issues/new).
- To report a security vulnerability in `eslint-github-bot`, please use our [HackerOne program](https://hackerone.com/eslint).
- To report an issue that does not have security impact, please [create an issue on GitHub](https://github.com/eslint/eslint-github-bot/issues/new).
- To create a feature request, [create an issue on GitHub](https://github.com/eslint/eslint-github-bot/issues/new).

Please keep in mind that `eslint-github-bot` is primarily intended for the ESLint team's use cases. You're welcome to use the code for your own purposes, but we are unlikely to accept a feature request unless we would use the feature for the ESLint team's repositories.

Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@

## Environment Variables:

* `APP_ID` (required): The numeric GitHub app ID
* `PRIVATE_KEY` (required): the contents of the private key you downloaded after creating the app.
* `WEBHOOK_SECRET` (required): Secret setup for GitHub webhook or you generated when you created the app.
* `PORT`: Port for web server _(optional, defaults to 8000)_.
- `APP_ID` (required): The numeric GitHub app ID
- `PRIVATE_KEY` (required): the contents of the private key you downloaded after creating the app.
- `WEBHOOK_SECRET` (required): Secret setup for GitHub webhook or you generated when you created the app.
- `PORT`: Port for web server _(optional, defaults to 8000)_.

## :wrench: Setup

* Clone this repo
* `npm install`
* `npm test`
- Clone this repo
- `npm install`
- `npm test`

To start the server locally, you'll need:

* A PEM file
* A `.env` file that specifies the required environment variables
- A PEM file
- A `.env` file that specifies the required environment variables

The `APP_ID` and `WEBHOOK_SECRET` need to be present but need not be the registered application ID or webhook secret to start the server. `PRIVATE_KEY` must be a valid PEM private key.

Expand Down
48 changes: 24 additions & 24 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,28 @@ const eslintConfigESLint = require("eslint-config-eslint/cjs");
const globals = require("globals");

module.exports = defineConfig([
globalIgnores(["coverage/"]),
eslintConfigESLint,
{
rules: {
camelcase: ["error", { properties: "never" }],
}
},
{
files: ["eslint.config.js"],
rules: {
"n/no-unpublished-require": "off"
}
},
{
files: ["tests/**/*.test.js"],
languageOptions: {
globals: {
...globals.jest
}
},
rules: {
"n/no-unpublished-require": "off"
}
}
globalIgnores(["coverage/"]),
eslintConfigESLint,
{
rules: {
camelcase: ["error", { properties: "never" }],
},
},
{
files: ["eslint.config.js"],
rules: {
"n/no-unpublished-require": "off",
},
},
{
files: ["tests/**/*.test.js"],
languageOptions: {
globals: {
...globals.jest,
},
},
rules: {
"n/no-unpublished-require": "off",
},
},
]);
Loading
Loading