Skip to content

Commit 39d1365

Browse files
committed
Implement CI ci.yml tests.yml update config.py load_postgres.py pyproject.toml
1 parent dd9ce65 commit 39d1365

File tree

5 files changed

+211
-5
lines changed

5 files changed

+211
-5
lines changed

.github/workflows/ci.yml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: CI Pipeline
2+
3+
on:
4+
push:
5+
branches:
6+
- dev
7+
pull_request:
8+
branches:
9+
- staging
10+
- main
11+
12+
env:
13+
NIFIPULSE_AUTO_ENV: "1"
14+
PGUSER: postgres
15+
PGPASSWORD: postgres
16+
PGHOST: localhost
17+
PGPORT: "5432"
18+
PGDATABASE: metrics_db
19+
20+
jobs:
21+
build-test-dev:
22+
if: github.ref == 'refs/heads/dev'
23+
runs-on: ubuntu-latest
24+
25+
steps:
26+
- uses: actions/checkout@v4
27+
28+
# Install dependencies (change this depending on your stack)
29+
- name: Set up Python
30+
uses: actions/setup-python@v5
31+
with:
32+
python-version: '3.11'
33+
34+
- name: Install dependencies
35+
run: |
36+
pip install -U pip
37+
pip install -e .
38+
pip install flake8
39+
40+
- name: Lint
41+
run: |
42+
pip install flake8
43+
flake8 .
44+
45+
- name: Docker build (dev)
46+
run: |
47+
docker build -t nifipulse-dev .
48+
49+
integration-test-staging:
50+
if: github.event.pull_request.base.ref == 'staging'
51+
runs-on: ubuntu-latest
52+
53+
steps:
54+
- uses: actions/checkout@v4
55+
56+
- name: Docker build
57+
run: docker build -t nifipulse-staging .
58+
59+
- name: Docker compose up
60+
run: docker compose -f docker-compose.yml up -d
61+
62+
- name: Wait for services
63+
run: sleep 15
64+
65+
- name: Integration tests
66+
run: |
67+
pip install -r tests/requirements.txt
68+
pytest tests/integration
69+
70+
release-main:
71+
if: github.event.pull_request.base.ref == 'main'
72+
runs-on: ubuntu-latest
73+
74+
steps:
75+
- uses: actions/checkout@v4
76+
77+
- name: Docker build (prod)
78+
run: docker build -t nifipulse-prod .
79+
80+
- name: Tag release
81+
run: |
82+
VERSION="v1.${{ github.run_number }}"
83+
echo "Tagging version: $VERSION"
84+
git tag $VERSION
85+
git push origin $VERSION
86+
87+
- name: Push to container registry
88+
run: |
89+
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
90+
docker tag nifipulse-prod myregistry/nifipulse:$VERSION
91+
docker push myregistry/nifipulse:$VERSION

.github/workflows/tests.yml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [ dev ]
6+
pull_request:
7+
branches: [ dev, staging, main ]
8+
9+
jobs:
10+
unit-integration:
11+
runs-on: ubuntu-latest
12+
13+
services:
14+
postgres:
15+
image: postgres:15-alpine
16+
env:
17+
POSTGRES_USER: postgres
18+
POSTGRES_PASSWORD: postgres
19+
POSTGRES_DB: metrics_db
20+
ports:
21+
- 5432:5432
22+
options: >-
23+
--health-cmd="pg_isready -U postgres -d metrics_db"
24+
--health-interval=5s
25+
--health-timeout=5s
26+
--health-retries=12
27+
28+
steps:
29+
- uses: actions/checkout@v4
30+
31+
- uses: actions/setup-python@v5
32+
with:
33+
python-version: '3.11'
34+
35+
- name: Install project and test deps
36+
run: |
37+
pip install -U pip
38+
pip install -e .
39+
pip install pytest "sqlalchemy>=2" psycopg2-binary pandas requests
40+
41+
- name: Wait for Postgres
42+
run: |
43+
python - <<'PY'
44+
import time, psycopg2
45+
for i in range(30):
46+
try:
47+
psycopg2.connect(host="localhost", port=5432, user="postgres", password="postgres", dbname="metrics_db").close()
48+
print("Postgres ready"); break
49+
except Exception as e:
50+
print("Waiting...", e); time.sleep(2)
51+
else:
52+
raise SystemExit("Postgres not ready")
53+
PY
54+
55+
- name: Initialize schema (SQLAlchemy)
56+
run: |
57+
python - <<'PY'
58+
from sqlalchemy import create_engine, text
59+
ddl = """
60+
CREATE TABLE IF NOT EXISTS dim_instance (instance_id SERIAL PRIMARY KEY, instance_name TEXT UNIQUE NOT NULL);
61+
CREATE TABLE IF NOT EXISTS dim_metric (metric_id SERIAL PRIMARY KEY, metric_name TEXT UNIQUE NOT NULL, original_unit TEXT);
62+
CREATE TABLE IF NOT EXISTS dim_component (component_id SERIAL PRIMARY KEY, component_name TEXT NOT NULL, component_type TEXT NOT NULL, UNIQUE (component_name, component_type));
63+
CREATE TABLE IF NOT EXISTS dim_date (date_id SERIAL PRIMARY KEY, timestamp_utc TIMESTAMPTZ UNIQUE NOT NULL, year INT, month INT, day INT, hour INT, minute INT, second INT);
64+
CREATE TABLE IF NOT EXISTS fact_metrics (fact_id SERIAL PRIMARY KEY, date_id INT REFERENCES dim_date(date_id), instance_id INT REFERENCES dim_instance(instance_id), metric_id INT REFERENCES dim_metric(metric_id), component_id INT REFERENCES dim_component(component_id), value DOUBLE PRECISION, UNIQUE (date_id, instance_id, metric_id, component_id));
65+
"""
66+
eng = create_engine("postgresql+psycopg2://postgres:postgres@localhost:5432/metrics_db")
67+
with eng.begin() as c:
68+
for stmt in [s.strip() for s in ddl.split(';') if s.strip()]:
69+
c.execute(text(stmt))
70+
print("Schema ready")
71+
PY
72+
73+
- name: Run tests
74+
run: pytest -q

