Skip to content

Commit aa8ba28

Browse files
authored
Merge pull request #21 from SharanRP/Sharan/rules
feat(git): configure Git hooks and enhance project setup
2 parents e050b7c + d336b7f commit aa8ba28

File tree

11 files changed

+218
-76
lines changed

11 files changed

+218
-76
lines changed

.gitconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[core]
2+
hooksPath = .husky
3+
ignorecase = false
4+
5+
[hooks]
6+
enforceForAll = true
7+
8+
[receive]
9+
denyNonFastForwards = true

.github/workflows/branch-check.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Branch Name Check
2+
3+
on:
4+
push:
5+
branches-ignore:
6+
- main
7+
- develop
8+
pull_request:
9+
branches:
10+
- main
11+
- develop
12+
13+
jobs:
14+
check-branch-name:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Check branch name
20+
run: |
21+
if [ "${{ github.event_name }}" = "pull_request" ]; then
22+
BRANCH="${{ github.head_ref }}"
23+
else
24+
BRANCH=${GITHUB_REF#refs/heads/}
25+
fi
26+
27+
if [[ ! $BRANCH =~ ^[a-zA-Z0-9]+/[a-zA-Z0-9-]+$ ]]; then
28+
echo "🚫 Branch name validation failed"
29+
echo "Branch: $BRANCH"
30+
echo "Required format: username/feature-name"
31+
exit 1
32+
fi
33+
echo "✅ Branch name follows convention: $BRANCH"
34+
35+
validate-commit:
36+
runs-on: ubuntu-latest
37+
steps:
38+
- uses: actions/checkout@v4
39+
with:
40+
fetch-depth: 0
41+
42+
- name: Setup Node.js
43+
uses: actions/setup-node@v4
44+
with:
45+
node-version: '18'
46+
47+
- name: Install commitlint
48+
run: |
49+
npm install --save-dev @commitlint/cli @commitlint/config-conventional
50+
51+
- name: Check commit message
52+
run: |
53+
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
54+
git log -1 --pretty=format:"%s" | npx commitlint

.husky/commit-msg

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# #!/usr/bin/env sh
2-
# . "$(dirname -- "$0")/_/husky.sh"
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
33

44
# Validate commit message format
55
npx --no -- commitlint --edit "$1"
@@ -9,10 +9,14 @@ BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
99
BRANCH_PATTERN="^[a-zA-Z0-9]+/[a-zA-Z0-9-]+$"
1010

1111
if ! echo "$BRANCH_NAME" | grep -E "$BRANCH_PATTERN" > /dev/null; then
12-
echo "🚫 Branch name must follow pattern: username/feature-name"
13-
echo "❌ Your branch name: $BRANCH_NAME"
14-
echo "✅ Example: john/add-footer"
12+
echo "🚫 Branch name validation failed"
13+
echo "Branch: $BRANCH_NAME"
14+
echo "Required format: username/feature-name"
15+
echo "Examples:"
16+
echo "✅ john/add-footer"
17+
echo "✅ jane/fix-auth"
18+
echo "❌ feature-only"
19+
echo "❌ MainBranch"
1520
exit 1
1621
fi
17-
1822
echo "✅ Branch name follows convention: $BRANCH_NAME"

.husky/pre-receive

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/sh
2+
3+
# Enforce branch naming
4+
while read oldrev newrev refname; do
5+
branch=$(echo "$refname" | sed -n 's|refs/heads/||p')
6+
if [[ ! $branch =~ ^[a-zA-Z0-9]+/[a-zA-Z0-9-]+$ ]]; then
7+
echo "🚫 ERROR: Branch '$branch' does not follow naming convention"
8+
echo "✅ Required format: username/feature-name"
9+
exit 1
10+
fi
11+
done
12+
13+
# Block force pushes
14+
if git rev-list $newrev..$oldrev >/dev/null 2>&1; then
15+
echo "🚫 Force pushes are not allowed"
16+
exit 1
17+
fi

Dockerfile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ FROM node:18-alpine AS deps
33
WORKDIR /app
44

55
# Install dependencies needed for build
6-
RUN apk add --no-cache libc6-compat
6+
RUN apk add --no-cache libc6-compat git
77

88
# Copy package files
9-
COPY package.json package-lock.json ./
9+
COPY package*.json ./
1010

11-
# Install dependencies
12-
RUN npm ci
11+
# Install dependencies (without husky)
12+
RUN npm ci --ignore-scripts
1313

1414
# Stage 2: Builder
1515
FROM node:18-alpine AS builder
@@ -22,6 +22,7 @@ COPY . .
2222
# Set environment variables for build
2323
ENV NEXT_TELEMETRY_DISABLED 1
2424
ENV NODE_ENV production
25+
ENV HUSKY 0
2526

2627
# Build application
2728
RUN npm run build

README.md

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ npm install
1818
3. **Run development server**
1919
```bash
2020
npm run dev
21+
# or with Docker
22+
docker compose up --build
2123
```
2224

2325
Open [http://localhost:3000](http://localhost:3000) to view the project.
@@ -27,43 +29,67 @@ Open [http://localhost:3000](http://localhost:3000) to view the project.
2729
### Prerequisites
2830
- Node.js (v18 or higher)
2931
- npm (v9 or higher)
32+
- Docker (optional)
3033

3134
### Environment Setup
3235
1. Copy the environment template:
3336
```bash
34-
cp .env.example .env.local
37+
cp .env.example .env.production
3538
```
3639

3740
2. Install husky hooks:
3841
```bash
3942
npm run prepare
43+
git config core.hooksPath .husky
44+
```
45+
46+
## 🐳 Docker
47+
48+
### Build and Run
49+
```bash
50+
docker compose up --build
51+
```
52+
53+
### Environment Variables
54+
Required in `.env.production`:
55+
```env
56+
GOOGLE_CLIENT_ID=your_client_id
57+
GOOGLE_CLIENT_SECRET=your_client_secret
58+
NEXTAUTH_URL=http://localhost:3000
59+
NEXTAUTH_SECRET=your_secret
60+
POSTHOG_KEY=your_key
61+
POSTHOG_HOST=your_host
4062
```
4163

4264
## 📝 Contributing
4365

66+
### Strict Git Enforcement
67+
All commits and branches are strictly enforced through:
68+
- Local git hooks (husky)
69+
- Server-side hooks
70+
- GitHub Actions
71+
- GUI client configurations
72+
4473
### Branch Naming Convention
4574
All branches must follow the pattern:
4675
```
4776
username/feature-name
4877
```
4978
Example: `john/add-ai-page`
5079

51-
### Pre-commit Checks
52-
Before committing, ensure:
53-
1. Code is linted and formatted:
54-
```bash
55-
npm run lint
56-
```
57-
58-
2. TypeScript types are valid:
59-
```bash
60-
npm run type-check
61-
```
80+
Enforcement:
81+
- Pre-receive hooks
82+
- GitHub Actions
83+
- Local git hooks
84+
- No force pushes allowed
6285

63-
3. Build succeeds:
64-
```bash
65-
npm run build
66-
```
86+
### Pre-commit Checks
87+
Before committing, the following are automatically enforced:
88+
1. Code linting and formatting
89+
2. TypeScript type checking
90+
3. Successful build
91+
4. Branch name validation
92+
5. Commit message format
6793

6894
### Commit Message Format
6995
Follow the conventional commits specification:

app/layout.tsx

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Montserrat } from 'next/font/google';
55
import { PostHogProvider } from '@/components/providers/PostHogProvider'
66
import { PostHogPageview } from '@/components/PostHogPageview'
77
import { NextAuthProvider } from '@/components/providers/NextAuthProvider'
8+
import { websiteSchema, organizationSchema } from './schema'
89

910
const geistSans = localFont({
1011
src: "./fonts/GeistVF.woff",
@@ -25,46 +26,45 @@ const montserrat = Montserrat({
2526
export const metadata: Metadata = {
2627
metadataBase: new URL('https://coc-landing.vercel.app'),
2728
title: {
28-
default: "VJTI Resources & Communities",
29-
template: "%s | VJTI Resources"
30-
},
31-
description: "Access curated educational resources, join tech communities, and connect with VJTI's developer ecosystem. Features AI, Web Dev, CP, and academic materials.",
32-
keywords: ["VJTI", "education", "resources", "developer communities", "engineering", "tech clubs", "Mumbai","AI","Web Dev","CP","academic materials","coc","coding"],
33-
authors: [{ name: "VJTI Resources Team" }],
34-
openGraph: {
35-
type: "website",
36-
locale: "en_IN",
37-
url: "https://coc-landing.vercel.app",
38-
siteName: "VJTI Resources",
39-
images: [{
40-
url: "/coc_vjti.jpeg",
41-
width: 1200,
42-
height: 630,
43-
alt: "VJTI Resources & Communities Logo"
44-
}],
45-
},
46-
twitter: {
47-
card: "summary_large_image",
48-
site: "@vjti_resources",
49-
images: "/coc_vjti.jpeg",
50-
},
51-
icons: {
52-
icon: "/coc_vjti.jpeg",
29+
default: "Community of Coders VJTI | COC Landing",
30+
template: "%s | Community of Coders VJTI"
5331
},
32+
description: "Access curated educational resources, join tech communities, and explore learning paths for Web Development, AI/ML, Competitive Programming at VJTI.",
33+
keywords: ["VJTI", "COC", "tech communities", "educational resources", "web development", "AI/ML", "competitive programming", "student clubs"],
34+
authors: [{ name: "Community of Coders" }],
35+
creator: "Community of Coders VJTI",
36+
publisher: "VJTI",
5437
robots: {
5538
index: true,
5639
follow: true,
5740
googleBot: {
5841
index: true,
5942
follow: true,
60-
"max-video-preview": -1,
61-
"max-image-preview": "large",
62-
"max-snippet": -1,
43+
'max-video-preview': -1,
44+
'max-image-preview': 'large',
45+
'max-snippet': -1,
6346
},
6447
},
65-
verification: {
66-
google: "your-google-verification-code",
48+
openGraph: {
49+
type: 'website',
50+
locale: 'en_US',
51+
url: 'https://coc-landing.vercel.app',
52+
title: 'Community of Coders VJTI',
53+
description: 'Access curated educational resources and join tech communities at VJTI.',
54+
siteName: 'Community of Coders VJTI',
55+
},
56+
twitter: {
57+
card: 'summary_large_image',
58+
title: 'Community of Coders VJTI',
59+
description: 'Access curated educational resources and join tech communities at VJTI.',
60+
creator: '@COC_VJTI',
6761
},
62+
alternates: {
63+
canonical: 'https://coc-landing.vercel.app',
64+
},
65+
verification: {
66+
google: 'your-google-verification-code',
67+
}
6868
};
6969

7070
export default function RootLayout({
@@ -74,6 +74,20 @@ export default function RootLayout({
7474
}>) {
7575
return (
7676
<html lang="en">
77+
<head>
78+
<script
79+
type="application/ld+json"
80+
dangerouslySetInnerHTML={{
81+
__html: JSON.stringify(websiteSchema)
82+
}}
83+
/>
84+
<script
85+
type="application/ld+json"
86+
dangerouslySetInnerHTML={{
87+
__html: JSON.stringify(organizationSchema)
88+
}}
89+
/>
90+
</head>
7791
<body
7892
className={`${geistSans.variable} ${geistMono.variable} ${montserrat.variable} antialiased`}
7993
>

app/schema.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
export const websiteSchema = {
2+
"@context": "https://schema.org",
3+
"@type": "WebSite",
4+
"name": "Community of Coders VJTI",
5+
"url": "https://coc-landing.vercel.app",
6+
"potentialAction": {
7+
"@type": "SearchAction",
8+
"target": "https://coc-landing.vercel.app/search?q={search_term_string}",
9+
"query-input": "required name=search_term_string"
10+
}
11+
};
12+
13+
export const organizationSchema = {
14+
"@context": "https://schema.org",
15+
"@type": "Organization",
16+
"name": "Community of Coders VJTI",
17+
"url": "https://coc-landing.vercel.app",
18+
"logo": "https://coc-landing.vercel.app/logo.png",
19+
"sameAs": [
20+
"https://www.linkedin.com/company/community-of-coders-vjti",
21+
"https://github.com/Community-Of-Coders"
22+
]
23+
};

app/sitemap.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { domains } from '@/config/navigation'
44
export default function sitemap(): MetadataRoute.Sitemap {
55
const baseUrl = 'https://coc-landing.vercel.app'
66

7-
// Base routes
87
const routes = [
98
'',
109
'/about',

0 commit comments

Comments
 (0)