Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0ee94c0
initiated dev environment
Zaiidmo Mar 29, 2026
7234e61
ops (ci): standardize publish validation and dependabot across all pa…
Zaiidmo Mar 30, 2026
f797ab7
security: added CODEOWNER file for branches security \\
Zaiidmo Mar 30, 2026
a199f1e
ops: updated relese check workflow#
Zaiidmo Mar 31, 2026
afcf4dd
chore(config): add @interfaces/* and @indicators/* path aliases
SAAD-MOUMOU Mar 31, 2026
2e42a1d
chore(config): rename eslint.config.js to .mjs to fix ESM loading
SAAD-MOUMOU Mar 31, 2026
f856137
chore(git): fix husky pre-commit hook for v10 compatibility
SAAD-MOUMOU Mar 31, 2026
c74b8ae
feat(interfaces): add IHealthIndicator, HealthStatus, HealthIndicator…
SAAD-MOUMOU Mar 31, 2026
41d7af3
feat(indicators): add PostgresHealthIndicator (SELECT 1 + timeout)
SAAD-MOUMOU Mar 31, 2026
8f9af5e
test(indicators): add PostgresHealthIndicator unit tests (success/err…
SAAD-MOUMOU Mar 31, 2026
5dff0e2
feat(indicators): add RedisHealthIndicator (PING + timeout)
SAAD-MOUMOU Mar 31, 2026
af6f235
test(indicators): add RedisHealthIndicator unit tests (success/error/…
SAAD-MOUMOU Mar 31, 2026
a5d8377
feat(indicators): add HttpHealthIndicator (GET + 2xx check + timeout)
SAAD-MOUMOU Mar 31, 2026
914f341
test(indicators): add HttpHealthIndicator unit tests (2xx/non-2xx/net…
SAAD-MOUMOU Mar 31, 2026
60eedae
chore(deps): update package-lock after npm install
SAAD-MOUMOU Mar 31, 2026
f27a411
chore(config): set module to CommonJS and moduleResolution to Node fo…
SAAD-MOUMOU Apr 1, 2026
a3ff296
chore(package): rename to @ciscode/health-kit
SAAD-MOUMOU Apr 1, 2026
e732894
chore(deps): update package-lock
SAAD-MOUMOU Apr 1, 2026
15f7b7f
feat(indicators): add MongoHealthIndicator with ping command and timeout
SAAD-MOUMOU Apr 1, 2026
686dc9e
test(indicators): add MongoHealthIndicator unit tests (success/error/…
SAAD-MOUMOU Apr 1, 2026
90f4e9d
feat(services): add HealthService with Promise.allSettled orchestration
SAAD-MOUMOU Apr 1, 2026
e0c0e53
test(services): add HealthService unit tests (liveness/readiness/conc…
SAAD-MOUMOU Apr 1, 2026
de52d73
feat(controllers): add HealthController factory (GET live/ready, plat…
SAAD-MOUMOU Apr 1, 2026
840988c
I health indicator interface and built in indicators (#1)
saadmoumou Apr 1, 2026
224ad90
test(controllers): add HealthController unit tests (200 ok / 503 Serv…
SAAD-MOUMOU Apr 1, 2026
831dcc1
feat(module): add HealthKitModule.register() dynamic module
SAAD-MOUMOU Apr 1, 2026
5b5f872
feat(exports): update public API exports for health-kit
SAAD-MOUMOU Apr 1, 2026
e96fab9
Merge branch 'develop' into HealthModule-and-health-endpoints
saadmoumou Apr 2, 2026
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
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @CISCODE-MA/devops
20 changes: 20 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/"
schedule:
interval: monthly
open-pull-requests-limit: 1
groups:
npm-dependencies:
patterns:
- "*"
assignees:
- CISCODE-MA/cloud-devops
labels:
- "dependencies"
- "npm"
commit-message:
prefix: "chore(deps)"
include: "scope"
rebase-strategy: auto
2 changes: 1 addition & 1 deletion .github/workflows/pr-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: npm

- name: Install
Expand Down
66 changes: 52 additions & 14 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,82 @@
name: Publish to NPM

on:
# push:
# tags:
# - "v*.*.*"
push:
branches:
- master
workflow_dispatch:

jobs:
publish:
runs-on: ubuntu-latest

permissions:
contents: read
packages: write
id-token: write

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Validate version tag and package.json
run: |
PKG_VERSION=$(grep '"version"' package.json | head -1 | sed 's/.*"version": "\([^"]*\)".*/\1/')
TAG="v${PKG_VERSION}"

