Skip to content

Commit 8e7100e

Browse files
andris9claude
andcommitted
Modernize SDK with PHP 8.1+, resources, tests, and CI
Major SDK rewrite with modern PHP patterns: - Resource-based architecture for all EmailEngine endpoints - Typed properties, constructor promotion, match expressions - Specific exception classes for error handling - HttpClient with proper error mapping New resources: Accounts, Messages, Mailboxes, Outbox, Settings, Tokens, Templates, Gateways, OAuth2, Webhooks, Stats, Blocklists Testing infrastructure: - PHPUnit 10 with unit and integration test suites - Docker setup for multi-PHP version testing (8.1-8.4) - Integration tests with EmailEngine Docker service CI/CD: - GitHub Actions workflow with concurrent run cancellation - Matrix testing across PHP 8.1, 8.2, 8.3, 8.4 - Code coverage on main branch Backward compatible with legacy API via LegacyEmailEngine class. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 452c5f3 commit 8e7100e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+6130
-412
lines changed

.github/workflows/tests.yml

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: ['*']
6+
pull_request:
7+
branches: [master, main]
8+
9+
# Cancel in-progress runs when a new commit is pushed
10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
jobs:
15+
# ==========================================================================
16+
# Unit Tests - Multiple PHP Versions
17+
# ==========================================================================
18+
unit-tests:
19+
name: Unit Tests (PHP ${{ matrix.php }})
20+
runs-on: ubuntu-latest
21+
22+
strategy:
23+
fail-fast: false
24+
matrix:
25+
php: ['8.1', '8.2', '8.3', '8.4']
26+
27+
steps:
28+
- name: Checkout code
29+
uses: actions/checkout@v4
30+
31+
- name: Setup PHP ${{ matrix.php }}
32+
uses: shivammathur/setup-php@v2
33+
with:
34+
php-version: ${{ matrix.php }}
35+
extensions: json, mbstring
36+
coverage: xdebug
37+
tools: composer:v2
38+
39+
- name: Get Composer cache directory
40+
id: composer-cache
41+
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
42+
43+
- name: Cache Composer dependencies
44+
uses: actions/cache@v4
45+
with:
46+
path: ${{ steps.composer-cache.outputs.dir }}
47+
key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}
48+
restore-keys: |
49+
${{ runner.os }}-php-${{ matrix.php }}-composer-
50+
51+
- name: Install dependencies
52+
run: composer install --prefer-dist --no-progress
53+
54+
- name: Run unit tests
55+
run: ./vendor/bin/phpunit --testsuite unit
56+
57+
# ==========================================================================
58+
# Code Quality
59+
# ==========================================================================
60+
code-quality:
61+
name: Code Quality
62+
runs-on: ubuntu-latest
63+
64+
steps:
65+
- name: Checkout code
66+
uses: actions/checkout@v4
67+
68+
- name: Setup PHP
69+
uses: shivammathur/setup-php@v2
70+
with:
71+
php-version: '8.3'
72+
extensions: json, mbstring
73+
tools: composer:v2
74+
75+
- name: Get Composer cache directory
76+
id: composer-cache
77+
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
78+
79+
- name: Cache Composer dependencies
80+
uses: actions/cache@v4
81+
with:
82+
path: ${{ steps.composer-cache.outputs.dir }}
83+
key: ${{ runner.os }}-php-8.3-composer-${{ hashFiles('**/composer.json') }}
84+
restore-keys: |
85+
${{ runner.os }}-php-8.3-composer-
86+
87+
- name: Install dependencies
88+
run: composer install --prefer-dist --no-progress
89+
90+
- name: Check code style (PSR-12)
91+
run: ./vendor/bin/phpcs --standard=PSR12 src
92+
continue-on-error: true
93+
94+
- name: Run PHPStan
95+
run: ./vendor/bin/phpstan analyse src --level=6
96+
continue-on-error: true
97+
98+
# ==========================================================================
99+
# Integration Tests with EmailEngine
100+
# ==========================================================================
101+
integration-tests:
102+
name: Integration Tests
103+
runs-on: ubuntu-latest
104+
needs: unit-tests # Only run if unit tests pass
105+
106+
services:
107+
redis:
108+
image: redis:7-alpine
109+
ports:
110+
- 6379:6379
111+
options: >-
112+
--health-cmd "redis-cli ping"
113+
--health-interval 10s
114+
--health-timeout 5s
115+
--health-retries 5
116+
117+
steps:
118+
- name: Checkout code
119+
uses: actions/checkout@v4
120+
121+
- name: Setup PHP
122+
uses: shivammathur/setup-php@v2
123+
with:
124+
php-version: '8.3'
125+
extensions: json, mbstring
126+
tools: composer:v2
127+
128+
- name: Setup Node.js (for EmailEngine CLI)
129+
uses: actions/setup-node@v4
130+
with:
131+
node-version: '20'
132+
133+
- name: Install EmailEngine CLI
134+
run: npm install -g emailengine
135+
136+
- name: Get Composer cache directory
137+
id: composer-cache
138+
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
139+
140+
- name: Cache Composer dependencies
141+
uses: actions/cache@v4
142+
with:
143+
path: ${{ steps.composer-cache.outputs.dir }}
144+
key: ${{ runner.os }}-php-8.3-composer-${{ hashFiles('**/composer.json') }}
145+
restore-keys: |
146+
${{ runner.os }}-php-8.3-composer-
147+
148+
- name: Install dependencies
149+
run: composer install --prefer-dist --no-progress
150+
151+
- name: Start EmailEngine
152+
run: |
153+
# Run EmailEngine in background
154+
docker run -d \
155+
--name emailengine \
156+
--network host \
157+
-e EENGINE_REDIS="redis://127.0.0.1:6379" \
158+
-e EENGINE_API_PROXY="false" \
159+
-e EENGINE_LOG_LEVEL="warn" \
160+
postalsys/emailengine:latest
161+
162+
# Wait for EmailEngine to be ready
163+
echo "Waiting for EmailEngine to start..."
164+
for i in {1..60}; do
165+
if curl -sf http://127.0.0.1:3000/v1/stats > /dev/null 2>&1; then
166+
echo "EmailEngine is ready!"
167+
break
168+
fi
169+
if [ $i -eq 60 ]; then
170+
echo "EmailEngine failed to start"
171+
docker logs emailengine
172+
exit 1
173+
fi
174+
sleep 1
175+
done
176+
177+
- name: Generate access token
178+
id: token
179+
run: |
180+
TOKEN=$(emailengine tokens issue \
181+
-d "GitHub Actions Test" \
182+
-s "*" \
183+
--dbs.redis="redis://127.0.0.1:6379" 2>/dev/null | grep -E '^[a-f0-9]{64}$' | tail -n1)
184+
185+
if [ -z "$TOKEN" ]; then
186+
echo "Failed to generate token"
187+
exit 1
188+
fi
189+
190+
echo "token=${TOKEN}" >> $GITHUB_OUTPUT
191+
echo "Token generated: ${TOKEN:0:16}..."
192+
193+
- name: Run integration tests
194+
env:
195+
EMAILENGINE_ACCESS_TOKEN: ${{ steps.token.outputs.token }}
196+
EMAILENGINE_BASE_URL: http://127.0.0.1:3000
197+
run: ./vendor/bin/phpunit --testsuite integration
198+
199+
- name: Stop EmailEngine
200+
if: always()
201+
run: |
202+
docker stop emailengine || true
203+
docker rm emailengine || true
204+
205+
# ==========================================================================
206+
# Test Coverage (on main branch only)
207+
# ==========================================================================
208+
coverage:
209+
name: Code Coverage
210+
runs-on: ubuntu-latest
211+
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main'
212+
needs: unit-tests
213+
214+
steps:
215+
- name: Checkout code
216+
uses: actions/checkout@v4
217+
218+
- name: Setup PHP
219+
uses: shivammathur/setup-php@v2
220+
with:
221+
php-version: '8.3'
222+
extensions: json, mbstring
223+
coverage: xdebug
224+
tools: composer:v2
225+
226+
- name: Get Composer cache directory
227+
id: composer-cache
228+
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
229+
230+
- name: Cache Composer dependencies
231+
uses: actions/cache@v4
232+
with:
233+
path: ${{ steps.composer-cache.outputs.dir }}
234+
key: ${{ runner.os }}-php-8.3-composer-${{ hashFiles('**/composer.json') }}
235+
restore-keys: |
236+
${{ runner.os }}-php-8.3-composer-
237+
238+
- name: Install dependencies
239+
run: composer install --prefer-dist --no-progress
240+
241+
- name: Generate coverage report
242+
run: ./vendor/bin/phpunit --testsuite unit --coverage-clover coverage.xml
243+
244+
- name: Upload coverage to Codecov
245+
uses: codecov/codecov-action@v4
246+
with:
247+
files: coverage.xml
248+
fail_ci_if_error: false
249+
continue-on-error: true

.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
# Dependencies
12
composer.lock
23
vendor/
34

5+
# Testing
6+
.phpunit.cache/
7+
.phpunit.result.cache
8+
coverage/
9+
10+
# IDE
11+
.idea/
12+
.vscode/
13+
*.swp
14+
*.swo
15+
*~
16+
17+
# OS
18+
.DS_Store
19+
Thumbs.db
20+
21+
# PHPStan
22+
phpstan.neon.local

0 commit comments

Comments
 (0)