Skip to content

Commit 64ba5df

Browse files
committed
Add comprehensive CI/CD infrastructure (Priority 4)
GitHub Actions Workflows: - .github/workflows/ci.yml: Main CI pipeline with code quality, unit tests, integration tests, and docs build - .github/workflows/mpi-tests.yml: Weekly MPI matrix testing (different node counts) - .github/workflows/docs.yml: Automatic documentation deployment on docs changes - .github/workflows/release.yml: Automated PyPI publishing and GitHub releases Release Automation: - .github/scripts/prepare-release.sh: Helper script for preparing releases - Automated PyPI publishing on version tag push - Automatic GitHub release creation with changelog - PyPI package verification after publishing Dependencies: - Added docs dependencies (mkdocs-material stack) - Added build dependencies (build, twine) - Added pytest-benchmark for performance testing - Updated project.optional-dependencies in pyproject.toml CI/CD Features: - Multi-Python version testing (3.8, 3.10, 3.12) - Multi-node MPI testing (2, 4, 8 processes) - Code quality checks (black, isort, ruff) - Coverage reporting via codecov - Weekly scheduled performance tests - Documentation deployment to ReadTheDocs - Automated PyPI publishing - GitHub release creation with changelog Branch Protection: - CI checks required before merging - Test all workflows before pushing Next Steps: 1. Configure repository secrets (PYPI_API_TOKEN, READTHEDOCS_WEBHOOK_URL) 2. Enable branch protection on main branch 3. First release: ./.github/scripts/prepare-release.sh 0.1.0 4. Git push with tags to trigger release workflow
1 parent d0bae97 commit 64ba5df

6 files changed

Lines changed: 486 additions & 0 deletions

File tree

