Skip to content
Closed
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
118 changes: 118 additions & 0 deletions .github/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# GitHub Actions CI/CD Setup

This repository includes comprehensive GitHub Actions workflows for continuous integration, security scanning, and automated releases.

## Workflows

### 🔄 CI Workflow (`.github/workflows/ci.yml`)

**Triggers:** Push or Pull Request to `main` or `develop` branches

**What it does:**
- Sets up PostgreSQL 15 database service
- Installs Elixir 1.15.7 with OTP 26.1
- Caches dependencies for faster builds
- Runs code formatting checks
- Performs static analysis with Credo
- Compiles with warnings treated as errors
- Executes tests with coverage reporting
- Runs quality checks using `mix quality`

### 🚀 Release Workflow (`.github/workflows/release.yml`)

**Triggers:** Git tags starting with `v*` (e.g., `v1.0.0`)

**What it does:**
- Builds production release
- Generates documentation
- Creates GitHub release with auto-generated notes
- Optionally publishes to Hex.pm (requires `HEX_API_KEY` secret)

### 🔒 Security Workflow (`.github/workflows/security.yml`)

**Triggers:**
- Push or Pull Request to `main`
- Weekly schedule (Mondays at 10:00 UTC)

**What it does:**
- Scans for security vulnerabilities using Trivy
- Uploads results to GitHub Security tab
- Runs automatically on a weekly basis

### 🧪 Matrix Testing (`.github/workflows/matrix.yml`)

**Triggers:**
- Push or Pull Request to `main`
- Weekly schedule (Sundays at 6:00 UTC)

**What it does:**
- Tests across multiple Elixir/OTP version combinations
- Ensures compatibility with minimum and latest supported versions
- Includes Elixir 1.15.0-1.16.0 with OTP 26.0-26.2

## Configuration

### Required Secrets

For full functionality, add these secrets to your repository:

- `HEX_API_KEY` - Required for automatic Hex.pm publishing on releases
- `GITHUB_TOKEN` - Automatically provided by GitHub Actions

### Database Setup

All workflows use PostgreSQL with these credentials (matching `config/test.exs`):
- **Username:** `postgres`
- **Password:** `postgres`
- **Database:** `postgres`
- **Port:** `5432`

### Coverage Reporting

The CI workflow generates coverage reports using ExCoveralls and uploads them to GitHub. The project requires a minimum of 85% test coverage as configured in `.coveralls.exs`.

## Status Badges

Add these badges to your README.md:

```markdown
[![CI](https://github.com/agoodway/tango/actions/workflows/ci.yml/badge.svg)](https://github.com/agoodway/tango/actions/workflows/ci.yml)
[![Security](https://github.com/agoodway/tango/actions/workflows/security.yml/badge.svg)](https://github.com/agoodway/tango/actions/workflows/security.yml)
```

## Local Development

To run the same checks locally:

```bash
# Install dependencies
mix deps.get

# Run formatting check
mix format --check-formatted

# Run static analysis
mix credo

# Run tests with coverage
mix coveralls

# Run all quality checks
mix quality
```

## Troubleshooting

### Common Issues

1. **Database Connection Errors**: Ensure PostgreSQL is running locally with the credentials in `config/test.exs`
2. **Coverage Failures**: Check that tests meet the 85% minimum coverage requirement
3. **Formatting Errors**: Run `mix format` to auto-fix formatting issues
4. **Credo Warnings**: Address static analysis issues highlighted by Credo

### Workflow Debugging

- Check the Actions tab for detailed logs
- Failed steps will show specific error messages
- Use the re-run feature to retry failed workflows
- Check the matrix workflow for compatibility issues across Elixir versions
79 changes: 79 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: CI

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

env:
MIX_ENV: test
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jobs:
test:
name: Test & Quality
runs-on: ubuntu-latest

services:
postgres:
image: postgres:15
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432

strategy:
matrix:
elixir: ['1.15.7']
otp: ['26.1']

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

- name: Set up Elixir
uses: erlef/setup-beam@v1
with:
elixir-version: ${{ matrix.elixir }}
otp-version: ${{ matrix.otp }}

- name: Cache dependencies
uses: actions/cache@v3
with:
path: |
deps
_build
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-mix-

- name: Install dependencies
run: |
mix local.hex --force
mix local.rebar --force
mix deps.get

- name: Check formatting
run: mix format --check-formatted

- name: Run static analysis (Credo)
run: mix credo

- name: Compile
run: mix compile --warnings-as-errors

- name: Run tests with coverage
run: mix coveralls.github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Run quality checks
run: mix quality
79 changes: 79 additions & 0 deletions .github/workflows/matrix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Matrix Tests

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
# Run every week on Sunday at 6:00 UTC
- cron: '0 6 * * 0'

env:
MIX_ENV: test

jobs:
test-matrix:
name: Test (Elixir ${{ matrix.elixir }}, OTP ${{ matrix.otp }})
runs-on: ubuntu-latest

services:
postgres:
image: postgres:15
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432

strategy:
fail-fast: false
matrix:
include:
# Minimum supported versions
- elixir: '1.15.0'
otp: '26.0'
# Current stable versions
- elixir: '1.15.7'
otp: '26.1'
# Latest versions
- elixir: '1.16.0'
otp: '26.2'

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

- name: Set up Elixir
uses: erlef/setup-beam@v1
with:
elixir-version: ${{ matrix.elixir }}
otp-version: ${{ matrix.otp }}

- name: Cache dependencies
uses: actions/cache@v3
with:
path: |
deps
_build
key: ${{ runner.os }}-mix-${{ matrix.elixir }}-${{ matrix.otp }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-mix-${{ matrix.elixir }}-${{ matrix.otp }}-

- name: Install dependencies
run: |
mix local.hex --force
mix local.rebar --force
mix deps.get

- name: Compile
run: mix compile

- name: Run tests
run: mix test
82 changes: 82 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Release

on:
push:
tags:
- 'v*'

env:
MIX_ENV: prod

jobs:
release:
name: Build and Release
runs-on: ubuntu-latest

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

- name: Set up Elixir
uses: erlef/setup-beam@v1
with:
elixir-version: '1.15.7'
otp-version: '26.1'

- name: Cache dependencies
uses: actions/cache@v3
with:
path: |
deps
_build
key: ${{ runner.os }}-mix-prod-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-mix-prod-

- name: Install dependencies
run: |
mix local.hex --force
mix local.rebar --force
mix deps.get --only=prod

- name: Compile
run: mix compile

- name: Build documentation
run: mix docs

- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: |
doc/**/*
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

publish:
name: Publish to Hex
runs-on: ubuntu-latest
needs: release
if: startsWith(github.ref, 'refs/tags/v')

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

- name: Set up Elixir
uses: erlef/setup-beam@v1
with:
elixir-version: '1.15.7'
otp-version: '26.1'

- name: Install dependencies
run: |
mix local.hex --force
mix local.rebar --force
mix deps.get

- name: Publish to Hex
run: mix hex.publish --yes
env:
HEX_API_KEY: ${{ secrets.HEX_API_KEY }}
33 changes: 33 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Security

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
# Run every Monday at 10:00 UTC
- cron: '0 10 * * 1'

jobs:
secrets-scan:
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 scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: 'trivy-results.sarif'
Loading
Loading