Skip to content

feat(surveys): add posthog-android-surveys-compose default UI module … #231

feat(surveys): add posthog-android-surveys-compose default UI module …

feat(surveys): add posthog-android-surveys-compose default UI module … #231

Workflow file for this run

name: 'Release'
permissions:
contents: read
on:
push:
branches: [main]
paths:
- '.changeset/*.md'
workflow_dispatch:
# Concurrency control: only one release process can run at a time
# This prevents race conditions if multiple releasable changesets merge simultaneously
concurrency:
group: release
cancel-in-progress: false
jobs:
check-changesets:
name: Check for changesets
runs-on: ubuntu-latest
outputs:
has-changesets: ${{ steps.check.outputs.has-changesets }}
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
ref: main
fetch-depth: 0
- name: Check for changesets
id: check
run: |
if [ ! -d ".changeset" ] || [ -z "$(ls -A .changeset/*.md 2>/dev/null | grep -v README.md)" ]; then
echo "❌ No changesets found. Cannot proceed with release."
echo "Please ensure your PR includes a changeset file."
echo "has-changesets=false" >> "$GITHUB_OUTPUT"
else
echo "✓ Found changesets to process"
echo "has-changesets=true" >> "$GITHUB_OUTPUT"
fi
notify-approval-needed:
name: Notify Slack - Approval Needed
needs: check-changesets
if: needs.check-changesets.outputs.has-changesets == 'true'
uses: PostHog/.github/.github/workflows/notify-approval-needed.yml@5fc4680761e8ac29a61b212756230eba0e276d8c
with:
slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }}
slack_user_group_id: ${{ vars.GROUP_CLIENT_LIBRARIES_SLACK_GROUP_ID }}
secrets:
slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }}
posthog_project_api_key: ${{ secrets.POSTHOG_PROJECT_API_KEY }}
version-bump:
name: Bump versions and commit to main
needs: [check-changesets, notify-approval-needed]
runs-on: ubuntu-latest
if: always() && needs.check-changesets.outputs.has-changesets == 'true'
environment: 'Release'
permissions:
contents: write
outputs:
committed: ${{ steps.commit-version-bump.outputs.commit-hash != '' }}
steps:
- name: Notify Slack - Approved
continue-on-error: true
uses: PostHog/.github/.github/actions/slack-thread-reply@5fc4680761e8ac29a61b212756230eba0e276d8c
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: '✅ Release approved! Version bump in progress...'
emoji_reaction: 'white_check_mark'
- name: Get GitHub App token
id: releaser
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ secrets.GH_APP_POSTHOG_ANDROID_RELEASER_APP_ID }}
private-key: ${{ secrets.GH_APP_POSTHOG_ANDROID_RELEASER_PRIVATE_KEY }}
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
ref: main
fetch-depth: 0
token: ${{ steps.releaser.outputs.token }}
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Setup environment
uses: ./.github/actions/setup
- name: Update versions and changelogs
run: pnpm changeset version
- name: Sync versions to gradle.properties
run: |
# Sync package.json versions back to gradle.properties
CORE_VERSION=$(node -p "require('./posthog/package.json').version")
ANDROID_VERSION=$(node -p "require('./posthog-android/package.json').version")
SURVEYS_COMPOSE_VERSION=$(node -p "require('./posthog-android-surveys-compose/package.json').version")
SERVER_VERSION=$(node -p "require('./posthog-server/package.json').version")
PLUGIN_VERSION=$(node -p "require('./posthog-android-gradle-plugin/package.json').version")
sed -i "s/^coreVersion=.*/coreVersion=$CORE_VERSION/" gradle.properties
sed -i "s/^androidVersion=.*/androidVersion=$ANDROID_VERSION/" gradle.properties
sed -i "s/^surveysComposeVersion=.*/surveysComposeVersion=$SURVEYS_COMPOSE_VERSION/" gradle.properties
sed -i "s/^serverVersion=.*/serverVersion=$SERVER_VERSION/" gradle.properties
sed -i "s/^androidPluginVersion=.*/androidPluginVersion=$PLUGIN_VERSION/" posthog-android-gradle-plugin/gradle.properties
- name: Check for version bump changes
id: check-changes
run: |
if [ -z "$(git status --porcelain)" ]; then
echo "No changes to commit"
echo "committed=false" >> "$GITHUB_OUTPUT"
else
echo "committed=true" >> "$GITHUB_OUTPUT"
fi
- name: Commit version bump
id: commit-version-bump
if: steps.check-changes.outputs.committed == 'true'
uses: planetscale/ghcommit-action@25309d8005ac7c3bcd61d3fe19b69e0fe47dbdde # v0.2.20
with:
commit_message: "chore: update versions and changelogs [version bump] [skip ci]"
repo: ${{ github.repository }}
branch: main
env:
GITHUB_TOKEN: ${{ steps.releaser.outputs.token }}
- name: Notify Slack - Failed
continue-on-error: true
if: ${{ failure() && needs.notify-approval-needed.outputs.slack_ts != '' }}
uses: PostHog/.github/.github/actions/slack-thread-reply@5fc4680761e8ac29a61b212756230eba0e276d8c
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 bump versions for `posthog-android`! <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|View logs>'
emoji_reaction: 'x'
notify-rejected:
name: Notify Slack - Rejected
needs: [version-bump, notify-approval-needed]
runs-on: ubuntu-latest
if: always() && needs.version-bump.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<<EOF'
echo "🚫 Release was rejected: $COMMENT"
echo 'EOF'
} >> "$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@5fc4680761e8ac29a61b212756230eba0e276d8c
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'
publish:
name: Publish packages
needs: [version-bump, notify-approval-needed]
runs-on: ubuntu-latest
if: always() && needs.version-bump.outputs.committed == 'true'
permissions:
contents: write
actions: write
env:
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
strategy:
# If any package fails to publish, stop immediately — don't publish dependents against a broken/missing dependency
fail-fast: true
# Order matters: posthog (core) must be released before posthog-android and posthog-server
# since they are transitive dependencies. We use max-parallel: 1 to enforce sequential execution.
max-parallel: 1
matrix:
package:
- name: posthog
tag_prefix: core
make_dry_target: dryReleaseCore
make_release_target: releaseCore
changelog: posthog/CHANGELOG.md
- name: posthog-android
tag_prefix: android
make_dry_target: dryReleaseAndroid
make_release_target: releaseAndroid
changelog: posthog-android/CHANGELOG.md
- name: posthog-android-surveys-compose
tag_prefix: surveysCompose
make_dry_target: dryReleaseSurveysCompose
make_release_target: releaseSurveysCompose
changelog: posthog-android-surveys-compose/CHANGELOG.md
- name: posthog-server
tag_prefix: server
make_dry_target: dryReleaseServer
make_release_target: releaseServer
changelog: posthog-server/CHANGELOG.md
- name: posthog-android-gradle-plugin
tag_prefix: androidPlugin
make_dry_target: dryReleaseAndroidPlugin
make_release_target: releaseAndroidPlugin
changelog: posthog-android-gradle-plugin/CHANGELOG.md
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
ref: main
fetch-depth: 0
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: 'Set up Java 17'
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
java-version: '17'
distribution: 'temurin'
- name: Setup environment
uses: ./.github/actions/setup
with:
install: false
- name: Detect version change for ${{ matrix.package.name }}
id: detect-version
run: |
# Get the current version from the package's package.json (source of truth for changesets)
CURRENT_VERSION=$(node -p "require('./${{ matrix.package.name }}/package.json').version")
if [ -z "$CURRENT_VERSION" ]; then
echo "Could not determine current version for ${{ matrix.package.name }}"
echo "has-new-version=false" >> "$GITHUB_OUTPUT"
exit 0
fi
TAG="${{ matrix.package.tag_prefix }}-v${CURRENT_VERSION}"
# Check if this tag already exists
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "Tag $TAG already exists - no new version to release"
echo "has-new-version=false" >> "$GITHUB_OUTPUT"
else
echo "Tag $TAG does not exist - new version detected: $CURRENT_VERSION"
echo "has-new-version=true" >> "$GITHUB_OUTPUT"
echo "version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
fi
- name: Dry release ${{ matrix.package.name }}
if: steps.detect-version.outputs.has-new-version == 'true'
run: make ${{ matrix.package.make_dry_target }}
- name: Release ${{ matrix.package.name }}
if: steps.detect-version.outputs.has-new-version == 'true'
run: make ${{ matrix.package.make_release_target }}
- name: Tag and push ${{ matrix.package.name }}
if: steps.detect-version.outputs.has-new-version == 'true'
env:
RELEASE_TAG: ${{ steps.detect-version.outputs.tag }}
RELEASE_VERSION: ${{ steps.detect-version.outputs.version }}
PACKAGE_NAME: ${{ matrix.package.name }}
run: |
git tag -a "$RELEASE_TAG" -m "$PACKAGE_NAME $RELEASE_VERSION"
git push origin "$RELEASE_TAG"
- name: Create GitHub release for ${{ matrix.package.name }}
if: steps.detect-version.outputs.has-new-version == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_TAG: ${{ steps.detect-version.outputs.tag }}
CHANGELOG_FILE: ${{ matrix.package.changelog }}
run: |
# Read the latest changelog entry, skipping "## Next" and the version header line
# e.g. given: ## Next\n\n# 3.32.1 - 2026-02-19\n\n- no user facing changes\n\n## 3.31.0 ...
# it extracts: - no user facing changes
LAST_CHANGELOG_ENTRY=$(awk -v defText="see CHANGELOG.md" '
/^## Next/ { next }
/^#+ [0-9]/ { if (found_version) exit; found_version=1; next }
found_version && /^## / { exit }
found_version { print }
END { if (!found_version) print defText }
' "$CHANGELOG_FILE" | sed '/[^[:space:]]/,$!d' | tac | sed '/[^[:space:]]/,$!d' | tac)
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
/repos/${{ github.repository }}/releases \
-f tag_name="$RELEASE_TAG" \
-f target_commitish='main' \
-f name="$RELEASE_TAG" \
-f body="$LAST_CHANGELOG_ENTRY" \
-F draft=false \
-F prerelease=false \
-F generate_release_notes=false
- name: Send failure event to PostHog
if: ${{ failure() }}
uses: PostHog/posthog-github-action@58dea254b598fb5d469c0699c98af8288a7f7650 # v1.2.0
with:
posthog-token: '${{ secrets.POSTHOG_PROJECT_API_KEY }}'
event: 'posthog-android-github-release-workflow-failure'
properties: >-
{
"commitSha": "${{ github.sha }}",
"jobStatus": "${{ job.status }}",
"ref": "${{ github.ref }}",
"packageName": "${{ matrix.package.name }}",
"packageVersion": "${{ steps.detect-version.outputs.version }}"
}
- name: Notify Slack - Failed
continue-on-error: true
if: ${{ failure() && needs.notify-approval-needed.outputs.slack_ts != '' }}
uses: PostHog/.github/.github/actions/slack-thread-reply@5fc4680761e8ac29a61b212756230eba0e276d8c
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 `${{ matrix.package.name }}@${{ steps.detect-version.outputs.version }}`! <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|View logs>'
emoji_reaction: 'x'
notify-released:
name: Notify Slack - Released
needs: [notify-approval-needed, publish]
runs-on: ubuntu-latest
if: always() && needs.publish.result == 'success' && needs.notify-approval-needed.outputs.slack_ts != ''
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Notify Slack - Released
continue-on-error: true
uses: PostHog/.github/.github/actions/slack-thread-reply@5fc4680761e8ac29a61b212756230eba0e276d8c
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: '🚀 All packages released successfully!'
emoji_reaction: 'rocket'