Automated release process

* Scriptify rolling the version numbers.
* Delegate building release versions on the CI server.
* Add ability to promot to bintray.
* Add ability to sync to maven central.
* Add ability to promote to bintray
This commit is contained in:
Greg Turnquist
2018-11-27 11:04:47 -06:00
parent b6f6147ea2
commit 4c67b43fe7
9 changed files with 351 additions and 19 deletions

View File

@@ -74,17 +74,35 @@ You can also import the project into your IDE.
To do a release (.RELEASE, .RC?, .M?):
. Check in all changes and ensure there are no edited files.
. Bump up the version in `pom.xml` to the desired version and commit the change.
. `git tag <version>` (like v2.0.1.RELEASE)
. Execute a maven deploy.
* For a milestone: `USERNAME=<user> PASSWORD=<encrypted password> mvn -Pdistribute,milestone,docs clean deploy`
* For a release: `USERNAME=<user> PASSWORD=<encrypted password> mvn -Pdistribute,release,docs clean deploy`
* For a release to maven central: `USERNAME=<user> PASSWORD=<nexus password> mvn -Pdistribute,gpg,central clean deploy -s settings.xml` (At SonaType, *close* and *releases*)
. Bump up the version in `pom.xml` again to the next BUILD-SNAPSHOT.
. Commit the change.
. Run `ci/create-release-2.0.x.sh <release version> <snapshot version>` e.g. (`ci/create-release-2.0.x.sh 2.1.1.RELEASE 2.1.2.BUILD-SNAPSHOT`)
From here, test things out locally.
. `git checkout release-2.0.x`
. `./mvnw clean package`
. ...do all your testing...
Once verified, push the `release-2.0.x` branch to `origin` and let the CI server deploy it.
. `git push`
After a clean release, switch back to 2.0.x branch and push it.
. `git checkout 2.0.x`
. `git push`
. `git push --tags`
. Inspect handiwork at https://repo.spring.io/ or https://oss.sonatype.org/#stagingRepositories
//To deploy your changes:
//
//. `git checkout release`
//. Execute a maven deploy.
//* For a milestone: `USERNAME=<user> PASSWORD=<encrypted password> ./mvnw -Pdistribute,milestone,docs clean deploy`
//* For a release: `USERNAME=<user> PASSWORD=<encrypted password> ./mvnw -Pdistribute,release,docs clean deploy`
//* For a release to maven central: `USERNAME=<user> PASSWORD=<nexus password> ./mvnw -Pdistribute,gpg,central clean deploy -s settings.xml` (At SonaType, *close* and *releases*)
//. Inspect handiwork at https://repo.spring.io/ or https://oss.sonatype.org/#stagingRepositories
CI server should build the new snapshot and automatically deploy to artifactory.
NOTE: A word about reference documentation. Based upon https://github.com/spring-projects/spring-framework/wiki/gradle-build-and-release-faq#user-content-wiki-docs_schema_dist_publication[this], the `distribute` profile contains an artifactory property that is applied to the ZIP file generated by the `docs` profile. A CRON job will scoop up the zipped up docs and unpack them inside the target location.

View File

@@ -28,8 +28,8 @@ WARNING: Do NOT check this file into source control! If you'll check, `credentia
With this in place, run the following `fly` commands to create pipelines:
----
% fly -t <team-name> sp -p spring-session-data-mongodb -c ci/pipeline-template.yml -l credentials.yml -v branch=master
% fly -t <team-name> sp -p spring-session-data-mongodb-2.0.x -c ci/pipeline-template.yml -l credentials.yml -v branch=2.0.x
% fly -t spring-team sp -p spring-session-data-mongodb -c ci/pipeline-template.yml -l credentials.yml -v branch=master -v release-branch=release
% fly -t spring-team sp -p spring-session-data-mongodb-2.0.x -c ci/pipeline-template.yml -l credentials.yml -v branch=2.0.x -v release-branch=release-2.0.x
----
This creates pipelines for:
@@ -40,8 +40,8 @@ This creates pipelines for:
With these pipelines in place, you can now activate and expose them:
----
% fly -t <team-name> unpause-pipeline -p spring-session-data-mongodb
% fly -t <team-name> expose-pipeline -p spring-session-data-mongodb
% fly -t <team-name> unpause-pipeline -p spring-session-data-mongodb-2.0.x
% fly -t <team-name> expose-pipeline -p spring-session-data-mongodb-2.x
% fly -t spring-team unpause-pipeline -p spring-session-data-mongodb
% fly -t spring-team expose-pipeline -p spring-session-data-mongodb
% fly -t spring-team unpause-pipeline -p spring-session-data-mongodb-2.0.x
% fly -t spring-team expose-pipeline -p spring-session-data-mongodb-2.x
----

