Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,10 @@ subprojects {
// But since the dependsOn is within the conditional, the dependency is not created for release versions
// so the publish in that case is never executed.
if (version.toString().endsWith('SNAPSHOT')) {
dependsOn tasks.publish
exec {
workingDir project.projectDir
commandLine 'bash', "${project.rootDir}/scripts/snapshot_management.sh", project.name, project.version
}
}
doFirst {
if (!version.toString().endsWith('SNAPSHOT')) {
Expand Down
32 changes: 21 additions & 11 deletions scripts/publish_to_maven_central.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,34 @@ echo "Executing in directory = $(pwd)"

zipfile=${subproject}.${version}.zip

pushd build/local-repo
zip -qr ${zipfile} *

bearer_token=$(echo "$MAVEN_CENTRAL_PORTAL_TOKEN_USERNAME:$MAVEN_CENTRAL_PORTAL_TOKEN_PASSWORD" | base64)

# Ensure jq is available if later used by callers; not strictly required here but helpful to surface missing deps early.
if ! command -v jq >/dev/null 2>&1; then
echo "Warning: jq not found. Some scripts expect jq for JSON parsing. Continue if you're sure it's not needed."
fi

pushd build/local-repo >/dev/null
zip -qr "${zipfile}" *

# Build Authorization header: prefer an explicit bearer token, otherwise fall back to Basic auth built from username/password
if [ -n "${MAVEN_CENTRAL_PORTAL_BEARER_TOKEN:-}" ]; then
auth_header="Authorization: Bearer ${MAVEN_CENTRAL_PORTAL_BEARER_TOKEN}"
elif [ -n "${MAVEN_CENTRAL_PORTAL_TOKEN_USERNAME:-}" ] && [ -n "${MAVEN_CENTRAL_PORTAL_TOKEN_PASSWORD:-}" ]; then
basic_token=$(echo -n "${MAVEN_CENTRAL_PORTAL_TOKEN_USERNAME}:${MAVEN_CENTRAL_PORTAL_TOKEN_PASSWORD}" | base64 | tr -d '\n')
auth_header="Authorization: Basic ${basic_token}"
else
echo "Error: No credentials found. Set MAVEN_CENTRAL_PORTAL_BEARER_TOKEN or MAVEN_CENTRAL_PORTAL_TOKEN_USERNAME and MAVEN_CENTRAL_PORTAL_TOKEN_PASSWORD."
popd >/dev/null || true
exit 1
fi

# Upload to maven central.
# publishingType=USER_MANAGED means that the artefacts will be uploaded and verified, but not yet published.
# See https://central.sonatype.com/publishing/deployments (you need to login as mobilitydata)
# From this page you can examine the list of artefacts, and either drop them or release them.
# If you want to remove that step, use publishingType=AUTOMATIC below, that will publish directly.
# Note that once published you cannot remove or alter the artifacts.
answer=$(curl --request POST \
--verbose \
--header "Authorization: Bearer ${bearer_token}" \
--form bundle="@${zipfile}" \
'https://central.sonatype.com/api/v1/publisher/upload?publishingType=USER_MANAGED')
answer=$(curl --request POST --silent --show-error --header "${auth_header}" --form bundle="@${zipfile}" 'https://central.sonatype.com/api/v1/publisher/upload?publishingType=USER_MANAGED')

echo "curl request answer: $answer"

popd
popd >/dev/null
56 changes: 56 additions & 0 deletions scripts/snapshot_management.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/bin/bash
# This script manages the uploading of snapshots to the Maven Central snapshot repository, and deletion of the associated snapshots after a set retention time.
set -e

subproject=$1
version=$2

echo "Running $(basename $0) for subproject \"$subproject\" and version \"$version\""
echo "Executing in directory = $(pwd)"

zipfile=${subproject}.${version}.zip

# Ensure jq is available for JSON parsing
if ! command -v jq >/dev/null 2>&1; then
echo "Error: jq is required but not installed. Please install jq and retry."
exit 1
fi

pushd build/local-repo >/dev/null
zip -qr "${zipfile}" *

# Build Authorization header: prefer an explicit bearer token, otherwise fall back to Basic auth built from username/password
if [ -n "${MAVEN_CENTRAL_PORTAL_BEARER_TOKEN:-}" ]; then
auth_header="Authorization: Bearer ${MAVEN_CENTRAL_PORTAL_BEARER_TOKEN}"
elif [ -n "${MAVEN_CENTRAL_PORTAL_TOKEN_USERNAME:-}" ] && [ -n "${MAVEN_CENTRAL_PORTAL_TOKEN_PASSWORD:-}" ]; then
basic_token=$(echo -n "${MAVEN_CENTRAL_PORTAL_TOKEN_USERNAME}:${MAVEN_CENTRAL_PORTAL_TOKEN_PASSWORD}" | base64 | tr -d '\n')
auth_header="Authorization: Basic ${basic_token}"
else
echo "Error: No credentials found. Set MAVEN_CENTRAL_PORTAL_BEARER_TOKEN or MAVEN_CENTRAL_PORTAL_TOKEN_USERNAME and MAVEN_CENTRAL_PORTAL_TOKEN_PASSWORD."
popd >/dev/null || true
exit 1
fi

# Delete older snapshots before uploading the newest one to the project's snapshot repository on Maven Central.
# Query the deployments/files endpoint and delete each returned deployment id.
response=$(curl -s --request POST --header "${auth_header}" 'https://central.sonatype.com/api/v1/publisher/deployments/files')
if [ -z "${response}" ]; then
echo "No response from Sonatype when listing deployments."
else
staleIds=$(echo "${response}" | jq -r '.deploymentIds[]?')
if [ -z "${staleIds}" ]; then
echo "No stale deployment ids found."
else
for id in ${staleIds}; do
echo "Deleting stale deployment id: ${id}"
curl -s --request DELETE --header "${auth_header}" "https://central.sonatype.com/api/v1/publisher/deployments/${id}" || echo "Warning: failed to delete deployment ${id}"
done
fi
fi

# Publish to the snapshot repository automatically (no manual intervention).
answer=$(curl --request POST --silent --show-error --header "${auth_header}" --form bundle="@${zipfile}" 'https://central.sonatype.com/api/v1/publisher/upload?publishingType=AUTOMATIC')

echo "curl request answer: $answer"

popd >/dev/null
Loading