Skip to content

Commit f68882f

Browse files
committed
CI/CD
1 parent 9c554bf commit f68882f

32 files changed

+1885
-18
lines changed

.eslintrc.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module.exports = {
2+
env: {
3+
browser: true,
4+
es2021: true,
5+
webextensions: true,
6+
node: true
7+
},
8+
extends: [
9+
'eslint:recommended'
10+
],
11+
parserOptions: {
12+
ecmaVersion: 'latest',
13+
sourceType: 'module'
14+
},
15+
ignorePatterns: [
16+
'dist/**',
17+
'build-firefox/**',
18+
'node_modules/**',
19+
'*.min.js',
20+
'*.bundle.js'
21+
],
22+
rules: {
23+
'no-unused-vars': 'warn',
24+
'no-console': 'off',
25+
'no-unsafe-finally': 'warn',
26+
'no-func-assign': 'warn',
27+
'no-cond-assign': 'warn',
28+
'no-case-declarations': 'warn',
29+
'no-redeclare': 'warn',
30+
'no-fallthrough': 'warn'
31+
},
32+
globals: {
33+
chrome: 'readonly',
34+
browser: 'readonly',
35+
module: 'readonly',
36+
content: 'readonly',
37+
errorMessage: 'readonly',
38+
AIService: 'readonly',
39+
ContentFetcher: 'readonly'
40+
}
41+
};

.github/workflows/ci-cd.yml

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
name: CI/CD Pipeline
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main ]
8+
release:
9+
types: [ published ]
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
15+
strategy:
16+
matrix:
17+
node-version: [18.x, 20.x]
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Setup Node.js ${{ matrix.node-version }}
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version: ${{ matrix.node-version }}
27+
cache: 'npm'
28+
29+
- name: Install dependencies
30+
run: npm ci
31+
32+
- name: Run linting
33+
run: npm run lint
34+
35+
- name: Run type checking
36+
run: npm run typecheck
37+
38+
- name: Run tests
39+
run: npm test
40+
41+
- name: Build extension
42+
run: npm run build
43+
44+
- name: Build Firefox version
45+
run: npm run build:firefox
46+
47+
- name: Create packages
48+
run: npm run package:all-formats
49+
50+
- name: Upload artifacts
51+
uses: actions/upload-artifact@v4
52+
with:
53+
name: extension-packages-${{ matrix.node-version }}
54+
path: |
55+
*.zip
56+
*.crx
57+
*.xpi
58+
retention-days: 30
59+
60+
security-scan:
61+
runs-on: ubuntu-latest
62+
steps:
63+
- name: Checkout code
64+
uses: actions/checkout@v4
65+
66+
- name: Setup Node.js
67+
uses: actions/setup-node@v4
68+
with:
69+
node-version: '20.x'
70+
cache: 'npm'
71+
72+
- name: Install dependencies
73+
run: npm ci
74+
75+
- name: Run security audit
76+
run: npm audit --audit-level=moderate
77+
78+
- name: Scan for vulnerabilities
79+
uses: securecodewarrior/github-action-add-sarif@v1
80+
if: always()
81+
with:
82+
sarif-file: 'security-scan-results.sarif'
83+
84+
release:
85+
needs: [test, security-scan]
86+
runs-on: ubuntu-latest
87+
if: github.event_name == 'release'
88+
89+
steps:
90+
- name: Checkout code
91+
uses: actions/checkout@v4
92+
93+
- name: Setup Node.js
94+
uses: actions/setup-node@v4
95+
with:
96+
node-version: '20.x'
97+
cache: 'npm'
98+
99+
- name: Install dependencies
100+
run: npm ci
101+
102+
- name: Build and package
103+
run: |
104+
npm run build
105+
npm run build:firefox
106+
npm run package:all-formats
107+
108+
- name: Upload release assets
109+
uses: softprops/action-gh-release@v1
110+
with:
111+
files: |
112+
*.zip
113+
*.crx
114+
*.xpi
115+
env:
116+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
117+
118+
deploy-stores:
119+
needs: [test, security-scan]
120+
runs-on: ubuntu-latest
121+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
122+
123+
steps:
124+
- name: Checkout code
125+
uses: actions/checkout@v4
126+
127+
- name: Setup Node.js
128+
uses: actions/setup-node@v4
129+
with:
130+
node-version: '20.x'
131+
cache: 'npm'
132+
133+
- name: Install dependencies
134+
run: npm ci
135+
136+
- name: Build and package
137+
run: |
138+
npm run build
139+
npm run build:firefox
140+
npm run package:all-formats
141+
142+
- name: Deploy to Chrome Web Store
143+
uses: PlasmoHQ/bpp@v2
144+
with:
145+
keys: ${{ secrets.CHROME_WEBSTORE_KEY }}
146+
zip-path: blog-link-analyzer-*.zip
147+
client-id: ${{ secrets.CHROME_CLIENT_ID }}
148+
client-secret: ${{ secrets.CHROME_CLIENT_SECRET }}
149+
refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }}
150+
151+
- name: Deploy to Firefox Add-ons
152+
uses: firefox-devops/firefox-addon-submit@v1
153+
with:
154+
api-key: ${{ secrets.FIREFOX_API_KEY }}
155+
api-secret: ${{ secrets.FIREFOX_API_SECRET }}
156+
xpi-path: blog-link-analyzer-firefox-*.xpi
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Semantic Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
jobs:
9+
release:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout
13+
uses: actions/checkout@v4
14+
with:
15+
fetch-depth: 0
16+
token: ${{ secrets.GITHUB_TOKEN }}
17+
18+
- name: Setup Node.js
19+
uses: actions/setup-node@v4
20+
with:
21+
node-version: '20.x'
22+
cache: 'npm'
23+
24+
- name: Install dependencies
25+
run: npm ci
26+
27+
- name: Install semantic-release
28+
run: npm install -g semantic-release @semantic-release/changelog @semantic-release/git @semantic-release/github
29+
30+
- name: Run semantic-release
31+
env:
32+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33+
run: semantic-release

