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
9 changes: 8 additions & 1 deletion .github/AUTOMATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ This repository uses **simple, lightweight GitHub Actions** to automate issue ma
## What's Automated

### 1. **Auto-Label Issues** (`.github/workflows/auto-label.yml`)

Runs when issues are opened or edited.

- Detects: bug, enhancement, documentation, question
- Marks incomplete issues with `needs-info` label
- No configuration needed - works out of the box

**Script**: `scripts/auto-label.js`

### 2. **Issue Reminders** (`.github/workflows/issue-reminder.yml`)

Runs every 12 hours.

- Finds open assigned issues inactive for 32+ hours
- Comments reminder once (avoids spam)
- Asks for blockers, progress, and ETA
Expand All @@ -23,6 +27,7 @@ Runs every 12 hours.
## Local Testing

### Test Auto-Label

```bash
export GITHUB_TOKEN="your_token"
export GITHUB_REPOSITORY_OWNER="your_username"
Expand All @@ -33,6 +38,7 @@ node scripts/auto-label.js
```

### Test Reminders

```bash
export GITHUB_TOKEN="your_token"
export GITHUB_REPOSITORY_OWNER="your_username"
Expand Down Expand Up @@ -71,11 +77,12 @@ scripts/
✓ **Easy to debug** - Transparent logging
✓ **No spam** - Reminds only once per issue
✓ **Maintainable** - <100 lines per script
✓ **Zero config** - Works immediately
✓ **Zero config** - Works immediately

## Future Additions

When you have more contributors, consider:

- Stale issue auto-closing (30+ days inactive)
- PR greetings for first-time contributors
- Automatic assignment rotation
Expand Down
10 changes: 10 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
## 📝 Description

<!-- Clear and concise description of what this PR does -->

## 🔗 Related Issues

<!-- Link to related issues: Fixes #123, Relates to #456 -->

Fixes #

## 📋 Type of Change

<!-- Mark the type of change this PR represents -->

- [ ] 🐛 Bug fix (non-breaking change which fixes an issue)
Expand All @@ -19,6 +22,7 @@ Fixes #
- [ ] 🧪 Test update

## 🔄 Changes Made

<!-- Detailed list of changes -->

- Change 1
Expand All @@ -28,24 +32,29 @@ Fixes #
## ✅ Testing

### How to Test

<!-- Steps to test your changes -->

1.
2.
3.

### Test Coverage

- [ ] Unit tests added/updated
- [ ] Integration tests added/updated
- [ ] E2E tests added/updated (if applicable)

## 📸 Screenshots (if applicable)

<!-- Add screenshots or GIFs showing the changes -->

## 🚀 Deployment Notes

<!-- Any special deployment steps or considerations? -->

## ⚠️ Breaking Changes

<!-- List any breaking changes -->

- None
Expand All @@ -63,6 +72,7 @@ Fixes #
- [ ] I have linked related issues

## 📝 Additional Context

<!-- Any other information that reviewers should know -->

---
Expand Down
18 changes: 15 additions & 3 deletions .github/scripts/auto-label.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ async function autoLabel() {
const labelsToAdd = [];

// Detect issue type
if (content.includes("bug") || content.includes("error") || content.includes("broken")) {
if (
content.includes("bug") ||
content.includes("error") ||
content.includes("broken")
) {
if (!currentLabels.includes("bug")) {
labelsToAdd.push("bug");
}
Expand All @@ -44,11 +48,19 @@ async function autoLabel() {
if (!currentLabels.includes("enhancement")) {
labelsToAdd.push("enhancement");
}
} else if (content.includes("doc") || content.includes("readme") || content.includes("guide")) {
} else if (
content.includes("doc") ||
content.includes("readme") ||
content.includes("guide")
) {
if (!currentLabels.includes("documentation")) {
labelsToAdd.push("documentation");
}
} else if (content.includes("?") || content.includes("how to") || content.includes("question")) {
} else if (
content.includes("?") ||
content.includes("how to") ||
content.includes("question")
) {
if (!currentLabels.includes("question")) {
labelsToAdd.push("question");
}
Expand Down
2 changes: 1 addition & 1 deletion .github/scripts/remind-issues.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async function remindIssues() {
const hasReminder = comments.data.some(
(comment) =>
comment.user.login === "github-actions[bot]" &&
comment.body.includes("Any progress update")
comment.body.includes("Any progress update"),
);

if (hasReminder) {
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/auto-label.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
1 change: 0 additions & 1 deletion .github/workflows/contributor-welcome.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ permissions:
issues: write
pull-requests: write


jobs:
welcome:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/issue-reminder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
GITHUB_REPOSITORY: ${{ github.repository }}
run: node .github/scripts/remind-issues.mjs
run: node .github/scripts/remind-issues.mjs
61 changes: 38 additions & 23 deletions BUG_FIX_PATCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,27 @@
## 1. controller/auth.js

### Change 1.1: Line 320-326 (resendVerificationEmail - missing email)

```diff
if (!email) {
if (wantsHtml(req)) {
- return res.status(400).render("resend-verification", {
- error: "Email address is required."
- return res.status(400).render("resend-verification", {
- error: "Email address is required."
- });
+ return res.status(400).render("resend-verification", {
+ return res.status(400).render("resend-verification", {
+ error: "Email address is required.",
+ success: null
+ });
}
```

### Change 1.2: Line 330-338 (resendVerificationEmail - user not found)

```diff
if (!user) {
// Don't reveal whether email exists
if (wantsHtml(req)) {
return res.render("resend-verification", {
return res.render("resend-verification", {
success: "If that email address is in our system, you'll receive a verification email shortly.",
- error: null,
+ error: null
Expand All @@ -40,10 +42,11 @@
```

### Change 1.3: Line 340-346 (resendVerificationEmail - already verified)

```diff
if (user.isVerified) {
if (wantsHtml(req)) {
return res.render("resend-verification", {
return res.render("resend-verification", {
success: "Your email is already verified. You can log in now.",
- error: null,
+ error: null
Expand All @@ -52,22 +55,24 @@
```

### Change 1.4: Line 368-374 (resendVerificationEmail - email send failure)

```diff
} catch (emailError) {
console.error("Failed to send verification email:", emailError);
if (wantsHtml(req)) {
return res.status(500).render("resend-verification", {
- error: "Failed to send verification email. Please try again later."
return res.status(500).render("resend-verification", {
- error: "Failed to send verification email. Please try again later."
+ error: "Failed to send verification email. Please try again later.",
+ success: null
});
}
```

### Change 1.5: Line 380-386 (resendVerificationEmail - success)

```diff
if (wantsHtml(req)) {
return res.render("resend-verification", {
return res.render("resend-verification", {
success: "Verification email sent! Please check your inbox.",
- error: null,
+ error: null
Expand All @@ -76,11 +81,12 @@
```

### Change 1.6: Line 247-253 (verifyEmail - no token)

```diff
if (!token) {
if (wantsHtml(req)) {
return res.status(400).render("verify-email", {
- error: "Invalid verification link. Please request a new one."
return res.status(400).render("verify-email", {
- error: "Invalid verification link. Please request a new one."
+ error: "Invalid verification link. Please request a new one.",
+ success: null,
+ expiredToken: false,
Expand All @@ -90,11 +96,12 @@
```

### Change 1.7: Line 262-268 (verifyEmail - user not found)

```diff
if (!user) {
if (wantsHtml(req)) {
return res.status(400).render("verify-email", {
- error: "Invalid verification link. Please request a new one."
return res.status(400).render("verify-email", {
- error: "Invalid verification link. Please request a new one."
+ error: "Invalid verification link. Please request a new one.",
+ success: null,
+ expiredToken: false,
Expand All @@ -104,10 +111,11 @@
```

### Change 1.8: Line 271-277 (verifyEmail - already verified)

```diff
if (user.isVerified) {
if (wantsHtml(req)) {
return res.render("verify-email", {
return res.render("verify-email", {
success: "Your email is already verified. You can log in now.",
- error: null,
+ error: null,
Expand All @@ -118,10 +126,11 @@
```

### Change 1.9: Line 280-288 (verifyEmail - token expired)

```diff
if (isVerificationTokenExpired(user.verificationTokenExpiry)) {
if (wantsHtml(req)) {
return res.status(410).render("verify-email", {
return res.status(410).render("verify-email", {
error: "Verification link has expired. Please request a new one.",
- expiredToken: true,
- userEmail: user.email,
Expand All @@ -133,9 +142,10 @@
```

### Change 1.10: Line 309-315 (verifyEmail - success)

```diff
if (wantsHtml(req)) {
return res.render("verify-email", {
return res.render("verify-email", {
success: "Your email has been verified successfully! You can now log in.",
- error: null,
+ error: null,
Expand All @@ -150,12 +160,14 @@
## 2. view/resend-verification.ejs

### Change 2.1: Line 215 (error condition)

```diff
- <% if (error) { %>
+ <% if (typeof error !== 'undefined' && error) { %>
```

### Change 2.2: Line 222 (success condition)

```diff
- <% if (success) { %>
+ <% if (typeof success !== 'undefined' && success) { %>
Expand All @@ -166,12 +178,14 @@
## 3. view/verify-email.ejs

### Change 3.1: Line 177 (success condition)

```diff
- <% if (success) { %>
+ <% if (typeof success !== 'undefined' && success) { %>
```

### Change 3.2: Line 189 (error condition)

```diff
- <% } else if (error) { %>
+ <% } else if (typeof error !== 'undefined' && error) { %>
Expand All @@ -181,13 +195,13 @@

## 🎯 Summary of Changes

| Change Type | Count | Purpose |
|-------------|-------|---------|
| Added `success: null` to error renders | 4 | Prevent undefined variable errors |
| Added missing template variables | 6 | Ensure all variables are defined |
| Type-safe EJS checks | 4 | Use `typeof` to prevent ReferenceError |
| Formatting cleanup | 15 | Removed trailing commas, consistency |
| **Total Lines** | **+29** | |
| Change Type | Count | Purpose |
| -------------------------------------- | ------- | -------------------------------------- |
| Added `success: null` to error renders | 4 | Prevent undefined variable errors |
| Added missing template variables | 6 | Ensure all variables are defined |
| Type-safe EJS checks | 4 | Use `typeof` to prevent ReferenceError |
| Formatting cleanup | 15 | Removed trailing commas, consistency |
| **Total Lines** | **+29** | |

---

Expand All @@ -206,9 +220,10 @@
## 🧪 Testing

All test cases pass:

- ✅ Initial page load
- ✅ Resend with valid email
- ✅ Resend with unregistered email
- ✅ Resend with unregistered email
- ✅ Resend with already verified email
- ✅ Resend with no email
- ✅ Email verification success
Expand Down
Loading