From bc93f4116c63959b1a6a149aaa0d45b04dfae3a2 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Fri, 26 Mar 2021 10:34:39 -0500 Subject: [PATCH 1/9] CI overhaul We need to remove the dependency on Bintray/JCenter --- gradle/shipkit.gradle | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/gradle/shipkit.gradle b/gradle/shipkit.gradle index f14617aad8..0512155941 100644 --- a/gradle/shipkit.gradle +++ b/gradle/shipkit.gradle @@ -1,4 +1,3 @@ -apply plugin: "org.shipkit.shipkit-auto-version" apply plugin: "org.shipkit.shipkit-changelog" apply plugin: "org.shipkit.shipkit-github-release" @@ -42,3 +41,16 @@ static boolean shouldReleaseToCentral(project) { } return centralRelease } + +//TODO: remove bintray and rename this file to release.gradle +if (version.endsWith("-SNAPSHOT")) { + tasks.named("githubRelease") { + //snapshot versions do not produce changelog / GitHub releases + enabled = false + } +//TODO enable below when nexus publish plugin is applied +// tasks.named("closeAndReleaseStagingRepository") { +// //snapshot binaries are available in Sonatype without the need to close the staging repo +// enabled = false +// } +} From 587b78e60d8e381d631fc8e3e19837a9516879d5 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Sat, 27 Mar 2021 17:06:34 -0500 Subject: [PATCH 2/9] Progress on CI overhaul --- .github/workflows/ci.yml | 6 ++---- README.md | 19 ++++++++++++----- build.gradle | 6 ++---- gradle/java-publication.gradle | 38 ---------------------------------- gradle/shipkit.gradle | 36 ++++---------------------------- 5 files changed, 22 insertions(+), 83 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b711181d1..846a439d32 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -80,7 +80,7 @@ jobs: steps: - - name: Check out code + - name: Check out code uses: actions/checkout@v2 # https://github.com/actions/checkout with: fetch-depth: '0' # https://github.com/shipkit/shipkit-changelog#fetch-depth-on-ci @@ -91,11 +91,9 @@ jobs: distribution: 'adopt' java-version: 8 - - name: Build and publish to Bintray/MavenCentral + - name: Build and release run: ./gradlew bintrayUpload githubRelease --scan env: - MAVEN_CENTRAL_RELEASE: ${{contains(toJSON(github.event.commits.*.message), '[ci maven-central-release]')}} GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - BINTRAY_API_KEY: ${{secrets.BINTRAY_API_KEY}} NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}} NEXUS_TOKEN_PWD: ${{secrets.NEXUS_TOKEN_PWD}} diff --git a/README.md b/README.md index 69cd1d4450..400e56331a 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,8 @@ Most popular mocking framework for Java [![Coverage Status](https://img.shields.io/codecov/c/github/mockito/mockito.svg)](https://codecov.io/github/mockito/mockito) [![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/mockito/mockito/blob/release/3.x/LICENSE) -[![Release Notes](https://img.shields.io/badge/release%20notes-3.x-yellow.svg)](https://github.com/mockito/mockito/blob/release/3.x/doc/release-notes/official.md) +[![Release Notes](https://img.shields.io/badge/release%20notes-3.x-yellow.svg)](https://github.com/mockito/mockito/releases/) [![Maven Central](https://img.shields.io/maven-central/v/org.mockito/mockito-core.svg)](https://search.maven.org/artifact/org.mockito/mockito-core/) -[![Bintray](https://img.shields.io/bintray/v/mockito/maven/mockito-development)](https://bintray.com/mockito/maven/mockito/_latestVersion) [![Javadoc](https://www.javadoc.io/badge/org.mockito/mockito-core.svg)](https://www.javadoc.io/doc/org.mockito/mockito-core) @@ -23,15 +22,25 @@ Still on Mockito 1.x? See [what's new](https://github.com/mockito/mockito/wiki/W Available as part of the Tidelift Subscription -The maintainers of org.mockito:mockito-core and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/maven-org-mockito-mockito-core?utm_source=maven-org-mockito-mockito-core&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) +The maintainers of org.mockito:mockito-core and thousands of other packages are working with Tidelift to deliver +commercial support and maintenance for the open source dependencies you use to build your applications. Save time, +reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. +[Learn more.](https://tidelift.com/subscription/pkg/maven-org-mockito-mockito-core?utm_source=maven-org-mockito-mockito-core&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) ## Development -Mockito [continuously delivers](https://github.com/mockito/mockito/wiki/Continuous-Delivery-Overview) improvements using Shipkit library (http://shipkit.org). See the [latest release notes](https://github.com/mockito/mockito/blob/release/3.x/doc/release-notes/official.md) and [latest documentation](https://javadoc.io/page/org.mockito/mockito-core/latest/org/mockito/Mockito.html). Docs in javadoc.io are available 24h after release. Read also about [semantic versioning in Mockito](https://github.com/mockito/mockito/wiki/Semantic-Versioning). **Note: not every version is published to Maven Central.** +Mockito publishes every change as a `-SNAPSHOT` version to a public Sonatype repository. Roughly once a month, we +publish a new minor or patch version to Maven Central. For release automation we use Shipkit +library (http://shipkit.org), Gradle Nexus [Publish Plugin](https://github.com/gradle-nexus/publish-plugin), and +Allegro's [Axion Release Plugin](https://github.com/allegro/axion-release-plugin). Fully automated releases are awesome, +and you should do that for your libraries, too! +See the [latest release notes](https://github.com/mockito/mockito/releases/) +and [latest documentation](https://javadoc.io/page/org.mockito/mockito-core/latest/org/mockito/Mockito.html). Docs in +javadoc.io are available 24h after release. Read also +about [semantic versioning in Mockito](https://github.com/mockito/mockito/wiki/Semantic-Versioning). Older 1.x and 2.x releases are available in [Central Repository](https://search.maven.org/artifact/org.mockito/mockito-core/1.10.19/jar) -, [Bintray](https://bintray.com/mockito/maven/mockito/1.10.19/view) and [javadoc.io](https://javadoc.io/doc/org.mockito/mockito-core/1.10.19/org/mockito/Mockito.html) (documentation). ## More information diff --git a/build.gradle b/build.gradle index 9b914880fd..189851add5 100644 --- a/build.gradle +++ b/build.gradle @@ -9,10 +9,8 @@ buildscript { classpath 'gradle.plugin.nl.javadude.gradle.plugins:license-gradle-plugin:0.14.0' classpath 'net.ltgt.gradle:gradle-errorprone-plugin:2.0.1' - //Using buildscript.classpath so that we can resolve plugins from maven local, during local testing - classpath "org.shipkit:shipkit-auto-version:1.1.9" - classpath "org.shipkit:shipkit-changelog:1.1.15" - classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.+" + classpath "org.shipkit:shipkit-auto-version:1.+" + classpath "org.shipkit:shipkit-changelog:1.+" classpath 'com.google.googlejavaformat:google-java-format:1.10.0' } diff --git a/gradle/java-publication.gradle b/gradle/java-publication.gradle index 9fa7d62a5c..8611103b93 100644 --- a/gradle/java-publication.gradle +++ b/gradle/java-publication.gradle @@ -90,41 +90,3 @@ publishing { //fleshes out problems with Maven pom generation when building tasks.build.dependsOn("publishJavaLibraryPublicationToMavenLocal") - -//Bintray Gradle plugin configuration (https://github.com/bintray/gradle-bintray-plugin) -//Plugin jars are added to the buildscript classpath in the root build.gradle file -apply plugin: "com.jfrog.bintray" - -bintray { - //We need to use some user id here, because the Bintray key is associated with the user - //However, any user id is good, so longer the user has necessary privileges to the repository - user = 'szczepiq' //https://bintray.com/szczepiq - key = System.getenv('BINTRAY_API_KEY') - publish = true //can be changed to 'false' for testing - dryRun = project.hasProperty("bintrayDryRun") - publications = ['javaLibrary'] - - pkg { - repo = 'maven' //https://bintray.com/mockito/maven - userOrg = 'mockito' //https://bintray.com/mockito - - //See our Bintray packages at https://bintray.com/mockito/maven - name = project.rootProject.ext.mavenCentralRelease? "mockito" : "mockito-development" - - licenses = ['MIT'] - labels = ['mocks', 'tdd', 'unit tests'] - vcsUrl = "https://github.com/mockito/mockito.git" - - version { - name = project.version - vcsTag = "v$project.version" - - //Notable versions are automatically synced to Maven Central repository (https://oss.sonatype.org/) - mavenCentralSync { - sync = project.rootProject.ext.mavenCentralRelease - user = System.env.NEXUS_TOKEN_USER - password = System.env.NEXUS_TOKEN_PWD - } - } - } -} diff --git a/gradle/shipkit.gradle b/gradle/shipkit.gradle index 0512155941..1f749bf2a8 100644 --- a/gradle/shipkit.gradle +++ b/gradle/shipkit.gradle @@ -16,41 +16,13 @@ tasks.named("githubRelease") { githubToken = System.getenv("GITHUB_TOKEN") } -/** - * Mockito team does not publish to Maven Central every release as requested by the community. - * We publish to maven central only some versions. All versions are published to Bintray on every change. - * See https://github.com/mockito/mockito/issues/911 - */ -ext.mavenCentralRelease = shouldReleaseToCentral(project) - -/** - * Finds out if we should release to Maven Central. - * To test this logic, run build with '-i' (info logging) and inspect the build output. - */ -static boolean shouldReleaseToCentral(project) { - boolean centralReleaseByCommit = 'true' == System.getenv("MAVEN_CENTRAL_RELEASE") - boolean centralReleaseByProjectProperty = project.hasProperty("maven-central-release") - boolean centralRelease = centralReleaseByCommit || centralReleaseByProjectProperty - def message = """Bintray publish was using following settings: - - commit message contains '[ci maven-central-release]': $centralReleaseByCommit - - project property 'maven-central-release' exists: $centralReleaseByProjectProperty - - Maven Central release is enabled: $centralRelease""" - project.logger.info(message) - project.afterEvaluate { - project.tasks.bintrayPublish.doLast { logger.lifecycle(message) } - } - return centralRelease -} - -//TODO: remove bintray and rename this file to release.gradle if (version.endsWith("-SNAPSHOT")) { tasks.named("githubRelease") { //snapshot versions do not produce changelog / GitHub releases enabled = false } -//TODO enable below when nexus publish plugin is applied -// tasks.named("closeAndReleaseStagingRepository") { -// //snapshot binaries are available in Sonatype without the need to close the staging repo -// enabled = false -// } + tasks.named("closeAndReleaseStagingRepository") { + //snapshot binaries are available in Sonatype without the need to close the staging repo + enabled = false + } } From ef9ada45b4146ce37ad173efd16b0fac822ee9e0 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Sat, 8 May 2021 21:30:48 -0500 Subject: [PATCH 3/9] CI overhaul --- .github/workflows/ci.yml | 6 ++-- build.gradle | 35 ++++++++++++------- gradle/java-publication.gradle | 10 +++++- gradle/shipkit.gradle | 18 +++++++++- src/main/java/org/mockito/Mockito.java | 14 +++----- .../osgi-test/osgi-test-bundles.gradle | 2 +- version.properties | 2 -- 7 files changed, 59 insertions(+), 28 deletions(-) delete mode 100644 version.properties diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 846a439d32..397e7d74a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,7 +57,7 @@ jobs: run: ./gradlew spotlessCheck - name: 6. Build on Java ${{ matrix.java }} with ${{ matrix.mock-maker }} - run: ./gradlew build bintrayUpload idea --scan -PbintrayDryRun + run: ./gradlew build idea --scan env: MOCK_MAKER: ${{ matrix.mock-maker }} @@ -92,8 +92,10 @@ jobs: java-version: 8 - name: Build and release - run: ./gradlew bintrayUpload githubRelease --scan + run: ./gradlew githubRelease publishToSonatype closeAndReleaseStagingRepository env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}} NEXUS_TOKEN_PWD: ${{secrets.NEXUS_TOKEN_PWD}} + PGP_KEY: ${{secrets.PGP_KEY}} + PGP_PWD: ${{secrets.PGP_PWD}} diff --git a/build.gradle b/build.gradle index 189851add5..4be8ef5f65 100644 --- a/build.gradle +++ b/build.gradle @@ -1,33 +1,49 @@ buildscript { repositories { mavenLocal() //for local testing of mockito-release-tools - jcenter() - maven { url "https://plugins.gradle.org/m2/" } + maven { url 'https://plugins.gradle.org/m2/' } } dependencies { classpath 'gradle.plugin.nl.javadude.gradle.plugins:license-gradle-plugin:0.14.0' classpath 'net.ltgt.gradle:gradle-errorprone-plugin:2.0.1' - classpath "org.shipkit:shipkit-auto-version:1.+" - classpath "org.shipkit:shipkit-changelog:1.+" + classpath "io.github.gradle-nexus:publish-plugin:1.+" + classpath 'org.shipkit:shipkit-changelog:1.+' classpath 'com.google.googlejavaformat:google-java-format:1.10.0' + + classpath 'pl.allegro.tech.build:axion-release-plugin:1.+' } } plugins { - id "com.diffplug.gradle.spotless" version "4.5.1" + id 'com.diffplug.gradle.spotless' version '4.5.1' id 'eclipse' id 'com.github.ben-manes.versions' version '0.38.0' id 'biz.aQute.bnd.builder' version '5.3.0' id 'ru.vyarus.animalsniffer' version '1.5.2' } +apply plugin: "pl.allegro.tech.build.axion-release" + +scmVersion { + tag { + prefix = 'v' + versionSeparator = '' + } +} + +allprojects { + version = scmVersion.version +} + +println "Building version $version" + description = 'Mockito mock objects library core API and implementation' apply plugin: 'base' -archivesBaseName = "mockito-core" +archivesBaseName = 'mockito-core' apply from: 'gradle/shipkit.gradle' @@ -46,7 +62,7 @@ apply from: 'gradle/dependencies.gradle' allprojects { proj -> repositories { - jcenter() + mavenCentral() } plugins.withId('java') { proj.apply from: "$rootDir/gradle/errorprone.gradle" @@ -101,11 +117,6 @@ animalsniffer { annotation = 'org.mockito.internal.SuppressSignatureCheck' } -wrapper { - gradleVersion = '5.3.1' - distributionSha256Sum = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' -} - spotless { // We run the check separately on CI, so don't run this by default enforceCheck = false diff --git a/gradle/java-publication.gradle b/gradle/java-publication.gradle index 8611103b93..914c0fa55b 100644 --- a/gradle/java-publication.gradle +++ b/gradle/java-publication.gradle @@ -33,7 +33,7 @@ tasks.withType(GenerateModuleMetadata) { apply plugin: "maven-publish" publishing { publications { - javaLibrary(MavenPublication) { //name of the publication + javaLibrary(MavenPublication) { from components.java artifact sourcesJar artifact javadocJar @@ -90,3 +90,11 @@ publishing { //fleshes out problems with Maven pom generation when building tasks.build.dependsOn("publishJavaLibraryPublicationToMavenLocal") + +apply plugin: 'signing' //https://docs.gradle.org/current/userguide/signing_plugin.html +signing { + if (System.getenv('PGP_KEY')) { + useInMemoryPgpKeys(System.getenv('PGP_KEY'), System.getenv('PGP_PWD')) + sign publishing.publications.javaLibrary + } +} diff --git a/gradle/shipkit.gradle b/gradle/shipkit.gradle index 1f749bf2a8..8db16b24f7 100644 --- a/gradle/shipkit.gradle +++ b/gradle/shipkit.gradle @@ -2,7 +2,7 @@ apply plugin: "org.shipkit.shipkit-changelog" apply plugin: "org.shipkit.shipkit-github-release" tasks.named("generateChangelog") { - previousRevision = project.ext.'shipkit-auto-version.previous-tag' + previousRevision = 'HEAD' //TODO, this will generate empty release notes githubToken = System.getenv("GITHUB_TOKEN") repository = "mockito/mockito" } @@ -16,6 +16,22 @@ tasks.named("githubRelease") { githubToken = System.getenv("GITHUB_TOKEN") } +apply plugin: 'io.github.gradle-nexus.publish-plugin' +nexusPublishing { + repositories { + if (System.getenv('NEXUS_TOKEN_PWD')) { + sonatype { + // Publishing to: https://s01.oss.sonatype.org (faster instance) + nexusUrl = uri('https://s01.oss.sonatype.org/service/local/') + snapshotRepositoryUrl = uri('https://s01.oss.sonatype.org/content/repositories/snapshots/') + + username = System.getenv('NEXUS_TOKEN_USER') + password = System.getenv('NEXUS_TOKEN_PWD') + } + } + } +} + if (version.endsWith("-SNAPSHOT")) { tasks.named("githubRelease") { //snapshot versions do not produce changelog / GitHub releases diff --git a/src/main/java/org/mockito/Mockito.java b/src/main/java/org/mockito/Mockito.java index f6d214a718..a27e2556a9 100644 --- a/src/main/java/org/mockito/Mockito.java +++ b/src/main/java/org/mockito/Mockito.java @@ -28,17 +28,13 @@ import org.mockito.quality.Strictness; import org.mockito.session.MockitoSessionBuilder; import org.mockito.session.MockitoSessionLogger; - -import java.util.function.Function; import org.mockito.stubbing.Answer; import org.mockito.stubbing.LenientStubber; import org.mockito.stubbing.OngoingStubbing; import org.mockito.stubbing.Stubber; -import org.mockito.verification.After; -import org.mockito.verification.Timeout; -import org.mockito.verification.VerificationAfterDelay; -import org.mockito.verification.VerificationMode; -import org.mockito.verification.VerificationWithTimeout; +import org.mockito.verification.*; + +import java.util.function.Function; /** *

