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
48 changes: 48 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

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

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

strategy:
matrix:
elixir: ["1.16", "1.19"]
otp: ["26", "27", "28"]
exclude:
- elixir: "1.16"
otp: "28"

steps:
- uses: actions/checkout@v4

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

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

- name: Install dependencies
run: mix deps.get

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

- name: Run tests
run: mix test

- name: Check compilation warnings
run: mix compile --warnings-as-errors
39 changes: 39 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Publish to Hex.pm

on:
push:
tags:
- 'v*.*.*'

jobs:
publish:
name: Publish to Hex.pm
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

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

- name: Restore dependencies cache
uses: actions/cache@v4
with:
path: deps
key: ${{ runner.os }}-mix-26-1.16-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-26-1.16-

- name: Install dependencies
run: mix deps.get

- name: Run tests
run: mix test

- name: Publish to Hex
env:
HEX_API_KEY: ${{ secrets.HEX_API_KEY }}
run: |
mix hex.publish --yes
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- **Automatic HTTP retries** - `FYI.Client` module with exponential backoff for sink delivery
- Retries transient failures (network errors, 5xx status codes) up to 3 times
- Exponential backoff with delays of 1s, 2s, 4s
- Respects `Retry-After` response headers
- Configurable via `:http_client` config (max_retries, retry_delay)

### Changed

- Sinks now use `FYI.Client.post/2` for HTTP requests instead of raw `Req.post/2`

## [1.0.0] - 2024-12-26

### Added
Expand Down
153 changes: 153 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Contributing to FYI

Thank you for your interest in contributing to FYI! This guide will help you get started.

## Development Setup

1. **Clone the repository**
```bash
git clone https://github.com/chrisgreg/fyi.git
cd fyi
```

2. **Install dependencies**
```bash
mix deps.get
```

3. **Run tests**
```bash
mix test
```

4. **Check formatting**
```bash
mix format --check-formatted
```

## Making Changes

1. **Create a branch** for your changes
```bash
git checkout -b your-feature-name
```

2. **Make your changes** and write tests

3. **Update the CHANGELOG**
- Add your changes to the `[Unreleased]` section in `CHANGELOG.md`
- Use the existing format: `- **Feature name** - Description`
- Categorize under `### Added`, `### Changed`, `### Fixed`, or `### Removed`

4. **Ensure tests pass and code is formatted**
```bash
mix test
mix format
```

5. **Commit your changes**
```bash
git add .
git commit -m "Add feature X"
```

6. **Push and create a pull request**
```bash
git push origin your-feature-name
```

## Release Process

> **Note**: Only maintainers can create releases.

Releases are managed using semantic versioning (MAJOR.MINOR.PATCH):
- **PATCH** (1.0.1): Bug fixes, no breaking changes
- **MINOR** (1.1.0): New features, backwards compatible
- **MAJOR** (2.0.0): Breaking changes

### Steps to Release

1. **Ensure you're on main with latest changes**
```bash
git checkout main
git pull origin main
```

2. **Verify the CHANGELOG has an [Unreleased] section with changes**
- Check that all changes since the last release are documented
- Ensure changes are categorized properly (Added/Changed/Fixed/Removed)

3. **Run the release script**
```bash
./scripts/release.sh patch # For bug fixes (1.0.0 -> 1.0.1)
./scripts/release.sh minor # For new features (1.0.0 -> 1.1.0)
./scripts/release.sh major # For breaking changes (1.0.0 -> 2.0.0)
```

The script will:
- Bump the version in `mix.exs`
- Move `[Unreleased]` to the new version with today's date in `CHANGELOG.md`
- Create a new empty `[Unreleased]` section
- Commit the changes
- Create a git tag (e.g., `v1.0.1`)

4. **Review the changes**
```bash
git show # Review the commit
git show v1.0.1 # Review the tag
```

5. **Push to GitHub** (this triggers the publish workflow)
```bash
git push origin main --tags
```

6. **GitHub Actions will automatically**:
- Run the full test suite
- Publish the new version to Hex.pm (using the `HEX_API_KEY` secret)

### If Something Goes Wrong

If you need to undo a release before pushing:

```bash
git reset --hard HEAD~1 # Undo the commit
git tag -d v1.0.1 # Delete the tag
```

If you already pushed, you'll need to:
1. Yank the version from Hex.pm if it was published
2. Delete the tag from GitHub
3. Revert the commit

### First-Time Release Setup

The `HEX_API_KEY` secret must be configured in GitHub:

1. Generate a Hex API key:
```bash
mix hex.user key generate
```

2. Add it to GitHub:
- Go to repository Settings β†’ Secrets and variables β†’ Actions
- Click "New repository secret"
- Name: `HEX_API_KEY`
- Value: Your generated key

## Code Style

- Follow the existing code style
- Run `mix format` before committing
- Write descriptive commit messages
- Add tests for new features
- Update documentation as needed

## Questions?

If you have questions or need help, feel free to:
- Open an issue
- Start a discussion
- Reach out to the maintainers

Thank you for contributing! πŸŽ‰
119 changes: 119 additions & 0 deletions scripts/release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#!/bin/bash
set -e

# Color output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Get current version from mix.exs
CURRENT_VERSION=$(grep '@version' mix.exs | sed 's/.*"\(.*\)".*/\1/')

echo -e "${GREEN}Current version: ${CURRENT_VERSION}${NC}"
echo ""

# Parse version
IFS='.' read -r -a VERSION_PARTS <<< "$CURRENT_VERSION"
MAJOR="${VERSION_PARTS[0]}"
MINOR="${VERSION_PARTS[1]}"
PATCH="${VERSION_PARTS[2]}"

# Determine new version based on argument
case "${1:-}" in
major)
NEW_MAJOR=$((MAJOR + 1))
NEW_VERSION="${NEW_MAJOR}.0.0"
;;
minor)
NEW_MINOR=$((MINOR + 1))
NEW_VERSION="${MAJOR}.${NEW_MINOR}.0"
;;
patch)
NEW_PATCH=$((PATCH + 1))
NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}"
;;
*)
echo -e "${RED}Usage: $0 {major|minor|patch}${NC}"
echo ""
echo "Examples:"
echo " $0 patch # ${CURRENT_VERSION} -> ${MAJOR}.${MINOR}.$((PATCH + 1))"
echo " $0 minor # ${CURRENT_VERSION} -> ${MAJOR}.$((MINOR + 1)).0"
echo " $0 major # ${CURRENT_VERSION} -> $((MAJOR + 1)).0.0"
exit 1
;;
esac

echo -e "${YELLOW}Releasing version ${NEW_VERSION}${NC}"
echo ""

# Check for uncommitted changes
if ! git diff-index --quiet HEAD --; then
echo -e "${RED}Error: You have uncommitted changes. Please commit or stash them first.${NC}"
exit 1
fi

# Check if on main branch
CURRENT_BRANCH=$(git branch --show-current)
if [ "$CURRENT_BRANCH" != "main" ]; then
echo -e "${YELLOW}Warning: You're not on the main branch (current: ${CURRENT_BRANCH})${NC}"
read -p "Continue anyway? [y/N] " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi

# Check if [Unreleased] section exists
if ! grep -q "## \[Unreleased\]" CHANGELOG.md; then
echo -e "${RED}Error: No [Unreleased] section found in CHANGELOG.md${NC}"
echo "Please add your changes to an [Unreleased] section first."
exit 1
fi

# Check if there are actual changes in [Unreleased]
if grep -A 3 "## \[Unreleased\]" CHANGELOG.md | grep -q "^## \["; then
echo -e "${RED}Error: [Unreleased] section appears to be empty${NC}"
echo "Please add your changes to the [Unreleased] section first."
exit 1
fi

echo "πŸ“ Updating mix.exs..."
sed -i.bak "s/@version \"${CURRENT_VERSION}\"/@version \"${NEW_VERSION}\"/" mix.exs
rm mix.exs.bak

echo "πŸ“ Updating CHANGELOG.md..."
TODAY=$(date +%Y-%m-%d)
sed -i.bak "s/## \[Unreleased\]/## [${NEW_VERSION}] - ${TODAY}/" CHANGELOG.md
rm CHANGELOG.md.bak

# Add a new [Unreleased] section at the top
sed -i.bak "/^## \[${NEW_VERSION}\]/i\\
## [Unreleased]\\
\\
" CHANGELOG.md
rm CHANGELOG.md.bak

echo "βœ… Committing changes..."
git add mix.exs CHANGELOG.md
git commit -m "Release v${NEW_VERSION}"

echo "🏷️ Creating git tag..."
git tag "v${NEW_VERSION}"

echo ""
echo -e "${GREEN}✨ Release ${NEW_VERSION} prepared successfully!${NC}"
echo ""
echo "Next steps:"
echo " 1. Review the commit and tag:"
echo " git show"
echo " git show v${NEW_VERSION}"
echo ""
echo " 2. Push to GitHub (this will trigger the publish workflow):"
echo " git push origin main --tags"
echo ""
echo " 3. The GitHub Action will automatically publish to Hex.pm"
echo ""
echo -e "${YELLOW}Note: You can undo this release with:${NC}"
echo " git reset --hard HEAD~1"
echo " git tag -d v${NEW_VERSION}"