Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 18 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4

[*.{yml,yaml,json}]
indent_size = 2

[*.md]
trim_trailing_whitespace = false

[Makefile]
indent_style = tab
27 changes: 27 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copy this file to .env and fill in real values before running docker compose.
# cp .env.example .env

# ── PostgreSQL ─────────────────────────────────────────────────────────────────
POSTGRES_USER=admin
POSTGRES_PASSWORD=admin_pass
POSTGRES_DB=payment_db

# ── Grafana ────────────────────────────────────────────────────────────────────
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=admin

# ── OpenTelemetry / Jaeger ─────────────────────────────────────────────────────
# Automatically set to http://jaeger:4318/v1/traces by docker-compose.yml.
# Override here only if pointing to an external collector.
# OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4318/v1/traces

# ── Redis (profile: cache) ─────────────────────────────────────────────────────
# Redis only starts with: docker compose --profile cache up -d
# SPRING_REDIS_HOST=redis
# SPRING_REDIS_PORT=6379

# ── Spring overrides (set automatically by docker-compose.yml) ─────────────────
# SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/payment_db
# SPRING_DATASOURCE_USERNAME=admin
# SPRING_DATASOURCE_PASSWORD=admin_pass
# SPRING_KAFKA_BOOTSTRAP_SERVERS=kafka:29092
31 changes: 31 additions & 0 deletions .githooks/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/sh
# Validates that the commit message follows Conventional Commits.
# Enable with: git config core.hooksPath .githooks
#
# Format: tipo(escopo opcional): descrição
# Tipos permitidos: feat, fix, docs, style, refactor, test, chore, build, ci, perf, revert

COMMIT_MSG_FILE="$1"
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")

# Allow merge commits and fixup commits
case "$COMMIT_MSG" in
Merge*|Revert*|fixup!*|squash!*) exit 0 ;;
esac

PATTERN="^(feat|fix|docs|style|refactor|test|chore|build|ci|perf|revert)(\([a-zA-Z0-9/_-]+\))?: .{1,100}$"

if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
echo ""
echo " ✗ Commit message does not follow Conventional Commits."
echo ""
echo " Format : tipo(escopo): descrição"
echo " Example: feat(payment): add charge creation use case"
echo " Types : feat fix docs style refactor test chore build ci perf revert"
echo ""
echo " Your message: $COMMIT_MSG"
echo ""
exit 1
fi

exit 0
8 changes: 8 additions & 0 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh
# Run full Maven verify (unit + integration tests) before every push.
# Enable with: git config core.hooksPath .githooks
set -e

echo ">>> pre-push: running ./mvnw verify ..."
./mvnw verify
echo ">>> pre-push: OK"
82 changes: 41 additions & 41 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,60 +1,60 @@
name: CI

on:
pull_request:
branches: ["main"]
push:
branches: ["main"]
branches: [develop, main]
pull_request:
branches: [main]

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build and Test
unit-tests:
name: Lint + Unit Tests
runs-on: ubuntu-latest

services:
postgres:
image: postgres:15
env:
POSTGRES_DB: payment_db
POSTGRES_USER: admin
POSTGRES_PASSWORD: admin_pass
ports:
- 5432:5432
options: >-
--health-cmd="pg_isready -U admin -d payment_db"
--health-interval=10s
--health-timeout=5s
--health-retries=5

redis:
image: redis:alpine
ports:
- 6379:6379
options: >-
--health-cmd="redis-cli ping"
--health-interval=10s
--health-timeout=5s
--health-retries=5

env:
DB_HOST: localhost
DB_NAME: payment_db
DB_USER: admin
DB_PASSWORD: admin_pass
timeout-minutes: 15

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

- name: Setup Java
uses: actions/setup-java@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
cache: maven

- name: Run tests
- name: Check formatting (Spotless)
run: ./mvnw spotless:check

- name: Check style (Checkstyle)
run: ./mvnw checkstyle:check

- name: Run unit tests
run: ./mvnw test

full-verify:
name: Full Verify + Docker Build
# Runs on pushes to main and on PRs targeting main
if: github.ref == 'refs/heads/main' || github.base_ref == 'main'
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- uses: actions/checkout@v4

- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
cache: maven

- name: Run full verify (unit + integration tests)
run: ./mvnw verify

- name: Build Docker image
run: docker build -t payment-api:ci .
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ target/
!**/src/main/**/target/
!**/src/test/**/target/

# Secrets — never commit real env file
.env
!.env.example

### STS ###
.apt_generated
.classpath
Expand Down
26 changes: 26 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# ── Build stage ────────────────────────────────────────────────────────────────
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app

# Cache dependency layer: copy descriptor first, then source
COPY pom.xml .
RUN mvn dependency:go-offline -q

COPY src ./src
RUN mvn package -DskipTests -q

# ── Runtime stage ───────────────────────────────────────────────────────────────
FROM eclipse-temurin:21-jre-alpine
RUN addgroup -S app && adduser -S app -G app
WORKDIR /app

COPY --from=builder /app/target/*.jar app.jar
RUN chown app:app app.jar

USER app
EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=5s --start-period=40s --retries=3 \
CMD wget -qO- http://localhost:8080/actuator/health || exit 1

ENTRYPOINT ["java", "-jar", "app.jar"]
37 changes: 37 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.PHONY: up down clean logs test verify format db help

help:
@echo "Available targets:"
@echo " up - Build and start all services (docker compose up -d --build)"
@echo " down - Stop services, keep data volumes"
@echo " clean - Stop services and remove data volumes"
@echo " logs - Tail app service logs"
@echo " test - Run unit tests (no Docker required)"
@echo " verify - Run unit + integration tests (requires Docker)"
@echo " format - Apply Spotless formatter to all Java files"
@echo " db - Open psql shell in the running postgres container"

up:
docker compose up -d --build

down:
docker compose down

clean:
docker compose down -v

logs:
docker compose logs -f app

test:
./mvnw test

verify:
./mvnw verify

format:
./mvnw spotless:apply

db:
@source .env 2>/dev/null || true; \
docker compose exec postgres psql -U "$${POSTGRES_USER}" "$${POSTGRES_DB}"
Loading
Loading