Mockito logo

@@ -125,7 +121,7 @@ * *

  * repositories {
- *   jcenter()
+ *   mavenCentral()
  * }
  * dependencies {
  *   testCompile "org.mockito:mockito-core:+"
@@ -147,7 +143,7 @@
  *
  * 

  * repositories {
- *   jcenter()
+ *   mavenCentral()
  * }
  * dependencies {
  *   testCompile "org.mockito:mockito-inline:+"
diff --git a/subprojects/osgi-test/osgi-test-bundles.gradle b/subprojects/osgi-test/osgi-test-bundles.gradle
index a2b9feac89..bcecd725eb 100644
--- a/subprojects/osgi-test/osgi-test-bundles.gradle
+++ b/subprojects/osgi-test/osgi-test-bundles.gradle
@@ -1,6 +1,6 @@
 buildscript {
     repositories {
-        jcenter()
+        mavenCentral()
     }
     dependencies {
         classpath libraries.bndGradle
diff --git a/version.properties b/version.properties
deleted file mode 100644
index d80caeaf10..0000000000
--- a/version.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-# Used by Shipkit Auto Version Gradle plugin: https://github.com/shipkit/shipkit-auto-version
-version=3.9.*

From 4392c42dc16004135a6acff08159cfbe1cc3a929 Mon Sep 17 00:00:00 2001
From: Szczepan Faber 
Date: Sun, 9 May 2021 08:15:41 -0500
Subject: [PATCH 4/9] Added release summary

---
 .github/workflows/ci.yml |  2 +-
 gradle/shipkit.gradle    | 18 +++++++++++++++++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 397e7d74a0..e249052cc6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -92,7 +92,7 @@ jobs:
         java-version: 8
 
     - name: Build and release
-      run: ./gradlew githubRelease publishToSonatype closeAndReleaseStagingRepository
+      run: ./gradlew githubRelease publishToSonatype closeAndReleaseStagingRepository releaseSummary
       env:
         GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
         NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}}
diff --git a/gradle/shipkit.gradle b/gradle/shipkit.gradle
index 8db16b24f7..169f014ec8 100644
--- a/gradle/shipkit.gradle
+++ b/gradle/shipkit.gradle
@@ -32,7 +32,8 @@ nexusPublishing {
     }
 }
 
-if (version.endsWith("-SNAPSHOT")) {
+def isSnapshot = version.endsWith("-SNAPSHOT")
+if (isSnapshot) {
     tasks.named("githubRelease") {
         //snapshot versions do not produce changelog / GitHub releases
         enabled = false
@@ -42,3 +43,18 @@ if (version.endsWith("-SNAPSHOT")) {
         enabled = false
     }
 }
+
+tasks.register("releaseSummary") {
+    doLast {
+        if (isSnapshot) {
+            println "RELEASE SUMMARY\n" +
+                "  SNAPSHOTS released to: https://s01.oss.sonatype.org/content/repositories/snapshots/org/mockito/mockito-core\n" +
+                "  Release to Maven Central: SKIPPED FOR SNAPSHOTS\n" +
+                "  Github releases: SKIPPED FOR SNAPSHOTS"
+        } else {
+            println "RELEASE SUMMARY\n" +
+                "  Release to Maven Central (available in few hours): https://repo1.maven.org/maven2/org/mockito/mockito-core/\n" +
+                "  Github releases: https://github.com/mockito/mockito/releases"
+        }
+    }
+}

From 17239aec26a22d8c895ac6b8de1e11dd00c00acd Mon Sep 17 00:00:00 2001
From: Szczepan Faber 
Date: Sun, 9 May 2021 08:22:36 -0500
Subject: [PATCH 5/9] Updated readme

---
 README.md | 31 +++++++++++--------------------
 1 file changed, 11 insertions(+), 20 deletions(-)

diff --git a/README.md b/README.md
index 400e56331a..93c98de953 100644
--- a/README.md
+++ b/README.md
@@ -63,8 +63,8 @@ To build locally:
 
      ./gradlew build
 
-To develop in IntelliJ IDEA you can use built-in Gradle import wizard in IDEA.
-Alternatively generate the importable IDEA metadata files using:
+To develop in IntelliJ IDEA you can use built-in Gradle import wizard in IDEA. Alternatively generate the importable
+IDEA metadata files using:
 
      ./gradlew idea
 
@@ -72,23 +72,14 @@ Then, _open_ the generated *.ipr file in IDEA.
 
 ## How to release new version?
 
-Mockito [implements Continuous Delivery model](https://github.com/mockito/mockito/wiki/Continuous-Delivery-Overview).
-Every change on the main branch (for example merging a pull request) triggers a release build on CI.
-The build publishes new version if specific criteria are met: all tests green, no 'ci skip release' used in commit message, see the build log for more information.
-Every new version is published to ["mockito/maven" Bintray repository](https://bintray.com/mockito/maven).
-New versions that Mockito team deems "notable" are additionally published to [Maven Central](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.mockito%22) and [JCenter](https://bintray.com/bintray/jcenter).
-We used to publish every version to Maven Central but we changed this strategy based on feedback from the community ([#911](https://github.com/mockito/mockito/issues/911)).
+1. Every change on the main development branch is released as -SNAPSHOT version to Sonatype snapshot repo
+   at https://s01.oss.sonatype.org/content/repositories/snapshots/org/mockito/mockito-core.
+2. In order to release a non-snapshot version to Maven Central push an annotated tag, for example:
 
-* Q: What's new in Mockito release model?
+```
+git tag -a -m "Release 3.4.5" v3.4.5
+git push origin v3.4.5
+```
 
-  A: In Q2 2017 we implemented [Mockito Continuous Delivery Pipeline 2.0](https://github.com/mockito/mockito/issues/911).
-  Not every version is published to Maven Central.
-
-* Q: How to publish to Maven Central?
-
-  A: Include "[ci maven-central-release]" in the **merge** commit when merging the PR.
-  **Hint**: To signify a new feature consider updating version to next minor/major, like: "2.8.0", "2.9.0", "3.0.0".
-
-* Q: How to promote already released version to a notable version?
-
-  A: It isn't automated at the moment. [What's the use case?](https://github.com/mockito/mockito/issues/911)
+3. At the moment, you **may not create releases from GitHub Web UI**. Doing so will make the CI build fail because the
+   CI creates the changelog and posts to GitHub releases. We'll support this in the future.

From cef375d00cf895f1f9fcf7d5f0df6811a7ed3cfd Mon Sep 17 00:00:00 2001
From: Szczepan Faber 
Date: Sun, 9 May 2021 08:42:19 -0500
Subject: [PATCH 6/9] Minor fixes, locked versions

---
 .github/workflows/ci.yml | 6 +++---
 build.gradle             | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e249052cc6..0f0086bc63 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -81,9 +81,9 @@ jobs:
     steps:
 
       - name: Check out code
-      uses: actions/checkout@v2 # https://github.com/actions/checkout
-      with:
-        fetch-depth: '0' # https://github.com/shipkit/shipkit-changelog#fetch-depth-on-ci
+        uses: actions/checkout@v2 # https://github.com/actions/checkout
+        with:
+          fetch-depth: '0' # https://github.com/shipkit/shipkit-changelog#fetch-depth-on-ci
 
     - name: Set up Java 8
       uses: actions/setup-java@v2
diff --git a/build.gradle b/build.gradle
index 4be8ef5f65..4d83088a69 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,12 +8,12 @@ buildscript {
         classpath 'gradle.plugin.nl.javadude.gradle.plugins:license-gradle-plugin:0.14.0'
         classpath 'net.ltgt.gradle:gradle-errorprone-plugin:2.0.1'
 
-        classpath "io.github.gradle-nexus:publish-plugin:1.+"
-        classpath 'org.shipkit:shipkit-changelog:1.+'
+        classpath "io.github.gradle-nexus:publish-plugin:1.1.0"
+        classpath 'org.shipkit:shipkit-changelog:1.1.15'
 
         classpath 'com.google.googlejavaformat:google-java-format:1.10.0'
 
-        classpath 'pl.allegro.tech.build:axion-release-plugin:1.+'
+        classpath 'pl.allegro.tech.build:axion-release-plugin:1.13.2'
     }
 }
 

From 78b821c933ed429e5572d4c4f5d0f58736aecf17 Mon Sep 17 00:00:00 2001
From: Szczepan Faber 
Date: Sun, 9 May 2021 09:25:04 -0500
Subject: [PATCH 7/9] Fixed bug in yml

---
 .github/workflows/ci.yml | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0f0086bc63..ecbcee612b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -85,15 +85,15 @@ jobs:
         with:
           fetch-depth: '0' # https://github.com/shipkit/shipkit-changelog#fetch-depth-on-ci
 
-    - name: Set up Java 8
-      uses: actions/setup-java@v2
-      with:
-        distribution: 'adopt'
-        java-version: 8
+      - name: Set up Java 8
+        uses: actions/setup-java@v2
+        with:
+          distribution: 'adopt'
+          java-version: 8
 
-    - name: Build and release
-      run: ./gradlew githubRelease publishToSonatype closeAndReleaseStagingRepository releaseSummary
-      env:
+      - name: Build and release
+        run: ./gradlew githubRelease publishToSonatype closeAndReleaseStagingRepository releaseSummary
+        env:
         GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
         NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}}
         NEXUS_TOKEN_PWD: ${{secrets.NEXUS_TOKEN_PWD}}

From f25e46602955c5ade1dcf441b50eed0bbc7db959 Mon Sep 17 00:00:00 2001
From: Szczepan Faber 
Date: Sun, 9 May 2021 09:27:53 -0500
Subject: [PATCH 8/9] Fixed issue in iml

---
 .github/workflows/ci.yml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ecbcee612b..00489063f6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -94,8 +94,8 @@ jobs:
       - name: Build and release
         run: ./gradlew githubRelease publishToSonatype closeAndReleaseStagingRepository releaseSummary
         env:
-        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
-        NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}}
-        NEXUS_TOKEN_PWD: ${{secrets.NEXUS_TOKEN_PWD}}
-        PGP_KEY: ${{secrets.PGP_KEY}}
-        PGP_PWD: ${{secrets.PGP_PWD}}
+          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
+          NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}}
+          NEXUS_TOKEN_PWD: ${{secrets.NEXUS_TOKEN_PWD}}
+          PGP_KEY: ${{secrets.PGP_KEY}}
+          PGP_PWD: ${{secrets.PGP_PWD}}

From 1e20c6966d0fbb642b98f23eb2fc53bf6134b023 Mon Sep 17 00:00:00 2001
From: Szczepan Faber 
Date: Sun, 9 May 2021 19:31:01 -0500
Subject: [PATCH 9/9] Fixed CI triggers

---
 .github/workflows/ci.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 00489063f6..03020e8309 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,7 +10,7 @@ name: CI
 on:
   push:
     branches: ['release/3.x']
-    tags-ignore: [v*] # release tags are automatically generated after a successful CI build, no need to run CI against them
+    tags: [v*]
   pull_request:
     branches: ['**']
 
@@ -74,7 +74,7 @@ jobs:
     needs: [build] # build job must pass before we can release
 
     if: github.event_name == 'push'
-        && github.ref == 'refs/heads/release/3.x'
+        && (github.ref == 'refs/heads/release/3.x' || startsWith(github.ref, 'refs/tags/v'))
         && github.repository == 'mockito/mockito'
         && !contains(toJSON(github.event.commits.*.message), '[skip release]')