25
ci/create-release-2.0.x.sh Executable file
View File

@@ -0,0 +1,25 @@
#!/bin/bash
set -euo pipefail
RELEASE=$1
SNAPSHOT=$2
git branch -f release-2.0.x
git checkout release-2.0.x
# Bump up the version in pom.xml to the desired version and commit the change
./mvnw versions:set -DnewVersion=$RELEASE -DgenerateBackupPoms=false
git add .
git commit --message "Releasing Spring Session MongoDB v$RELEASE"
# Tag the release
git tag -s v$RELEASE -m "v$RELEASE"
# Bump up the version in pom.xml to the next snapshot
git checkout 2.0.x
./mvnw versions:set -DnewVersion=$SNAPSHOT -DgenerateBackupPoms=false
git add .
git commit --message "Continue development on v$SNAPSHOT"

25
ci/create-release.sh Executable file
View File

@@ -0,0 +1,25 @@
#!/bin/bash
set -euo pipefail
RELEASE=$1
SNAPSHOT=$2
git branch -f release
git checkout release
# Bump up the version in pom.xml to the desired version and commit the change
./mvnw versions:set -DnewVersion=$RELEASE -DgenerateBackupPoms=false
git add .
git commit --message "Releasing Spring Session MongoDB v$RELEASE"
# Tag the release
git tag -s v$RELEASE -m "v$RELEASE"
# Bump up the version in pom.xml to the next snapshot
git checkout master
./mvnw versions:set -DnewVersion=$SNAPSHOT -DgenerateBackupPoms=false
git add .
git commit --message "Continue development on v$SNAPSHOT"

View File