if [[ -z "$PKG_VERSION" ]]; then
echo "❌ ERROR: Could not read version from package.json"
exit 1
fi

if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ ERROR: Invalid version format in package.json: '$PKG_VERSION'"
echo "Expected format: x.y.z (e.g., 1.0.0, 0.2.3)"
exit 1
fi

if ! git rev-parse "$TAG" >/dev/null 2>&1; then
echo "❌ ERROR: Tag $TAG not found!"
echo ""
echo "This typically happens when:"
echo " 1. You forgot to run 'npm version patch|minor|major' on your feature branch"
echo " 2. You didn't push the tag: git push origin <feat/your-feature> --tags"
echo " 3. The tag was created locally but never pushed to remote"
echo ""
echo "📋 Correct workflow:"
echo " 1. On feat/** or feature/**: npm version patch (or minor/major)"
echo " 2. Push branch + tag: git push origin feat/your-feature --tags"
echo " 3. PR feat/** → develop, then PR develop → master"
echo " 4. Workflow automatically triggers on master push"
echo ""
exit 1
fi

echo "✅ package.json version: $PKG_VERSION"
echo "✅ Tag $TAG exists in repo"
Comment on lines +55 to +57
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tag validation only checks that the version tag exists somewhere in the repo; it does not verify that the current commit being published is actually tagged with that version. Consider asserting the tag points at HEAD (or at least that package.json version matches the commit tag) to prevent publishing an unintended revision.

Suggested change
echo "✅ package.json version: $PKG_VERSION"
echo "✅ Tag $TAG exists in repo"
HEAD_SHA=$(git rev-parse HEAD)
TAG_SHA=$(git rev-parse "$TAG")
if [[ "$HEAD_SHA" != "$TAG_SHA" ]]; then
echo "❌ ERROR: Tag $TAG does not point at HEAD."
echo ""
echo "HEAD commit: $HEAD_SHA"
echo "Tag commit: $TAG_SHA"
echo ""
echo "Ensure that the commit being pushed to master is the one tagged with $TAG."
echo "Typically you should:"
echo " 1. Create the version with 'npm version patch|minor|major' on the release commit"
echo " 2. Push branch + tag so that $TAG points at the commit being published"
exit 1
fi
echo "✅ package.json version: $PKG_VERSION"
echo "✅ Tag $TAG exists in repo"
echo "✅ Tag $TAG points at HEAD"

Copilot uses AI. Check for mistakes.
echo "TAG_VERSION=$TAG" >> $GITHUB_ENV

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
node-version: "22"
registry-url: "https://registry.npmjs.org"
cache: "npm"

- name: Install dependencies
run: npm ci

- name: Run lint (if present)
run: npm run lint --if-present
continue-on-error: false
- name: Build
run: npm run build --if-present

- name: Run tests (if present)
run: npm test --if-present
continue-on-error: false
- name: Lint
run: npm run lint --if-present 2>/dev/null || true

- name: Build package
run: npm run build
- name: Test
run: npm test --if-present 2>/dev/null || true
Comment on lines +70 to +77
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lint/test steps swallow failures (|| true), so the workflow can publish even when linting or tests fail. Remove the error suppression so publishing is blocked on failing checks (or make it explicitly conditional with a separate opt-in).

Copilot uses AI. Check for mistakes.

- name: Publish to NPM
run: npm publish --access public
run: npm publish --access public --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
39 changes: 22 additions & 17 deletions .github/workflows/release-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@ name: CI - Release Check
on:
pull_request:
branches: [master]
workflow_dispatch:
inputs:
sonar:
description: "Run SonarCloud analysis"
required: true
default: "false"
type: choice
options:
- "false"
- "true"

concurrency:
group: ci-release-${{ github.ref }}
Expand All @@ -22,13 +12,17 @@ jobs:
ci:
name: release checks
runs-on: ubuntu-latest

permissions:
contents: read
statuses: write
timeout-minutes: 25

# Config stays in the workflow file (token stays in repo secrets)
env:
SONAR_HOST_URL: "https://sonarcloud.io"
SONAR_ORGANIZATION: "ciscode"
SONAR_PROJECT_KEY: "CISCODE-MA_LoggingKit"
SONAR_PROJECT_KEY: "CISCODE-MA_HealthKit"

