diff --git a/.ci/build.sh b/.ci/build.sh index e9190622d8..bac9151745 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -106,7 +106,8 @@ function build() { pmd_ci_build_and_upload_doc pmd_ci_log_group_end - if pmd_ci_maven_isReleaseBuild; then + # release is published only for the case b) pmd-cli/pmd-dist release + if pmd_ci_maven_isReleaseBuild && [[ "${PMD_CI_TAG}" == *-dist ]]; then pmd_ci_log_group_start "Publishing Release" pmd_ci_gh_releases_publishRelease "$GH_RELEASE" pmd_ci_sourceforge_selectDefault "${PMD_CI_MAVEN_PROJECT_VERSION}" @@ -114,10 +115,14 @@ function build() { pmd_ci_log_group_end fi + # create a baseline for snapshot builds (when pmd-dist is built) + # or for release builds for case b) when pmd-cli/pmd-dist is released + if pmd_ci_maven_isSnapshotBuild || [[ "${PMD_CI_TAG}" == *-dist ]]; then pmd_ci_log_group_start "Creating new baseline for regression tester" regression_tester_setup_ci regression_tester_uploadBaseline pmd_ci_log_group_end + fi # # everything from here runs only on snapshots, not on release builds @@ -182,26 +187,52 @@ function pmd_ci_build_run() { pmd_ci_log_info "This is a snapshot build" fi - ./mvnw clean deploy -P${mvn_profiles} --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}" + # There are two possible builds: + if [[ "${PMD_CI_TAG}" != *-dist ]]; then + # a) pmd-core and languages modules + ./mvnw clean deploy -P${mvn_profiles},'!cli-dist' --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}" + else + # b) pmd-cli and pmd-dist + ./mvnw clean deploy -pl pmd-cli,pmd-dist --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}" + fi } # # Deploys the binary distribution # function pmd_ci_deploy_build_artifacts() { - # Deploy to sourceforge files https://sourceforge.net/projects/pmd/files/pmd/ - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip" - # Deploy SBOM - cp pmd-dist/target/bom.xml "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" - cp pmd-dist/target/bom.json "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" + if pmd_ci_maven_isSnapshotBuild; then + # Deploy to sourceforge files https://sourceforge.net/projects/pmd/files/pmd/ + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip" + # Deploy SBOM + cp pmd-dist/target/bom.xml "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" + cp pmd-dist/target/bom.json "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" + fi - if pmd_ci_maven_isReleaseBuild; then + # release build case a): only pmd-core and language modules released + if pmd_ci_maven_isReleaseBuild && [[ "${PMD_CI_TAG}" != *-dist ]]; then # create a draft github release pmd_ci_gh_releases_createDraftRelease "${PMD_CI_TAG}" "$(git rev-list -n 1 "${PMD_CI_TAG}")" GH_RELEASE="$RESULT" + fi + + # release build case b): pmd-cli and pmd-dist are released + if pmd_ci_maven_isReleaseBuild && [[ "${PMD_CI_TAG}" == *-dist ]]; then + # Deploy to sourceforge files https://sourceforge.net/projects/pmd/files/pmd/ + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip" + # Deploy SBOM + cp pmd-dist/target/bom.xml "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" + cp pmd-dist/target/bom.json "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" + + # draft release has already been created + pmd_ci_gh_releases_getLatestDraftRelease + GH_RELEASE="$RESULT" # Deploy to github releases pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" @@ -221,7 +252,7 @@ function pmd_ci_build_and_upload_doc() { pmd_doc_create_archive pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" - if pmd_ci_maven_isReleaseBuild; then + if pmd_ci_maven_isReleaseBuild && [[ "${PMD_CI_TAG}" != *-dist ]]; then pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" fi @@ -230,19 +261,21 @@ function pmd_ci_build_and_upload_doc() { # Deploy javadoc to https://docs.pmd-code.org/apidocs/*/${PMD_CI_MAVEN_PROJECT_VERSION}/ pmd_code_uploadJavadoc "${PMD_CI_MAVEN_PROJECT_VERSION}" "$(pwd)" - # render release notes - # updating github release text - rm -f .bundle/config - bundle config set --local path vendor/bundle - bundle config set --local with release_notes_preprocessing - bundle install - # renders, and skips the first 6 lines - the Jekyll front-matter - local rendered_release_notes - rendered_release_notes=$(bundle exec docs/render_release_notes.rb docs/pages/release_notes.md | tail -n +6) - local release_name - release_name="PMD ${PMD_CI_MAVEN_PROJECT_VERSION} ($(date -u +%d-%B-%Y))" - # Upload to https://sourceforge.net/projects/pmd/files/pmd/${PMD_CI_MAVEN_PROJECT_VERSION}/ReadMe.md - pmd_ci_sourceforge_uploadReleaseNotes "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "${rendered_release_notes}" + if pmd_ci_maven_isSnapshotBuild || [[ "${PMD_CI_TAG}" != *-dist ]]; then + # render release notes + # updating github release text + rm -f .bundle/config + bundle config set --local path vendor/bundle + bundle config set --local with release_notes_preprocessing + bundle install + # renders, and skips the first 6 lines - the Jekyll front-matter + local rendered_release_notes + rendered_release_notes=$(bundle exec docs/render_release_notes.rb docs/pages/release_notes.md | tail -n +6) + local release_name + release_name="PMD ${PMD_CI_MAVEN_PROJECT_VERSION} ($(date -u +%d-%B-%Y))" + # Upload to https://sourceforge.net/projects/pmd/files/pmd/${PMD_CI_MAVEN_PROJECT_VERSION}/ReadMe.md + pmd_ci_sourceforge_uploadReleaseNotes "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "${rendered_release_notes}" + fi if pmd_ci_maven_isSnapshotBuild && [ "${PMD_CI_BRANCH}" = "master" ]; then # only for snapshot builds from branch master: https://docs.pmd-code.org/snapshot -> pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION} @@ -254,7 +287,7 @@ function pmd_ci_build_and_upload_doc() { pmd_ci_sourceforge_rsyncSnapshotDocumentation "${PMD_CI_MAVEN_PROJECT_VERSION}" "snapshot" fi - if pmd_ci_maven_isReleaseBuild; then + if pmd_ci_maven_isReleaseBuild && [[ "${PMD_CI_TAG}" != *-dist ]]; then # documentation is already uploaded to https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION} # we only need to setup symlinks for the released version pmd_code_createSymlink "${PMD_CI_MAVEN_PROJECT_VERSION}" "latest" diff --git a/do-release.sh b/do-release.sh index 60d060c944..0f4e593c52 100755 --- a/do-release.sh +++ b/do-release.sh @@ -101,8 +101,8 @@ echo " the new release based on the release notes. Also add any deprecated ru echo echo "* Update **../pmd.github.io/_config.yml** to mention the new release" echo -echo "* Update property \`pmd-designer.version\` in **pom.xml** to reference the latest pmd-designer release" -echo " See for the available releases." +echo "* Update property \`pmd-designer.version\` in **pom.xml** to reference the version, that will be released" +echo " later in this process." echo echo "Press enter to continue..." read -r @@ -170,8 +170,8 @@ git commit -a -m "Prepare pmd release ${RELEASE_VERSION}" -DreleaseVersion="${RELEASE_VERSION}" \ -DdevelopmentVersion="${DEVELOPMENT_VERSION}" \ -DscmCommentPrefix="[release] " \ - -Pgenerate-rule-docs - + -Darguments='-Pgenerate-rule-docs,!cli-dist' \ + '-Pgenerate-rule-docs,!cli-dist' echo echo "Tag has been pushed.... now check github actions: " @@ -235,14 +235,45 @@ EOF git commit -a -m "Prepare next development version [skip ci]" git push origin "${CURRENT_BRANCH}" ./mvnw -B release:clean + echo echo echo +echo "* Wait until the new version is synced to maven central and appears as latest version in" +echo " ." +echo +echo +echo "Then proceed with releasing pmd-designer..." +echo +echo "Press enter to continue when pmd-designer is available in maven-central..." +echo "." +read -r + +echo +echo "Continuing with release of pmd-cli and pmd-dist..." +git checkout "pmd_releases/${RELEASE_VERSION}" +./mvnw versions:update-parent -DparentVersion="${RELEASE_VERSION}" -DskipResolution=true -DgenerateBackupPoms=false -pl pmd-cli,pmd-dist +git add pmd-cli/pom.xml pmd-dist/pom.xml +git commit -m "[release] prepare release pmd_releases/${RELEASE_VERSION}-dist" +git tag -m "[release] copy for tag pmd_releases/${RELEASE_VERSION}-dist" "pmd_releases/${RELEASE_VERSION}-dist" +git push origin tag "pmd_releases/${RELEASE_VERSION}-dist" +git checkout master +# make sure parent reference is correct +./mvnw versions:update-parent -DparentVersion="${DEVELOPMENT_VERSION}" -DskipResolution=true -DgenerateBackupPoms=false -pl pmd-cli,pmd-dist +git add pmd-cli/pom.xml pmd-dist/pom.xml +changes=$(git status --porcelain 2>/dev/null| grep -c -E "^[AMDRC]") +if [ "$changes" -gt 0 ]; then + git commit -m "Prepare next development version [skip ci]" + git push origin "${CURRENT_BRANCH}" +fi + +echo +echo "Second tag 'pmd_releases/${RELEASE_VERSION}-dist' has been pushed ... now check github actions: " +echo +echo echo "Verify the new release on github: " echo "and the news entry at " echo -echo "* Wait until the new version is synced to maven central and appears as latest version in" -echo " ." echo "* Send out an announcement mail to the mailing list:" echo echo "To: PMD Developers List " diff --git a/docs/pages/pmd/projectdocs/committers/releasing.md b/docs/pages/pmd/projectdocs/committers/releasing.md index 92ddf8035c..58d12d31ea 100644 --- a/docs/pages/pmd/projectdocs/committers/releasing.md +++ b/docs/pages/pmd/projectdocs/committers/releasing.md @@ -7,8 +7,7 @@ last_updated: April 2021 This page describes the current status of the release process. -Since versions 5.4.5 / 5.5.4 there is an automated release process using [travis-ci](https://travis-ci.com) -in place. Since 6.30.0, the automated release process is using [Github Actions](https://github.com/pmd/pmd/actions). +Since 6.30.0, the automated release process is using [Github Actions](https://github.com/pmd/pmd/actions). However, there are still a few steps, that need manual examination. @@ -19,10 +18,16 @@ required in order to verify that the release was successful or in case the autom some reason. Then individual steps need to be executed manually. Because the build is reproducible, these steps can be repeated again if the same tag is used. +There is one special case in this project: The release of PMD is done in two steps: +1. All modules except pmd-cli and pmd-dist are released. That means, pmd-core and all the language modules + are released. This is, so that these libs can be used by pmd-designer to create a new release. +2. pmd-cli and pmd-dist are released afterwards. Both depend on pmd-designer, and this two-step release + process is used for now to break the cycling release dependency. + The three main steps are: -* Preparations (which creates the tag) - use `do-release.sh` for that -* The actual release (which is automated) +* Preparations (which creates the tags) - use `do-release.sh` for that +* The actual release (which is automated) - GitHub Actions will build the tags when they have been pushed. * Prepare the next release (make sure the current main branch is ready for further development) ## Preparations @@ -30,7 +35,7 @@ The three main steps are: This is the first step. It is always manual and is executed locally. It creates in the end the tag from which the release is created. -Make sure code is up to date and everything is committed and pushed with git: +Make sure code is up-to-date and everything is committed and pushed with git: $ ./mvnw clean $ git pull @@ -71,8 +76,8 @@ pmd: The release type could be one of "bugfix" (e.g. 6.34.x), "minor" (6.x.0), or "major" (x.0.0). -The release notes usual mention any new rules that have been added since the last release. -Please double check the file `pmd-core/src/main/resources/rulesets/releases/.xml`, so +The release notes usually mention any new rules that have been added since the last release. +Please double-check the file `pmd-core/src/main/resources/rulesets/releases/.xml`, so that all new rules are listed. Add the new rules as comments to the quickstart rulesets: @@ -80,12 +85,12 @@ Add the new rules as comments to the quickstart rulesets: * `pmd-java/src/main/resources/rulesets/java/quickstart.xml` The designer lives at [pmd/pmd-designer](https://github.com/pmd/pmd-designer). -Update property `pmd-designer.version` in **pom.xml** to reference the latest pmd-designer release. -See for the available releases. +Update property `pmd-designer.version` in **pom.xml** to reference the new version, that will be released +shortly. Note: This version does at the moment not exist. Starting with PMD 6.23.0 we'll provide small statistics for every release. This needs to be added to the release notes as the last section. To count the closed issues and pull requests, the milestone -on github with the title of the new release is searched. Make sure, there is a milestone +on GitHub with the title of the new release is searched. Make sure, there is a milestone on . The following snippet will create the numbers, that can be attached to the release notes as a last section: @@ -149,27 +154,31 @@ next snapshot version after the release. RELEASE_VERSION=6.34.0 DEVELOPMENT_VERSION=6.35.0-SNAPSHOT ./mvnw -B release:clean release:prepare \ - -Dtag=pmd_releases/${RELEASE_VERSION} \ - -DreleaseVersion=${RELEASE_VERSION} \ - -DdevelopmentVersion=${DEVELOPMENT_VERSION} + -Dtag="pmd_releases/${RELEASE_VERSION}" \ + -DreleaseVersion="${RELEASE_VERSION}" \ + -DdevelopmentVersion="${DEVELOPMENT_VERSION}" \ + -DscmCommentPrefix="[release] " \ + -Darguments='-Pgenerate-rule-docs,!cli-dist' \ + '-Pgenerate-rule-docs,!cli-dist' ``` Once the maven plugin has pushed the tag, github actions will start and build a new version from this tag. Since it is a tag build and a released version build, the build script will do a couple of additional stuff. This is all automated in `.ci/build.sh`. +Note: The profile "cli-dist" is deactivated, so this release command doesn't include pmd-cli and pmd-dist. +They will be released separately after pmd-designer is released. Since pmd-dist is not included in this first +step, no binaries are created yet. + Here is, what happens: * Deploy and release the build to maven central, so that it can be downloaded from . This is done automatically, if all unit tests pass and the build doesn't fail for any other reason. The plugin [nexus-staging-maven-plugin](https://github.com/sonatype/nexus-maven-plugins/tree/master/staging/maven-plugin) is used for that. -* Upload the new binaries to github releases under . It also uploads - the release notes from `docs/pages/release_notes.md`. - Note: The during the process, the release is a draft mode and not visible yet. - At the end of the process, the release will be published. -* Upload the new binaries additionally to sourceforge, so that they can be downloaded from - , including the release notes. +* Create a draft release on GitHub and upload the release notes from `docs/pages/release_notes.md`. + Note: During the process, the release is a draft mode and not visible yet. + At the end of the process, the release will be published. * Render the documentation in `docs/` with `bundle exec jekyll build` and create a zip file from it. * Upload the doc zip file to the current github release under and to . @@ -186,15 +195,47 @@ Here is, what happens: * Copy the documentation to sourceforge's web space, so that it is available as . All previously copied versions are listed under . + +The release on github actions currently takes about 30-45 minutes. Once this is done, you +can proceed with releasing pmd designer, see . +Make sure to release the version, you have used earlier for the property `pmd-designer.version`. + +Once the pmd-designer release is done, you can proceed with part 2. We'll checkout the release tag, add +a new commit with the changed versions for pmd-cli and pmd-dist on top of it and create a new tag: + +```shell +git checkout "pmd_releases/${RELEASE_VERSION}" +./mvnw versions:update-parent -DparentVersion="${RELEASE_VERSION}" -DskipResolution=true -DgenerateBackupPoms=false -pl pmd-cli,pmd-dist +git add pmd-cli/pom.xml pmd-dist/pom.xml +git commit -m "[release] prepare release pmd_releases/${RELEASE_VERSION}-dist" +git tag -m "[release] copy for tag pmd_releases/${RELEASE_VERSION}-dist" "pmd_releases/${RELEASE_VERSION}-dist" +git push origin tag "pmd_releases/${RELEASE_VERSION}-dist" +git checkout master +# make sure parent reference is correct +./mvnw versions:update-parent -DparentVersion="${DEVELOPMENT_VERSION}" -DskipResolution=true -DgenerateBackupPoms=false -pl pmd-cli,pmd-dist +git add pmd-cli/pom.xml pmd-dist/pom.xml +git commit -m "Prepare next development version [skip ci]" +git push origin "${CURRENT_BRANCH}" +``` + +Since pmd-cli/pmd-dist were not part of the first maven-release-plugin call, we might need to fix the parent references +manually to set to the new development version. + +The new created tag ends with the suffix `-dist`, and this is used as a marker for the GitHub action. The same build +script `.ci/build.sh` is executed, but now, it does the following steps: + +* Build only modules pmd-cli and pmd-dist +* Upload the new binaries to the existing draft release under . +* Upload the new binaries additionally to sourceforge, so that they can be downloaded from + , including the release notes. * After all this is done, the release on github () is published - and the news post on sourceforge (https://sourceforge.net/p/pmd/news/> is publishes as well. + and the news post on sourceforge (https://sourceforge.net/p/pmd/news/> is published as well. * The new binary at is selected as the new default for PMD. * As a last step, a new baseline for the [regression tester](https://github.com/pmd/pmd-regression-tester) is created and uploaded to . -The release on github actions currently takes about 30-45 minutes. Once this is done, you can spread additional -news: +Once this second GitHub Action run is done, you can spread additional news: * Write an email to the mailing list