.github/scripts/prepare-release.sh

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/bin/bash
2+
# Script to prepare a release
3+
4+
set -e
5+
6+
VERSION=$1
7+
8+
# Check if version provided
9+
if [ -z "$VERSION" ]; then
10+
echo "Usage: ./prepare-release.sh <version>"
11+
echo "Example: ./prepare-release.sh 1.2.3"
12+
exit 1
13+
fi
14+
15+
# Validate version format
16+
if ! [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
17+
echo "Invalid version format. Use X.Y.Z"
18+
exit 1
19+
fi
20+
21+
echo "Preparing release $VERSION..."
22+
23+
# Update version in __init__.py
24+
if [ -f "src/ezmpi/__init__.py" ]; then
25+
sed -i.bak "s/__version__ = \".*\"/__version__ = \"$VERSION\"/g" src/ezmpi/__init__.py
26+
rm src/ezmpi/__init__.py.bak
27+
echo "✓ Updated version in src/ezmpi/__init__.py"
28+
else
29+
echo "✗ src/ezmpi/__init__.py not found"
30+
exit 1
31+
fi
32+
33+
# Update CHANGELOG.md if it exists
34+
if [ -f "CHANGELOG.md" ]; then
35+
# Check if version already exists in changelog
36+
if grep -q "## \[$VERSION\]" CHANGELOG.md; then
37+
echo "✓ Version $VERSION already exists in CHANGELOG.md"
38+
else
39+
# Add new version section at the top
40+
TODAY=$(date +%Y-%m-%d)
41+
sed -i.bak "2a\\
42+
## [$VERSION] - $TODAY\\
43+
\\
44+
### Added\\
45+
-\\
46+
\\
47+
### Changed\\
48+
-\\
49+
\\
50+
### Fixed\\
51+
-\\
52+
" CHANGELOG.md
53+
rm CHANGELOG.md.bak
54+
echo "✓ Added $VERSION section to CHANGELOG.md"
55+
fi
56+
else
57+
echo "✗ CHANGELOG.md not found"
58+
exit 1
59+
fi
60+
61+
# Check if we're in a git repository
62+
if [ -d ".git" ]; then
63+
# Check if there are any changes to commit
64+
if ! git diff --quiet; then
65+
git add src/ezmpi/__init__.py CHANGELOG.md
66+
git commit -m "Prepare release v$VERSION"
67+
echo "✓ Committed version update"
68+
else
69+
echo "✓ No changes to commit"
70+
fi
71+
72+
# Create and push tag
73+
git tag -a "v$VERSION" -m "Release version $VERSION"
74+
echo "✓ Created tag v$VERSION"
75+
76+
# Ask about pushing
77+
echo "Ready to push. Run: git push origin main --tags"
78+
echo "This will trigger the release workflow."
79+
else
80+
echo "✗ Not in a git repository"
81+
exit 1
82+
fi
83+
84+
echo ""
85+
echo "Release v$VERSION prepared successfully!"
86+
echo "Next steps:"
87+
echo "1. Review changes: git log --oneline -3"
88+
echo "2. Push to trigger release: git push origin main --tags"

.github/workflows/ci.yml

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
workflow_dispatch:
9+
10+
jobs:
11+
code-quality:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v4
18+
with:
19+
python-version: '3.10'
20+
21+
- name: Install code quality tools
22+
run: |
23+
python -m pip install --upgrade pip
24+
pip install black isort ruff
25+
26+
- name: Check code formatting with black
27+
run: black --check src/ tests/
28+
29+
- name: Check import sorting with isort
30+
run: isort --check-only src/ tests/
31+
32+
- name: Lint with ruff
33+
run: ruff check src/ tests/
34+
35+
unit-tests:
36+
runs-on: ubuntu-latest
37+
strategy:
38+
matrix:
39+
python-version: ['3.8', '3.10', '3.12']
40+
41+
steps:
42+
- uses: actions/checkout@v4
43+
44+
- name: Set up Python ${{ matrix.python-version }}
45+
uses: actions/setup-python@v4
46+
with:
47+
python-version: ${{ matrix.python-version }}
48+
49+
- name: Install dependencies
50+
run: |
51+
python -m pip install --upgrade pip
52+
pip install -e ".[test]"
53+
54+
- name: Run unit tests
55+
run: pytest tests/test_unit.py -v --cov=ezmpi --cov-report=xml
56+
57+
- name: Upload coverage to Codecov
58+
uses: codecov/codecov-action@v3
59+
with:
60+
file: ./coverage.xml
61+
flags: unittests
62+
name: codecov-umbrella
63+
fail_ci_if_error: false
64+
65+
integration-tests:
66+
runs-on: ubuntu-latest
67+
68+
steps:
69+
- uses: actions/checkout@v4
70+
71+
- name: Install MPI
72+
run: |
73+
sudo apt-get update
74+
sudo apt-get install -y openmpi-bin libopenmpi-dev
75+
76+
- name: Set up Python
77+
uses: actions/setup-python@v4
78+
with:
79+
python-version: '3.10'
80+
81+
- name: Install dependencies
82+
run: |
83+
python -m pip install --upgrade pip
84+
pip install -e ".[test,dill]"
85+
86+
- name: Run integration tests
87+
run: mpiexec -n 4 pytest tests/test_integration.py -v --cov=ezmpi --cov-report=xml --cov-append
88+
89+
- name: Upload coverage to Codecov
90+
uses: codecov/codecov-action@v3
91+
with:
92+
file: ./coverage.xml
93+
flags: integration
94+
name: codecov-umbrella
95+
fail_ci_if_error: false
96+
97+
docs-build:
98+
runs-on: ubuntu-latest
99+
100+
steps:
101+
- uses: actions/checkout@v4
102+
103+
- name: Set up Python
104+
uses: actions/setup-python@v4
105+
with:
106+
python-version: '3.10'
107+
108+
- name: Install dependencies
109+
run: |
110+
python -m pip install --upgrade pip
111+
pip install -e ".[docs,dill]"
112+
113+
- name: Build documentation
114+
run: mkdocs build --strict

.github/workflows/docs.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Deploy Documentation
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
paths:
7+
- 'docs/**'
8+
- 'mkdocs.yml'
9+
- 'src/ezmpi/**'
10+
workflow_dispatch:
11+
12+
jobs:
13+
docs-build:
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v4
21+
with:
22+
python-version: '3.10'
23+
24+
- name: Install dependencies
25+
run: |
26+
python -m pip install --upgrade pip
27+
pip install -e ".[docs,dill]"
28+
29+
- name: Build documentation
30+
run: mkdocs build --strict
31+
32+
- name: Upload built docs
33+
uses: actions/upload-artifact@v3
34+
with:
35+
name: docs-site
36+
path: site/
37+
retention-days: 7
38+
39+
# Trigger ReadTheDocs build
40+
trigger-rtd:
41+
needs: docs-build
42+
runs-on: ubuntu-latest
43+
44+
steps:
45+
- name: Trigger ReadTheDocs build
46+
run: |
47+
curl -X POST -d "" ${{ secrets.READTHEDOCS_WEBHOOK_URL }} || echo "RTD webhook not configured"

.github/workflows/mpi-tests.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: MPI Tests
2+
3+
on:
4+
schedule:
5+
- cron: '0 2 * * 0' # Weekly on Sunday 2 AM
6+
workflow_dispatch:
7+
push:
8+
branches: [ main ]
9+
paths:
10+
- 'src/**'
11+
- 'tests/**'
12+
13+
jobs:
14+
mpi-matrix:
15+
strategy:
16+
matrix:
17+
mpi: [openmpi]
18+
python-version: ['3.8', '3.10', '3.12']
19+
nodes: [2, 4, 8]
20+
fail-fast: false
21+
22+
runs-on: ubuntu-latest
23+
24+
steps:
25+
- uses: actions/checkout@v4
26+
27+
- name: Install MPI (${{ matrix.mpi }})
28+
run: |
29+
sudo apt-get update
30+
sudo apt-get install -y openmpi-bin libopenmpi-dev
31+
32+
- name: Set up Python ${{ matrix.python-version }}
33+
uses: actions/setup-python@v4
34+
with:
35+
python-version: ${{ matrix.python-version }}
36+
37+
- name: Install dependencies
38+
run: |
39+
python -m pip install --upgrade pip
40+
pip install -e ".[test,dill]"
41+
42+
- name: Run tests with ${{ matrix.nodes }} nodes
43+
run: mpiexec -n ${{ matrix.nodes }} pytest tests/ -v --cov=ezmpi --cov-report=xml
44+
45+
- name: Upload coverage
46+
uses: codecov/codecov-action@v3
47+
with:
48+
file: ./coverage.xml
49+
flags: mpi-${{ matrix.nodes }}
50+
name: mpi-tests-py${{ matrix.python-version }}-n${{ matrix.nodes }}
51+
fail_ci_if_error: false
52+
53+
performance-tests:
54+
runs-on: ubuntu-latest
55+
56+
steps:
57+
- uses: actions/checkout@v4
58+
59+
- name: Install MPI
60+
run: |
61+
sudo apt-get update
62+
sudo apt-get install -y openmpi-bin libopenmpi-dev
63+
64+
- name: Set up Python
65+
uses: actions/setup-python@v4
66+
with:
67+
python-version: '3.10'
68+
69+
- name: Install dependencies
70+
run: |
71+
python -m pip install --upgrade pip
72+
pip install -e ".[test,dill]"
73+
74+
- name: Run performance tests
75+
run: mpiexec -n 4 pytest tests/test_performance.py -v
76+
77+
- name: Upload benchmark results
78+
uses: actions/upload-artifact@v3
79+
with:
80+
name: benchmark-results
81+
path: |
82+
benchmark.json
83+
.benchmarks/
84+
retention-days: 30

0 commit comments

Comments
 (0)