.husky/pre-commit

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
3+
4+
echo "🔍 Running pre-commit checks..."
5+
6+
# Run linting
7+
echo "📝 Running ESLint..."
8+
npm run lint
9+
if [ $? -ne 0 ]; then
10+
echo "❌ ESLint failed. Please fix linting errors before committing."
11+
exit 1
12+
fi
13+
14+
# Run type checking
15+
echo "🔷 Running TypeScript type checking..."
16+
npm run typecheck
17+
if [ $? -ne 0 ]; then
18+
echo "❌ Type checking failed. Please fix type errors before committing."
19+
exit 1
20+
fi
21+
22+
# Run tests
23+
echo "🧪 Running tests..."
24+
npm test
25+
if [ $? -ne 0 ]; then
26+
echo "❌ Tests failed. Please fix failing tests before committing."
27+
exit 1
28+
fi
29+
30+
# Check if package.json is valid
31+
echo "📦 Validating package.json..."
32+
node -e "JSON.parse(require('fs').readFileSync('package.json', 'utf8'))"
33+
if [ $? -ne 0 ]; then
34+
echo "❌ package.json is not valid JSON."
35+
exit 1
36+
fi
37+
38+
# Check if manifest.json is valid
39+
echo "📋 Validating manifest.json..."
40+
node -e "JSON.parse(require('fs').readFileSync('manifest.json', 'utf8'))"
41+
if [ $? -ne 0 ]; then
42+
echo "❌ manifest.json is not valid JSON."
43+
exit 1
44+
fi
45+
46+
# Check for console.log statements in production files
47+
echo "🚫 Checking for console.log statements..."
48+
if grep -r "console\.log" --include="*.js" --exclude-dir=node_modules --exclude-dir=dist --exclude-dir=build-firefox .; then
49+
echo "⚠️ Warning: console.log statements found in source files. Consider removing them for production."
50+
fi
51+
52+
# Check file sizes
53+
echo "📏 Checking file sizes..."
54+
MAX_SIZE=$((5 * 1024 * 1024)) # 5MB limit
55+
for file in *.js; do
56+
if [ -f "$file" ] && [ "$file" != "node_modules" ]; then
57+
size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null || echo 0)
58+
if [ "$size" -gt "$MAX_SIZE" ]; then
59+
echo "⚠️ Warning: $file is larger than 5MB ($(($size / 1024 / 1024))MB)"
60+
fi
61+
fi
62+
done
63+
64+
echo "✅ All pre-commit checks passed!"
65+
exit 0

.husky/pre-push

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
3+
4+
echo "🔍 Running pre-push checks..."
5+
6+
# Run full validation
7+
echo "🔧 Running full validation..."
8+
npm run validate
9+
if [ $? -ne 0 ]; then
10+
echo "❌ Validation failed. Please fix issues before pushing."
11+
exit 1
12+
fi
13+
14+
# Build extension
15+
echo "🏗️ Building extension..."
16+
npm run build
17+
if [ $? -ne 0 ]; then
18+
echo "❌ Build failed. Please fix build errors before pushing."
19+
exit 1
20+
fi
21+
22+
# Build Firefox version
23+
echo "🦊 Building Firefox version..."
24+
npm run build:firefox
25+
if [ $? -ne 0 ]; then
26+
echo "❌ Firefox build failed. Please fix build errors before pushing."
27+
exit 1
28+
fi
29+
30+
# Create packages
31+
echo "📦 Creating packages..."
32+
npm run package:all-formats
33+
if [ $? -ne 0 ]; then
34+
echo "❌ Package creation failed. Please fix packaging errors before pushing."
35+
exit 1
36+
fi
37+
38+
# Check if packages were created
39+
echo "📋 Verifying packages..."
40+
if [ ! -f "blog-link-analyzer-$(node -p \"require('./package.json').version\").zip" ]; then
41+
echo "❌ Chrome package not found."
42+
exit 1
43+
fi
44+
45+
if [ ! -f "blog-link-analyzer-firefox-$(node -p \"require('./package.json').version\").zip" ]; then
46+
echo "❌ Firefox package not found."
47+
exit 1
48+
fi
49+
50+
echo "✅ All pre-push checks passed!"
51+
exit 0

.releaserc.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"branches": ["main"],
3+
"plugins": [
4+
"@semantic-release/commit-analyzer",
5+
"@semantic-release/release-notes-generator",
6+
"@semantic-release/changelog",
7+
"@semantic-release/github",
8+
[
9+
"@semantic-release/git",
10+
{
11+
"assets": ["CHANGELOG.md", "package.json"],
12+
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
13+
}
14+
]
15+
]
16+
}

0 commit comments

Comments
 (0)