A temperature unit converter (Celsius, Fahrenheit, Kelvin) built with Node.js and paired with a complete Jenkins CI/CD pipeline demonstrating automated build, test, Docker image creation, and deployment stages.
The application itself is deliberately simple — the purpose of this project is to demonstrate a production-quality DevOps pipeline configuration that can be adapted to any Node.js project.
- Application Overview
- Pipeline Overview
- Tech Stack
- Prerequisites
- Local Setup
- Running the Converter
- Running Tests
- Jenkins Pipeline Configuration
- Docker
- Project Structure
- Conversion Formulas
- Contributing
- License
The converter exposes both a programmatic API (importable Node.js module) and a simple CLI for quick conversions:
node app.js 100 C F # 100 Celsius → Fahrenheit → 212
node app.js 32 F C # 32 Fahrenheit → Celsius → 0
node app.js 0 C K # 0 Celsius → Kelvin → 273.15It is fully unit-tested with 100% code coverage and validates all inputs before processing.
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Checkout │ -> │ Install │ -> │ Test │ -> │ Build │ -> │ Deploy │
│ Code │ │ Deps │ │ Coverage │ │ Docker │ │ Image │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
Every push to main or develop triggers the full pipeline. Pull requests trigger up to the Test stage only (no deployment).
| Stage | Command | Failure behavior |
|---|---|---|
| Checkout | SCM checkout | Abort |
| Install | npm ci |
Abort |
| Lint | npm run lint |
Fail build |
| Test | npm test -- --coverage |
Fail build |
| Coverage Gate | Enforce >= 80% | Fail build |
| Build Image | docker build |
Fail build |
| Push Image | Push to registry | Fail build |
| Deploy | Rolling update | Notify only |
| Component | Technology |
|---|---|
| Runtime | Node.js 18.x |
| Testing | Jest 29.x |
| Linting | ESLint |
| CI/CD | Jenkins 2.x |
| Containerization | Docker 24.x |
| Registry | Docker Hub or private registry |
For local development:
For the full pipeline:
- Jenkins server with the following plugins:
- Pipeline
- Docker Pipeline
- Git
- JUnit (for test result publishing)
- Cobertura or Coverage (for coverage reports)
- Docker installed on the Jenkins agent
- Access to a Docker registry (Docker Hub or private)
git clone https://github.com/Salmanahmed1078/Temperature-Converter-Jenkines-Pipeline.git
cd Temperature-Converter-Jenkines-Pipeline
npm installnode app.js <value> <from_unit> <to_unit>| Argument | Valid values |
|---|---|
value |
Any number (integer or decimal) |
from_unit |
C (Celsius), F (Fahrenheit), K (Kelvin) |
to_unit |
C, F, or K (different from from_unit) |
Examples:
node app.js 37 C F # Body temperature: 98.6°F
node app.js 212 F C # Boiling point: 100°C
node app.js 300 K C # 300K in Celsius: 26.85°C
node app.js -40 C F # -40°C = -40°F (they converge here)const { convert } = require('./src/converter');
console.log(convert(100, 'C', 'F')); // 212
console.log(convert(32, 'F', 'C')); // 0
console.log(convert(0, 'C', 'K')); // 273.15
console.log(convert(373.15, 'K', 'F')); // 212# Run all tests
npm test
# Run with coverage report
npm run test:coverage
# Watch mode during development
npm run test:watchCoverage output is written to coverage/ and also published as a Jenkins artifact. The pipeline enforces a minimum 80% coverage threshold — builds below this threshold are marked as failed.
In Jenkins:
- New Item > Pipeline
- Under Pipeline, select Pipeline script from SCM
- SCM: Git, Repository URL: your fork URL
- Script Path:
Jenkinsfile
In Jenkins > Credentials, add:
DOCKER_CREDENTIALS— Docker Hub username and passwordDEPLOY_SSH_KEY— SSH private key for deployment target (if applicable)
The Jenkinsfile reads the following environment variables:
environment {
DOCKER_IMAGE = 'your-dockerhub-username/temperature-converter'
DOCKER_TAG = "${BUILD_NUMBER}"
REGISTRY = 'https://registry.hub.docker.com'
}Edit these in the Jenkinsfile before running the pipeline.
Push any commit to main — the webhook (configured in Jenkins > your repo) triggers the pipeline automatically. Or click Build Now to trigger manually.
docker build -t temperature-converter:latest .docker run --rm temperature-converter:latest node app.js 100 C F
# Output: 212docker-compose upThis starts the converter with a simple HTTP wrapper at http://localhost:3000:
curl "http://localhost:3000/convert?value=100&from=C&to=F"
# {"result": 212, "unit": "F"}Temperature-Converter-Jenkines-Pipeline/
├── src/
│ ├── converter.js # Core conversion logic
│ ├── validator.js # Input validation
│ └── units.js # Unit constants and metadata
├── tests/
│ ├── converter.test.js # Unit tests for all conversions
│ ├── validator.test.js # Input validation tests
│ └── edge-cases.test.js # Boundary and error conditions
├── app.js # CLI entry point
├── server.js # Optional HTTP wrapper
├── Jenkinsfile # Pipeline definition
├── Dockerfile
├── docker-compose.yml
├── .eslintrc.js
├── jest.config.js
└── package.json
| From | To | Formula |
|---|---|---|
| Celsius | Fahrenheit | (C × 9/5) + 32 |
| Celsius | Kelvin | C + 273.15 |
| Fahrenheit | Celsius | (F − 32) × 5/9 |
| Fahrenheit | Kelvin | (F − 32) × 5/9 + 273.15 |
| Kelvin | Celsius | K − 273.15 |
| Kelvin | Fahrenheit | (K − 273.15) × 9/5 + 32 |
All results are rounded to 2 decimal places unless the result is a whole number.
- Fork the repository
- Create a feature branch:
git checkout -b feat/your-feature - Ensure
npm run lintandnpm testboth pass - Open a pull request with a clear description
MIT © Salman Ahmed