@@ -4,7 +4,7 @@ resource_types:
type: docker-image
source:
repository: springio/artifactory-resource
tag: 0.0.4
tag: 0.0.6
- name: github-status
type: docker-image
@@ -48,7 +48,7 @@ resources:
uri: https://repo.spring.io
username: ((artifactory-username))
password: ((artifactory-password))
build_name: Spring Session for MongoDB
build_name: spring-session-data-mongodb
- name: spring-session-data-mongodb-pull-requests
type: pull-request
@@ -57,6 +57,12 @@ resources:
repo: spring-projects/spring-session-data-mongodb
base: ((branch))
- name: spring-session-data-mongodb-release
type: git
source:
uri: https://github.com/spring-projects/spring-session-data-mongodb.git
branch: ((release-branch))
- name: spring-session-data-mongodb-status
type: github-status
source:
@@ -84,6 +90,11 @@ groups:
- name: pull-requests
jobs:
- spring-session-data-mongodb-pull-requests
- name: release
jobs:
- release-to-artifactory
- promote-to-bintray
- sync-to-maven-central
jobs:
- name: Test - JDK 8
@@ -445,7 +456,7 @@ jobs:
attachments:
- color: danger
fallback: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME <FAILURE>"
text: "Build has failed"
text: "Pull request has failed"
title: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME"
title_link: $ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME
on_success:
@@ -459,6 +470,149 @@ jobs:
attachments:
- color: good
fallback: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME <SUCCESS>"
text: "Build has succeeded!"
text: "Pull request has succeeded!"
title: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME"
title_link: $ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME
- name: release-to-artifactory
serial: true
public: true
plan:
- get: spring-session-data-mongodb-github
resource: spring-session-data-mongodb-release
trigger: true
- put: spring-session-data-mongodb-status
params:
commit: spring-session-data-mongodb-github
state: pending
- task: build
file: spring-session-data-mongodb-github/ci/build.yml
- put: spring-session-data-mongodb-artifactory
params:
build_number: ${BUILD_NAME}
build_uri: ${ATC_EXTERNAL_URL}/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}
repo: libs-release-local
folder: spring-session-data-mongodb-artifactory
artifact_set:
- include:
- "/**"
properties:
archives: '*:*:*:*@zip zip.name:spring-session-data-mongodb, zip.displayname:Spring Session Data MongoDB, zip.deployed:false'
on_failure:
aggregate:
- put: spring-session-data-mongodb-status
params:
commit: spring-session-data-mongodb-github
state: failure
- put: slack
params:
attachments:
- color: danger
fallback: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME <FAILURE>"
text: "Releasing to artifactory has failed"
title: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME"
title_link: $ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME
on_success:
aggregate:
- put: spring-session-data-mongodb-status
params:
commit: spring-session-data-mongodb-github
state: success
- put: slack
params:
attachments:
- color: good
fallback: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME <SUCCESS>"
text: "Releasing to artifactory has succeeded!"
title: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME"
title_link: $ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME
- name: promote-to-bintray
serial: true
plan:
- get: spring-session-data-mongodb-github
- get: spring-session-data-mongodb-artifactory
trigger: true
passed: [release-to-artifactory]
params:
save_build_info: true
- task: promote-to-bintray
file: spring-session-data-mongodb-github/ci/promote-to-bintray.yml
params:
ARTIFACTORY_USERNAME: ((artifactory-username))
ARTIFACTORY_PASSWORD: ((artifactory-password))
on_failure:
aggregate:
- put: spring-session-data-mongodb-status
params:
commit: spring-session-data-mongodb-github
state: failure
- put: slack
params:
attachments:
- color: danger
fallback: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME <FAILURE>"
text: "Promoting to bintray has failed"
title: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME"
title_link: $ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME
on_success:
aggregate:
- put: spring-session-data-mongodb-status
params:
commit: spring-session-data-mongodb-github
state: success
- put: slack
params:
attachments:
- color: good
fallback: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME <SUCCESS>"
text: "Promoting to bintray has succeeded!"
title: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME"
title_link: $ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME
- name: sync-to-maven-central
serial: true
plan:
- get: spring-session-data-mongodb-github
- get: spring-session-data-mongodb-artifactory
trigger: true
passed: [promote-to-bintray]
params:
save_build_info: true
- task: sync-to-maven-central
file: spring-session-data-mongodb-github/ci/sync-to-maven-central.yml
params:
BINTRAY_USERNAME: ((bintray-username))
BINTRAY_API_KEY: ((bintray-api-key))
SONATYPE_USER_TOKEN: ((sonatype-user-token))
SONATYPE_PASSWORD_TOKEN: ((sonatype-user-token-password))
ARTIFACTORY_USERNAME: ((artifactory-username))
ARTIFACTORY_PASSWORD: ((artifactory-password))
on_failure:
aggregate:
- put: spring-session-data-mongodb-status
params:
commit: spring-session-data-mongodb-github
state: failure
- put: slack
params:
attachments:
- color: danger
fallback: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME <FAILURE>"
text: "Syncing to maven central has failed"
title: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME"
title_link: $ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME
on_success:
aggregate:
- put: spring-session-data-mongodb-status
params:
commit: spring-session-data-mongodb-github
state: success
- put: slack
params:
attachments:
- color: good
fallback: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME <SUCCESS>"
text: "Syncing to maven central has succeeded!"
title: "$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME #$BUILD_NAME"
title_link: $ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME

