diff --git a/JenkinsJobs/Releng/FOLDER.groovy b/JenkinsJobs/Releng/FOLDER.groovy index 1b34a4561b8..a4c419384cb 100644 --- a/JenkinsJobs/Releng/FOLDER.groovy +++ b/JenkinsJobs/Releng/FOLDER.groovy @@ -15,7 +15,7 @@ then deploys the artifacts for Eclipse-Platform, JDT, Snapshots are deployed to https://repo.eclipse.org/content/repositories/eclipse-snapshots/.
  • -Releases are deployed to Maven central by deploying to a staging repository. +Releases are published to Maven central through the Central Portal.
  • @@ -31,7 +31,7 @@ If left blank (not recommended), the latest I-build is deployed. Snapshots are deployed to https://repo.eclipse.org/content/repositories/eclipse-snapshots/.

  • -Releases are deployed to Maven central by deploying to a staging repository. +Releases are published to Maven central through the Central Portal.
  • ''') diff --git a/JenkinsJobs/Releng/deployToMaven.jenkinsfile b/JenkinsJobs/Releng/deployToMaven.jenkinsfile index 46680c59122..f202cb122d6 100644 --- a/JenkinsJobs/Releng/deployToMaven.jenkinsfile +++ b/JenkinsJobs/Releng/deployToMaven.jenkinsfile @@ -95,6 +95,7 @@ pipeline { stage('Deploy project to Maven'){ environment { SETTINGS = "/home/jenkins/.m2/settings-deploy-ossrh-${PROJECT == 'platform' ? 'releng': PROJECT}.xml" + SONATYPE_BEARER_TOKEN = credentials("central-sonatype-bearer-token-${PROJECT}") // The location of the temporarily file that contains the secret file content // (see https://www.jenkins.io/doc/book/pipeline/syntax/#supported-credentials-type): KEYRING = credentials("secret-subkeys-${PROJECT == 'platform' ? 'releng': PROJECT}.asc") @@ -109,8 +110,7 @@ pipeline { for pomFile in $(cat "${WORKSPACE}/artifacts-${PROJECT}.txt"); do set +x pomFolder=$(dirname ${pomFile}) - version=$(basename ${pomFolder}) - if [[ $version == *-SNAPSHOT ]]; then + if [ "${DEPLOYMENT_TYPE}" != 'release' ]; then URL=https://repo.eclipse.org/content/repositories/eclipse-snapshots/ REPO_ID=repo.eclipse.org # server-id in the settings.xml, used for authentication MAVEN_CENTRAL_URL=https://repo1.maven.org/maven2/${pomFolder%-SNAPSHOT} @@ -119,8 +119,7 @@ pipeline { echo "The released version of file "${pomFile}" is already present at $MAVEN_CENTRAL_URL." fi else - URL=https://oss.sonatype.org/service/local/staging/deploy/maven2/ - REPO_ID=ossrh # server-id in the settings.xml, used for authentication + URL=file://$(pwd) MAVEN_CENTRAL_URL=https://repo1.maven.org/maven2/${pomFolder} echo "Checking ${MAVEN_CENTRAL_URL}" if curl --output /dev/null --silent --head --fail "$MAVEN_CENTRAL_URL"; then @@ -160,6 +159,44 @@ pipeline { ${SOURCES_ARG} ${JAVADOC_ARG} done ''' + script { + if ("${DEPLOYMENT_TYPE}" == 'release') { + // Documentation of the Central Portal Publisher API + // - https://central.sonatype.org/publish/publish-portal-api + // - https://central.sonatype.com/api-doc + sh 'zip -r "${PROJECT}-artifacts.zip" "org/eclipse/${PROJECT}"' + def deploymentId = sh(returnStdout: true, script: ''' + curl --request POST \ + --verbose \ + --header "Authorization: Bearer ${SONATYPE_BEARER_TOKEN}" \ + --header 'accept: text/plain' \ + --header 'Content-Type: multipart/form-data' \ + --form "bundle=@${PROJECT}-artifacts.zip" \ + 'https://central.sonatype.com/api/v1/publisher/upload?publishingType=USER_MANAGED' + ''') + writeFile(file: "${WORKSPACE}/deploymentId-${PROJECT}.txt", text: "${deploymentId}") + waitUntil(initialRecurrencePeriod: 5_000) { + // See https://central.sonatype.org/publish/publish-portal-api/#verify-status-of-the-deployment + def deploymentStatusResponse = sh(returnStdout: true, script: """ + curl --request POST \ + --verbose \ + --header "Authorization: Bearer \${SONATYPE_BEARER_TOKEN}" \ + --header 'accept: application/json' \ + "https://central.sonatype.com/api/v1/publisher/status?id=${deploymentId}" + """).trim() + def deploymentStatus = readJSON(text: deploymentStatusResponse, returnPojo: true) + if (deploymentStatus.deploymentState == 'VALIDATED' && !deploymentStatus.errors) { + echo "Upload to Maven Central Portal successful:\n${groovy.json.JsonOutput.prettyPrint(deploymentStatusResponse)}" + return true + } else if(deploymentStatus.deploymentState == 'PENDING' || deploymentStatus.deploymentState == 'VALIDATING') { + echo "Upload is being processed: ${deploymentStatus.deploymentState}" + return false + } else { + error "Upload failed or has an unexpected status:\n${groovy.json.JsonOutput.prettyPrint(deploymentStatusResponse)}" + } + } + } + } } } } @@ -171,7 +208,7 @@ pipeline { always { archiveArtifacts allowEmptyArchive: true, artifacts: '\ repo/**, \ - coordinates*.txt, artifacts*.txt' + coordinates*.txt, artifacts*.txt, deploymentId-*.txt' } failure { emailext subject: "Publication of Maven artifacts failed", diff --git a/RELEASE.md b/RELEASE.md index 8461445357e..bb5749eb456 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -112,8 +112,8 @@ The actual steps to release - Deploying to maven should happen by at least Tuesday before the release since there is up to a 24 hour delay for the maven mirrors. - Run the [Deploy to Maven](https://ci.eclipse.org/releng/job/Releng/job/deployToMaven/) job in Jenkins with the release build as `sourceRepository`. - About a minute after triggering the job, Jenkins will ask for confirmation on the console, if the specified build should really be deployed to Maven-Central staging. - - Once that deploy-job has completed successfully, log into https://oss.sonatype.org/#stagingRepositories and close the Platform, JDT and PDE repositories. - - If you do not have an account on oss.sonatype.org for performing the rest of the release request one by creating an issue like https://issues.sonatype.org/browse/OSSRH-43870 to get permissions for platform, JDT and PDE projects and tag an existing release engineer to give approval. + - Once that deploy-job has completed successfully, log into https://central.sonatype.com/ and close the `Platform`, `JDT` and `PDE` repositories. + - If you do not have an account on `central.sonatype.com` for performing the rest of the release request one by creating an [EF Help Desk](https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/issues) issue to get permissions for platform, JDT and PDE projects and tag an existing release engineer to give approval. * **Contribute to SimRel** - If SimRel is not updated before the I-builds are cleaned up (specifically the build for RC2/GA) it will break.