Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 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
840988c
I health indicator interface and built in indicators (#1)
saadmoumou Apr 1, 2026
6c73aac
Health module and health endpoints (#2)
saadmoumou Apr 2, 2026
639590a
Ihealth indicator interface and built in indicators (#3)
saadmoumou Apr 2, 2026
2285e52
Health module and health endpoints (#5)
saadmoumou Apr 2, 2026
66e667b
Custom indicator api and health service (#7)
saadmoumou Apr 2, 2026
f6e9b89
Feat/compt 80 ihealth indicator interface and built in indicators (#8)
saadmoumou Apr 2, 2026
32d84b4
Feat/compt 81 health module and health endpoints (#9)
saadmoumou Apr 2, 2026
029d320
Feat/compt 82 custom indicator api and health service (#11)
saadmoumou Apr 2, 2026
fb8ea34
Feat/compt 80 ihealth indicator interface and built in indicators (#12)
saadmoumou Apr 2, 2026
beddae8
Feat/compt 81 health module and health endpoints (#18)
saadmoumou Apr 2, 2026
0e1d258
Feat/compt 82 custom indicator api and health service (#23)
saadmoumou Apr 2, 2026
3162d4d
Feat/compt 83 testing suite (#25)
saadmoumou Apr 2, 2026
d37d01b
Feat/compt 84 readme changeset publish v0.1.0 (#26)
saadmoumou Apr 2, 2026
1b1f44a
docs(readme): rewrite README and add changeset for v0.1.0 (#28)
saadmoumou Apr 3, 2026
4a0c2b0
Feat/compt 84 readme changeset publish v0.1.0 (#30)
saadmoumou Apr 3, 2026
e6941b2
chore(release): version packages (#31)
saadmoumou Apr 3, 2026
3af194e
ci: update release check workflow
Zaiidmo Apr 6, 2026
40692ef
ops: updated release check jobs
Zaiidmo Apr 7, 2026
0740776
Merge branch 'develop' of github.com:CISCODE-MA/HealthKit into develop
Zaiidmo Apr 7, 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
2 changes: 1 addition & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"baseBranch": "develop",
"updateInternalDependencies": "patch",
"ignore": [],
"repo": "ciscode/nest-js-developer-kit",
"repo": "CISCODE-MA/HealthKit",
"preState": null
}
5 changes: 0 additions & 5 deletions .changeset/thick-maps-raise.md

This file was deleted.

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

Comment on lines +23 to +55
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

This publish workflow requires a v${package.json version} git tag to already exist, but the repo’s release flow uses Changesets (npm run release / changeset publish) which does not inherently create git tags. Unless tagging is guaranteed elsewhere, this step will block publishes; consider removing the tag requirement or generating/verifying tags as part of the Changesets release process instead.

Copilot uses AI. Check for mistakes.
echo "✅ package.json version: $PKG_VERSION"
echo "✅ Tag $TAG exists in repo"
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

- name: Publish to NPM
run: npm publish --access public
run: npm publish --access public --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
181 changes: 148 additions & 33 deletions .github/workflows/release-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,44 @@ 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 }}
cancel-in-progress: true

env:
SONAR_HOST_URL: "https://sonarcloud.io"
SONAR_ORGANIZATION: "ciscode"
SONAR_PROJECT_KEY: "CISCODE-MA_HealthKit"
NODE_VERSION: "22"

# ─── Job 1: Static checks (fast feedback, runs in parallel with test) ──────────
jobs:
ci:
name: release checks
quality:
name: Quality Checks
runs-on: ubuntu-latest
timeout-minutes: 25
timeout-minutes: 10

# 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"
permissions:
contents: read

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

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "22"
node-version: ${{ env.NODE_VERSION }}
cache: "npm"

- name: Install
run: npm ci

- name: Security Audit
# Only fail on high/critical — moderate noise in dev deps is expected
run: npm audit --production --audit-level=high

- name: Format
run: npm run format

Expand All @@ -54,30 +50,149 @@ jobs:
- name: Lint
run: npm run lint

# ─── Job 2: Tests + Coverage (artifact passed to Sonar) ────────────────────────
test:
name: Test & Coverage
runs-on: ubuntu-latest
timeout-minutes: 15

permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"

- name: Install
run: npm ci

- name: Test (with coverage)
run: npm run test:cov

- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
retention-days: 1

# ─── Job 3: Build ──────────────────────────────────────────────────────────────
build:
name: Build
runs-on: ubuntu-latest
needs: [quality, test]
timeout-minutes: 10

permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"

- name: Install
run: npm ci

- name: Build
run: npm run build

# ─── Job 4: SonarCloud (depends on test for coverage data) ─────────────────────
sonar:
name: SonarCloud Analysis
runs-on: ubuntu-latest
needs: [test]
timeout-minutes: 15

permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@v4
with:
# Full history required for accurate blame & new code detection
fetch-depth: 0

- name: Download coverage report
uses: actions/download-artifact@v4
with:
name: coverage-report
path: coverage/

- name: Cache SonarCloud packages
uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: sonar-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: sonar-${{ runner.os }}-

- 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
-Dsonar.test.inclusions=**/*.spec.ts,**/*.test.ts
-Dsonar.exclusions=**/node_modules/**,**/dist/**,**/coverage/**,**/*.d.ts
-Dsonar.coverage.exclusions=**/*.spec.ts,**/*.test.ts,**/index.ts
-Dsonar.javascript.lcov.reportPaths=coverage/lcov.info
-Dsonar.typescript.tsconfigPath=tsconfig.json
-Dsonar.qualitygate.wait=true
-Dsonar.qualitygate.timeout=300

- 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 }}
# ─── Job 5: Final status report (always runs) ──────────────────────────────────
report:
name: Report CI Status
runs-on: ubuntu-latest
needs: [quality, test, build, sonar]
# Run even if upstream jobs failed
if: always()
timeout-minutes: 5

permissions:
contents: read
statuses: write

steps:
- name: Resolve overall result
id: result
run: |
results="${{ needs.quality.result }} ${{ needs.test.result }} ${{ needs.build.result }} ${{ needs.sonar.result }}"
if echo "$results" | grep -qE "failure|cancelled"; then
echo "state=failure" >> $GITHUB_OUTPUT
echo "desc=One or more CI checks failed" >> $GITHUB_OUTPUT
else
echo "state=success" >> $GITHUB_OUTPUT
echo "desc=All CI checks passed" >> $GITHUB_OUTPUT
fi

- name: Post commit status
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: context.sha,
state: '${{ steps.result.outputs.state }}',
context: 'CI / Release Check',
description: '${{ steps.result.outputs.desc }}',
target_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`
})
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 3, 2026

Choose a reason for hiding this comment

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

This Husky hook no longer has a shebang or the standard husky.sh bootstrap. On many systems Git expects hooks to be executable scripts; without the shebang/bootstrapping this may fail to run. Restore the Husky header (or ensure the file is executable and uses a proper interpreter).

Copilot uses AI. Check for mistakes.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# @ciscode/health-kit

## 0.1.0

### Minor Changes

- 1b1f44a: Initial release of `@ciscode/health-kit` v0.1.0.

### Features
- `HealthKitModule.register()` and `registerAsync()` — dynamic NestJS module with configurable liveness and readiness probes
- Built-in `PostgresHealthIndicator` (`SELECT 1`), `RedisHealthIndicator` (`PING`), `HttpHealthIndicator` (GET 2xx check) — all with configurable timeout
- `createIndicator(name, fn)` — inline factory for simple custom indicators
- `BaseHealthIndicator` abstract class + `@HealthIndicator('liveness' | 'readiness')` decorator for DI-based custom indicators
- `GET /{path}/live` and `GET /{path}/ready` endpoints — 200 OK / 503 with `{ status, results[] }` body
- All indicators run concurrently via `Promise.allSettled`
- `path` option defaults to `"health"`
Loading
Loading