From e45f7ecd827625082d67bc916e6770a4b82db283 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Mon, 4 May 2026 14:00:35 +0200 Subject: [PATCH 1/6] chore: trigger releases from main changesets --- .changeset/config.json | 11 + .github/pull_request_template.md | 3 +- .github/workflows/release.yml | 233 +++------ .gitignore | 1 + RELEASING.md | 53 +- package.json | 13 + pnpm-lock.yaml | 805 +++++++++++++++++++++++++++++++ pnpm-workspace.yaml | 2 + 8 files changed, 941 insertions(+), 180 deletions(-) create mode 100644 .changeset/config.json create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..2be13d4 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 660cbee..e0eca5e 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -16,7 +16,6 @@ ### If releasing new changes -- [ ] Added the `release` label to the PR -- [ ] Added exactly one version bump label: `bump-patch`, `bump-minor`, or `bump-major` +- [ ] Ran `pnpm changeset` to generate a changeset file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d516e28..38999e6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,42 +1,27 @@ name: "Release" on: - pull_request: - types: [closed] + push: branches: [main] + paths: + - '.changeset/**' workflow_dispatch: - inputs: - bump_type: - description: Version bump to apply - required: true - type: choice - options: - - patch - - minor - - major permissions: contents: read # Concurrency control: only one release process can run at a time -# This prevents race conditions if multiple PRs with 'release' label merge simultaneously +# This prevents race conditions if multiple releasable changesets merge simultaneously concurrency: group: release cancel-in-progress: false jobs: - check-release-label: - name: Check for release label + check-changesets: + name: Check for changesets runs-on: ubuntu-latest - # Run when PR with 'release' label is merged to main, or when manually triggered - if: | - github.event_name == 'workflow_dispatch' || - (github.event_name == 'pull_request' && - github.event.pull_request.merged == true && - contains(github.event.pull_request.labels.*.name, 'release')) outputs: - should-release: ${{ steps.check.outputs.should-release }} - bump-type: ${{ steps.check.outputs.bump-type }} + has-changesets: ${{ steps.check.outputs.has-changesets }} steps: - name: Checkout repository uses: actions/checkout@v6 @@ -44,36 +29,22 @@ jobs: ref: main fetch-depth: 0 - - name: Check release conditions + - name: Check for changesets id: check - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - EVENT_NAME: ${{ github.event_name }} - INPUT_BUMP_TYPE: ${{ inputs.bump_type }} - HAS_BUMP_MAJOR: ${{ contains(github.event.pull_request.labels.*.name, 'bump-major') }} - HAS_BUMP_MINOR: ${{ contains(github.event.pull_request.labels.*.name, 'bump-minor') }} - HAS_BUMP_PATCH: ${{ contains(github.event.pull_request.labels.*.name, 'bump-patch') }} run: | - # Determine bump type from workflow input or PR labels - if [ "$EVENT_NAME" = "workflow_dispatch" ]; then - echo "bump-type=$INPUT_BUMP_TYPE" >> "$GITHUB_OUTPUT" - echo "should-release=true" >> "$GITHUB_OUTPUT" - echo "Manual release requested with bump type '$INPUT_BUMP_TYPE'" - elif [ "$HAS_BUMP_MAJOR" = "true" ]; then - echo "bump-type=major" >> "$GITHUB_OUTPUT" - echo "should-release=true" >> "$GITHUB_OUTPUT" - elif [ "$HAS_BUMP_MINOR" = "true" ]; then - echo "bump-type=minor" >> "$GITHUB_OUTPUT" - echo "should-release=true" >> "$GITHUB_OUTPUT" - elif [ "$HAS_BUMP_PATCH" = "true" ]; then - echo "bump-type=patch" >> "$GITHUB_OUTPUT" - echo "should-release=true" >> "$GITHUB_OUTPUT" + changeset_count=$(find .changeset -name '*.md' ! -name 'README.md' 2>/dev/null | wc -l) + if [ "$changeset_count" -gt 0 ]; then + echo "has-changesets=true" >> "$GITHUB_OUTPUT" + echo "Found $changeset_count changeset(s), ready to release" + else + echo "has-changesets=false" >> "$GITHUB_OUTPUT" + echo "No changesets to release" fi notify-approval-needed: name: Notify Slack - Approval Needed - needs: check-release-label - if: needs.check-release-label.outputs.should-release == 'true' + needs: check-changesets + if: needs.check-changesets.outputs.has-changesets == 'true' uses: posthog/.github/.github/workflows/notify-approval-needed.yml@main with: slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }} @@ -83,13 +54,11 @@ jobs: posthog_project_api_key: ${{ secrets.POSTHOG_PROJECT_API_KEY }} release: - name: Bump versions and release - needs: [check-release-label, notify-approval-needed] + name: Bump version and release + needs: [check-changesets, notify-approval-needed] runs-on: ubuntu-latest - # Use `always()` to ensure the job runs even if the check-release-label job fails - # but still depend on it to be able to use `needs.notify-approval-needed.outputs.slack_ts` - if: always() && needs.check-release-label.outputs.should-release == 'true' - environment: "Release" # This will require an approval from a maintainer, they are notified in Slack above + if: always() && needs.check-changesets.outputs.has-changesets == 'true' + environment: "Release" permissions: contents: write actions: write @@ -103,13 +72,12 @@ jobs: thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }} message: "✅ Release approved! Version bump in progress..." emoji_reaction: "white_check_mark" - - name: Get GitHub App token id: releaser uses: actions/create-github-app-token@v3 with: client-id: ${{ secrets.GH_APP_POSTHOG_PHP_RELEASER_APP_ID }} - private-key: ${{ secrets.GH_APP_POSTHOG_PHP_RELEASER_PRIVATE_KEY }} # Secrets available only inside the 'Release' environment, requires approval from a maintainer + private-key: ${{ secrets.GH_APP_POSTHOG_PHP_RELEASER_PRIVATE_KEY }} - name: Checkout repository uses: actions/checkout@v6 @@ -118,69 +86,68 @@ jobs: fetch-depth: 0 token: ${{ steps.releaser.outputs.token }} - - name: Bump version - id: bump-version + - name: Configure Git run: | - current_version=$(grep -oP "public const VERSION = '\K[^']+" lib/PostHog.php) - IFS='.' read -ra version_parts <<< "$current_version" - major=${version_parts[0]} - minor=${version_parts[1]} - patch=${version_parts[2]} - - if [ "${{ needs.check-release-label.outputs.bump-type }}" == "major" ]; then - new_version="$((major + 1)).0.0" - elif [ "${{ needs.check-release-label.outputs.bump-type }}" == "minor" ]; then - new_version="$major.$((minor + 1)).0" - else - new_version="$major.$minor.$((patch + 1))" - fi + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" - sed -i "s/public const VERSION = '$current_version'/public const VERSION = '$new_version'/" lib/PostHog.php - sed -i "s/\"version\": \"$current_version\"/\"version\": \"$new_version\"/" composer.json + - name: Setup pnpm + uses: pnpm/action-setup@v4 - echo "current_version=$current_version" >> $GITHUB_OUTPUT - echo "new_version=$new_version" >> $GITHUB_OUTPUT + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 22 + cache: pnpm - if ! git diff --quiet lib/PostHog.php composer.json; then - echo "has_changes=true" >> "$GITHUB_OUTPUT" - else - echo "has_changes=false" >> "$GITHUB_OUTPUT" - fi + - name: Install dependencies + run: pnpm install --frozen-lockfile - - name: Update CHANGELOG.md - env: - CURRENT_VERSION: ${{ steps.bump-version.outputs.current_version }} - NEW_VERSION: ${{ steps.bump-version.outputs.new_version }} + - name: Apply changesets and update version + id: apply-changesets run: | - release_date=$(date +%Y-%m-%d) - echo -e "## $NEW_VERSION - $release_date\n\n* [Full Changelog](https://github.com/PostHog/posthog-php/compare/${CURRENT_VERSION}...${NEW_VERSION})\n\n$(cat CHANGELOG.md)" > CHANGELOG.md + pnpm changeset version + NEW_VERSION=$(node -p "require('./package.json').version") + python3 - <<'PY' + import json + from pathlib import Path + version = json.loads(Path('package.json').read_text())['version'] + posthog = Path('lib/PostHog.php') + posthog.write_text(__import__('re').sub(r"public const VERSION = '[^']+'", f"public const VERSION = '{version}'", posthog.read_text())) + composer = Path('composer.json') + data = json.loads(composer.read_text()) + data['version'] = version + composer.write_text(json.dumps(data, indent="\t") + "\n") + PY + echo "new-version=$NEW_VERSION" >> "$GITHUB_OUTPUT" + echo "New version: $NEW_VERSION" - name: Commit version bump - if: steps.bump-version.outputs.has_changes == 'true' - uses: planetscale/ghcommit-action@25309d8005ac7c3bcd61d3fe19b69e0fe47dbdde # v0.2.20 - with: - commit_message: "chore: bump version to ${{ steps.bump-version.outputs.new_version }} [version bump]" - repo: ${{ github.repository }} - branch: main - file_pattern: "lib/PostHog.php composer.json CHANGELOG.md" + id: commit-version-bump env: - GITHUB_TOKEN: ${{ steps.releaser.outputs.token }} + NEW_VERSION: ${{ steps.apply-changesets.outputs.new-version }} + run: | + git add -A + if git diff --staged --quiet; then + echo "No changes to commit" + echo "committed=false" >> "$GITHUB_OUTPUT" + else + git commit -m "chore: release $NEW_VERSION [version bump]" + git push origin main + echo "committed=true" >> "$GITHUB_OUTPUT" + fi - name: Create GitHub release - if: steps.bump-version.outputs.has_changes == 'true' + if: steps.commit-version-bump.outputs.committed == 'true' env: GH_TOKEN: ${{ steps.releaser.outputs.token }} - NEW_VERSION: ${{ steps.bump-version.outputs.new_version }} + NEW_VERSION: ${{ steps.apply-changesets.outputs.new-version }} run: | - LAST_CHANGELOG_ENTRY=$(awk -v defText="see CHANGELOG.md" '/^## /{if (flag) exit; flag=1} flag && /^##$/{exit} flag; END{if (!flag) print defText}' CHANGELOG.md) - gh release create "$NEW_VERSION" \ - --target main \ - --title "$NEW_VERSION" \ - --notes "$LAST_CHANGELOG_ENTRY" + CHANGELOG_ENTRY=$(awk -v defText="see CHANGELOG.md" '/^## /{if (flag) exit; flag=1} flag && /^##$/{exit} flag; END{if (!flag) print defText}' CHANGELOG.md) + gh release create "$NEW_VERSION" --target main --title "$NEW_VERSION" --notes "$CHANGELOG_ENTRY" - # Notify in case of a failure - name: Send failure event to PostHog - if: ${{ failure() }} + if: failure() uses: PostHog/posthog-github-action@v1 with: posthog-token: "${{ secrets.POSTHOG_PROJECT_API_KEY }}" @@ -190,73 +157,15 @@ jobs: "commitSha": "${{ github.sha }}", "jobStatus": "${{ job.status }}", "ref": "${{ github.ref }}", - "version": "${{ steps.bump-version.outputs.new_version }}" + "version": "${{ steps.apply-changesets.outputs.new-version }}" } - name: Notify Slack - Failed - if: ${{ failure() && needs.notify-approval-needed.outputs.slack_ts != '' }} + if: failure() && needs.notify-approval-needed.outputs.slack_ts != '' uses: posthog/.github/.github/actions/slack-thread-reply@main with: slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }} slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }} thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }} - message: "❌ Failed to release `posthog-php@${{ steps.bump-version.outputs.new_version }}`! " + message: "❌ Failed to release `posthog-php@${{ steps.apply-changesets.outputs.new-version }}`! " emoji_reaction: "x" - - notify-released: - name: Notify Slack - Released - needs: [notify-approval-needed, release] - runs-on: ubuntu-latest - if: always() && needs.release.result == 'success' && needs.notify-approval-needed.outputs.slack_ts != '' - steps: - - name: Checkout repository - uses: actions/checkout@v6 - - - name: Notify Slack - Released - uses: posthog/.github/.github/actions/slack-thread-reply@main - with: - slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }} - slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }} - thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }} - message: "🚀 posthog-php released successfully!" - emoji_reaction: "rocket" - - notify-rejected: - name: Notify Slack - Rejected - needs: [release, notify-approval-needed] - runs-on: ubuntu-latest - if: always() && needs.release.result == 'failure' && needs.notify-approval-needed.outputs.slack_ts != '' - steps: - - name: Check for rejection - id: check-rejection - env: - GH_TOKEN: ${{ github.token }} - run: | - RESPONSE=$(gh api /repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/approvals) - REJECTED=$(echo "$RESPONSE" | jq '[.[] | select(.state == "rejected")] | length') - if [ "$REJECTED" -gt 0 ]; then - echo "was_rejected=true" >> "$GITHUB_OUTPUT" - COMMENT=$(echo "$RESPONSE" | jq -r '.[] | select(.state == "rejected") | .comment // empty' | head -1) - if [ -n "$COMMENT" ]; then - { - echo 'message<> "$GITHUB_OUTPUT" - else - echo "message=🚫 Release was rejected." >> "$GITHUB_OUTPUT" - fi - else - echo "was_rejected=false" >> "$GITHUB_OUTPUT" - fi - - - name: Notify Slack - Rejected - if: steps.check-rejection.outputs.was_rejected == 'true' - continue-on-error: true - uses: PostHog/.github/.github/actions/slack-thread-reply@main - with: - slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }} - slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }} - thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }} - message: '${{ steps.check-rejection.outputs.message }}' - emoji_reaction: 'no_entry_sign' diff --git a/.gitignore b/.gitignore index 48f678d..d456527 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ clover.xml xdebug.log .DS_Store .env +node_modules/ diff --git a/RELEASING.md b/RELEASING.md index 6bb555c..b0fe3d2 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,24 +1,45 @@ # Releasing -Releases are semi-automated via GitHub Actions. When a PR with the `release` and a version bump label is merged to `main`, the release workflow is triggered. You can also trigger the `Release` workflow manually from GitHub Actions and choose the bump type. +This repository uses [Changesets](https://github.com/changesets/changesets) for version management and an automated GitHub Actions workflow for releases. -You'll need an approval from a PostHog engineer. If you're an employee, you can see the request in the [#approvals-client-libraries](https://app.slack.com/client/TSS5W8YQZ/C0A3UEVDDNF) channel. +## How to Release -## Release Process +### 1. Add a Changeset -1. Either: - - **Create your PR** with the changes you want to release, add the `release` label, add exactly one version bump label (`bump-patch`, `bump-minor`, or `bump-major`), and **merge the PR** to `main`, or - - open the `Release` workflow in GitHub Actions, click **Run workflow**, and choose `patch`, `minor`, or `major` +When making a change that should be released, add a changeset: -Once the workflow is triggered, the following happens automatically: +```bash +pnpm changeset +``` -1. A Slack notification is sent to the client libraries channel requesting approval -2. A maintainer approves the release in the GitHub `Release` environment -3. The version is bumped in `lib/PostHog.php` and `composer.json` based on the version label (`patch`, `minor`, or `major`, extracted from the label) -4. The `CHANGELOG.md` is updated with a link to the full changelog -5. Changes are committed and pushed to `main` -6. A git tag is created (e.g., `v1.8.0`) -7. A GitHub release is created with the changelog content -8. Slack is notified of the successful release +This prompts you to select the version bump (`patch`, `minor`, or `major`) and write a short release summary. Commit the generated file in `.changeset/` with your pull request. -Releases are installed directly from GitHub. +### 2. Merge the Pull Request + +After review, merge the PR to `main`. No GitHub release label is required. + +A push to `main` that includes `.changeset/**` changes automatically starts the release workflow. The workflow then: + +1. Checks for pending changesets +2. Notifies the client libraries team in Slack for approval +3. Waits for approval from a maintainer via the GitHub `Release` environment +4. The workflow applies Changesets, syncs `lib/PostHog.php` and `composer.json`, tags the release, and creates a GitHub Release. +5. Notifies Slack when the release completes or fails + +### Manual Trigger + +You can also manually trigger the release workflow from the Actions tab with `workflow_dispatch`. Manual runs still require pending changesets. + +## Version Bumping + +Changesets determines the next version from the committed changeset files: + +- **patch**: bug fixes, documentation updates, and internal changes +- **minor**: backwards-compatible features +- **major**: breaking changes + +## Troubleshooting + +### No changesets found + +If the release workflow reports that no changesets were found, make sure your PR includes at least one releasable `.changeset/*.md` file. diff --git a/package.json b/package.json new file mode 100644 index 0000000..1dc2032 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "posthog-php", + "version": "4.2.4", + "private": true, + "description": "Release metadata and changesets for the PostHog PHP SDK", + "packageManager": "pnpm@10.33.2", + "scripts": { + "changeset": "changeset" + }, + "devDependencies": { + "@changesets/cli": "^2.30.0" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..e491371 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,805 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@changesets/cli': + specifier: ^2.30.0 + version: 2.31.0 + +packages: + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@changesets/apply-release-plan@7.1.1': + resolution: {integrity: sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==} + + '@changesets/assemble-release-plan@6.0.10': + resolution: {integrity: sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A==} + + '@changesets/changelog-git@0.2.1': + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} + + '@changesets/cli@2.31.0': + resolution: {integrity: sha512-AhI4enNTgHu2IZr6K4WZyf0EPch4XVMn1yOMFmCD9gsfBGqMYaHXls5HyDv6/CL5axVQABz68eG30eCtbr2wFg==} + hasBin: true + + '@changesets/config@3.1.4': + resolution: {integrity: sha512-pf0bvD/v6WI2cRlZ6hzpjtZdSlXDXMAJ+Iz7xfFzV4ZxJ8OGGAON+1qYc99ZPrijnt4xp3VGG7eNvAOGS24V1Q==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.4': + resolution: {integrity: sha512-ZsS00x6WvmHq3sQv8oCMwL0f/z3wbXCVuSVTJwCnnmbC/iBdNJGFx1EcbMG4PC6sXRyH69liM4A2WKXzn/kRPg==} + + '@changesets/get-release-plan@4.0.16': + resolution: {integrity: sha512-2K5Om6CrMPm45rtvckfzWo7e9jOVCKLCnXia5eUPaURH7/LWzri7pK1TycdzAuAtehLkW7VPbWLCSExTHmiI6g==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.4': + resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.3': + resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==} + + '@changesets/pre@2.0.2': + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} + + '@changesets/read@0.6.7': + resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==} + + '@changesets/should-skip-package@0.1.2': + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.1.0': + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} + + '@changesets/write@0.4.0': + resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + human-id@4.1.3: + resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} + hasBin: true + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + spawndamnit@3.0.1: + resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + +snapshots: + + '@babel/runtime@7.29.2': {} + + '@changesets/apply-release-plan@7.1.1': + dependencies: + '@changesets/config': 3.1.4 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.7.4 + + '@changesets/assemble-release-plan@6.0.10': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.7.4 + + '@changesets/changelog-git@0.2.1': + dependencies: + '@changesets/types': 6.1.0 + + '@changesets/cli@2.31.0': + dependencies: + '@changesets/apply-release-plan': 7.1.1 + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.4 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/get-release-plan': 4.0.16 + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 + '@inquirer/external-editor': 1.0.3 + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + enquirer: 2.4.1 + fs-extra: 7.0.1 + mri: 1.2.0 + package-manager-detector: 0.2.11 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.7.4 + spawndamnit: 3.0.1 + term-size: 2.2.1 + transitivePeerDependencies: + - '@types/node' + + '@changesets/config@3.1.4': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/logger': 0.1.1 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.4': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.7.4 + + '@changesets/get-release-plan@4.0.16': + dependencies: + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/config': 3.1.4 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.3': + dependencies: + '@changesets/types': 6.1.0 + js-yaml: 4.1.1 + + '@changesets/pre@2.0.2': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.7': + dependencies: + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.3 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.2': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.1.0': {} + + '@changesets/write@0.4.0': + dependencies: + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + human-id: 4.1.3 + prettier: 2.8.8 + + '@inquirer/external-editor@1.0.3': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.29.2 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.29.2 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@types/node@12.20.55': {} + + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-union@2.1.0: {} + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + chardet@2.1.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + detect-indent@6.1.0: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + esprima@4.0.1: {} + + extendable-error@0.1.7: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + graceful-fs@4.2.11: {} + + human-id@4.1.3: {} + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-windows@1.0.2: {} + + isexe@2.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + lodash.startcase@4.4.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mri@1.2.0: {} + + outdent@0.5.0: {} + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-map@2.1.0: {} + + p-try@2.2.0: {} + + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.11 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-type@4.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + pify@4.0.1: {} + + prettier@2.8.8: {} + + quansync@0.2.11: {} + + queue-microtask@1.2.3: {} + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.2 + pify: 4.0.1 + strip-bom: 3.0.0 + + resolve-from@5.0.0: {} + + reusify@1.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safer-buffer@2.1.2: {} + + semver@7.7.4: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + slash@3.0.0: {} + + spawndamnit@3.0.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + sprintf-js@1.0.3: {} + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: {} + + term-size@2.2.1: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + universalify@0.1.2: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..4de91a3 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - '.' From 11c9cb2424d6be783d5a2d53455874e3da536d21 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Mon, 4 May 2026 14:10:25 +0200 Subject: [PATCH 2/6] chore: pin pnpm action setup --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 38999e6..2ce675c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -92,7 +92,7 @@ jobs: git config user.email "github-actions[bot]@users.noreply.github.com" - name: Setup pnpm - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4 - name: Setup Node.js uses: actions/setup-node@v6 From 3619e96b47f13fcc6dfce64bce64c94882adeae0 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Mon, 4 May 2026 14:16:08 +0200 Subject: [PATCH 3/6] chore: skip release workflow on version bump commits --- .github/workflows/release.yml | 4 ++-- RELEASING.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2ce675c..b5a3488 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,7 +4,7 @@ on: push: branches: [main] paths: - - '.changeset/**' + - '.changeset/*.md' workflow_dispatch: permissions: @@ -132,7 +132,7 @@ jobs: echo "No changes to commit" echo "committed=false" >> "$GITHUB_OUTPUT" else - git commit -m "chore: release $NEW_VERSION [version bump]" + git commit -m "chore: release $NEW_VERSION [version bump] [skip ci]" git push origin main echo "committed=true" >> "$GITHUB_OUTPUT" fi diff --git a/RELEASING.md b/RELEASING.md index b0fe3d2..6afe8a9 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -18,7 +18,7 @@ This prompts you to select the version bump (`patch`, `minor`, or `major`) and w After review, merge the PR to `main`. No GitHub release label is required. -A push to `main` that includes `.changeset/**` changes automatically starts the release workflow. The workflow then: +A push to `main` that includes `.changeset/*.md` changes automatically starts the release workflow. The workflow then: 1. Checks for pending changesets 2. Notifies the client libraries team in Slack for approval From f83852efdd1a51a953fe84daf1176b5ef5d79e09 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Mon, 4 May 2026 14:40:25 +0200 Subject: [PATCH 4/6] chore: use Node.js 24 for changesets --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b5a3488..2f8ae80 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -97,7 +97,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22 + node-version: 24 cache: pnpm - name: Install dependencies From 74e8a31ea482d6085c3ee765659d003bc897b900 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Mon, 4 May 2026 14:43:11 +0200 Subject: [PATCH 5/6] chore: move PHP version sync to script --- .github/workflows/release.yml | 12 +----------- scripts/bump-version.sh | 12 ++++++++++++ 2 files changed, 13 insertions(+), 11 deletions(-) create mode 100755 scripts/bump-version.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2f8ae80..7ffc9d5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -108,17 +108,7 @@ jobs: run: | pnpm changeset version NEW_VERSION=$(node -p "require('./package.json').version") - python3 - <<'PY' - import json - from pathlib import Path - version = json.loads(Path('package.json').read_text())['version'] - posthog = Path('lib/PostHog.php') - posthog.write_text(__import__('re').sub(r"public const VERSION = '[^']+'", f"public const VERSION = '{version}'", posthog.read_text())) - composer = Path('composer.json') - data = json.loads(composer.read_text()) - data['version'] = version - composer.write_text(json.dumps(data, indent="\t") + "\n") - PY + ./scripts/bump-version.sh "$NEW_VERSION" echo "new-version=$NEW_VERSION" >> "$GITHUB_OUTPUT" echo "New version: $NEW_VERSION" diff --git a/scripts/bump-version.sh b/scripts/bump-version.sh new file mode 100755 index 0000000..677ceed --- /dev/null +++ b/scripts/bump-version.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +NEW_VERSION="$1" + +perl -0pi -e "s/public const VERSION = '[^']+'/public const VERSION = '$NEW_VERSION'/" lib/PostHog.php +perl -0pi -e "s/\"version\": \"[^\"]+\"/\"version\": \"$NEW_VERSION\"/" composer.json From 6153250794014201f12b749a07c33749830fbe90 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Mon, 4 May 2026 14:45:44 +0200 Subject: [PATCH 6/6] chore: restore release Slack notifications --- .github/workflows/release.yml | 58 +++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7ffc9d5..44993f0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -159,3 +159,61 @@ jobs: thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }} message: "❌ Failed to release `posthog-php@${{ steps.apply-changesets.outputs.new-version }}`! " emoji_reaction: "x" + + notify-released: + name: Notify Slack - Released + needs: [notify-approval-needed, release] + runs-on: ubuntu-latest + if: always() && needs.release.result == 'success' && needs.notify-approval-needed.outputs.slack_ts != '' + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Notify Slack - Released + uses: posthog/.github/.github/actions/slack-thread-reply@main + with: + slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }} + slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }} + thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }} + message: "🚀 posthog-php released successfully!" + emoji_reaction: "rocket" + + notify-rejected: + name: Notify Slack - Rejected + needs: [release, notify-approval-needed] + runs-on: ubuntu-latest + if: always() && needs.release.result == 'failure' && needs.notify-approval-needed.outputs.slack_ts != '' + steps: + - name: Check for rejection + id: check-rejection + env: + GH_TOKEN: ${{ github.token }} + run: | + RESPONSE=$(gh api /repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/approvals) + REJECTED=$(echo "$RESPONSE" | jq '[.[] | select(.state == "rejected")] | length') + if [ "$REJECTED" -gt 0 ]; then + echo "was_rejected=true" >> "$GITHUB_OUTPUT" + COMMENT=$(echo "$RESPONSE" | jq -r '.[] | select(.state == "rejected") | .comment // empty' | head -1) + if [ -n "$COMMENT" ]; then + { + echo 'message<> "$GITHUB_OUTPUT" + else + echo "message=🚫 Release was rejected." >> "$GITHUB_OUTPUT" + fi + else + echo "was_rejected=false" >> "$GITHUB_OUTPUT" + fi + + - name: Notify Slack - Rejected + if: steps.check-rejection.outputs.was_rejected == 'true' + continue-on-error: true + uses: PostHog/.github/.github/actions/slack-thread-reply@main + with: + slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }} + slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }} + thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }} + message: '${{ steps.check-rejection.outputs.message }}' + emoji_reaction: 'no_entry_sign'