steps:
- name: Checkout
Expand Down Expand Up @@ -61,23 +55,34 @@ jobs:
run: npm run build

- name: SonarCloud Scan
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.sonar == 'true' }}
uses: SonarSource/sonarqube-scan-action@v6
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ env.SONAR_HOST_URL }}
with:
args: >
-Dsonar.organization=${{ env.SONAR_ORGANIZATION }} \
-Dsonar.projectKey=${{ env.SONAR_PROJECT_KEY }} \
-Dsonar.sources=src \
-Dsonar.tests=test \
-Dsonar.organization=${{ env.SONAR_ORGANIZATION }}
-Dsonar.projectKey=${{ env.SONAR_PROJECT_KEY }}
-Dsonar.sources=src
-Dsonar.tests=test
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sonar is configured with -Dsonar.tests=test, but this repo’s Jest config also places many tests under src/**/*.spec.ts. As-is, Sonar may treat src/**/*.spec.ts as source code (or miss tests/coverage attribution). Consider setting sonar.tests to include src (or adding explicit sonar.test.inclusions / sonar.exclusions for **/*.spec.ts).

Suggested change
-Dsonar.tests=test
-Dsonar.tests=src,test
-Dsonar.test.inclusions=**/*.spec.ts

Copilot uses AI. Check for mistakes.
-Dsonar.javascript.lcov.reportPaths=coverage/lcov.info

- name: SonarCloud Quality Gate
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.sonar == 'true' }}
uses: SonarSource/sonarqube-quality-gate-action@v1
timeout-minutes: 10
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ env.SONAR_HOST_URL }}

- name: Report CI status
if: always()
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: context.sha,
state: '${{ job.status }}' === 'success' ? 'success' : 'failure',
description: 'CI checks completed'
})
3 changes: 0 additions & 3 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hook is missing the usual husky bootstrap (#!/usr/bin/env sh and sourcing ./_/husky.sh). Without it, PATH setup and Husky’s skip logic can break on some environments and it’s inconsistent with the pre-push hook. Restore the standard Husky header for reliability.

Copilot uses AI. Check for mistakes.
80 changes: 0 additions & 80 deletions eslint.config.js

This file was deleted.

76 changes: 57 additions & 19 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,42 +1,80 @@
// @ts-check
import eslint from "@eslint/js";
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
import globals from "globals";
import importPlugin from "eslint-plugin-import";
import tseslint from "typescript-eslint";

export default tseslint.config(
export default [
{
ignores: ["eslint.config.mjs"],
ignores: [
"dist/**",
"coverage/**",
"node_modules/**",
// Ignore all example files for CSR architecture
"src/example-kit.*",
"src/controllers/example.controller.ts",
"src/services/example.service.ts",
"src/entities/example.entity.ts",
"src/repositories/example.repository.ts",
"src/guards/example.guard.ts",
"src/decorators/example.decorator.ts",
"src/dto/create-example.dto.ts",
"src/dto/update-example.dto.ts",
],
},

eslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
eslintPluginPrettierRecommended,

// TypeScript ESLint (includes recommended rules)
...tseslint.configs.recommended,

// Base TS rules (all TS files)
{
files: ["**/*.ts"],
languageOptions: {
globals: {
...globals.node,
...globals.jest,
},
sourceType: "commonjs",
parser: tseslint.parser,
parserOptions: {
projectService: true,
project: "./tsconfig.eslint.json",
tsconfigRootDir: import.meta.dirname,
ecmaVersion: "latest",
sourceType: "module",
},
globals: { ...globals.node, ...globals.jest },
},
plugins: {
"@typescript-eslint": tseslint.plugin,
import: importPlugin,
},
rules: {
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
"@typescript-eslint/consistent-type-imports": ["error", { prefer: "type-imports" }],

"import/no-duplicates": "error",
"import/order": [
"error",
{
"newlines-between": "always",
alphabetize: { order: "asc", caseInsensitive: true },
},
],
},
},

// Architecture boundary: core must not import Nest
{
files: ["src/core/**/*.ts"],
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-floating-promises": "warn",
"@typescript-eslint/no-unsafe-argument": "warn",
"@typescript-eslint/no-unused-vars": [
"no-restricted-imports": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
patterns: [
{
group: ["@nestjs/*"],
message: "Do not import NestJS in core/. Keep core framework-free.",
},
],
},
],
"no-unused-vars": "off",
},
},
);
];
Loading
Loading