Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
39 changes: 39 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Server Configuration
PORT=8080
HOST=0.0.0.0
ENVIRONMENT=development # development, staging, production
READ_TIMEOUT=15s
WRITE_TIMEOUT=15s
IDLE_TIMEOUT=60s
SHUTDOWN_TIMEOUT=30s

# Database Configuration
DB_TYPE=file # file or postgres
DB_FILE_PATH=posts.json

# PostgreSQL Configuration (when DB_TYPE=postgres)
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=postgres
DB_NAME=postanalyzer
DB_SSL_MODE=disable

Choose a reason for hiding this comment

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

medium

Using disable for DB_SSL_MODE is insecure for production environments, as it allows for unencrypted database connections. It's good for local development, but you should add a comment strongly recommending the use of require or verify-full in production to prevent man-in-the-middle attacks.

DB_SSL_MODE=disable # Use 'require' or 'verify-full' in production

DB_MAX_CONNS=25
DB_MIN_CONNS=5

# Security Configuration
RATE_LIMIT_REQUESTS=100
RATE_LIMIT_WINDOW=1m
MAX_BODY_SIZE=1048576 # 1MB in bytes
ALLOWED_ORIGINS=* # Comma-separated list or * for all
TRUSTED_PROXIES= # Comma-separated list of trusted proxy IPs

# Logging Configuration
LOG_LEVEL=info # debug, info, warn, error
LOG_FORMAT=json # json or text
LOG_OUTPUT=stdout # stdout or file path
LOG_TIME_FORMAT=2006-01-02T15:04:05Z07:00

# External API Configuration
JSONPLACEHOLDER_URL=https://jsonplaceholder.typicode.com/posts
HTTP_TIMEOUT=30s
199 changes: 199 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
name: CI/CD Pipeline

on:
push:
branches: [ main, master, claude/* ]
pull_request:
branches: [ main, master ]

env:
GO_VERSION: '1.21'
DOCKER_IMAGE: post-analyzer

jobs:
# Linting and code quality
lint:
name: Lint Code
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

- name: Run golangci-lint
uses: golangci/golangci-lint-action@v4
with:
version: latest
args: --timeout=5m

# Unit and integration tests
test:
name: Run Tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_DB: testdb
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

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

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-

- name: Download dependencies
run: go mod download

- name: Run tests
run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./...
env:
DB_HOST: localhost
DB_PORT: 5432
DB_USER: postgres
DB_PASSWORD: postgres
DB_NAME: testdb

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
file: ./coverage.txt
fail_ci_if_error: false

# Build and verify
build:
name: Build Application
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

- name: Build application
run: |
go build -v -ldflags="-w -s" -o post-analyzer main_new.go

- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: post-analyzer
path: post-analyzer
retention-days: 1

# Docker build and push
docker:
name: Build and Push Docker Image
runs-on: ubuntu-latest
needs: [build]
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
if: github.event_name == 'push'

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ secrets.DOCKER_USERNAME }}/${{ env.DOCKER_IMAGE }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: ${{ github.event_name == 'push' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

# Security scanning
security:
name: Security Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'

- name: Upload Trivy results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'

# Deployment (optional - customize for your deployment target)
deploy:
name: Deploy Application
runs-on: ubuntu-latest
needs: [docker]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Deploy to production
run: |
echo "Add your deployment steps here"
echo "Examples: kubectl apply, helm upgrade, SSH to server, etc."
# Uncomment and customize based on your deployment method:
# - name: Deploy to Kubernetes
# run: |
# kubectl set image deployment/post-analyzer post-analyzer=${{ secrets.DOCKER_USERNAME }}/${{ env.DOCKER_IMAGE }}:latest
#
# - name: Deploy to Render
# run: |
# curl -X POST ${{ secrets.RENDER_DEPLOY_HOOK }}
58 changes: 58 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool
*.out
coverage.txt
coverage.html

# Dependency directories
vendor/

# Go workspace file
go.work

# Environment variables
.env
.env.local
.env.*.local

# IDE files
.idea/
.vscode/
*.swp
*.swo
*~

# OS files
.DS_Store
Thumbs.db

# Application specific
posts.json
*.log
logs/

# Build output
bin/
dist/
build/

# Database
*.db
*.sqlite
*.sqlite3

# Docker volumes
data/

# Temporary files
tmp/
temp/
Loading
Loading