Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI overhaul, migrated from Bintray #2243

Merged
merged 9 commits into from May 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 22 additions & 22 deletions .github/workflows/ci.yml
Expand Up @@ -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: ['**']

Expand Down Expand Up @@ -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 }}

Expand All @@ -74,28 +74,28 @@ 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]')

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

- name: Set up Java 8
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: 8

- name: Build and publish to Bintray/MavenCentral
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}}
- 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

- 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:
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}}
50 changes: 25 additions & 25 deletions README.md
Expand Up @@ -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)


Expand All @@ -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
Expand All @@ -54,32 +63,23 @@ 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

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.
37 changes: 23 additions & 14 deletions build.gradle
@@ -1,35 +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'

//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 "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.13.2'
}
}

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'

Expand All @@ -48,7 +62,7 @@ apply from: 'gradle/dependencies.gradle'

allprojects { proj ->
repositories {
jcenter()
mavenCentral()
}
plugins.withId('java') {
proj.apply from: "$rootDir/gradle/errorprone.gradle"
Expand Down Expand Up @@ -103,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
Expand Down
42 changes: 6 additions & 36 deletions gradle/java-publication.gradle
Expand Up @@ -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
Expand Down Expand Up @@ -91,40 +91,10 @@ 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
}
}
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
}
}
64 changes: 40 additions & 24 deletions gradle/shipkit.gradle
@@ -1,9 +1,8 @@
apply plugin: "org.shipkit.shipkit-auto-version"
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"
}
Expand All @@ -17,28 +16,45 @@ 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)
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/')

/**
* 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) }
username = System.getenv('NEXUS_TOKEN_USER')
password = System.getenv('NEXUS_TOKEN_PWD')
szpak marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}

def isSnapshot = version.endsWith("-SNAPSHOT")
if (isSnapshot) {
tasks.named("githubRelease") {
//snapshot versions do not produce changelog / GitHub releases
enabled = false
}
tasks.named("closeAndReleaseStagingRepository") {
//snapshot binaries are available in Sonatype without the need to close the staging repo
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" +
Copy link
Member

@szpak szpak May 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did they degrade so much recently? It's true that the search index is updated after a few hours, but when I checked it a year ago (or so), the artifacts were available in https://repo1.maven.org/maven2/... (and ready for usage in Gradle/Maven/...) after a few (maybe several) minutes.

You can check that with the next Mockito release and update that statement if needed (e.g. to change the hours to minutes :) ).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

" Github releases: https://github.com/mockito/mockito/releases"
}
}
return centralRelease
}