servcraft 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +29 -0
- package/.github/CODEOWNERS +18 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +46 -0
- package/.github/dependabot.yml +59 -0
- package/.github/workflows/ci.yml +188 -0
- package/.github/workflows/release.yml +195 -0
- package/AUDIT.md +602 -0
- package/README.md +1070 -1
- package/dist/cli/index.cjs +2026 -2168
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +2026 -2168
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +595 -616
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +114 -52
- package/dist/index.d.ts +114 -52
- package/dist/index.js +595 -616
- package/dist/index.js.map +1 -1
- package/docs/CLI-001_MULTI_DB_PLAN.md +546 -0
- package/docs/DATABASE_MULTI_ORM.md +399 -0
- package/docs/PHASE1_BREAKDOWN.md +346 -0
- package/docs/PROGRESS.md +550 -0
- package/docs/modules/ANALYTICS.md +226 -0
- package/docs/modules/API-VERSIONING.md +252 -0
- package/docs/modules/AUDIT.md +192 -0
- package/docs/modules/AUTH.md +431 -0
- package/docs/modules/CACHE.md +346 -0
- package/docs/modules/EMAIL.md +254 -0
- package/docs/modules/FEATURE-FLAG.md +291 -0
- package/docs/modules/I18N.md +294 -0
- package/docs/modules/MEDIA-PROCESSING.md +281 -0
- package/docs/modules/MFA.md +266 -0
- package/docs/modules/NOTIFICATION.md +311 -0
- package/docs/modules/OAUTH.md +237 -0
- package/docs/modules/PAYMENT.md +804 -0
- package/docs/modules/QUEUE.md +540 -0
- package/docs/modules/RATE-LIMIT.md +339 -0
- package/docs/modules/SEARCH.md +288 -0
- package/docs/modules/SECURITY.md +327 -0
- package/docs/modules/SESSION.md +382 -0
- package/docs/modules/SWAGGER.md +305 -0
- package/docs/modules/UPLOAD.md +296 -0
- package/docs/modules/USER.md +505 -0
- package/docs/modules/VALIDATION.md +294 -0
- package/docs/modules/WEBHOOK.md +270 -0
- package/docs/modules/WEBSOCKET.md +691 -0
- package/package.json +53 -38
- package/prisma/schema.prisma +395 -1
- package/src/cli/commands/add-module.ts +520 -87
- package/src/cli/commands/db.ts +3 -4
- package/src/cli/commands/docs.ts +256 -6
- package/src/cli/commands/generate.ts +12 -19
- package/src/cli/commands/init.ts +384 -214
- package/src/cli/index.ts +0 -4
- package/src/cli/templates/repository.ts +6 -1
- package/src/cli/templates/routes.ts +6 -21
- package/src/cli/utils/docs-generator.ts +6 -7
- package/src/cli/utils/env-manager.ts +717 -0
- package/src/cli/utils/field-parser.ts +16 -7
- package/src/cli/utils/interactive-prompt.ts +223 -0
- package/src/cli/utils/template-manager.ts +346 -0
- package/src/config/database.config.ts +183 -0
- package/src/config/env.ts +0 -10
- package/src/config/index.ts +0 -14
- package/src/core/server.ts +1 -1
- package/src/database/adapters/mongoose.adapter.ts +132 -0
- package/src/database/adapters/prisma.adapter.ts +118 -0
- package/src/database/connection.ts +190 -0
- package/src/database/interfaces/database.interface.ts +85 -0
- package/src/database/interfaces/index.ts +7 -0
- package/src/database/interfaces/repository.interface.ts +129 -0
- package/src/database/models/mongoose/index.ts +7 -0
- package/src/database/models/mongoose/payment.schema.ts +347 -0
- package/src/database/models/mongoose/user.schema.ts +154 -0
- package/src/database/prisma.ts +1 -4
- package/src/database/redis.ts +101 -0
- package/src/database/repositories/mongoose/index.ts +7 -0
- package/src/database/repositories/mongoose/payment.repository.ts +380 -0
- package/src/database/repositories/mongoose/user.repository.ts +255 -0
- package/src/database/seed.ts +6 -1
- package/src/index.ts +9 -20
- package/src/middleware/security.ts +2 -6
- package/src/modules/analytics/analytics.routes.ts +80 -0
- package/src/modules/analytics/analytics.service.ts +364 -0
- package/src/modules/analytics/index.ts +18 -0
- package/src/modules/analytics/types.ts +180 -0
- package/src/modules/api-versioning/index.ts +15 -0
- package/src/modules/api-versioning/types.ts +86 -0
- package/src/modules/api-versioning/versioning.middleware.ts +120 -0
- package/src/modules/api-versioning/versioning.routes.ts +54 -0
- package/src/modules/api-versioning/versioning.service.ts +189 -0
- package/src/modules/audit/audit.repository.ts +206 -0
- package/src/modules/audit/audit.service.ts +27 -59
- package/src/modules/auth/auth.controller.ts +2 -2
- package/src/modules/auth/auth.middleware.ts +3 -9
- package/src/modules/auth/auth.routes.ts +10 -107
- package/src/modules/auth/auth.service.ts +126 -23
- package/src/modules/auth/index.ts +3 -4
- package/src/modules/cache/cache.service.ts +367 -0
- package/src/modules/cache/index.ts +10 -0
- package/src/modules/cache/types.ts +44 -0
- package/src/modules/email/email.service.ts +3 -10
- package/src/modules/email/templates.ts +2 -8
- package/src/modules/feature-flag/feature-flag.repository.ts +303 -0
- package/src/modules/feature-flag/feature-flag.routes.ts +247 -0
- package/src/modules/feature-flag/feature-flag.service.ts +566 -0
- package/src/modules/feature-flag/index.ts +20 -0
- package/src/modules/feature-flag/types.ts +192 -0
- package/src/modules/i18n/i18n.middleware.ts +186 -0
- package/src/modules/i18n/i18n.routes.ts +191 -0
- package/src/modules/i18n/i18n.service.ts +456 -0
- package/src/modules/i18n/index.ts +18 -0
- package/src/modules/i18n/types.ts +118 -0
- package/src/modules/media-processing/index.ts +17 -0
- package/src/modules/media-processing/media-processing.routes.ts +111 -0
- package/src/modules/media-processing/media-processing.service.ts +245 -0
- package/src/modules/media-processing/types.ts +156 -0
- package/src/modules/mfa/index.ts +20 -0
- package/src/modules/mfa/mfa.repository.ts +206 -0
- package/src/modules/mfa/mfa.routes.ts +595 -0
- package/src/modules/mfa/mfa.service.ts +572 -0
- package/src/modules/mfa/totp.ts +150 -0
- package/src/modules/mfa/types.ts +57 -0
- package/src/modules/notification/index.ts +20 -0
- package/src/modules/notification/notification.repository.ts +356 -0
- package/src/modules/notification/notification.service.ts +483 -0
- package/src/modules/notification/types.ts +119 -0
- package/src/modules/oauth/index.ts +20 -0
- package/src/modules/oauth/oauth.repository.ts +219 -0
- package/src/modules/oauth/oauth.routes.ts +446 -0
- package/src/modules/oauth/oauth.service.ts +293 -0
- package/src/modules/oauth/providers/apple.provider.ts +250 -0
- package/src/modules/oauth/providers/facebook.provider.ts +181 -0
- package/src/modules/oauth/providers/github.provider.ts +248 -0
- package/src/modules/oauth/providers/google.provider.ts +189 -0
- package/src/modules/oauth/providers/twitter.provider.ts +214 -0
- package/src/modules/oauth/types.ts +94 -0
- package/src/modules/payment/index.ts +19 -0
- package/src/modules/payment/payment.repository.ts +733 -0
- package/src/modules/payment/payment.routes.ts +390 -0
- package/src/modules/payment/payment.service.ts +354 -0
- package/src/modules/payment/providers/mobile-money.provider.ts +274 -0
- package/src/modules/payment/providers/paypal.provider.ts +190 -0
- package/src/modules/payment/providers/stripe.provider.ts +215 -0
- package/src/modules/payment/types.ts +140 -0
- package/src/modules/queue/cron.ts +438 -0
- package/src/modules/queue/index.ts +87 -0
- package/src/modules/queue/queue.routes.ts +600 -0
- package/src/modules/queue/queue.service.ts +842 -0
- package/src/modules/queue/types.ts +222 -0
- package/src/modules/queue/workers.ts +366 -0
- package/src/modules/rate-limit/index.ts +59 -0
- package/src/modules/rate-limit/rate-limit.middleware.ts +134 -0
- package/src/modules/rate-limit/rate-limit.routes.ts +269 -0
- package/src/modules/rate-limit/rate-limit.service.ts +348 -0
- package/src/modules/rate-limit/stores/memory.store.ts +165 -0
- package/src/modules/rate-limit/stores/redis.store.ts +322 -0
- package/src/modules/rate-limit/types.ts +153 -0
- package/src/modules/search/adapters/elasticsearch.adapter.ts +326 -0
- package/src/modules/search/adapters/meilisearch.adapter.ts +261 -0
- package/src/modules/search/adapters/memory.adapter.ts +278 -0
- package/src/modules/search/index.ts +21 -0
- package/src/modules/search/search.service.ts +234 -0
- package/src/modules/search/types.ts +214 -0
- package/src/modules/security/index.ts +40 -0
- package/src/modules/security/sanitize.ts +223 -0
- package/src/modules/security/security-audit.service.ts +388 -0
- package/src/modules/security/security.middleware.ts +398 -0
- package/src/modules/session/index.ts +3 -0
- package/src/modules/session/session.repository.ts +159 -0
- package/src/modules/session/session.service.ts +340 -0
- package/src/modules/session/types.ts +38 -0
- package/src/modules/swagger/index.ts +7 -1
- package/src/modules/swagger/schema-builder.ts +16 -4
- package/src/modules/swagger/swagger.service.ts +9 -10
- package/src/modules/swagger/types.ts +0 -2
- package/src/modules/upload/index.ts +14 -0
- package/src/modules/upload/types.ts +83 -0
- package/src/modules/upload/upload.repository.ts +199 -0
- package/src/modules/upload/upload.routes.ts +311 -0
- package/src/modules/upload/upload.service.ts +448 -0
- package/src/modules/user/index.ts +3 -3
- package/src/modules/user/user.controller.ts +15 -9
- package/src/modules/user/user.repository.ts +237 -113
- package/src/modules/user/user.routes.ts +39 -164
- package/src/modules/user/user.service.ts +4 -3
- package/src/modules/validation/validator.ts +12 -17
- package/src/modules/webhook/index.ts +91 -0
- package/src/modules/webhook/retry.ts +196 -0
- package/src/modules/webhook/signature.ts +135 -0
- package/src/modules/webhook/types.ts +181 -0
- package/src/modules/webhook/webhook.repository.ts +358 -0
- package/src/modules/webhook/webhook.routes.ts +442 -0
- package/src/modules/webhook/webhook.service.ts +457 -0
- package/src/modules/websocket/features.ts +504 -0
- package/src/modules/websocket/index.ts +106 -0
- package/src/modules/websocket/middlewares.ts +298 -0
- package/src/modules/websocket/types.ts +181 -0
- package/src/modules/websocket/websocket.service.ts +692 -0
- package/src/utils/errors.ts +7 -0
- package/src/utils/pagination.ts +4 -1
- package/tests/helpers/db-check.ts +79 -0
- package/tests/integration/auth-redis.test.ts +94 -0
- package/tests/integration/cache-redis.test.ts +387 -0
- package/tests/integration/mongoose-repositories.test.ts +410 -0
- package/tests/integration/payment-prisma.test.ts +637 -0
- package/tests/integration/queue-bullmq.test.ts +417 -0
- package/tests/integration/user-prisma.test.ts +441 -0
- package/tests/integration/websocket-socketio.test.ts +552 -0
- package/tests/setup.ts +11 -9
- package/vitest.config.ts +3 -8
- package/npm-cache/_cacache/content-v2/sha512/1c/d0/03440d500a0487621aad1d6402978340698976602046db8e24fa03c01ee6c022c69b0582f969042d9442ee876ac35c038e960dd427d1e622fa24b8eb7dba +0 -0
- package/npm-cache/_cacache/content-v2/sha512/42/55/28b493ca491833e5aab0e9c3108d29ab3f36c248ca88f45d4630674fce9130959e56ae308797ac2b6328fa7f09a610b9550ed09cb971d039876d293fc69d +0 -0
- package/npm-cache/_cacache/content-v2/sha512/e0/12/f360dc9315ee5f17844a0c8c233ee6bf7c30837c4a02ea0d56c61c7f7ab21c0e958e50ed2c57c59f983c762b93056778c9009b2398ffc26def0183999b13 +0 -0
- package/npm-cache/_cacache/content-v2/sha512/ed/b0/fae1161902898f4c913c67d7f6cdf6be0665aec3b389b9c4f4f0a101ca1da59badf1b59c4e0030f5223023b8d63cfe501c46a32c20c895d4fb3f11ca2232 +0 -0
- package/npm-cache/_cacache/index-v5/58/94/c2cba79e0f16b4c10e95a87e32255741149e8222cc314a476aab67c39cc0 +0 -5
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(git add:*)",
|
|
5
|
+
"Bash(git commit -m \"$\\(cat <<''EOF''\nfeat: Add advanced rate limiting module\n\n- Implemented three algorithms: fixed-window, sliding-window, token-bucket\n- Support for Memory and Redis stores\n- Flexible key generation \\(IP, User, API Key, custom\\)\n- Whitelist/Blacklist functionality\n- Custom limits per endpoint and user role\n- Pre-configured rate limiters \\(strict, standard, relaxed, auth\\)\n- Admin routes for rate limit management\n- Standard X-RateLimit-* headers\n- Updated documentation with usage examples\n\nAlso includes previous modules:\n- Cache module\n- MFA/TOTP module\n- Notification module\n- OAuth providers \\(Google, GitHub, Facebook, Twitter, Apple\\)\n- Payment providers \\(Stripe, PayPal, Mobile Money\\)\n- File upload module\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
6
|
+
"Bash(npx eslint:*)",
|
|
7
|
+
"Bash(git commit:*)",
|
|
8
|
+
"Bash(git push:*)",
|
|
9
|
+
"Bash(find:*)",
|
|
10
|
+
"Bash(done)",
|
|
11
|
+
"Bash(wc:*)",
|
|
12
|
+
"Bash(npm install:*)",
|
|
13
|
+
"Bash(npm run typecheck:*)",
|
|
14
|
+
"Bash(npm run lint:*)",
|
|
15
|
+
"Bash(npm test:*)",
|
|
16
|
+
"Bash(npm run db:generate:*)",
|
|
17
|
+
"Bash(npx prettier:*)",
|
|
18
|
+
"Bash(grep:*)",
|
|
19
|
+
"Bash(cat:*)",
|
|
20
|
+
"Bash(DATABASE_URL=\"postgresql://postgres:Lesourcier@localhost:5432/servcraft_test?schema=public\" npx prisma db push:*)",
|
|
21
|
+
"Bash(ls:*)",
|
|
22
|
+
"Bash(npm run build:*)",
|
|
23
|
+
"Bash(npm whoami:*)",
|
|
24
|
+
"Bash(npm login)",
|
|
25
|
+
"Bash(npm publish:*)",
|
|
26
|
+
"Bash(npm version:*)"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Code Owners for Servcraft
|
|
2
|
+
# These owners will be automatically requested for review
|
|
3
|
+
|
|
4
|
+
# Default owners for everything
|
|
5
|
+
* @le-sourcier
|
|
6
|
+
|
|
7
|
+
# Core modules require review
|
|
8
|
+
/src/core/ @le-sourcier
|
|
9
|
+
/src/database/ @le-sourcier
|
|
10
|
+
|
|
11
|
+
# Security modules require careful review
|
|
12
|
+
/src/modules/security/ @le-sourcier
|
|
13
|
+
/src/modules/auth/ @le-sourcier
|
|
14
|
+
|
|
15
|
+
# CI/CD changes
|
|
16
|
+
/.github/ @le-sourcier
|
|
17
|
+
/Dockerfile* @le-sourcier
|
|
18
|
+
/docker-compose* @le-sourcier
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
## Description
|
|
2
|
+
|
|
3
|
+
<!-- Describe your changes in detail -->
|
|
4
|
+
|
|
5
|
+
## Type of Change
|
|
6
|
+
|
|
7
|
+
- [ ] Bug fix (non-breaking change that fixes an issue)
|
|
8
|
+
- [ ] New feature (non-breaking change that adds functionality)
|
|
9
|
+
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
|
10
|
+
- [ ] Documentation update
|
|
11
|
+
- [ ] Refactoring (no functional changes)
|
|
12
|
+
- [ ] Performance improvement
|
|
13
|
+
- [ ] Test coverage improvement
|
|
14
|
+
|
|
15
|
+
## Related Issues
|
|
16
|
+
|
|
17
|
+
<!-- Link any related issues here using #issue_number -->
|
|
18
|
+
|
|
19
|
+
Closes #
|
|
20
|
+
|
|
21
|
+
## How Has This Been Tested?
|
|
22
|
+
|
|
23
|
+
<!-- Describe the tests you ran to verify your changes -->
|
|
24
|
+
|
|
25
|
+
- [ ] Unit tests
|
|
26
|
+
- [ ] Integration tests
|
|
27
|
+
- [ ] Manual testing
|
|
28
|
+
|
|
29
|
+
## Checklist
|
|
30
|
+
|
|
31
|
+
- [ ] My code follows the project's style guidelines
|
|
32
|
+
- [ ] I have performed a self-review of my code
|
|
33
|
+
- [ ] I have commented my code, particularly in hard-to-understand areas
|
|
34
|
+
- [ ] I have made corresponding changes to the documentation
|
|
35
|
+
- [ ] My changes generate no new warnings
|
|
36
|
+
- [ ] I have added tests that prove my fix is effective or that my feature works
|
|
37
|
+
- [ ] New and existing unit tests pass locally with my changes
|
|
38
|
+
- [ ] Any dependent changes have been merged and published
|
|
39
|
+
|
|
40
|
+
## Screenshots (if applicable)
|
|
41
|
+
|
|
42
|
+
<!-- Add screenshots to help explain your changes -->
|
|
43
|
+
|
|
44
|
+
## Additional Notes
|
|
45
|
+
|
|
46
|
+
<!-- Add any other context about the pull request here -->
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# npm dependencies
|
|
4
|
+
- package-ecosystem: "npm"
|
|
5
|
+
directory: "/"
|
|
6
|
+
schedule:
|
|
7
|
+
interval: "weekly"
|
|
8
|
+
day: "monday"
|
|
9
|
+
time: "09:00"
|
|
10
|
+
timezone: "Europe/Paris"
|
|
11
|
+
open-pull-requests-limit: 10
|
|
12
|
+
reviewers:
|
|
13
|
+
- "le-sourcier"
|
|
14
|
+
labels:
|
|
15
|
+
- "dependencies"
|
|
16
|
+
- "npm"
|
|
17
|
+
commit-message:
|
|
18
|
+
prefix: "chore(deps):"
|
|
19
|
+
groups:
|
|
20
|
+
development:
|
|
21
|
+
patterns:
|
|
22
|
+
- "@types/*"
|
|
23
|
+
- "eslint*"
|
|
24
|
+
- "prettier*"
|
|
25
|
+
- "vitest*"
|
|
26
|
+
- "typescript*"
|
|
27
|
+
update-types:
|
|
28
|
+
- "minor"
|
|
29
|
+
- "patch"
|
|
30
|
+
production:
|
|
31
|
+
patterns:
|
|
32
|
+
- "fastify*"
|
|
33
|
+
- "@fastify/*"
|
|
34
|
+
update-types:
|
|
35
|
+
- "patch"
|
|
36
|
+
|
|
37
|
+
# GitHub Actions
|
|
38
|
+
- package-ecosystem: "github-actions"
|
|
39
|
+
directory: "/"
|
|
40
|
+
schedule:
|
|
41
|
+
interval: "weekly"
|
|
42
|
+
day: "monday"
|
|
43
|
+
labels:
|
|
44
|
+
- "dependencies"
|
|
45
|
+
- "github-actions"
|
|
46
|
+
commit-message:
|
|
47
|
+
prefix: "ci(deps):"
|
|
48
|
+
|
|
49
|
+
# Docker
|
|
50
|
+
- package-ecosystem: "docker"
|
|
51
|
+
directory: "/"
|
|
52
|
+
schedule:
|
|
53
|
+
interval: "weekly"
|
|
54
|
+
day: "monday"
|
|
55
|
+
labels:
|
|
56
|
+
- "dependencies"
|
|
57
|
+
- "docker"
|
|
58
|
+
commit-message:
|
|
59
|
+
prefix: "chore(deps):"
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, develop]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
NODE_VERSION: '20'
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
lint:
|
|
14
|
+
name: Lint & Format
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Setup Node.js
|
|
20
|
+
uses: actions/setup-node@v4
|
|
21
|
+
with:
|
|
22
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
23
|
+
cache: 'npm'
|
|
24
|
+
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: npm ci
|
|
27
|
+
|
|
28
|
+
- name: Run ESLint
|
|
29
|
+
run: npm run lint
|
|
30
|
+
|
|
31
|
+
- name: Check formatting
|
|
32
|
+
run: npx prettier --check "src/**/*.ts"
|
|
33
|
+
|
|
34
|
+
typecheck:
|
|
35
|
+
name: TypeScript Check
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
|
|
40
|
+
- name: Setup Node.js
|
|
41
|
+
uses: actions/setup-node@v4
|
|
42
|
+
with:
|
|
43
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
44
|
+
cache: 'npm'
|
|
45
|
+
|
|
46
|
+
- name: Install dependencies
|
|
47
|
+
run: npm ci
|
|
48
|
+
|
|
49
|
+
- name: Generate Prisma client
|
|
50
|
+
run: npm run db:generate
|
|
51
|
+
|
|
52
|
+
- name: Run TypeScript check
|
|
53
|
+
run: npm run typecheck
|
|
54
|
+
|
|
55
|
+
build:
|
|
56
|
+
name: Build
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
needs: [lint, typecheck]
|
|
59
|
+
steps:
|
|
60
|
+
- uses: actions/checkout@v4
|
|
61
|
+
|
|
62
|
+
- name: Setup Node.js
|
|
63
|
+
uses: actions/setup-node@v4
|
|
64
|
+
with:
|
|
65
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
66
|
+
cache: 'npm'
|
|
67
|
+
|
|
68
|
+
- name: Install dependencies
|
|
69
|
+
run: npm ci
|
|
70
|
+
|
|
71
|
+
- name: Generate Prisma client
|
|
72
|
+
run: npm run db:generate
|
|
73
|
+
|
|
74
|
+
- name: Build
|
|
75
|
+
run: npm run build
|
|
76
|
+
|
|
77
|
+
- name: Upload build artifacts
|
|
78
|
+
uses: actions/upload-artifact@v4
|
|
79
|
+
with:
|
|
80
|
+
name: dist
|
|
81
|
+
path: dist/
|
|
82
|
+
retention-days: 7
|
|
83
|
+
|
|
84
|
+
test:
|
|
85
|
+
name: Tests
|
|
86
|
+
runs-on: ubuntu-latest
|
|
87
|
+
needs: [lint, typecheck]
|
|
88
|
+
|
|
89
|
+
services:
|
|
90
|
+
postgres:
|
|
91
|
+
image: postgres:16-alpine
|
|
92
|
+
env:
|
|
93
|
+
POSTGRES_USER: postgres
|
|
94
|
+
POSTGRES_PASSWORD: postgres
|
|
95
|
+
POSTGRES_DB: servcraft_test
|
|
96
|
+
ports:
|
|
97
|
+
- 5432:5432
|
|
98
|
+
options: >-
|
|
99
|
+
--health-cmd pg_isready
|
|
100
|
+
--health-interval 10s
|
|
101
|
+
--health-timeout 5s
|
|
102
|
+
--health-retries 5
|
|
103
|
+
|
|
104
|
+
redis:
|
|
105
|
+
image: redis:7-alpine
|
|
106
|
+
ports:
|
|
107
|
+
- 6379:6379
|
|
108
|
+
options: >-
|
|
109
|
+
--health-cmd "redis-cli ping"
|
|
110
|
+
--health-interval 10s
|
|
111
|
+
--health-timeout 5s
|
|
112
|
+
--health-retries 5
|
|
113
|
+
|
|
114
|
+
env:
|
|
115
|
+
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/servcraft_test?schema=public
|
|
116
|
+
REDIS_URL: redis://localhost:6379/1
|
|
117
|
+
JWT_SECRET: test-secret-key-for-ci-testing-purposes-only-32chars
|
|
118
|
+
JWT_REFRESH_SECRET: test-refresh-secret-key-for-ci-purposes-only
|
|
119
|
+
NODE_ENV: test
|
|
120
|
+
|
|
121
|
+
steps:
|
|
122
|
+
- uses: actions/checkout@v4
|
|
123
|
+
|
|
124
|
+
- name: Setup Node.js
|
|
125
|
+
uses: actions/setup-node@v4
|
|
126
|
+
with:
|
|
127
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
128
|
+
cache: 'npm'
|
|
129
|
+
|
|
130
|
+
- name: Install dependencies
|
|
131
|
+
run: npm ci
|
|
132
|
+
|
|
133
|
+
- name: Generate Prisma client
|
|
134
|
+
run: npm run db:generate
|
|
135
|
+
|
|
136
|
+
- name: Push database schema
|
|
137
|
+
run: npx prisma db push --skip-generate
|
|
138
|
+
|
|
139
|
+
- name: Run tests
|
|
140
|
+
run: npm test -- --run
|
|
141
|
+
|
|
142
|
+
- name: Run tests with coverage
|
|
143
|
+
run: npm run test:coverage -- --run
|
|
144
|
+
if: github.event_name == 'pull_request'
|
|
145
|
+
|
|
146
|
+
- name: Upload coverage report
|
|
147
|
+
uses: actions/upload-artifact@v4
|
|
148
|
+
if: github.event_name == 'pull_request'
|
|
149
|
+
with:
|
|
150
|
+
name: coverage
|
|
151
|
+
path: coverage/
|
|
152
|
+
retention-days: 7
|
|
153
|
+
|
|
154
|
+
security:
|
|
155
|
+
name: Security Audit
|
|
156
|
+
runs-on: ubuntu-latest
|
|
157
|
+
steps:
|
|
158
|
+
- uses: actions/checkout@v4
|
|
159
|
+
|
|
160
|
+
- name: Setup Node.js
|
|
161
|
+
uses: actions/setup-node@v4
|
|
162
|
+
with:
|
|
163
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
164
|
+
cache: 'npm'
|
|
165
|
+
|
|
166
|
+
- name: Install dependencies
|
|
167
|
+
run: npm ci
|
|
168
|
+
|
|
169
|
+
- name: Run npm audit
|
|
170
|
+
run: npm audit --audit-level=high
|
|
171
|
+
continue-on-error: true
|
|
172
|
+
|
|
173
|
+
all-checks:
|
|
174
|
+
name: All Checks Passed
|
|
175
|
+
runs-on: ubuntu-latest
|
|
176
|
+
needs: [lint, typecheck, build, test, security]
|
|
177
|
+
if: always()
|
|
178
|
+
steps:
|
|
179
|
+
- name: Check all jobs
|
|
180
|
+
run: |
|
|
181
|
+
if [[ "${{ needs.lint.result }}" != "success" ]] || \
|
|
182
|
+
[[ "${{ needs.typecheck.result }}" != "success" ]] || \
|
|
183
|
+
[[ "${{ needs.build.result }}" != "success" ]] || \
|
|
184
|
+
[[ "${{ needs.test.result }}" != "success" ]]; then
|
|
185
|
+
echo "One or more required jobs failed"
|
|
186
|
+
exit 1
|
|
187
|
+
fi
|
|
188
|
+
echo "All required checks passed!"
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
NODE_VERSION: '20'
|
|
10
|
+
REGISTRY: ghcr.io
|
|
11
|
+
IMAGE_NAME: ${{ github.repository }}
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
validate:
|
|
15
|
+
name: Validate Tag
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
outputs:
|
|
18
|
+
version: ${{ steps.get_version.outputs.version }}
|
|
19
|
+
steps:
|
|
20
|
+
- name: Get version from tag
|
|
21
|
+
id: get_version
|
|
22
|
+
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
|
|
23
|
+
|
|
24
|
+
- name: Validate semver
|
|
25
|
+
run: |
|
|
26
|
+
VERSION=${{ steps.get_version.outputs.version }}
|
|
27
|
+
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then
|
|
28
|
+
echo "Invalid version format: $VERSION"
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
test:
|
|
33
|
+
name: Run Tests
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
needs: validate
|
|
36
|
+
|
|
37
|
+
services:
|
|
38
|
+
postgres:
|
|
39
|
+
image: postgres:16-alpine
|
|
40
|
+
env:
|
|
41
|
+
POSTGRES_USER: postgres
|
|
42
|
+
POSTGRES_PASSWORD: postgres
|
|
43
|
+
POSTGRES_DB: servcraft_test
|
|
44
|
+
ports:
|
|
45
|
+
- 5432:5432
|
|
46
|
+
options: >-
|
|
47
|
+
--health-cmd pg_isready
|
|
48
|
+
--health-interval 10s
|
|
49
|
+
--health-timeout 5s
|
|
50
|
+
--health-retries 5
|
|
51
|
+
|
|
52
|
+
redis:
|
|
53
|
+
image: redis:7-alpine
|
|
54
|
+
ports:
|
|
55
|
+
- 6379:6379
|
|
56
|
+
options: >-
|
|
57
|
+
--health-cmd "redis-cli ping"
|
|
58
|
+
--health-interval 10s
|
|
59
|
+
--health-timeout 5s
|
|
60
|
+
--health-retries 5
|
|
61
|
+
|
|
62
|
+
env:
|
|
63
|
+
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/servcraft_test?schema=public
|
|
64
|
+
REDIS_URL: redis://localhost:6379/1
|
|
65
|
+
JWT_SECRET: test-secret-key-for-ci-testing-purposes-only-32chars
|
|
66
|
+
NODE_ENV: test
|
|
67
|
+
|
|
68
|
+
steps:
|
|
69
|
+
- uses: actions/checkout@v4
|
|
70
|
+
|
|
71
|
+
- name: Setup Node.js
|
|
72
|
+
uses: actions/setup-node@v4
|
|
73
|
+
with:
|
|
74
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
75
|
+
cache: 'npm'
|
|
76
|
+
|
|
77
|
+
- name: Install dependencies
|
|
78
|
+
run: npm ci
|
|
79
|
+
|
|
80
|
+
- name: Generate Prisma client
|
|
81
|
+
run: npm run db:generate
|
|
82
|
+
|
|
83
|
+
- name: Push database schema
|
|
84
|
+
run: npx prisma db push --skip-generate
|
|
85
|
+
|
|
86
|
+
- name: Run tests
|
|
87
|
+
run: npm test -- --run
|
|
88
|
+
|
|
89
|
+
build-and-push:
|
|
90
|
+
name: Build & Push Docker Image
|
|
91
|
+
runs-on: ubuntu-latest
|
|
92
|
+
needs: [validate, test]
|
|
93
|
+
permissions:
|
|
94
|
+
contents: read
|
|
95
|
+
packages: write
|
|
96
|
+
|
|
97
|
+
steps:
|
|
98
|
+
- uses: actions/checkout@v4
|
|
99
|
+
|
|
100
|
+
- name: Log in to Container Registry
|
|
101
|
+
uses: docker/login-action@v3
|
|
102
|
+
with:
|
|
103
|
+
registry: ${{ env.REGISTRY }}
|
|
104
|
+
username: ${{ github.actor }}
|
|
105
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
106
|
+
|
|
107
|
+
- name: Extract metadata
|
|
108
|
+
id: meta
|
|
109
|
+
uses: docker/metadata-action@v5
|
|
110
|
+
with:
|
|
111
|
+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
112
|
+
tags: |
|
|
113
|
+
type=semver,pattern={{version}}
|
|
114
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
115
|
+
type=semver,pattern={{major}}
|
|
116
|
+
type=raw,value=latest,enable={{is_default_branch}}
|
|
117
|
+
|
|
118
|
+
- name: Set up Docker Buildx
|
|
119
|
+
uses: docker/setup-buildx-action@v3
|
|
120
|
+
|
|
121
|
+
- name: Build and push
|
|
122
|
+
uses: docker/build-push-action@v5
|
|
123
|
+
with:
|
|
124
|
+
context: .
|
|
125
|
+
push: true
|
|
126
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
127
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
128
|
+
cache-from: type=gha
|
|
129
|
+
cache-to: type=gha,mode=max
|
|
130
|
+
|
|
131
|
+
create-release:
|
|
132
|
+
name: Create GitHub Release
|
|
133
|
+
runs-on: ubuntu-latest
|
|
134
|
+
needs: [validate, build-and-push]
|
|
135
|
+
permissions:
|
|
136
|
+
contents: write
|
|
137
|
+
|
|
138
|
+
steps:
|
|
139
|
+
- uses: actions/checkout@v4
|
|
140
|
+
with:
|
|
141
|
+
fetch-depth: 0
|
|
142
|
+
|
|
143
|
+
- name: Generate changelog
|
|
144
|
+
id: changelog
|
|
145
|
+
run: |
|
|
146
|
+
# Get previous tag
|
|
147
|
+
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
|
148
|
+
|
|
149
|
+
if [ -z "$PREV_TAG" ]; then
|
|
150
|
+
# First release, get all commits
|
|
151
|
+
CHANGELOG=$(git log --pretty=format:"- %s (%h)" --no-merges)
|
|
152
|
+
else
|
|
153
|
+
# Get commits since previous tag
|
|
154
|
+
CHANGELOG=$(git log $PREV_TAG..HEAD --pretty=format:"- %s (%h)" --no-merges)
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
# Escape for GitHub Actions
|
|
158
|
+
CHANGELOG="${CHANGELOG//'%'/'%25'}"
|
|
159
|
+
CHANGELOG="${CHANGELOG//$'\n'/'%0A'}"
|
|
160
|
+
CHANGELOG="${CHANGELOG//$'\r'/'%0D'}"
|
|
161
|
+
|
|
162
|
+
echo "changelog=$CHANGELOG" >> $GITHUB_OUTPUT
|
|
163
|
+
|
|
164
|
+
- name: Create Release
|
|
165
|
+
uses: softprops/action-gh-release@v1
|
|
166
|
+
with:
|
|
167
|
+
tag_name: ${{ github.ref_name }}
|
|
168
|
+
name: Release ${{ needs.validate.outputs.version }}
|
|
169
|
+
body: |
|
|
170
|
+
## What's Changed
|
|
171
|
+
|
|
172
|
+
${{ steps.changelog.outputs.changelog }}
|
|
173
|
+
|
|
174
|
+
## Docker Image
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.validate.outputs.version }}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Full Changelog
|
|
181
|
+
|
|
182
|
+
https://github.com/${{ github.repository }}/compare/${{ github.event.before }}...${{ github.ref_name }}
|
|
183
|
+
draft: false
|
|
184
|
+
prerelease: ${{ contains(needs.validate.outputs.version, '-') }}
|
|
185
|
+
|
|
186
|
+
notify:
|
|
187
|
+
name: Notify Release
|
|
188
|
+
runs-on: ubuntu-latest
|
|
189
|
+
needs: [validate, create-release]
|
|
190
|
+
if: success()
|
|
191
|
+
steps:
|
|
192
|
+
- name: Release notification
|
|
193
|
+
run: |
|
|
194
|
+
echo "🚀 Version ${{ needs.validate.outputs.version }} has been released!"
|
|
195
|
+
echo "Docker image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.validate.outputs.version }}"
|