From 3c1831952255232920989b68c6742b199e4263b6 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Thu, 23 Jul 2026 14:13:05 +0700 Subject: [PATCH 1/2] fix: harden release validation and publishing --- .changeset/calm-wolves-release.md | 5 +++++ .github/workflows/php.yml | 2 +- .github/workflows/release.yml | 27 +++++++++++++++++++++++---- RELEASING.md | 2 +- composer.lock | 2 +- 5 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 .changeset/calm-wolves-release.md diff --git a/.changeset/calm-wolves-release.md b/.changeset/calm-wolves-release.md new file mode 100644 index 0000000..a3a0bfc --- /dev/null +++ b/.changeset/calm-wolves-release.md @@ -0,0 +1,5 @@ +--- +"posthog-php": patch +--- + +Fix release validation and publishing safeguards diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 1d8d83e..8efefbd 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -48,7 +48,7 @@ jobs: - name: Validate composer files if: needs.detect-markdown-only.outputs.markdown_only != 'true' - run: composer validate --no-check-lock --no-check-version --strict + run: composer validate --no-check-version --strict public-api: needs: detect-markdown-only diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 665c5cd..2a19038 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -82,6 +82,12 @@ jobs: cache: true install: false + - name: Set up PHP 8.4 + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2 + with: + php-version: 8.4 + tools: composer + - name: Apply change intents and update version id: candidate env: @@ -104,6 +110,7 @@ jobs: fi ./scripts/bump-version.sh "$new_version" + composer update --lock --no-install --no-interaction --no-audit if [ -z "$(git status --porcelain)" ]; then echo "No release candidate changes were generated" >&2 @@ -113,7 +120,7 @@ jobs: changed_files=$(git diff --name-only) while IFS= read -r file; do case "$file" in - CHANGELOG.md|composer.json|package.json|lib/PostHog.php|.changeset/*) ;; + CHANGELOG.md|composer.json|composer.lock|package.json|lib/PostHog.php|.changeset/*) ;; *) echo "Unexpected release candidate change: $file" >&2 exit 1 @@ -244,7 +251,7 @@ jobs: tools: composer - name: Validate composer files - run: composer validate --no-check-lock --no-check-version --strict + run: composer validate --no-check-version --strict - name: Send failure event to PostHog if: ${{ failure() }} @@ -277,6 +284,9 @@ jobs: with: slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }} slack_user_group_id: ${{ vars.GROUP_CLIENT_LIBRARIES_SLACK_GROUP_ID }} + checkout_repository: false + tag_pattern: "[0-9]*" + tag_sort: version secrets: slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }} posthog_project_api_key: ${{ secrets.POSTHOG_PROJECT_API_KEY }} @@ -353,6 +363,7 @@ jobs: with: client-id: ${{ secrets.GH_APP_POSTHOG_PHP_RELEASER_APP_ID }} private-key: ${{ secrets.GH_APP_POSTHOG_PHP_RELEASER_PRIVATE_KEY }} + permission-contents: write - name: Commit version bump id: commit-version-bump @@ -361,12 +372,20 @@ jobs: commit_message: "chore: release ${{ needs.prepare-release-candidate.outputs.new-version }} [version bump] [skip ci]" repo: ${{ github.repository }} branch: main - file_pattern: "CHANGELOG.md composer.json package.json lib/PostHog.php .changeset" + file_pattern: "CHANGELOG.md composer.json composer.lock package.json lib/PostHog.php .changeset" env: GITHUB_TOKEN: ${{ steps.releaser.outputs.token }} + - name: Require release commit + env: + COMMIT_SHA: ${{ steps.commit-version-bump.outputs.commit-hash }} + run: | + if [ -z "$COMMIT_SHA" ]; then + echo "Release commit was not created" >&2 + exit 1 + fi + - name: Create GitHub release - if: steps.commit-version-bump.outputs.commit-hash != '' env: GH_TOKEN: ${{ steps.releaser.outputs.token }} NEW_VERSION: ${{ needs.prepare-release-candidate.outputs.new-version }} diff --git a/RELEASING.md b/RELEASING.md index d858188..a75ee28 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -21,7 +21,7 @@ After review, merge the PR to `main`. No GitHub release label is required. A push to `main` that includes `.changeset/*.md` changes automatically starts the release workflow. The workflow then: 1. Checks for pending change intents -2. Uses `pnpm version -r` to determine and apply the version bump, consume the intents, and update `CHANGELOG.md` and `.changeset/ledger.yaml` +2. Uses `pnpm version -r` to determine and apply the version bump, consume the intents, update `CHANGELOG.md` and `.changeset/ledger.yaml`, and refresh `composer.lock` 3. Prepares a release candidate patch for the triggering commit in a read-only job without release secrets, after verifying the release bump script hash 4. Verifies the release candidate in a separate read-only job and fails if the tag or GitHub Release already exists 5. Notifies the client libraries team in Slack for approval only after candidate preparation and verification both succeed diff --git a/composer.lock b/composer.lock index e4ade16..b77d872 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c11900659348ffada66c82406a3d8c6c", + "content-hash": "4ad7d75a06d730f2933ec1254892145e", "packages": [ { "name": "psr/clock", From e4c9bfc3a1bde9b5bab0506f3488d803b6ec81da Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Thu, 23 Jul 2026 14:17:39 +0700 Subject: [PATCH 2/2] chore: defer release change intent --- .changeset/calm-wolves-release.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .changeset/calm-wolves-release.md diff --git a/.changeset/calm-wolves-release.md b/.changeset/calm-wolves-release.md deleted file mode 100644 index a3a0bfc..0000000 --- a/.changeset/calm-wolves-release.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"posthog-php": patch ---- - -Fix release validation and publishing safeguards