- Library CI is the default for all libraries: unit tests, PHPStan, coverage, and no external services.
- Integration CI is optional and explicit: used only when real databases or services are required.
- Never mix Library CI and Integration CI in the same workflow.
- Integration CI options (PHPStan, coverage, services) must be enabled intentionally and justified.
- If Docker, DSNs, or real connections are needed β Integration CI. Otherwise β Library CI.
This repository contains official, centralized GitHub Actions workflows used across the Maatify ecosystem.
Its purpose is to standardize CI behavior, eliminate duplication, and enforce clear architectural boundaries between different project types.
CI must reflect the architectural nature of the project β not convenience.
Different project types require different CI responsibilities. Mixing them leads to flaky builds, unclear failures, and architectural drift.
Maatify defines two official CI workflows:
- Library CI
- Integration CI
Each serves a distinct purpose and must not be merged.
.github/workflows/library-ci.yml
- Infrastructure libraries
- Core libraries
- DTO / config / utility libraries
Examples:
infra-driversdata-adaptersrate-limitersecurity-guard(core phases)
- Runs PHPStan (blocking)
- Runs PHPUnit unit tests
- Generates code coverage
- Publishes GitHub Summary
- Sends Telegram notification
- Calculates execution duration
- Start Docker services
- Use environment variables (DSN, credentials)
- Connect to real databases
- Run integration tests
- Perform schema or migration setup
If any of the above is needed, Library CI is the wrong workflow.
| Property | Value |
|---|---|
| Determinism | High |
| Speed | Fast |
| Network | None |
| Secrets | Telegram only |
| Trigger | Every push / PR |
.github/workflows/integration.yml
- Projects with real external dependencies
- Integration or end-to-end validation
- Adapter or application-level testing
Examples:
- Applications
data-adapters(integration phase)security-guard(integration phase)
- Starts Docker services (MySQL / Redis / Mongo)
- Uses real DSNs and credentials
- Initializes schemas / collections
- Runs integration tests only
- Optionally runs PHPStan
- Optionally collects coverage
- Sends Telegram notification
- Publishes execution summary
- A replacement for Library CI
- A quality gate for every commit
- A fast or deterministic workflow
| Property | Value |
|---|---|
| Determinism | Medium |
| Speed | Slow |
| Network | Required |
| Secrets | Required |
| Trigger | Manual / Tags only |
If tests require Docker, DSNs, or real connections β use Integration CI. Otherwise β use Library CI.
There is no third option.
Practical usage examples for all official Maatify CI workflows are documented separately.
This includes:
- How to enable Library CI in a project
- How to enable Integration CI correctly
- Valid triggers and execution patterns
- Common misuses to avoid
β‘οΈ See USAGE.md for full usage instructions.
This README defines policy and enforcement.
USAGE.mdfocuses strictly on how to apply the workflows.
Integration CI supports several optional capabilities. These options exist to adapt the workflow to different project needs, but must be enabled intentionally.
Integration CI is not a quality gate by default. Each option must justify its execution cost.
- Before a release
- When integration changes introduce new logic paths
- When additional confidence is required beyond Library CI
- If PHPStan already runs in Library CI
- If integration runtime becomes excessively slow
- If enabled, PHPStan must be blocking
- Non-blocking static analysis is not allowed
- To observe real execution paths
- To validate behavior not covered by unit tests
- In application or adapter-heavy projects
- For pure infrastructure libraries
- When unit test coverage is sufficient
- When CI runtime is a concern
- Integration coverage is informational only
- No minimum coverage thresholds
- Coverage results must not block the pipeline
Integration CI may include non-blocking diagnostics to help troubleshoot service availability.
Examples:
- Redis ping
- MySQL connection check
- MongoDB ping
- Must use
continue-on-error: true - Must not affect CI success or failure
Integration CI may initialize:
- Database schemas
- Indexes
- Collections
- Integration schemas must be isolated
- Production schemas must never be reused
- Initialization scripts must live under test fixtures
Telegram notifications are mandatory for Integration CI.
They provide:
- Pass / Fail status
- Execution duration
- Repository and reference information
- Direct link to CI logs
Execution time must always be calculated.
Purpose:
- Detect performance regressions
- Identify stalled or hanging integration runs
- Monitor infrastructure stability
| Option | Default | Purpose |
|---|---|---|
| PHPStan | Off | Extra static confidence |
| Coverage | Off | Observe real execution paths |
| Debug services | Optional | Troubleshooting only |
| Schema init | Optional | Required for DB-backed tests |
| Telegram | On | Visibility & alerting |
| Duration | On | Performance monitoring |
If an integration option is enabled, it must be justified. Blindly enabling all options is considered misuse.
Integration CI options exist to increase confidence β not to compensate for missing unit tests.
- Projects must not modify centralized workflows locally
- CI changes are made only in this repository
- Any exception requires explicit architectural approval
- Integration CI must never run on every push
In your project repository:
jobs:
ci:
uses: maatify/.github/.github/workflows/library-ci.yml@main
secrets:
TELEGRAM_CI_BOT_TOKEN: ${{ secrets.TELEGRAM_CI_BOT_TOKEN }}
TELEGRAM_CI_CHAT_ID: ${{ secrets.TELEGRAM_CI_CHAT_ID }}Library CI protects code quality. Integration CI validates reality.
Confusing the two breaks both.
Β© 2025 Maatify.dev CI Architecture maintained by Mohamed Abdulalim