This commit is contained in:
nessar committed 2025-11-08 03:00:17 +01:00
1 parent 21bc6a3974
commit fd74cbdfd5
11 files changed
+1214 -21

No files matched your search

+45
View File
@@ -0,0 +1,45 @@
# Dependencies
node_modules
npm-debug.log
yarn-error.log
# Build artifacts
dist
.angular
# IDE and editor files
.vscode
.idea
*.swp
*.swo
*~
# Git
.git
.gitignore
# Docker
Dockerfile
.dockerignore
docker-compose.yml
# Testing
coverage
.karma
*.spec.ts
# Environment files
.env
.env.local
.env.*.local
# OS files
.DS_Store
Thumbs.db
# Misc
README.md
.editorconfig
.prettierrc
.eslintrc.json
*.md
+34
View File
@@ -0,0 +1,34 @@
version: 2
updates:
# Enable version updates for npm
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: 'weekly'
day: 'monday'
open-pull-requests-limit: 10
groups:
angular:
patterns:
- '@angular/*'
development-dependencies:
dependency-type: 'development'
update-types:
- 'minor'
- 'patch'
# Enable version updates for GitHub Actions
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'weekly'
day: 'monday'
open-pull-requests-limit: 5
# Enable version updates for Docker
- package-ecosystem: 'docker'
directory: '/'
schedule:
interval: 'weekly'
day: 'monday'
open-pull-requests-limit: 5
+41
View File
@@ -0,0 +1,41 @@
name: CodeQL Security Analysis
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 1' # Run every Monday at midnight UTC
jobs:
analyze:
name: Analyze Code
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
strategy:
fail-fast: false
matrix:
language: ['javascript-typescript']
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-extended,security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: '/language:${{matrix.language}}'
+65
View File
@@ -0,0 +1,65 @@
name: Docker Build and Push
on:
push:
branches: [main]
release:
types: [published]
workflow_dispatch:
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
security-events: write
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push
id: build
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.27.0
with:
image-ref: ghcr.io/thoguet/vac-optimizer@${{ steps.build.outputs.digest }}
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: 'trivy-results.sarif'
+105
View File
@@ -0,0 +1,105 @@
name: PR Validation
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
lint:
name: Lint Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Check code formatting with Prettier
run: npx prettier --check "src/**/*.{ts,html,scss,css,json}"
- name: Run ESLint
run: npx eslint "src/**/*.ts"
type-check:
name: TypeScript Type Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run TypeScript compiler
run: npx tsc --noEmit
test:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run unit tests
run: npm test -- --watch=false --browsers=ChromeHeadless --code-coverage
- name: Upload coverage reports
uses: codecov/codecov-action@v4
if: always()
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/vac-optimizer/lcov.info
fail_ci_if_error: false
build:
name: Build Application
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build production bundle
run: npm run build -- --configuration production
env:
NG_BUILD_CACHE: '.angular/cache'
- name: Check bundle size
run: |
du -sh dist/vac-optimizer/browser
echo "Build completed successfully"
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: dist/
retention-days: 7
+45
View File
@@ -0,0 +1,45 @@
# Stage 1: Build the Angular application
FROM node:20-alpine AS builder
# Set working directory
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production=false
# Copy source code
COPY . .
# Build the application for production
RUN npm run build
# Stage 2: Production image
FROM node:20-alpine AS production
# Set working directory
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install only production dependencies
RUN npm ci --only=production && npm cache clean --force
# Copy built application from builder stage
COPY --from=builder /app/dist ./dist
# Set environment to production
ENV NODE_ENV=production
# Expose port (default Express port)
EXPOSE 4000
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD node -e "require('http').get('http://localhost:4000', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
# Start the application
CMD ["node", "dist/vac-optimizer/server/server.mjs"]
+49
View File
@@ -0,0 +1,49 @@
services:
vac-optimizer:
build:
context: .
dockerfile: Dockerfile
image: vac-optimizer:latest
container_name: vac-optimizer-prod
restart: always
ports:
- '80:4000'
environment:
- NODE_ENV=production
- PORT=4000
healthcheck:
test:
[
'CMD',
'node',
'-e',
"require('http').get('http://localhost:4000', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})",
]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
logging:
driver: 'json-file'
options:
max-size: '10m'
max-file: '3'
networks:
- vac-optimizer-network
networks:
vac-optimizer-network:
driver: bridge
+31
View File
@@ -0,0 +1,31 @@
services:
vac-optimizer:
build:
context: .
dockerfile: Dockerfile
image: vac-optimizer:latest
container_name: vac-optimizer
restart: unless-stopped
ports:
- '4000:4000'
environment:
- NODE_ENV=production
- PORT=4000
healthcheck:
test:
[
'CMD',
'node',
'-e',
"require('http').get('http://localhost:4000', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})",
]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
- vac-optimizer-network
networks:
vac-optimizer-network:
driver: bridge
+34
View File
@@ -0,0 +1,34 @@
import eslintJs from '@eslint/js';
import tseslint from 'typescript-eslint';
import prettier from 'eslint-config-prettier';
import prettierPlugin from 'eslint-plugin-prettier';
export default [
eslintJs.configs.recommended,
...tseslint.configs.recommended,
prettier,
{
files: ['**/*.ts'],
plugins: {
prettier: prettierPlugin,
},
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
'prettier/prettier': 'error',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
],
},
},
{
ignores: ['dist/**', 'node_modules/**', '.angular/**', 'coverage/**'],
},
];
+764 -21
View File
File diff suppressed because it is too large. Load diff
+1
View File
@@ -39,6 +39,7 @@
"@fortawesome/free-brands-svg-icons": "^7.0.0",
"@fortawesome/free-regular-svg-icons": "^7.0.0",
"@fortawesome/free-solid-svg-icons": "^7.0.0",
"eslint": "^9.39.1",
"express": "^5.1.0",
"http-proxy-middleware": "^3.0.5",
"rxjs": "~7.8.0",