46
ci/promote-to-bintray.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/bin/bash
set -e -u
apt-get update
apt-get install -y jq
buildName=$( cat spring-session-data-mongodb-artifactory/build-info.json | jq -r '.buildInfo.name' )
buildNumber=$( cat spring-session-data-mongodb-artifactory/build-info.json | jq -r '.buildInfo.number' )
groupId=$( cat spring-session-data-mongodb-artifactory/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/\(.*\):.*:.*/\1/' )
version=$( cat spring-session-data-mongodb-artifactory/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
targetRepo="libs-release-local"
echo "Promoting ${buildName}/${buildNumber} to ${targetRepo}"
curl \
-s \
--connect-timeout 240 \
--max-time 2700 \
-u ${ARTIFACTORY_USERNAME}:${ARTIFACTORY_PASSWORD} \
-H "Content-type:application/json" \
-d "{\"sourceRepos\": [\"libs-release-local\"], \"targetRepo\" : \"spring-distributions\", \"async\":\"true\"}" \
-f \
-X \
POST "https://repo.spring.io/api/build/distribute/${buildName}/${buildNumber}" > /dev/null || { echo "Failed to distribute" >&2; exit 1; }
echo "Waiting for artifacts to be published"
ARTIFACTS_PUBLISHED=false
WAIT_TIME=10
COUNTER=0
while [ $ARTIFACTS_PUBLISHED == "false" ] && [ $COUNTER -lt 120 ]; do
result=$( curl -s https://api.bintray.com/packages/spring/jars/"${groupId}" )
versions=$( echo "$result" | jq -r '.versions' )
exists=$( echo "$versions" | grep "$version" -o || true )
if [ "$exists" = "$version" ]; then
ARTIFACTS_PUBLISHED=true
fi
COUNTER=$(( COUNTER + 1 ))
sleep $WAIT_TIME
done

19
ci/promote-to-bintray.yml Normal file
View File

@@ -0,0 +1,19 @@
---
platform: linux
image_resource:
type: docker-image
source:
repository: openjdk
tag: 8-jdk
inputs:
- name: spring-session-data-mongodb-artifactory
- name: spring-session-data-mongodb-github
run:
path: spring-session-data-mongodb-github/ci/promote-to-bintray.sh
params:
ARTIFACTORY_USERNAME:
ARTIFACTORY_PASSWORD:

24
ci/sync-to-maven-central.sh Executable file
View File

@@ -0,0 +1,24 @@
#!/bin/bash
set -e -u
apt-get update
apt-get install -y jq
buildName=$( cat spring-session-data-mongodb-artifactory/build-info.json | jq -r '.buildInfo.name' )
buildNumber=$( cat spring-session-data-mongodb-artifactory/build-info.json | jq -r '.buildInfo.number' )
groupId=$( cat spring-session-data-mongodb-artifactory/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/\(.*\):.*:.*/\1/' )
version=$( cat spring-session-data-mongodb-artifactory/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
echo "Syncing ${buildName}/${buildNumber} to Maven Central"
curl \
-s \
--connect-timeout 240 \
--max-time 2700 \
-u ${BINTRAY_USERNAME}:${BINTRAY_API_KEY} \
-H "Content-Type: application/json" -d "{ \"username\": \"${SONATYPE_USER_TOKEN}\", \"password\": \"${SONATYPE_PASSWORD_TOKEN}\"}" \
-f \
-X \
POST "https://api.bintray.com/maven_central_sync/spring/jars/${groupId}/versions/${version}" > /dev/null || { echo "Failed to sync" >&2; exit 1; }
echo "Sync complete"

View File

@@ -0,0 +1,21 @@
---
platform: linux
image_resource:
type: docker-image
source:
repository: openjdk
tag: 8-jdk
inputs:
- name: spring-session-data-mongodb-artifactory
- name: spring-session-data-mongodb-github
run:
path: spring-session-data-mongodb-github/ci/sync-to-maven-central.sh
params:
BINTRAY_USERNAME:
BINTRAY_API_KEY:
SONATYPE_USER_TOKEN:
SONATYPE_PASSWORD_TOKEN: