Skip to content

Commit e04b789

Browse files
committed
chore: release version 0.2.1 with enhanced resilience and performance features
- Introduced Circuit Breaker Pattern and Retry Logic for improved error handling during Redis outages - Enhanced CacheConfig with new connection pool management and resilience settings - Added comprehensive health check and metrics collection capabilities - Improved async/sync context handling with explicit method variants - Updated documentation to reflect new features and configuration options - Streamlined navigation in MkDocs for better user experience
1 parent ab4405a commit e04b789

24 files changed

+4693
-174
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
name: Manual Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Version to release (e.g., 0.2.1)'
8+
required: true
9+
type: string
10+
create_tag:
11+
description: 'Create git tag for this version'
12+
required: true
13+
type: boolean
14+
default: true
15+
draft:
16+
description: 'Create as draft release'
17+
required: false
18+
type: boolean
19+
default: false
20+
21+
permissions:
22+
contents: write
23+
id-token: write
24+
25+
jobs:
26+
manual-release:
27+
runs-on: ubuntu-latest
28+
steps:
29+
- name: Checkout code
30+
uses: actions/checkout@v4
31+
with:
32+
fetch-depth: 0
33+
34+
- name: Set up Python
35+
uses: actions/setup-python@v4
36+
with:
37+
python-version: '3.11'
38+
39+
- name: Install dependencies
40+
run: |
41+
python -m pip install --upgrade pip
42+
pip install build twine
43+
44+
- name: Verify version matches
45+
run: |
46+
PACKAGE_VERSION=$(python -c "from src.yokedcache import __version__; print(__version__)")
47+
if [ "$PACKAGE_VERSION" != "${{ github.event.inputs.version }}" ]; then
48+
echo "Package version ($PACKAGE_VERSION) doesn't match input version (${{ github.event.inputs.version }})"
49+
echo "Please update src/yokedcache/__init__.py to version ${{ github.event.inputs.version }}"
50+
exit 1
51+
fi
52+
53+
- name: Create tag
54+
if: github.event.inputs.create_tag == 'true'
55+
run: |
56+
git config user.name github-actions
57+
git config user.email github-actions@github.com
58+
git tag -a "v${{ github.event.inputs.version }}" -m "Release v${{ github.event.inputs.version }}"
59+
git push origin "v${{ github.event.inputs.version }}"
60+
61+
- name: Extract changelog for this version
62+
id: changelog
63+
run: |
64+
python << 'EOF'
65+
import re
66+
67+
version = "${{ github.event.inputs.version }}"
68+
69+
try:
70+
with open('CHANGELOG.md', 'r') as f:
71+
content = f.read()
72+
73+
pattern = rf'## \[{re.escape(version)}\].*?\n(.*?)(?=\n## \[|\n---|\Z)'
74+
match = re.search(pattern, content, re.DOTALL)
75+
76+
if match:
77+
changelog_content = match.group(1).strip()
78+
changelog_content = re.sub(r'\n---+.*$', '', changelog_content, flags=re.MULTILINE)
79+
80+
with open('release_notes.md', 'w') as f:
81+
f.write(changelog_content)
82+
print(f"Extracted changelog for version {version}")
83+
else:
84+
print(f"No changelog found for version {version}")
85+
with open('release_notes.md', 'w') as f:
86+
f.write(f"Manual release {version}")
87+
except Exception as e:
88+
print(f"Error extracting changelog: {e}")
89+
with open('release_notes.md', 'w') as f:
90+
f.write(f"Manual release {version}")
91+
EOF
92+
93+
- name: Build package
94+
run: |
95+
python -m build
96+
97+
- name: Run tests
98+
run: |
99+
pip install -e .
100+
pip install pytest pytest-cov pytest-asyncio
101+
python -m pytest tests/ --tb=short
102+
103+
- name: Create GitHub Release
104+
uses: softprops/action-gh-release@v1
105+
with:
106+
tag_name: v${{ github.event.inputs.version }}
107+
name: Release ${{ github.event.inputs.version }}
108+
body_path: release_notes.md
109+
files: |
110+
dist/*.whl
111+
dist/*.tar.gz
112+
draft: ${{ github.event.inputs.draft }}
113+
prerelease: ${{ contains(github.event.inputs.version, 'rc') || contains(github.event.inputs.version, 'beta') || contains(github.event.inputs.version, 'alpha') }}
114+
115+
- name: Publish to PyPI
116+
if: github.event.inputs.draft == 'false'
117+
uses: pypa/gh-action-pypi-publish@release/v1
118+
with:
119+
print-hash: true

.github/workflows/release.yml

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
name: Create Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*' # Triggers on version tags like v0.2.1, v1.0.0, etc.
7+
8+
permissions:
9+
contents: write # Required for creating releases
10+
id-token: write # Required for PyPI trusted publishing
11+
12+
jobs:
13+
create-release:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0 # Get full history for changelog generation
20+
21+
- name: Set up Python
22+
uses: actions/setup-python@v4
23+
with:
24+
python-version: '3.11'
25+
26+
- name: Install dependencies
27+
run: |
28+
python -m pip install --upgrade pip
29+
pip install build twine
30+
31+
- name: Extract version from tag
32+
id: version
33+
run: |
34+
TAG=${GITHUB_REF#refs/tags/v}
35+
echo "version=$TAG" >> $GITHUB_OUTPUT
36+
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
37+
38+
- name: Verify version matches
39+
run: |
40+
PACKAGE_VERSION=$(python -c "from src.yokedcache import __version__; print(__version__)")
41+
if [ "$PACKAGE_VERSION" != "${{ steps.version.outputs.version }}" ]; then
42+
echo "Package version ($PACKAGE_VERSION) doesn't match tag version (${{ steps.version.outputs.version }})"
43+
exit 1
44+
fi
45+
46+
- name: Extract changelog for this version
47+
id: changelog
48+
run: |
49+
# Extract changelog section for this version
50+
python << 'EOF'
51+
import re
52+
import sys
53+
54+
version = "${{ steps.version.outputs.version }}"
55+
56+
try:
57+
with open('CHANGELOG.md', 'r') as f:
58+
content = f.read()
59+
60+
# Find the section for this version
61+
pattern = rf'## \[{re.escape(version)}\].*?\n(.*?)(?=\n## \[|\n---|\Z)'
62+
match = re.search(pattern, content, re.DOTALL)
63+
64+
if match:
65+
changelog_content = match.group(1).strip()
66+
# Remove any trailing dashes or separators
67+
changelog_content = re.sub(r'\n---+.*$', '', changelog_content, flags=re.MULTILINE)
68+
69+
# Write to file for GitHub Actions
70+
with open('release_notes.md', 'w') as f:
71+
f.write(changelog_content)
72+
print(f"Extracted changelog for version {version}")
73+
else:
74+
print(f"No changelog found for version {version}")
75+
with open('release_notes.md', 'w') as f:
76+
f.write(f"Release {version}")
77+
except Exception as e:
78+
print(f"Error extracting changelog: {e}")
79+
with open('release_notes.md', 'w') as f:
80+
f.write(f"Release {version}")
81+
EOF
82+
83+
- name: Build package
84+
run: |
85+
python -m build
86+
87+
- name: Create GitHub Release
88+
uses: softprops/action-gh-release@v1
89+
with:
90+
tag_name: ${{ steps.version.outputs.tag }}
91+
name: Release ${{ steps.version.outputs.version }}
92+
body_path: release_notes.md
93+
files: |
94+
dist/*.whl
95+
dist/*.tar.gz
96+
draft: false
97+
prerelease: ${{ contains(steps.version.outputs.version, 'rc') || contains(steps.version.outputs.version, 'beta') || contains(steps.version.outputs.version, 'alpha') }}
98+
99+
- name: Publish to PyPI
100+
uses: pypa/gh-action-pypi-publish@release/v1
101+
with:
102+
print-hash: true
103+
104+
update-docs:
105+
needs: create-release
106+
runs-on: ubuntu-latest
107+
if: github.repository == 'sirstig/yokedcache' # Only run on main repo
108+
steps:
109+
- name: Checkout code
110+
uses: actions/checkout@v4
111+
112+
- name: Set up Python
113+
uses: actions/setup-python@v4
114+
with:
115+
python-version: '3.11'
116+
117+
- name: Install documentation dependencies
118+
run: |
119+
pip install -r requirements-dev.txt
120+
pip install mkdocs mkdocs-material mkdocstrings[python]
121+
122+
- name: Build documentation
123+
run: mkdocs build --strict
124+
125+
- name: Deploy documentation
126+
run: mkdocs gh-deploy --force
127+
env:
128+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CHANGELOG.md

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,59 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.2.1] - 2025-08-23
11+
1012
### Added
1113

12-
- Star request button prominently displayed in README
13-
- Documentation build verification with `mkdocs build --strict`
14+
- **Circuit Breaker Pattern**: Advanced resilience pattern to prevent cascading failures during Redis outages
15+
- **Connection Pool Management**: Enhanced Redis connection configuration with custom pool parameters
16+
- **Async/Sync Context Detection**: Smart handling to prevent Task object returns in mixed async/sync environments
17+
- **Comprehensive Metrics System**: Real-time performance tracking with hit rates, error rates, and response times
18+
- **Enhanced Error Handling**: Graceful fallback mechanisms when cache operations fail
19+
- **Health Check Endpoint**: Detailed cache status monitoring including connection pool stats and performance metrics
20+
- **Retry Mechanism**: Exponential backoff retry logic for transient Redis failures
21+
- **Improved Configuration**: Extended `CacheConfig` with circuit breaker, retry, and resilience settings
22+
- **FastAPI Dependency Enhancement**: Better support for generator-based dependencies and database session handling
23+
- **Comprehensive Test Suite**: 240+ tests with 64% coverage including circuit breaker, configuration, and utilities
24+
- **Production-Ready Features**: Implementation of all critical priority items from real-world testing feedback
1425

1526
### Changed
1627

17-
- Updated documentation dependencies to latest versions
18-
- Enhanced CONTRIBUTING.md with documentation build requirements
19-
- Updated development setup to include docs dependencies
28+
- **Enhanced `CacheConfig`**: Added `connection_pool_kwargs`, circuit breaker settings, and error handling options
29+
- **Improved Cache Methods**: Added explicit async (`aget`, `aset`) and sync (`get_sync`, `set_sync`) method variants
30+
- **Better Dependency Injection**: Enhanced `cached_dependency` decorator to properly handle FastAPI generator patterns
31+
- **Upgraded Serialization**: Fixed datetime handling to use timezone-aware `datetime.now(timezone.utc)`
32+
- **Performance Optimizations**: Improved cache key generation and data serialization efficiency
2033

2134
### Fixed
2235

23-
- Fixed mkdocs navigation configuration to include all existing documentation files
24-
- Resolved relative link issues in documentation
25-
- Fixed missing file warnings in mkdocs build
36+
- **Critical Issue**: `CacheConfig` now properly accepts and validates `connection_pool_kwargs` parameter
37+
- **Async/Sync Handling**: Fixed Task object returns when sync methods called from async contexts
38+
- **FastAPI Integration**: Resolved generator dependency wrapping to return proper database session objects
39+
- **Environment Variables**: Enhanced parsing and validation of configuration overrides
40+
- **MyPy Compatibility**: Resolved all type checking errors for better code quality
41+
- **Test Stability**: Fixed file permission issues in Windows testing environment
2642

27-
### Removed
43+
### Security
44+
45+
- **Error Resilience**: Circuit breaker prevents system overload during Redis failures
46+
- **Connection Management**: Proper connection pool configuration prevents resource exhaustion
47+
- **Graceful Degradation**: Fallback mechanisms ensure application stability during cache issues
48+
49+
### Performance
50+
51+
- **64% Test Coverage**: Significantly improved from 55% with comprehensive testing of critical paths
52+
- **Circuit Breaker Efficiency**: 92% test coverage for resilience patterns
53+
- **Configuration Validation**: 98% test coverage for robust configuration management
54+
- **Utility Functions**: 72% test coverage for core helper functions
55+
56+
### Documentation
2857

29-
- Acknowledgments section from README.md (streamlined for professional appearance)
58+
- **Star request button prominently displayed in README**
59+
- **Documentation build verification with `mkdocs build --strict`**
60+
- **Updated documentation dependencies to latest versions**
61+
- **Enhanced CONTRIBUTING.md with documentation build requirements**
62+
- **Updated development setup to include docs dependencies**
3063

3164
## [0.2.0] - 2024-01-15
3265

0 commit comments

Comments
 (0)