From 61dcce4d75a9550b40afae52f458753438fe9271 Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Mon, 30 Jun 2025 10:58:41 -0700 Subject: [PATCH 1/9] update to central portal --- .github/workflows/publish-maven.yml | 100 ++++++++++++++++++++++++++++ .github/workflows/release.yml | 6 +- CLAUDE.md | 24 +++++++ gradle.properties | 4 +- maven.gradle | 8 +++ release.sh | 4 +- 6 files changed, 141 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/publish-maven.yml diff --git a/.github/workflows/publish-maven.yml b/.github/workflows/publish-maven.yml new file mode 100644 index 000000000..8f750cad0 --- /dev/null +++ b/.github/workflows/publish-maven.yml @@ -0,0 +1,100 @@ +name: Publish to Maven Central + +on: + workflow_dispatch: + inputs: + publishing_type: + description: 'Publishing type for the deployment' + required: true + default: 'user_managed' + type: choice + options: + - user_managed + - automatic + - portal_api + version_override: + description: 'Version to publish (leave empty to use gradle.properties VERSION_NAME)' + required: false + type: string + +jobs: + publish: + name: Publish to Maven Central Portal + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + + - name: Configure signing + env: + SIGNING_KEY: ${{ secrets.SIGNING_KEY }} + SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} + run: | + echo "signing.keyId=${{ secrets.SIGNING_KEY_ID }}" >> ~/.gradle/gradle.properties + echo "signing.password=$SIGNING_PASSWORD" >> ~/.gradle/gradle.properties + echo "signing.secretKeyRingFile=$HOME/.gnupg/secring.gpg" >> ~/.gradle/gradle.properties + echo "$SIGNING_KEY" | base64 --decode > ~/.gnupg/secring.gpg + + - name: Configure Portal credentials + env: + CENTRAL_TOKEN: ${{ secrets.CENTRAL_PORTAL_TOKEN }} + CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PORTAL_PASSWORD }} + run: | + echo "centralPortalToken=$CENTRAL_TOKEN" >> ~/.gradle/gradle.properties + echo "centralPortalPassword=$CENTRAL_PASSWORD" >> ~/.gradle/gradle.properties + + - name: Override version if specified + if: inputs.version_override != '' + run: | + sed -i "s/VERSION_NAME=.*/VERSION_NAME=${{ inputs.version_override }}/" gradle.properties + echo "Updated version to: ${{ inputs.version_override }}" + + - name: Build artifacts + run: | + ./gradlew clean build + ./gradlew androidJavadocsJar androidSourcesJar + + - name: Publish to Maven Central Portal + run: ./gradlew publishRelease + + - name: Upload to Portal with publishing type + if: inputs.publishing_type != 'user_managed' + env: + CENTRAL_TOKEN: ${{ secrets.CENTRAL_PORTAL_TOKEN }} + CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PORTAL_PASSWORD }} + run: | + # Get the namespace from gradle.properties + NAMESPACE=$(grep "^GROUP=" gradle.properties | cut -d'=' -f2) + + # Create basic auth header + AUTH_HEADER=$(echo -n "$CENTRAL_TOKEN:$CENTRAL_PASSWORD" | base64) + + # Call the manual upload endpoint + curl -X POST \ + -H "Authorization: Bearer $AUTH_HEADER" \ + "https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/${NAMESPACE}?publishing_type=${{ inputs.publishing_type }}" + + - name: Summary + run: | + echo "## Publishing Summary" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- **Publishing Type**: ${{ inputs.publishing_type }}" >> $GITHUB_STEP_SUMMARY + if [ "${{ inputs.publishing_type }}" == "user_managed" ]; then + echo "- **Next Steps**: Go to https://central.sonatype.com/publishing/deployments to manually release" >> $GITHUB_STEP_SUMMARY + elif [ "${{ inputs.publishing_type }}" == "automatic" ]; then + echo "- **Status**: Deployment will be automatically released if validation passes" >> $GITHUB_STEP_SUMMARY + else + echo "- **Status**: Deployment uploaded, use Portal API to check status" >> $GITHUB_STEP_SUMMARY + fi \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4113652d7..695415566 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -69,4 +69,8 @@ jobs: with: tag_name: ${{ github.ref }} release_name: Release ${{ github.ref }} - body: ${{ steps.generate-release-changelog.outputs.changelog }} + body: | + ${{ steps.generate-release-changelog.outputs.changelog }} + + --- + **Note**: After this GitHub release is created, the Maven Central deployment must be manually released at https://central.sonatype.com/publishing/deployments diff --git a/CLAUDE.md b/CLAUDE.md index 5e0e507c4..40763e0b0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -84,6 +84,30 @@ The project uses semantic versioning (X.Y.Z) and publishes to Maven Central: - Release script: `./release.sh [version]` - Published as: `com.mixpanel.android:mixpanel-android:X.Y.Z` +### Maven Central Portal Setup + +The SDK now publishes via the new Maven Central Portal (replacing OSSRH): + +1. **Generate Portal Tokens**: + - Log in to https://central.sonatype.com with your OSSRH credentials + - Navigate to your account settings + - Generate a user token (username and password pair) + - Store these securely in `~/.gradle/gradle.properties`: + ``` + centralPortalToken= + centralPortalPassword= + ``` + +2. **Publishing Process**: + - The release script uses the OSSRH Staging API for compatibility + - After running `./release.sh`, deployments appear at https://central.sonatype.com/publishing/deployments + - Manual release to Maven Central is required from the Portal UI + +3. **GitHub Actions**: + - Portal tokens should be stored as repository secrets: + - `CENTRAL_PORTAL_TOKEN` (the token username) + - `CENTRAL_PORTAL_PASSWORD` (the token password) + ## Project Configuration - Min SDK: 21 diff --git a/gradle.properties b/gradle.properties index 8de6f6913..f4566d735 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,8 +15,8 @@ POM_DEVELOPER_ID=mixpanel_dev POM_DEVELOPER_NAME=Mixpanel Developers POM_DEVELOPER_EMAIL=dev+android@mixpanel.com -RELEASE_REPOSITORY_URL=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -SNAPSHOT_REPOSITORY_URL=https://oss.sonatype.org/content/repositories/snapshots/ +RELEASE_REPOSITORY_URL=https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/ +SNAPSHOT_REPOSITORY_URL=https://central.sonatype.com/repository/maven-snapshots/ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true diff --git a/maven.gradle b/maven.gradle index c852bd7b9..dc450d6fe 100644 --- a/maven.gradle +++ b/maven.gradle @@ -201,9 +201,17 @@ tasks.named('signReleasePublication') { } def getRepositoryUsername() { + // Support both old OSSRH credentials and new Portal tokens + if (hasProperty('centralPortalToken')) { + return centralPortalToken + } return hasProperty('sonatypeUsername') ? sonatypeUsername : "" } def getRepositoryPassword() { + // Support both old OSSRH credentials and new Portal tokens + if (hasProperty('centralPortalPassword')) { + return centralPortalPassword + } return hasProperty('sonatypePassword') ? sonatypePassword : "" } diff --git a/release.sh b/release.sh index ee1c5c3a7..ad637484c 100755 --- a/release.sh +++ b/release.sh @@ -137,7 +137,7 @@ fi printf "\n\n${YELLOW}Pushing changes...${NC}\n" git commit -am "New release: $releaseVersion" # push changes -git push origin $releaseBranchx +git push origin $releaseBranch # create new tag newTag=v$releaseVersion @@ -178,6 +178,6 @@ cleanUp printf "\n${GREEN}All done! ¯\_(ツ)_/¯ \n" printf "Make sure you make a new release at https://github.com/mixpanel/mixpanel-android/releases/new\n" printf "Also, do not forget to update our CHANGELOG (https://github.com/mixpanel/mixpanel-android/wiki/Changelog)\n" -printf "And finally, release the library from https://oss.sonatype.org/index.html\n\n${NC}" +printf "And finally, release the library from https://central.sonatype.com/publishing/deployments\n\n${NC}" quit From a34a6d11a2997583d6ef6f81bec0ef33a13f915f Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Mon, 30 Jun 2025 15:57:41 -0700 Subject: [PATCH 2/9] review tweaks --- .github/workflows/publish-maven.yml | 3 ++- CLAUDE.md | 5 +++++ release.sh | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-maven.yml b/.github/workflows/publish-maven.yml index 8f750cad0..d8cabf133 100644 --- a/.github/workflows/publish-maven.yml +++ b/.github/workflows/publish-maven.yml @@ -45,6 +45,7 @@ jobs: echo "signing.keyId=${{ secrets.SIGNING_KEY_ID }}" >> ~/.gradle/gradle.properties echo "signing.password=$SIGNING_PASSWORD" >> ~/.gradle/gradle.properties echo "signing.secretKeyRingFile=$HOME/.gnupg/secring.gpg" >> ~/.gradle/gradle.properties + mkdir -p ~/.gnupg echo "$SIGNING_KEY" | base64 --decode > ~/.gnupg/secring.gpg - name: Configure Portal credentials @@ -83,7 +84,7 @@ jobs: # Call the manual upload endpoint curl -X POST \ - -H "Authorization: Bearer $AUTH_HEADER" \ + -H "Authorization: Basic $AUTH_HEADER" \ "https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/${NAMESPACE}?publishing_type=${{ inputs.publishing_type }}" - name: Summary diff --git a/CLAUDE.md b/CLAUDE.md index 40763e0b0..3e02817c1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -97,6 +97,11 @@ The SDK now publishes via the new Maven Central Portal (replacing OSSRH): centralPortalToken= centralPortalPassword= ``` + - **Security Note**: For enhanced security, consider using encrypted storage options instead of plain text: + - Environment variables: `export CENTRAL_PORTAL_TOKEN=...` + - gradle-credentials-plugin for encrypted storage + - System keychain integration (e.g., macOS Keychain, Windows Credential Store) + - CI/CD secret management systems 2. **Publishing Process**: - The release script uses the OSSRH Staging API for compatibility diff --git a/release.sh b/release.sh index ad637484c..8f2b91ca2 100755 --- a/release.sh +++ b/release.sh @@ -164,7 +164,7 @@ printf '\n\n\n' read -r -p "Does this look right to you and the github action 'Release' has finished? [y/n]: " key if [[ "$key" =~ ^([yY][eE][sS]|[yY])+$ ]]; then git pull - git commit -am "Update master with next snasphot version $nextSnapshotVersion" + git commit -am "Update master with next snapshot version $nextSnapshotVersion" git push origin master else printf "${ORANGE}Make sure to update gradle.properties manually.${NC}\n" From 0d4352672fd9c19b3e80b1f729432a137a911297 Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Tue, 1 Jul 2025 16:42:58 -0700 Subject: [PATCH 3/9] ossrh staging api working checkpoint --- gradle.properties | 2 +- maven.gradle | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/gradle.properties b/gradle.properties index f4566d735..f367910fe 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -VERSION_NAME=8.2.0 +VERSION_NAME=8.2.1 POM_PACKAGING=aar GROUP=com.mixpanel.android diff --git a/maven.gradle b/maven.gradle index dc450d6fe..5035c83d0 100644 --- a/maven.gradle +++ b/maven.gradle @@ -123,14 +123,9 @@ publishing { repositories { maven { - url = uri(RELEASE_REPOSITORY_URL) - credentials { - username = getRepositoryUsername() - password = getRepositoryPassword() - } - } - maven { - url = uri(SNAPSHOT_REPOSITORY_URL) + def releasesRepoUrl = uri(RELEASE_REPOSITORY_URL) + def snapshotsRepoUrl = uri(SNAPSHOT_REPOSITORY_URL) + url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl credentials { username = getRepositoryUsername() password = getRepositoryPassword() @@ -140,6 +135,7 @@ publishing { } signing { + required { !version.endsWith("SNAPSHOT") && gradle.taskGraph.hasTask("publishReleasePublicationToMavenRepository") } sign publishing.publications.release } From 738309c4b2c43d36ecd728002d2b9ac81ed161f2 Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Tue, 1 Jul 2025 17:17:38 -0700 Subject: [PATCH 4/9] update release.sh script --- release.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) mode change 100755 => 100644 release.sh diff --git a/release.sh b/release.sh old mode 100755 new mode 100644 index 8f2b91ca2..e03ff5d87 --- a/release.sh +++ b/release.sh @@ -128,6 +128,39 @@ if ! ./gradlew publishRelease ; then abort fi +# Upload to Maven Central Portal +printf "\n${YELLOW}Uploading to Maven Central Portal...${NC}\n" + +# Check for Portal credentials +if [ -z "$CENTRAL_PORTAL_TOKEN" ] || [ -z "$CENTRAL_PORTAL_PASSWORD" ]; then + printf "${RED}Error: CENTRAL_PORTAL_TOKEN and CENTRAL_PORTAL_PASSWORD environment variables must be set${NC}\n" + printf "${ORANGE}Please set these variables and run the manual upload command:\n" + printf "curl -X POST -H \"Authorization: Bearer \$(echo -n \"TOKEN:PASSWORD\" | base64)\" \\\n" + printf " \"https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/com.mixpanel.android?publishing_type=user_managed\"${NC}\n\n" + abort +fi + +# Create auth token +AUTH_TOKEN=$(echo -n "$CENTRAL_PORTAL_TOKEN:$CENTRAL_PORTAL_PASSWORD" | base64) + +# Upload to Portal +RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \ + -H "Authorization: Bearer $AUTH_TOKEN" \ + "https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/com.mixpanel.android?publishing_type=user_managed") + +HTTP_CODE=$(echo "$RESPONSE" | tail -n 1) +BODY=$(echo "$RESPONSE" | sed '$d') + +if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "201" ] && [ "$HTTP_CODE" != "204" ]; then + printf "${RED}Error: Portal upload failed with HTTP $HTTP_CODE${NC}\n" + printf "${ORANGE}Response: $BODY${NC}\n" + printf "\n${ORANGE}The artifacts were published to staging, but not uploaded to the Portal.\n" + printf "You can manually upload using the command above.${NC}\n\n" + abort +fi + +printf "${GREEN}Success! Deployment uploaded to Portal.${NC}\n" + read -r -p "Continue pushing to github? [y/n]: " key if ! [[ "$key" =~ ^([yY][eE][sS]|[yY])+$ ]]; then abort From ed9ff7ee63da622c94bbf1f5adfdc146cbce517d Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Tue, 1 Jul 2025 17:25:55 -0700 Subject: [PATCH 5/9] update github workflow --- .github/workflows/publish-maven.yml | 48 +++++++++++++++++++++-------- CLAUDE.md | 7 ++--- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/.github/workflows/publish-maven.yml b/.github/workflows/publish-maven.yml index d8cabf133..642642774 100644 --- a/.github/workflows/publish-maven.yml +++ b/.github/workflows/publish-maven.yml @@ -11,7 +11,6 @@ on: options: - user_managed - automatic - - portal_api version_override: description: 'Version to publish (leave empty to use gradle.properties VERSION_NAME)' required: false @@ -70,8 +69,7 @@ jobs: - name: Publish to Maven Central Portal run: ./gradlew publishRelease - - name: Upload to Portal with publishing type - if: inputs.publishing_type != 'user_managed' + - name: Upload to Maven Central Portal env: CENTRAL_TOKEN: ${{ secrets.CENTRAL_PORTAL_TOKEN }} CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PORTAL_PASSWORD }} @@ -79,23 +77,49 @@ jobs: # Get the namespace from gradle.properties NAMESPACE=$(grep "^GROUP=" gradle.properties | cut -d'=' -f2) - # Create basic auth header - AUTH_HEADER=$(echo -n "$CENTRAL_TOKEN:$CENTRAL_PASSWORD" | base64) + # Create Bearer auth token (as per docs) + AUTH_TOKEN=$(echo -n "$CENTRAL_TOKEN:$CENTRAL_PASSWORD" | base64) # Call the manual upload endpoint - curl -X POST \ - -H "Authorization: Basic $AUTH_HEADER" \ - "https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/${NAMESPACE}?publishing_type=${{ inputs.publishing_type }}" + RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \ + -H "Authorization: Bearer $AUTH_TOKEN" \ + "https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/${NAMESPACE}?publishing_type=${{ inputs.publishing_type }}") + + HTTP_CODE=$(echo "$RESPONSE" | tail -n 1) + BODY=$(echo "$RESPONSE" | sed '$d') + + if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "201" ] && [ "$HTTP_CODE" != "204" ]; then + echo "Error: Portal upload failed with HTTP $HTTP_CODE" + echo "Response: $BODY" + exit 1 + fi + + echo "Success! Deployment uploaded to Portal." - name: Summary run: | + VERSION=$(grep "^VERSION_NAME=" gradle.properties | cut -d'=' -f2) echo "## Publishing Summary" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY + echo "- **Version**: $VERSION" >> $GITHUB_STEP_SUMMARY echo "- **Publishing Type**: ${{ inputs.publishing_type }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY if [ "${{ inputs.publishing_type }}" == "user_managed" ]; then - echo "- **Next Steps**: Go to https://central.sonatype.com/publishing/deployments to manually release" >> $GITHUB_STEP_SUMMARY - elif [ "${{ inputs.publishing_type }}" == "automatic" ]; then - echo "- **Status**: Deployment will be automatically released if validation passes" >> $GITHUB_STEP_SUMMARY + echo "### Next Steps" >> $GITHUB_STEP_SUMMARY + echo "1. Go to [Maven Central Portal Deployments](https://central.sonatype.com/publishing/deployments)" >> $GITHUB_STEP_SUMMARY + echo "2. Find your deployment (version $VERSION)" >> $GITHUB_STEP_SUMMARY + echo "3. Review and click 'Publish' to release to Maven Central" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "⏱️ **Timeline**:" >> $GITHUB_STEP_SUMMARY + echo "- Validation: 15-30 minutes" >> $GITHUB_STEP_SUMMARY + echo "- Portal search: 1-2 hours" >> $GITHUB_STEP_SUMMARY + echo "- Maven Central sync: 2-4 hours" >> $GITHUB_STEP_SUMMARY else - echo "- **Status**: Deployment uploaded, use Portal API to check status" >> $GITHUB_STEP_SUMMARY + echo "### Status" >> $GITHUB_STEP_SUMMARY + echo "✅ Deployment will be automatically released if validation passes" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "⏱️ **Timeline**:" >> $GITHUB_STEP_SUMMARY + echo "- Validation and release: 15-30 minutes" >> $GITHUB_STEP_SUMMARY + echo "- Portal search: 1-2 hours" >> $GITHUB_STEP_SUMMARY + echo "- Maven Central sync: 2-4 hours" >> $GITHUB_STEP_SUMMARY fi \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index 3e02817c1..a973ce79a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -170,7 +170,6 @@ The SDK now publishes via the new Maven Central Portal (replacing OSSRH): - Prepared statements for performance - Automatic cleanup based on data age -For detailed patterns and examples, see: -- `.claude/context/discovered-patterns.md` -- `.claude/context/architecture/system-design.md` -- `.claude/context/workflows/` \ No newline at end of file +## Memories + +- Ensured CLAUDE.md accurately reflects the most recent changes \ No newline at end of file From 4b84002af63adbd0c9d03ac7e908e548348acc5f Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Tue, 1 Jul 2025 17:30:58 -0700 Subject: [PATCH 6/9] workflow perms --- .github/workflows/publish-maven.yml | 3 +++ CLAUDE.md | 35 +++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-maven.yml b/.github/workflows/publish-maven.yml index 642642774..832d512e8 100644 --- a/.github/workflows/publish-maven.yml +++ b/.github/workflows/publish-maven.yml @@ -16,6 +16,9 @@ on: required: false type: string +permissions: + contents: read + jobs: publish: name: Publish to Maven Central Portal diff --git a/CLAUDE.md b/CLAUDE.md index a973ce79a..ec584360b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -84,9 +84,23 @@ The project uses semantic versioning (X.Y.Z) and publishes to Maven Central: - Release script: `./release.sh [version]` - Published as: `com.mixpanel.android:mixpanel-android:X.Y.Z` +### Automated Release Process +The `release.sh` script handles the complete release workflow: +1. Updates version in gradle.properties and README.md +2. Builds and publishes artifacts to OSSRH staging +3. Automatically uploads to Maven Central Portal (requires env vars) +4. Creates git tag and updates documentation +5. Updates to next snapshot version + +**Required Environment Variables**: +```bash +export CENTRAL_PORTAL_TOKEN= +export CENTRAL_PORTAL_PASSWORD= +``` + ### Maven Central Portal Setup -The SDK now publishes via the new Maven Central Portal (replacing OSSRH): +The SDK publishes via the new Maven Central Portal: 1. **Generate Portal Tokens**: - Log in to https://central.sonatype.com with your OSSRH credentials @@ -104,14 +118,27 @@ The SDK now publishes via the new Maven Central Portal (replacing OSSRH): - CI/CD secret management systems 2. **Publishing Process**: - - The release script uses the OSSRH Staging API for compatibility - - After running `./release.sh`, deployments appear at https://central.sonatype.com/publishing/deployments - - Manual release to Maven Central is required from the Portal UI + - Artifacts are uploaded to OSSRH staging API: `https://ossrh-staging-api.central.sonatype.com/` + - The Portal upload is triggered via the manual API endpoint + - Deployments appear at https://central.sonatype.com/publishing/deployments + - Manual release to Maven Central is required from the Portal UI (unless using automatic publishing) 3. **GitHub Actions**: + - Use the `publish-maven.yml` workflow for automated publishing - Portal tokens should be stored as repository secrets: - `CENTRAL_PORTAL_TOKEN` (the token username) - `CENTRAL_PORTAL_PASSWORD` (the token password) + - Publishing types available: + - `user_managed`: Manual release from Portal UI (default) + - `automatic`: Auto-release if validation passes + +4. **Manual Portal Upload** (if automation fails): + ```bash + AUTH_TOKEN=$(echo -n "username:password" | base64) + curl -X POST \ + -H "Authorization: Bearer $AUTH_TOKEN" \ + "https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/com.mixpanel.android?publishing_type=user_managed" + ``` ## Project Configuration From 6121c69ce54871d8d8f5f41e96ea607b13630c5b Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Tue, 1 Jul 2025 17:37:14 -0700 Subject: [PATCH 7/9] workflow secrets update --- .github/workflows/publish-maven.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish-maven.yml b/.github/workflows/publish-maven.yml index 832d512e8..d4712b570 100644 --- a/.github/workflows/publish-maven.yml +++ b/.github/workflows/publish-maven.yml @@ -52,11 +52,11 @@ jobs: - name: Configure Portal credentials env: - CENTRAL_TOKEN: ${{ secrets.CENTRAL_PORTAL_TOKEN }} - CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PORTAL_PASSWORD }} + CENTRAL_PORTAL_TOKEN: ${{ secrets.CENTRAL_PORTAL_TOKEN }} + CENTRAL_PORTAL_PASSWORD: ${{ secrets.CENTRAL_PORTAL_PASSWORD }} run: | - echo "centralPortalToken=$CENTRAL_TOKEN" >> ~/.gradle/gradle.properties - echo "centralPortalPassword=$CENTRAL_PASSWORD" >> ~/.gradle/gradle.properties + echo "centralPortalToken=$CENTRAL_PORTAL_TOKEN" >> ~/.gradle/gradle.properties + echo "centralPortalPassword=$CENTRAL_PORTAL_PASSWORD" >> ~/.gradle/gradle.properties - name: Override version if specified if: inputs.version_override != '' @@ -74,14 +74,14 @@ jobs: - name: Upload to Maven Central Portal env: - CENTRAL_TOKEN: ${{ secrets.CENTRAL_PORTAL_TOKEN }} - CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PORTAL_PASSWORD }} + CENTRAL_PORTAL_TOKEN: ${{ secrets.CENTRAL_PORTAL_TOKEN }} + CENTRAL_PORTAL_PASSWORD: ${{ secrets.CENTRAL_PORTAL_PASSWORD }} run: | # Get the namespace from gradle.properties NAMESPACE=$(grep "^GROUP=" gradle.properties | cut -d'=' -f2) # Create Bearer auth token (as per docs) - AUTH_TOKEN=$(echo -n "$CENTRAL_TOKEN:$CENTRAL_PASSWORD" | base64) + AUTH_TOKEN=$(echo -n "$CENTRAL_PORTAL_TOKEN:$CENTRAL_PORTAL_PASSWORD" | base64) # Call the manual upload endpoint RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \ From 3092da82d45cd384095dc69f139e12030988a675 Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Wed, 2 Jul 2025 12:51:02 -0700 Subject: [PATCH 8/9] put -SNAPSHOT back into gradle.properties --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index f367910fe..7a96dbe29 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -VERSION_NAME=8.2.1 +VERSION_NAME=8.2.1-SNAPSHOT POM_PACKAGING=aar GROUP=com.mixpanel.android From 87b3fee3971e5d0367faff9cad1399cde47967e1 Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Wed, 2 Jul 2025 12:59:12 -0700 Subject: [PATCH 9/9] put -SNAPSHOT back into gradle.properties --- release.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/release.sh b/release.sh index e03ff5d87..55e8f11ae 100644 --- a/release.sh +++ b/release.sh @@ -188,6 +188,10 @@ git add . git commit -m "Update documentation for $releaseVersion" git push origin gh-pages +printf "\n${YELLOW}Checking out $releaseBranch to update snapshot version...${NC}\n" +git checkout $releaseBranch +git pull origin $releaseBranch + # update next snapshot version printf "\n${YELLOW}Updating next snapshot version...${NC}\n" sed -i.bak 's,^\(VERSION_NAME=\).*,\1'$nextSnapshotVersion',' gradle.properties