nifipulse/config.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
1+
import os
2+
from urllib.parse import quote_plus
3+
14
class BaseConfig:
25
# Shared defaults
36
RESULTS_DIR = "results"
47
PROM_URL = "http://localhost:9090/api/v1/query"
58
CSV_SINK = "results/prometheus_metrics_log.csv"
69
CLEAN_DATA = "results/nifi_metrics_propre.csv"
10+
# Build DSN from env (override PGHOST to 'postgres' when running inside Docker)
11+
PW = quote_plus(os.getenv('PGPASSWORD', 'postgres'))
12+
PG_DSN = os.getenv(
13+
"PG_DSN",
14+
"postgresql+psycopg2://"
15+
f"{os.getenv('PGUSER','postgres')}:{PW}@"
16+
f"{os.getenv('PGHOST','localhost')}:{os.getenv('PGPORT','5432')}/"
17+
f"{os.getenv('PGDATABASE','metrics_db')}"
18+
)
719
class DevConfig(BaseConfig):
820
pass
921

@@ -26,4 +38,22 @@ def set_env(env_name):
2638
try:
2739
env = ENV_MAP[env_name]
2840
except KeyError:
29-
raise ValueError(f"Unknown environment: {env_name}")
41+
raise ValueError(f"Unknown environment: {env_name}")
42+
43+
def set_env_from_branch(branch_name: str):
44+
"""
45+
Map Git branch to environment: main->prod, staging->staged, dev->dev
46+
"""
47+
mapping = {"main": "prod", "staging": "staged", "dev": "dev"}
48+
set_env(mapping.get(branch_name, "prod"))
49+
50+
def auto_set_env():
51+
name = os.getenv("NIFIPULSE_ENV")
52+
if name:
53+
set_env(name)
54+
return
55+
branch = os.getenv("GITHUB_REF_NAME") or (os.getenv("GITHUB_REF","").split("/")[-1] or "main")
56+
set_env_from_branch(branch)
57+
58+
if os.getenv("NIFIPULSE_AUTO_ENV") == "1":
59+
auto_set_env()

nifipulse/load_postgres.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import pandas as pd
22
from sqlalchemy import create_engine, text
3+
from nifipulse import config
34

45
def load_postgres(clean_data):
56
print(" inserting into PostgreSQL ... ")
67
df = pd.read_csv(clean_data, parse_dates=['timestamp_utc'])
78
df['timestamp_utc'] = pd.to_datetime(df['timestamp_utc'], utc=True)
89

910
# Connexion PostgreSQL
10-
11+
# Use DSN from config (works on host and in Docker; override via env)
1112
engine = create_engine(
12-
"postgresql+psycopg2://postgres:postgres@localhost:5432/metrics_db"
13+
config.env.PG_DSN,
14+
connect_args={"options": "-c client_encoding=UTF8"}
1315
)
14-
1516

1617
print("- Connexion PostgreSQL OK")
1718

pyproject.toml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,14 @@ build-backend = "setuptools.build_meta"
2323
include = ["nifipulse*"]
2424

2525
[tool.setuptools.package-data]
26-
nifipulse = ["metrics_list.txt"]
26+
nifipulse = ["metrics_list.txt"]
27+
28+
[project.optional-dependencies]
29+
dev = [
30+
"pytest",
31+
"flake8",
32+
"black",
33+
"mypy",
34+
"types-requests",
35+
"python-dotenv"
36+
]

0 commit comments

Comments
 (0)