diff --git a/ci/pipeline.yml b/ci/pipeline.yml index 181a235f..4a03d0a0 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -3,14 +3,37 @@ resource_types: type: docker-image source: repository: springio/artifactory-resource - tag: 0.0.4 + tag: 0.0.5 +- name: pull-request + type: docker-image + source: + repository: jtarchie/pr +- name: github-status-resource + type: docker-image + source: + repository: dpb587/github-status-resource + tag: master +- name: slack-notification + type: docker-image + source: + repository: cfcommunity/slack-notification-resource + tag: latest resources: - name: git-repo type: git source: uri: ((github-repo)) + username: ((github-username)) + password: ((github-password)) branch: ((branch)) ignore_paths: ["ci/images/*"] +- name: git-pull-request + type: pull-request + source: + access_token: ((github-access-token)) + repo: spring-io/initializr + base: ((branch)) + ignore_paths: ["ci/*"] - name: ci-images-git-repo type: git source: @@ -31,6 +54,24 @@ resources: username: ((artifactory-username)) password: ((artifactory-password)) build_name: ((build-name)) +- name: slack-alert + type: slack-notification + source: + url: ((slack-webhook-url)) +- name: repo-status-build + type: github-status-resource + source: + repository: spring-io/initializr + access_token: ((github-access-token)) + branch: ((branch)) + context: build +- name: github-release + type: github-release + source: + owner: spring-io + repository: initializr + access_token: ((github-release-notes-access-token)) + pre_release: false jobs: - name: build-initializr-ci-image plan: @@ -49,6 +90,24 @@ jobs: - task: build-project image: initializr-ci-image file: git-repo/ci/tasks/build-project.yml + on_failure: + do: + - put: repo-status-build + params: { state: "failure", commit: "git-repo" } + - put: slack-alert + params: + text: ":concourse-failed: " + silent: true + icon_emoji: ":concourse:" + username: concourse-ci + - put: repo-status-build + params: { state: "success", commit: "git-repo" } + - put: slack-alert + params: + text: ":concourse-succeeded: " + silent: true + icon_emoji: ":concourse:" + username: concourse-ci - put: artifactory-repo params: &artifactory-params repo: libs-snapshot-local @@ -56,10 +115,90 @@ jobs: build_uri: "https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}" build_number: "${BUILD_PIPELINE_NAME}-${BUILD_JOB_NAME}-${BUILD_NAME}" disable_checksum_uploads: true +- name: build-pull-requests + serial: true + public: true + plan: + - get: initializr-ci-image + - get: git-repo + resource: git-pull-request + trigger: true + version: every + - do: + - put: git-pull-request + params: + path: git-repo + status: pending + - task: build-project + image: initializr-ci-image + file: git-repo/ci/tasks/build-pr-project.yml + on_success: + put: git-pull-request + params: + path: git-repo + status: success + on_failure: + put: git-pull-request + params: + path: git-repo + status: failure +- name: stage-release + serial: true + plan: + - get: initializr-ci-image + - get: git-repo + trigger: false + - task: stage + image: initializr-ci-image + file: git-repo/ci/tasks/stage.yml + - put: artifactory-repo + params: + <<: *artifactory-params + repo: libs-staging-local + - put: git-repo + params: + repository: stage-git-repo +- name: promote-release + serial: true + plan: + - get: initializr-ci-image + - get: git-repo + trigger: false + - get: artifactory-repo + trigger: false + passed: [stage-release] + params: + save_build_info: true + - task: promote + image: initializr-ci-image + file: git-repo/ci/tasks/promote.yml + params: + ARTIFACTORY_SERVER: ((artifactory-server)) + ARTIFACTORY_USERNAME: ((artifactory-username)) + ARTIFACTORY_PASSWORD: ((artifactory-password)) + - task: generate-release-notes + file: git-repo/ci/tasks/generate-release-notes.yml + params: + GITHUB_ORGANIZATION: spring-io + GITHUB_REPO: initializr + GITHUB_USERNAME: ((github-username)) + GITHUB_TOKEN: ((github-release-notes-access-token)) + - put: github-release + params: + name: generated-release-notes/version + tag: generated-release-notes/version + body: generated-release-notes/body groups: - name: "Build" jobs: - build +- name: "Build Pull Requests" + jobs: + - "build-pull-requests" - name: "CI Images" jobs: - build-initializr-ci-image +- name: "Release" + jobs: + - stage-release + - promote-release diff --git a/ci/scripts/generate-release-notes.sh b/ci/scripts/generate-release-notes.sh new file mode 100755 index 00000000..da59612a --- /dev/null +++ b/ci/scripts/generate-release-notes.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e + +source $(dirname $0)/common.sh + +version=$( cat version/version ) + +milestone=${version%.RELEASE} + +java -jar /github-release-notes-generator.jar \ + --releasenotes.github.username=${GITHUB_USERNAME} \ + --releasenotes.github.password=${GITHUB_TOKEN} \ + --releasenotes.github.organization=${GITHUB_ORGANIZATION} \ + --releasenotes.github.repository=${GITHUB_REPO} \ + ${milestone} generated-release-notes/release-notes.md + +echo ${version} > generated-release-notes/version +echo v${version} > generated-release-notes/tag diff --git a/ci/scripts/promote.sh b/ci/scripts/promote.sh new file mode 100755 index 00000000..e36ebb2a --- /dev/null +++ b/ci/scripts/promote.sh @@ -0,0 +1,27 @@ +#!/bin/bash +set -e + +source $(dirname $0)/common.sh + +buildName=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.name' ) +buildNumber=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.number' ) +groupId=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/\(.*\):.*:.*/\1/' ) +version=$( cat artifactory-repo/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 900 \ + -u ${ARTIFACTORY_USERNAME}:${ARTIFACTORY_PASSWORD} \ + -H "Content-type:application/json" \ + -d "{\"status\": \"staged\", \"sourceRepo\": \"libs-staging-local\", \"targetRepo\": \"${targetRepo}\"}" \ + -f \ + -X \ + POST "${ARTIFACTORY_SERVER}/api/build/promote/${buildName}/${buildNumber}" > /dev/null || { echo "Failed to promote" >&2; exit 1; } + +echo "Promotion complete" +echo $version > version/version \ No newline at end of file diff --git a/ci/scripts/stage.sh b/ci/scripts/stage.sh new file mode 100755 index 00000000..32f2233c --- /dev/null +++ b/ci/scripts/stage.sh @@ -0,0 +1,39 @@ +#!/bin/bash +set -e + +source $(dirname $0)/common.sh +repository=$(pwd)/distribution-repository + +pushd git-repo > /dev/null +git fetch --tags --all > /dev/null +popd > /dev/null + +git clone git-repo stage-git-repo > /dev/null + +pushd stage-git-repo > /dev/null + +snapshotVersion=$( get_revision_from_pom ) +stageVersion=$( get_next_release $snapshotVersion) +nextVersion=$( bump_version_number $snapshotVersion) +echo "Staging $stageVersion (next version will be $nextVersion)" + +set_revision_to_pom "$stageVersion" +git config user.name "Spring Buildmaster" > /dev/null +git config user.email "buildmaster@springframework.org" > /dev/null +git add pom.xml > /dev/null +git commit -m"Release v$stageVersion" > /dev/null +git tag -a "v$stageVersion" -m"Release v$stageVersion" > /dev/null + +./mvnw clean deploy -U -Pfull -DaltDeploymentRepository=distribution::default::file://${repository} + +git reset --hard HEAD^ > /dev/null +if [[ $nextVersion != $snapshotVersion ]]; then + echo "Setting next development version (v$nextVersion)" + set_revision_to_pom "$nextVersion" + git add pom.xml > /dev/null + git commit -m"Next development version (v$nextVersion)" > /dev/null +fi; + +echo "DONE" + +popd > /dev/null diff --git a/ci/tasks/build-pr-project.yml b/ci/tasks/build-pr-project.yml new file mode 100644 index 00000000..f5c7fc21 --- /dev/null +++ b/ci/tasks/build-pr-project.yml @@ -0,0 +1,10 @@ +--- +platform: linux +inputs: +- name: git-repo +outputs: +- name: distribution-repository +caches: +- path: maven +run: + path: git-repo/ci/scripts/build-project.sh \ No newline at end of file diff --git a/ci/tasks/generate-release-notes.yml b/ci/tasks/generate-release-notes.yml new file mode 100644 index 00000000..9d45c713 --- /dev/null +++ b/ci/tasks/generate-release-notes.yml @@ -0,0 +1,19 @@ +--- +platform: linux +image_resource: + type: docker-image + source: + repository: springio/github-release-notes-generator + tag: '0.0.2' +inputs: +- name: git-repo +- name: version +outputs: +- name: generated-release-notes +params: + GITHUB_ORGANIZATION: + GITHUB_REPO: + GITHUB_USERNAME: + GITHUB_TOKEN: +run: + path: git-repo/ci/scripts/generate-release-notes.sh \ No newline at end of file diff --git a/ci/tasks/promote.yml b/ci/tasks/promote.yml new file mode 100644 index 00000000..7d8b7bbc --- /dev/null +++ b/ci/tasks/promote.yml @@ -0,0 +1,13 @@ +--- +platform: linux +inputs: +- name: git-repo +- name: artifactory-repo +outputs: +- name: version +params: + ARTIFACTORY_SERVER: + ARTIFACTORY_USERNAME: + ARTIFACTORY_PASSWORD: +run: + path: git-repo/ci/scripts/promote.sh diff --git a/ci/tasks/stage.yml b/ci/tasks/stage.yml new file mode 100644 index 00000000..403ba7b8 --- /dev/null +++ b/ci/tasks/stage.yml @@ -0,0 +1,11 @@ +--- +platform: linux +inputs: +- name: git-repo +outputs: +- name: stage-git-repo +- name: distribution-repository +caches: +- path: maven +run: + path: git-repo/ci/scripts/stage.sh