This document describes how to create a new release of PretenderDB.
Before creating your first release, ensure you have:
- Maven Central Account: Account at https://central.sonatype.com with verified namespace for
io.github.pretenderdb - GPG Key: GPG key for signing artifacts, published to public keyservers
- GitHub Secrets: Five secrets configured in the repository settings
Note: As of 2024, Sonatype uses the Central Portal instead of the old JIRA-based system.
-
Register an Account
- Visit https://central.sonatype.com
- Click "Sign In" in the top right
- Choose authentication method:
- Recommended: Sign in with GitHub (provides automatic namespace verification)
- Alternative: Create username/password account
- Provide a valid email address (required for support and notifications)
-
Verify Namespace for
io.github.pretenderdbFor GitHub Organization namespaces:
- Currently,
io.github.<organization-name>namespaces are not automatically available - You must contact Maven Central Support to request the namespace
- Email Central Support at: https://central.sonatype.org/support
- Provide:
- Desired namespace:
io.github.pretenderdb - GitHub organization: https://github.com/PretenderDB
- Proof of ownership (you are an owner/admin of the PretenderDB organization)
- Desired namespace:
- They may provide a verification key and ask you to create a temporary public repository
Alternative (if using personal account):
- If you sign in with your personal GitHub account,
io.github.<your-username>is auto-verified - However, this won't match the
io.github.pretenderdbnamespace
- Currently,
-
Generate User Token
- Once your namespace is verified, visit https://central.sonatype.com
- Navigate to your Account page
- Click "Generate User Token"
- Save the generated username and password (this is your publishing token, not your login password)
- You'll use these credentials for Gradle/Maven publishing
Important Notes:
- The user token is different from your login credentials
- These tokens are used specifically for publishing via API/build tools
- Keep your token secure - treat it like a password
Generate a GPG key if you don't have one:
# Generate key (choose RSA and RSA, 4096 bits)
gpg --gen-key
# List keys to get the key ID
gpg --list-secret-keys --keyid-format=long
# Output shows: sec rsa4096/ABCD1234EFGH5678 ...
# The key ID is: ABCD1234EFGH5678
# Export private key for GitHub secrets (base64 encoded)
gpg --export-secret-keys YOUR_KEY_ID | base64 -w 0 > private-key.txt
# Publish public key to keyservers (required for Maven Central)
gpg --keyserver keyserver.ubuntu.com --send-keys YOUR_KEY_ID
gpg --keyserver keys.openpgp.org --send-keys YOUR_KEY_ID
# Verify key was published
gpg --keyserver keyserver.ubuntu.com --recv-keys YOUR_KEY_IDNavigate to: https://github.com/PretenderDB/PretenderDB/settings/secrets/actions
Add the following secrets:
| Secret Name | Value | Description |
|---|---|---|
CENTRAL_PORTAL_USERNAME |
User token username | Username from "Generate User Token" (NOT your login username) |
CENTRAL_PORTAL_PASSWORD |
User token password | Password from "Generate User Token" (NOT your login password) |
GPG_PRIVATE_KEY |
Content of private-key.txt | Base64-encoded GPG private key |
GPG_PASSPHRASE |
Your GPG key passphrase | Passphrase for the GPG key |
GPG_KEY_ID |
Last 8 chars of key ID | Short key ID (e.g., EFGH5678) |
Security Notes:
CENTRAL_PORTAL_USERNAMEandCENTRAL_PORTAL_PASSWORDare the user token credentials from https://central.sonatype.com, not your portal login credentials- Store the GPG key passphrase securely
- Delete
private-key.txtafter uploading to GitHub secrets - Never commit credentials to the repository
- Ensure the
mainbranch is clean and all tests pass:
git checkout main
git pull
./gradlew clean build test- Review changes since last release:
# List changes since last tag
git log --oneline v1.0.0..HEAD # Replace v1.0.0 with last tag
# Or if this is the first release
git log --oneline- Update documentation if needed:
- README.md
- CHANGELOG.md (if you maintain one)
- IMPLEMENTATION_SUMMARY.md
- Create a semantic version tag:
# For a regular release
git tag -a v1.0.0 -m "Release version 1.0.0"
# For a pre-release (RC, beta, alpha)
git tag -a v1.0.0-rc.1 -m "Release candidate 1.0.0-rc.1"- Push the tag to GitHub:
git push origin v1.0.0- The GitHub Actions workflow will automatically:
- Validate the tag format (must match
vX.Y.ZorvX.Y.Z-suffix) - Extract the version from the tag
- Build and test all modules
- Sign artifacts with GPG
- Publish to Maven Central via Central Portal
- Automatically release the deployment
- Create a GitHub release with JAR artifacts
- Validate the tag format (must match
-
Watch the GitHub Actions workflow at:
-
The workflow takes approximately 10-15 minutes to complete
-
If successful:
- GitHub release will be created at: https://github.com/PretenderDB/PretenderDB/releases
- Artifacts will be available in Maven Central within 15-120 minutes
- Pre-release flag will be set automatically for tags with suffixes
-
Check GitHub release:
-
Verify Maven Central (wait 15-120 minutes after release):
- https://repo1.maven.org/maven2/io/github/pretenderdb/
- Check that both published modules are present with correct version:
database-utilspretender
-
Test downloading the artifacts:
# Create a test project
mkdir /tmp/test-pretenderdb && cd /tmp/test-pretenderdb
# Create minimal build.gradle.kts
cat > build.gradle.kts << 'EOF'
plugins {
java
}
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.pretenderdb:pretender:1.0.0")
}
EOF
# Try to resolve
gradle dependencies --configuration runtimeClasspath-
Announce the release (optional):
- Social media
- Mailing lists
- Discussion forums
-
Update project status badges if applicable
PretenderDB follows Semantic Versioning:
- Major (X.0.0): Breaking API changes, incompatible changes
- Minor (1.X.0): New features, backward-compatible additions
- Patch (1.0.X): Bug fixes, backward-compatible fixes
- Pre-release (1.0.0-rc.1): Release candidates, alphas, betas
Examples:
v1.0.0- First stable releasev1.1.0- Added new featuresv1.1.1- Bug fixv2.0.0- Breaking changesv1.2.0-rc.1- Release candidate
Both published modules share the same version number.
Note: The pretender-integ module is for integration testing only and is not published to Maven Central.
Symptoms:
- Error message: "gpg: signing failed: No secret key"
- Error message: "gpg: signing failed: Inappropriate ioctl for device"
Solutions:
- Verify
GPG_PRIVATE_KEYsecret is correct (must be base64 encoded) - Verify
GPG_PASSPHRASEis correct - Verify
GPG_KEY_IDmatches the key in the private key - Ensure GPG public key is published to keyservers:
gpg --keyserver keyserver.ubuntu.com --recv-keys YOUR_KEY_ID
Symptoms:
- HTTP 401 Unauthorized
- "Could not authenticate" errors
- Authentication failures during publishing
Solutions:
- Verify
CENTRAL_PORTAL_USERNAMEandCENTRAL_PORTAL_PASSWORDsecrets contain the user token credentials (not your login credentials) - Regenerate user token at https://central.sonatype.com (Account page → Generate User Token)
- Check your namespace
io.github.pretenderdbis verified in Central Portal - Verify account has publishing rights for
io.github.pretenderdbnamespace - Try logging into https://central.sonatype.com to confirm your account is active
Symptoms:
- Error: "Gradle version does not match tag version"
Solutions:
- Ensure tag format is exactly
vX.Y.Z(e.g.,v1.0.0) - Check that
git describe --tags --exact-match HEADworks locally:git tag v1.0.0 git describe --tags --exact-match HEAD # Should output: v1.0.0
Symptoms:
- Build failed during test phase
Solutions:
- Run tests locally before tagging:
./gradlew clean build test - Fix any failing tests
- Delete the tag and re-tag after fixes:
git tag -d v1.0.0 git push --delete origin v1.0.0 # Fix issues, then re-tag git tag -a v1.0.0 -m "Release version 1.0.0" git push origin v1.0.0
Symptoms:
- Deployment fails validation on Central Portal
- Missing POM information or signatures
Solutions:
- Check POM files are generated correctly:
./gradlew generatePomFileForMavenJavaPublication find . -name "pom-default.xml" -exec cat {} \;
- Verify signing is working locally:
./gradlew signMavenJavaPublication find . -name "*.asc"
- Check deployment status at https://central.sonatype.com under "Deployments"
If the automated release fails after artifacts are uploaded:
- Log into https://central.sonatype.com
- Navigate to "Deployments" in the left sidebar
- Find your deployment (check status: Published, Failed, Pending, or Validated)
- Review any validation errors
- If validation passed but not published:
- The nmcp plugin should have auto-published
- Contact Central Support if stuck
- If validation failed:
- Note the errors
- Fix issues locally
- Delete the Git tag:
git push --delete origin v1.0.0 - Re-run the release after fixes
Note: The nmcp Gradle plugin handles the Central Portal publishing API automatically.
Important: You cannot unpublish from Maven Central. Once released, artifacts are permanent.
If you need to fix a released version:
- For critical bugs: Release a patch version (e.g., v1.0.1)
- For breaking issues: Mark the version as problematic in release notes
- For security issues: Release a hotfix immediately (e.g., v1.0.0-hotfix.1 or v1.0.1)
To mark a GitHub release as problematic:
- Edit the release at https://github.com/PretenderDB/PretenderDB/releases
- Check "Set as a pre-release" or add a warning to the description
- Create a new release with fixes
Before creating a production release, test the configuration locally:
# Create a test tag
git tag -a v0.1.0-test -m "Test tag"
# Verify version is extracted
./gradlew properties | grep "^version:"
# Should show: version: 0.1.0-test
# Remove test tag
git tag -d v0.1.0-test# Verify configuration
./gradlew verifyPublishConfig
# Expected output:
# Group: io.github.pretenderdb
# Artifact: pretender (or database-utils, pretender-integ)
# Version: 0.0.1-SNAPSHOT
# Is SNAPSHOT: true
# Repository: snapshots# Build and publish to local Maven repository
./gradlew clean build publishToMavenLocal
# Verify artifacts in ~/.m2/repository
ls -R ~/.m2/repository/io/github/pretenderdb/
# Expected structure:
# ~/.m2/repository/io/github/pretenderdb/
# ├── database-utils/
# ├── pretender/
# └── pretender-integ/# Configure GPG locally in ~/.gradle/gradle.properties:
cat >> ~/.gradle/gradle.properties << EOF
signing.gnupg.keyName=YOUR_KEY_ID
signing.gnupg.passphrase=YOUR_PASSPHRASE
EOF
# Test signing
./gradlew signMavenJavaPublication
# Check for signature files
find . -name "*.asc"For additional safety, you can create a manual dry-run workflow:
- Go to: https://github.com/PretenderDB/PretenderDB/actions
- Run "Release Dry Run" workflow (if implemented)
- Provide a test version like
0.0.1-dryrun - Verify the build completes successfully
This tests the build and artifact generation without publishing.
Use this checklist when creating a release:
- All tests pass locally:
./gradlew clean build test - Documentation is up to date (README, CLAUDE.md, etc.)
- Changes reviewed and ready for release
- Semantic version chosen appropriately
- Tag created with correct format:
vX.Y.Z - Tag pushed to GitHub
- GitHub Actions workflow succeeded
- GitHub release created
- Artifacts available in Maven Central (wait 15-120 minutes)
- Artifacts downloadable and usable
- Release announced (if applicable)
Follow semantic versioning:
- Breaking changes → increment major (2.0.0)
- New features → increment minor (1.1.0)
- Bug fixes → increment patch (1.0.1)
Automatic: SNAPSHOT versions are automatically published when pushing to the main branch. The snapshot.yml workflow handles this.
Manual: You can also publish snapshots manually:
./gradlew publishAggregationToCentralSnapshotsSnapshots are available at:
Users can depend on SNAPSHOT versions by adding the snapshots repository:
repositories {
maven("https://central.sonatype.com/repository/maven-snapshots/")
mavenCentral()
}
dependencies {
implementation("io.github.pretenderdb:pretender:0.0.1-SNAPSHOT")
}Typically 15-30 minutes, but can take up to 2 hours. The CDN and search index update separately.
Delete the tag before the workflow completes:
# Delete local tag
git tag -d v1.0.0
# Delete remote tag
git push --delete origin v1.0.0If the workflow already completed, you cannot unpublish from Maven Central. Create a new patch version instead.
Yes, you could add:
- Automatic version bumping based on commit messages
- Changelog generation
- Release notes templates
- Slack/Discord notifications
However, manual tagging provides more control and prevents accidental releases.
For questions or issues with releases:
- Create an issue: https://github.com/PretenderDB/PretenderDB/issues
- Contact: ned.wolpert@gmail.com