Skip to content

Latest commit

 

History

History
87 lines (63 loc) · 3.09 KB

File metadata and controls

87 lines (63 loc) · 3.09 KB

Contributing

Getting set up

composer install
npm install

PHP 8.2 is the minimum; CI runs 8.2 through 8.4. Beacon has no runtime dependencies and should keep none — the framework packages are dev dependencies here and suggested there.

Checks

composer check   # style, PHPStan level 8, PHPUnit
npm test         # the browser agent, in jsdom

Individually: composer cs, composer cs:fix, composer stan, composer test. All of it runs in CI on every pull request.

Testing against real databases

SQLite always runs. MySQL and PostgreSQL run the same contract when you point the tests at a server and skip when you do not, so a green local run does not mean the dialects are fine. CI points them at a server and treats a skip as a failure.

export BEACON_TEST_MYSQL_DSN='mysql:host=127.0.0.1;dbname=beacon;charset=utf8mb4'
export BEACON_TEST_MYSQL_USER=root BEACON_TEST_MYSQL_PASSWORD=secret
export BEACON_TEST_PGSQL_DSN='pgsql:host=127.0.0.1;dbname=beacon'
export BEACON_TEST_PGSQL_USER=postgres BEACON_TEST_PGSQL_PASSWORD=secret

CI runs MySQL at +05:00, because a driver that reads the session time zone passes against a UTC server and fails against that one. Point your local MySQL off UTC too if you are touching the timeline queries.

The browser agent

src/Assets/agent.js is a classic IIFE, inlined verbatim — no build step, no transpiler. Write it for the oldest browser you are willing to support.

tests/js/agent.js stands up PerformanceObserver and sendBeacon, which jsdom lacks, as recorders, and takes the agent's global listeners back off between tests.

Storage drivers

Both real drivers extend tests/StorageContract.php, which is the interface written down as behaviour. A new driver extends it too.

What to keep in mind

  • The privacy claims are testable, so test them. A change that touches what is stored needs a test asserting the address and user agent are absent in anonymous mode. IngestTest has the pattern.
  • The safe reading wins. No secret means no visitor token, not a weak one. An unknown mode is off.
  • Ingest never throws. Refuse and return zero.
  • Storage::DIMENSIONS is a security boundary. Dimensions are interpolated into SQL, so anything added there must be a real column name.
  • Comments are one sentence, or absent. Reasoning goes in the commit message.

Commits and pull requests

Commit subjects are imperative and describe the change, not the file (fix: count the day files without materialising them). Explain in the body why the change is right, not what the diff already shows. Mark breaking changes with !. One concern per pull request.

Releasing

Add the section to CHANGELOG.md first, then push the tag:

git tag -a v0.2.0 -m v0.2.0 && git push origin v0.2.0

A workflow turns the tag into a GitHub release using the matching ## [0.2.0] section and fails when there is none. It needs no repository secrets.

Packagist reads tags rather than releases, so the version appears as soon as the tag is pushed, provided the repository has the Packagist GitHub App installed.