Skip to content

Maven Release Process #1

Maven Release Process

Maven Release Process #1

name: Maven Release Process
on:
workflow_dispatch:
inputs:
release_version:
description: 'Release Version (yy.mm.dd[_lts_v##]])'
required: true
release_commit:
description: 'Commit Hash (default to latest commit)'
required: false
deploy_artifact:
description: 'Deploy Artifact'
type: boolean
default: true
required: false
update_plugins:
description: 'Update Plugins'
type: boolean
default: true
required: false
upload_javadocs:
description: 'Upload Javadocs'
type: boolean
default: true
required: false
update_github_labels:
description: 'Update GitHub labels'
type: boolean
default: false
required: false
notify_slack:
description: 'Notify Slack'
type: boolean
default: true
required: false
env:
JAVA_VERSION: 11
JAVA_DISTRO: temurin
JVM_TEST_MAVEN_OPTS: '-e -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn'
DOCKER_BUILD_CONTEXT: /home/runner/work/_temp/core-build
jobs:
prepare-release:
name: Prepare Release
runs-on: ubuntu-20.04
outputs:
release_version: ${{ steps.set-common-vars.outputs.release_version }}
release_tag: ${{ steps.set-common-vars.outputs.release_tag }}
date: ${{ steps.set-common-vars.outputs.date }}
steps:
- name: Validate Inputs
run: |
if [[ ! ${{ github.event.inputs.release_version }} =~ ^[0-9]{2}.[0-9]{2}.[0-9]{2}(_lts_v[0-9]{1,2})?$ ]]; then
echo 'Release version must be in the format yy.mm.dd or yy.mm.dd_lts_v##'
exit 1
fi
- run: echo 'GitHub context'
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
- name: Checkout core
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.CI_MACHINE_TOKEN }}
- uses: ./.github/actions/cleanup-runner
- name: Set Common Vars
id: set-common-vars
run: |
git config user.name "${{ secrets.CI_MACHINE_USER }}"
git config user.email "[email protected]"
release_version=${{ github.event.inputs.release_version }}
release_branch=release-${release_version}
release_tag=v${release_version}
release_commit=${{ github.event.inputs.release_commit }}
if [[ -z "${release_commit}" ]]; then
release_commit=$(git log -1 --pretty=%H)
fi
release_hash=${release_commit::7}
is_lts=false
[[ ${release_version} =~ ^[0-9]{2}.[0-9]{2}.[0-9]{2}_lts_v[0-9]{1,2}$ ]] && is_lts=true
echo "release_version=${release_version}" >> $GITHUB_OUTPUT
echo "release_branch=${release_branch}" >> $GITHUB_OUTPUT
echo "release_tag=${release_tag}" >> $GITHUB_OUTPUT
echo "release_commit=${release_commit}" >> $GITHUB_OUTPUT
echo "release_hash=${release_hash}" >> $GITHUB_OUTPUT
echo "is_lts=${is_lts}" >> $GITHUB_OUTPUT
echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT
- name: Set Release Version
id: set-release-version
run: |
release_tag=${{ steps.set-common-vars.outputs.release_tag }}
if git rev-parse "${release_tag}" >/dev/null 2>&1; then
echo "Tag ${release_tag} exists, removing it"
git push origin :refs/tags/${release_tag}
fi
git reset --hard ${{ steps.set-common-vars.outputs.release_commit }}
release_version=${{ steps.set-common-vars.outputs.release_version }}
release_branch=${{ steps.set-common-vars.outputs.release_branch }}
remote=$(git ls-remote --heads https://github.com/dotCMS/core.git ${release_branch} | wc -l | tr -d '[:space:]')
if [[ "${remote}" == '1' ]]; then
echo "Release branch ${release_branch} already exists, removing it"
git push origin :${release_branch}
fi
git checkout -b ${release_branch}
./mvnw -ntp \
${JVM_TEST_MAVEN_OPTS} \
versions:set \
versions:commit \
-DnewVersion=${release_version} \
-DprocessAllModules=true
./mvnw -ntp \
${JVM_TEST_MAVEN_OPTS} \
versions:set-property \
versions:commit \
-Dproperty=tika.api.version \
-DnewVersion=${release_version} \
--file independent-projects/pom.xml
git status
git commit -a -m "🏁 Publishing release version [${release_version}]"
git push origin ${release_branch}
release_commit=$(git log -1 --pretty=%H)
echo "release_commit=${release_commit}" >> $GITHUB_OUTPUT
- name: Setup Java
uses: actions/setup-java@v3
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ env.JAVA_DISTRO }}
- name: Build Core
run: |
mkdir -p ${DOCKER_BUILD_CONTEXT}
./mvnw -ntp \
${JVM_TEST_MAVEN_OPTS} \
-Dprod=true \
-Ddocker.buildArchiveOnly=${DOCKER_BUILD_CONTEXT} \
-DskipTests=true \
-DskipITs=true \
clean install \
--file pom.xml \
--show-version
rc=$?
if [[ $rc != 0 ]]; then
echo "Build failed with exit code $rc"
exit $rc
fi
- name: Setup Context
id: setup-docker-context
run: |
mkdir -p ${DOCKER_BUILD_CONTEXT}/context
tar -xvf ${DOCKER_BUILD_CONTEXT}/docker-build.tar -C ${DOCKER_BUILD_CONTEXT}/context
if: success()
- name: Cache Maven Repository
id: cache-maven
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: maven-core-${{ steps.set-common-vars.outputs.date }}-${{ github.run_id }}
restore-keys: |
maven-core-${{ steps.set-common-vars.outputs.date }}
if: success()
- name: Cache Core Output
id: cache-core-output
uses: actions/cache@v3
with:
path: |
./dotCMS/target/classes
./dotCMS/target/generated-sources
./dotCMS/target/dotcms-core-${{ steps.set-common-vars.outputs.release_version }}.zip
key: maven-core-output-${{ steps.set-common-vars.outputs.date }}-${{ github.run_id }}
restore-keys: |
maven-core-output-${{ steps.set-common-vars.outputs.date }}
if: success()
- name: Cache Node Binary
id: cache-node-binary
uses: actions/cache@v3
with:
path: |
core-web/installs
key: node-binary-${{ hashFiles('core-web/.nvmrc') }}
if: success()
- name: Cache NPM
id: cache-npm
uses: actions/cache@v3
with:
path: |
~/.npm
key: npm-${{ hashFiles('core-web/package-lock.json') }}
restore-keys: npm-
if: success()
- name: Cache Docker Context
id: cache-docker-context
uses: actions/cache@v3
with:
path: ${{ env.DOCKER_BUILD_CONTEXT }}/context
key: docker-context-${{ steps.set-common-vars.outputs.date }}-${{ github.run_id }}
restore-keys: |
docker-context-${{ steps.set-common-vars.outputs.date }}
if: success()
- name: Create Release
run: |
curl -X POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-H "Authorization: Bearer ${{ secrets.CI_MACHINE_TOKEN }}" \
https://api.github.com/repos/dotCMS/core/releases \
-d '{"tag_name": "${{ steps.set-common-vars.outputs.release_tag }}", "name": "Release ${{ steps.set-common-vars.outputs.release_version }}", "target_commitish": "${{ steps.set-release-version.outputs.release_commit }}", "draft": false, "prerelease": false, "generate_release_notes": false}'
if: success()
release-process:
name: Release Process
runs-on: ubuntu-latest
needs: prepare-release
env:
AWS_REGION: us-east-1
if: success()
steps:
- name: Checkout core
uses: actions/checkout@v4
with:
ref: ${{ needs.prepare-release.outputs.release_tag }}
- uses: ./.github/actions/cleanup-runner
- name: Restore Maven Repository
id: restore-maven
uses: actions/cache/restore@v3
with:
path: ~/.m2/repository
key: maven-core-${{ needs.prepare-release.outputs.date }}-${{ github.run_id }}
- name: Restore Core Output
id: restore-core-output
uses: actions/cache/restore@v3
with:
path: |
./dotCMS/target/classes
./dotCMS/target/generated-sources
./dotCMS/target/dotcms-core-${{ needs.prepare-release.outputs.release_version }}.zip
key: maven-core-output-${{ needs.prepare-release.outputs.date }}-${{ github.run_id }}
- name: Restore Node Binary
id: restore-node-binary
uses: actions/cache/restore@v3
with:
path: core-web/installs
key: node-binary-${{ hashFiles('core-web/.nvmrc') }}
- name: Restore NPM
id: restore-npm
uses: actions/cache/restore@v3
with:
path: ~/.npm
key: npm-${{ hashFiles('core-web/package-lock.json') }}
- name: Setup Java
uses: actions/setup-java@v3
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ env.JAVA_DISTRO }}
- name: maven-settings-xml-action
uses: whelk-io/maven-settings-xml-action@v20
with:
repositories: '[{ "id": "dotcms-libs", "name": "DotCMS libs Release", "url": "https://repo.dotcms.com/artifactory/libs-release" }]'
servers: '[{ "id": "dotcms-libs", "username": "${{ secrets.EE_REPO_USERNAME }}", "password": "${{ secrets.EE_REPO_PASSWORD }}" }]'
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Deploy Release
run: |
./mvnw -ntp \
${JVM_TEST_MAVEN_OPTS} \
-Dprod=true \
-DskipTests=true \
-DskipITs=true \
deploy \
--file dotCMS/pom.xml
if: github.event.inputs.deploy_artifact == 'true'
- name: Generate/Push Javadoc
run: |
./mvnw -ntp \
${JVM_TEST_MAVEN_OPTS} \
javadoc:javadoc \
--file dotCMS/pom.xml
rc=$?
if [[ $rc != 0 ]]; then
echo "Javadoc generation failed with exit code $rc"
exit $rc
fi
site_dir=./dotCMS/target/site
javadoc_dir=${site_dir}/javadocs
s3_uri=s3://static.dotcms.com/docs/${{ needs.prepare-release.outputs.release_version }}/javadocs
mv ${site_dir}/apidocs ${javadoc_dir}
echo "Running: aws s3 cp ${javadoc_dir} ${s3_uri} --recursive"
aws s3 cp ${javadoc_dir} ${s3_uri} --recursive
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
if: github.event.inputs.upload_javadocs == 'true'
- name: Update Plugins
run: |
release_version=${{ needs.prepare-release.outputs.release_version }}
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.CI_MACHINE_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/dotCMS/plugin-seeds/dispatches \
-d "{\"event_type\": \"on-plugins-release\", \"client_payload\": {\"release_version\": \"$release_version\"}}"
if: github.event.inputs.update_plugins == 'true'
build-push-image:
name: Build/Push Image
needs: prepare-release
uses: ./.github/workflows/maven-build-docker-image.yml
with:
ref: ${{ needs.prepare-release.outputs.release_tag }}
docker_platforms: linux/amd64,linux/arm64
docker_context_cache_key: docker-context-${{ needs.prepare-release.outputs.date }}-${{ github.run_id }}
secrets:
docker_io_username: ${{ secrets.DOCKER_USERNAME }}
docker_io_token: ${{ secrets.DOCKER_TOKEN }}
finish-release:
name: Finish Release
runs-on: ubuntu-latest
needs: [prepare-release, release-process, build-push-image]
if: success()
env:
NEXT_VERSION: '1.0.0-SNAPSHOT'
FETCH_VALUE: 'Next Release'
steps:
- name: Checkout core
uses: actions/checkout@v4
with:
ref: master
- uses: ./.github/actions/cleanup-runner
# - name: Fetch `Next Release` issues
# id: fetch-next-release-issues
# uses: ./.github/actions/issue-fetcher
# with:
# fetch_operation: 'WITH_LABELS'
# fetch_value: ${{ env.FETCH_VALUE }}
# github_token: ${{ secrets.GITHUB_TOKEN }}
# if: github.event.inputs.update_github_labels == 'true'
#
# - name: Clear next release issues
# uses: ./.github/actions/issue-labeler
# with:
# issues_json: ${{ steps.fetch-next-release-issues.outputs.issues }}
# labels: ${{ env.FETCH_VALUE }}
# operation: 'REMOVE'
# github_token: ${{ secrets.GITHUB_TOKEN }}
# if: github.event.inputs.update_github_labels == 'true'
#
# - name: Label current release issues
# uses: ./.github/actions/issue-labeler
# with:
# issues_json: ${{ steps.fetch-next-release-issues.outputs.issues }}
# labels: 'Release ${{ needs.prepare-release.outputs.release_version }}'
# operation: 'ADD'
# github_token: ${{ secrets.GITHUB_TOKEN }}
# if: github.event.inputs.update_github_labels == 'true'
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.RELEASE_SLACK_WEBHOOK }}
SLACK_USERNAME: dotBot
SLACK_TITLE: "Important news!"
SLACK_MSG_AUTHOR: " "
MSG_MINIMAL: true
SLACK_FOOTER: ""
SLACK_ICON: https://avatars.slack-edge.com/temp/2021-12-08/2830145934625_e4e464d502865ff576e4.png
SLACK_MESSAGE: "<!channel> This automated script is excited to announce the release of a new version of dotCMS `${{ needs.prepare-release.outputs.release_version }}` :rocket:\n:docker: Produced images: [${{ needs.build-push-image.outputs.formatted_tags }}]"
if: success() && github.event.inputs.notify_slack == 'true'