You are viewing a plain text version of this content. The canonical link for it is here.
Posted to gitbox@yetus.apache.org by aw...@apache.org on 2020/10/21 15:16:10 UTC

[yetus] branch main updated: YETUS-1032. Automate and update release documentation (#166)

This is an automated email from the ASF dual-hosted git repository.

aw pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/yetus.git


The following commit(s) were added to refs/heads/main by this push:
     new 12398ce  YETUS-1032. Automate and update release documentation (#166)
12398ce is described below

commit 12398cea8dda3d7e09b12a3758c450cd3dc991fb
Author: Allen Wittenauer <aw...@apache.org>
AuthorDate: Wed Oct 21 08:16:01 2020 -0700

    YETUS-1032. Automate and update release documentation (#166)
---
 Formula/.rubocop.yml                            | 158 -------------
 Formula/yetus.rb                                |  70 ------
 asf-site-src/pom.xml                            |   2 +
 asf-site-src/source/contribute/releases.html.md | 238 +++++++++-----------
 release/build-and-sign.sh                       | 286 ++++++++++++++++++++++++
 release/initial-patches.sh                      | 165 ++++++++++++++
 release/update-doc-versions.sh                  | 180 +++++++++++++++
 7 files changed, 735 insertions(+), 364 deletions(-)

diff --git a/Formula/.rubocop.yml b/Formula/.rubocop.yml
deleted file mode 100644
index 8f85f1d..0000000
--- a/Formula/.rubocop.yml
+++ /dev/null
@@ -1,158 +0,0 @@
-# BSD 2-Clause License
-
-# Copyright (c) 2009-present, Homebrew contributors
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-
-# * Redistributions of source code must retain the above copyright notice, this
-#   list of conditions and the following disclaimer.
-
-# * Redistributions in binary form must reproduce the above copyright notice,
-#   this list of conditions and the following disclaimer in the documentation
-#   and/or other materials provided with the distribution.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# Taken from Homebrew @ Dec 3, 2018. Modified to pass yamllint
-#
----
-AllCops:
-  NewCops: disable
-# make our hashes consistent
-Layout/HashAlignment:
-  EnforcedHashRocketStyle: table
-  EnforcedColonStyle: table
-
-# `system` is a special case and aligns on second argument
-Layout/ParameterAlignment:
-  Enabled: false
-
-# favour parens-less DSL-style arguments
-Lint/AmbiguousOperator:
-  Enabled: false
-
-# this is a bit less "floaty"
-Layout/CaseIndentation:
-  EnforcedStyle: end
-
-# this is a bit less "floaty"
-Layout/EndAlignment:
-  EnforcedStyleAlignWith: start_of_line
-
-# conflicts with DSL-style path concatenation with `/`
-Layout/SpaceAroundOperators:
-  Enabled: false
-
-# Auto-correct is broken (https://github.com/rubocop-hq/rubocop/issues/6300).
-Layout/EmptyLineAfterGuardClause:
-  Enabled: false
-
-# Auto-correct is broken (https://github.com/rubocop-hq/rubocop/issues/6258)
-# and layout is not configurable
-# (https://github.com/rubocop-hq/rubocop/issues/6254).
-Layout/RescueEnsureAlignment:
-  Enabled: false
-
-# favour parens-less DSL-style arguments
-Lint/AmbiguousBlockAssociation:
-  Enabled: false
-
-# so many of these in formulae and can't be autocorrected
-# TODO: fix these as `ruby -w` complains about them.
-Lint/AmbiguousRegexpLiteral:
-  Enabled: false
-
-# assignment in conditions are useful sometimes
-# TODO: add parentheses for these and remove
-Lint/AssignmentInCondition:
-  Enabled: false
-
-# we output how to use interpolated strings too often
-Lint/InterpolationCheck:
-  Enabled: false
-
-# so many of these in formulae and can't be autocorrected
-Lint/ParenthesesAsGroupedExpression:
-  Enabled: false
-
-# most metrics don't make sense to apply for formulae/taps
-Metrics/AbcSize:
-  Enabled: false
-Metrics/ClassLength:
-  Enabled: false
-Metrics/CyclomaticComplexity:
-  Enabled: false
-Metrics/MethodLength:
-  Enabled: false
-Metrics/ModuleLength:
-  Enabled: false
-Metrics/PerceivedComplexity:
-  Enabled: false
-
-# GitHub diff UI wraps beyond 118 characters (so that's the goal)
-Layout/LineLength:
-  Max: 170
-  # ignore manpage comments and long single-line strings
-  IgnoredPatterns: ['#: ', ' url "', ' mirror "', ' plist_options :']
-
-# our current conditional style is established
-# TODO: enable this when possible
-Style/ConditionalAssignment:
-  Enabled: false
-
-# most of our APIs are internal so don't require docs
-Style/Documentation:
-  Enabled: false
-
-# we want to add this slowly and manually
-# TODO: add to more files
-Style/FrozenStringLiteralComment:
-  Enabled: false
-
-# so many of these in formulae and can't be autocorrected
-Style/GuardClause:
-  Enabled: false
-
-# depends_on a: :b looks weird in formulae.
-Style/HashSyntax:
-  EnforcedStyle: hash_rockets
-  Exclude:
-    - '**/cmd/*.rb'
-
-# ruby style guide favorite
-Style/StringLiterals:
-  EnforcedStyle: double_quotes
-
-# consistency with above
-Style/StringLiteralsInInterpolation:
-  EnforcedStyle: double_quotes
-
-# make things a bit easier to read
-Style/TernaryParentheses:
-  EnforcedStyle: require_parentheses_when_complex
-
-# messes with existing plist/caveats style
-Style/TrailingBodyOnMethodDefinition:
-  Enabled: false
-
-# a bit confusing to non-Rubyists but useful for longer arrays
-Style/WordArray:
-  MinSize: 4
-
-Style/HashEachMethods:
-  Enabled: true
-Style/HashTransformKeys:
-  Enabled: true
-Style/HashTransformValues:
-  Enabled: true
diff --git a/Formula/yetus.rb b/Formula/yetus.rb
deleted file mode 100644
index eec276a..0000000
--- a/Formula/yetus.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Homebrew formula to install Apache Yetus
-class Yetus < Formula
-  desc "Enable contribution and release processes for software projects"
-  homepage "https://yetus.apache.org/"
-  url "https://www.apache.org/dyn/closer.lua?path=/yetus/0.12.0/apache-yetus-0.12.0-bin.tar.gz"
-  sha256 "295e01b710d68152a85c73d5bf70b1189818219f9146c2981e1623df3414232b"
-
-  option "with-all", "Build with all dependencies. Note that some dependencies such as "\
-    "Perl::Critic, Pylint, RuboCop and ruby-lint still need to be installed manually."
-
-  dependencies = [
-    # programming languages
-    :java,
-    "scala",
-
-    # build tools
-    "ant",
-    "autoconf",
-    "automake",
-    "cmake",
-    "libtool",
-    "gradle",
-    "maven",
-
-    # test tools
-    "hadolint",
-    "shellcheck",
-    "spotbugs",
-    "yamllint"
-  ]
-
-  dependencies.each do |dependency|
-    if build.with?("all")
-      depends_on dependency
-    else
-      depends_on dependency => :optional
-    end
-  end
-
-  def install
-    rm Dir["bin/*.{bat,cmd,dll,exe}"]
-    inreplace Dir["bin/*"], '$(dirname -- "${BASH_SOURCE-0}")/..', libexec
-    libexec.install Dir["*"]
-    bin.install_symlink Dir["#{libexec}/bin/*"]
-  end
-
-  test do
-    system "#{bin}/qbt", "--version"
-    system "#{bin}/releasedocmaker", "-V"
-    system "#{bin}/shelldocs", "-V"
-    system "#{bin}/smart-apply-patch", "--version"
-    system "#{bin}/test-patch", "--version"
-  end
-end
diff --git a/asf-site-src/pom.xml b/asf-site-src/pom.xml
index 3eec5f4..7144d41 100644
--- a/asf-site-src/pom.xml
+++ b/asf-site-src/pom.xml
@@ -45,6 +45,7 @@
         <artifactId>yetus-minimaven-plugin</artifactId>
         <version>${project.version}</version>
         <executions>
+          <!-- AUTOMATED_EDIT_BEGIN -->
           <execution>
             <id>0.10.0</id>
             <phase>pre-site</phase>
@@ -111,6 +112,7 @@
               <newLink>${basedir}/source/documentation/0.12.0.html.md</newLink>
             </configuration>
           </execution>
+          <!-- AUTOMATED_EDIT_END -->
           <execution>
             <!-- we create a symlink of current version->in-progress.  This will cause
                  middle man to generate two copies of the output. -->
diff --git a/asf-site-src/source/contribute/releases.html.md b/asf-site-src/source/contribute/releases.html.md
index 19128ef..288da4d 100644
--- a/asf-site-src/source/contribute/releases.html.md
+++ b/asf-site-src/source/contribute/releases.html.md
@@ -58,15 +58,9 @@ The Subversion project provides a nice set of pointers to installing on various
 
 ### Project Specific Build Tools
 
-To create our convenience binary artifact and the Apache Maven plug-ins, you'll need to build both our project docs and all of the individual components. If you usually only work on one part of the project, say Yetus Precommit, this might require some additional programming languages and tools.
-
-All of these tools should be in the Docker container that is launched by using the `./start-build-dev.sh` script.  If you wish to build outside of the container (not recommended), you will need:
-
-- Maven 3.2.0+
-- Java 8
-- Python 2.7
-- Ruby 2.x+
-- bash, tar, gzip, gpg, and shasum
+To create our convenience binary artifact and the Apache Maven plug-ins, you'll need to build both our project docs and all of the individual components.
+All of the tools will be in the Docker container that is launched by using the `./start-build-dev.sh` script. Note that you will need to have a properly
+configured GnuPG and Maven settings.xml setup.
 
 ## Setup
 
@@ -112,92 +106,38 @@ Like the rest of our project activity, we'll use an issue in JIRA to track manag
    For example, on the 0.7.0 release, you would use `https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12318920&version=12334330` for the URI field and 'yetus-0.7.0-jira' for the key.
 1. Finally, you should create a JIRA version that matches the release _following_ the one you are managing. This action is so that folks can continue to work on things that won't make it into the in-progress release while we evaluate candidates.
     1. Browse to the ASF JIRA project management page for versions: <https://issues.apache.org/jira/plugins/servlet/project-config/YETUS/versions>
-    1. Fill in a version one minor version up from the release you're managing. E.g., when managing the 0.7.0 release, fill in 0.3.0.
+    1. Fill in a version one minor version up from the release you're managing. E.g., when managing the 0.7.0 release, fill in 0.8.0.
     1. Set a start date of today.
     1. Click "Add"
 
 ### Work in Git
 
-Once you have an issue to track things, you can create the git branch for staging our release. This separate branch will allow you to polish the release while regular work continues on the main branch. You will need to update main for the next SNAPSHOT version and the branch for the release.
+Once you have an issue to track things, you can create the git branch for staging our release. This separate branch will allow you to polish the release while regular work continues on the main branch. For non-micro releases, you will need to update main for the next SNAPSHOT version and the branch for the release.
 
-Example commands, presuming the release under management is **0.7.0** and the JIRA issue is **YETUS-XXX**:
+- Major Release:
 
-```bash
-$ # Ensure main is up to date
-$ mvn clean
-$ git fetch origin
-$ git status
-# On branch main
-# Your branch is behind 'origin/main' by 6 commits, and can be fast-forwarded.
-#
-nothing to commit (working directory clean)
-$ git rebase origin/main
-First, rewinding head to replay your work on top of it...
-Fast-forwarded main to origin/main.
-$ git status
-# On branch main
-nothing to commit (working directory clean)
-$ # create a branch and push without changes
-$ git checkout -b YETUS-XXX
-Switched to a new branch 'YETUS-XXX'
-$ git push origin YETUS-XXX
-$ # find files we need to update for release
-$ grep -rl "0.7.0-SNAPSHOT" * 2>/dev/null
-asf-site-src/pom.xml
-audience-annotations-component/audience-annotations/pom.xml
-audience-annotations-component/audience-annotations-jdiff/pom.xml
-audience-annotations-component/pom.xml
-pom.xml
-precommit/pom.xml
-releasedocmaker/pom.xml
-shelldocs/pom.xml
-yetus-dist/pom.xml
-yetus-maven-plugin/pom.xml
-yetus-minimaven-plugin/pom.xml
-```
+  ```bash
+  $ release/initial-patches.sh --jira=<release JIRA> --version=<X.0.0>
+  ```
 
-At this point, you should edit the files mentioned above. They must have the version we expect upon a successful release. Search for instances of *VERSION-SNAPSHOT* and replace with *VERSION*; e.g., *0.7.0-SNAPSHOT* should become *0.7.0*:
+- Minor release:
 
-```bash
-$ perl -pi -e 's,0.7.0-SNAPSHOT,0.7.0,g' $(find . -type f)
-```
+  ```bash
+  $ release/initial-patches.sh --jira=<release JIRA>
+  ```
 
-After you are done, create a branch-specific patch and then prepare to update the main branch.
+- Micro release:
 
-```bash
-$ git add -p
-$ git commit -m "YETUS-XXX. Stage version 0.7.0."
-$ git format-patch --stdout origin/YETUS-XXX > path/to/patches/YETUS-XXX-YETUS-XXX.1.patch
-$ git checkout main
-$ grep -rl "0.7.0-SNAPSHOT" * 2>/dev/null
-asf-site-src/pom.xml
-audience-annotations-component/audience-annotations/pom.xml
-audience-annotations-component/audience-annotations-jdiff/pom.xml
-audience-annotations-component/pom.xml
-pom.xml
-precommit/pom.xml
-releasedocmaker/pom.xml
-shelldocs/pom.xml
-yetus-dist/pom.xml
-yetus-maven-plugin/pom.xml
-yetus-minimaven-plugin/pom.xml
-```
-
-Now update these files, but this time you should update them for the next minor version's SNAPSHOT. e.g., *0.7.0-SNAPSHOT* should become *0.8.0-SNAPSHOT*:
-
-```bash
-$ perl -pi -e 's,0.7.0-SNAPSHOT,0.8.0-SNAPSHOT,g' $(find . -type f)
-```
+  ```bash
+  $ release/initial-patches.sh --jira=<release JIRA> --startingbranch=rel/<previous micro version>
+  ```
 
-After you are done, create a patch.
+These commands will create one or two branches:
 
-```bash
-$ git add -p
-$ git commit -m "YETUS-XXX. bump main version to 0.8.0-SNAPSHOT"
-$ git format-patch --stdout origin/main > path/to/patches/YETUS-XXX.1.patch
-```
+- JIRA-release with updated poms that match the release you are working on
+- JIRA-main with updated poms that match the next SNAPSHOT release
 
-Both of these patch files should be uploaded to your release issue for review. Push them to the repository once the patches get approval.
+Verify these branches are correct and create the necessary PRs.  Once approved, merge to their respective branches.
 
 ## Release Candidate(s)
 
@@ -205,14 +145,17 @@ Depending on how candidate evaluation goes, you may end up performing these step
 
 1. Update JIRA version release date. Browse to the JIRA project version management page <https://issues.apache.org/jira/plugins/servlet/project-config/YETUS/versions>, mark the version as 'Release', and set the release date. Our generated release notes will use this date.
 1. Update your `${HOME}/.m2/settings.xml` file to include the Maven snapshot information as indicated on <https://www.apache.org/dev/publishing-maven-artifacts.html>
-1. Build release artifacts. You should use our convenience script to create the tarballs and markdown documents for a release. Run the following from the release staging branch and inspect the results:
+1. Build release artifacts. Run the following from the *release staging branch* created by the `release/initial-patches.sh` script and run these commands:
 
    ```bash
-   $ mvn --batch-mode clean deploy -Papache-release
-   $ mvn --batch-mode site site:stage
+   $ git checkout YETUS-XXX-release
+   $ ./start-build-env.sh
+   (container build and eventually a shell in your source repo)
+   $ release/build-and-sign.sh --asfrelease
    $ ls -lah yetus-dist/target/artifacts/*
    ```
 
+1. Exit the container.
 1. Check out the staging area for release candidates and make a directory for this candidate, somewhere outside of your working directory. Copy the artifacts from the previous step into place. For example, when working on RC1 for the 0.7.0 release
 
    ```bash
@@ -220,20 +163,9 @@ Depending on how candidate evaluation goes, you may end up performing these step
    $ cd yetus-dist-dev
    $ mkdir 0.7.0-RC1
    $ cd 0.7.0-RC1
-   $ cp path/to/yetus/target/RELEASENOTES.md path/to/yetus/target/CHANGELOG.md path/to/yetus/target/*.tar.gz .
+   $ cp path/to/yetus/yetus-dist/target/artifacts/* .
    ```
 
-1. While still in the staging area, sign the artifacts and create the needed checksum files:
-
-   ```bash
-   $ for artifact in *; do
-      echo ${artifact}
-      gpg --use-agent --armor --output "${artifact}".asc --detach-sig "${artifact}"
-      gpg --print-mds "${artifact}" >"${artifact}".mds
-      shasum -a 512 "${artifact}" >"${artifact}".sha512
-    done
-    ```
-
 1. Push the release candidate to staging distribution. This will make the artifacts visible for the vote.
 
    ```bash
@@ -500,6 +432,8 @@ If you've gone through all of the ASF required checks, you'll already have made
 
 Once a release candidate obtains majority approval from the PMC, there are several final maintenance tasks you must perform to close out the release.
 
+### Core Release Tasks
+
 1. Create shortcut links to the vote thread (e.g., <https://s.apache.org/yetus-0.7.0-rc1-vote>) and the result (e.g., <https://s.apache.org/yetus-0.7.0-vote-passes>) that point to the archives on mail-archives.apache.org.  Be aware that it may take several hours for the archive to get the posts that need to be referenced.
 1. Produce a signed release tag. You should create a signed tag and push it to the asf repo. The tag's message should include ASF-shortened links to the vote and results. It should be named 'rel/_version_' so that it will be immutable due to ASF infra's git configuration. Presuming we're working on the 0.7.0 release and the RC1 example above has passed:
 
@@ -515,7 +449,6 @@ Once a release candidate obtains majority approval from the PMC, there are sever
     Then push:
 
         $ git push origin rel/0.7.0
-1. Add the release to the ASF reporter tool. To make our project reports for the ASF Board easier, you should include the release in the [Apache Committee Report Helper website](https://reporter.apache.org/addrelease.html?yetus). Be sure to use the date release artifacts first were pushed to the distribution area, which should be the same release date as in JIRA. Note that this website is only available to PMC members. If you are not yet in the PMC, please ask them to add the release inf [...]
 1. Move release artifacts to the distribution area. The release officially happens once the artifacts are pushed to the ASF distribution servers. From this server, the artifacts will automatically be copied to the long-term archive as well as the various mirrors that will be used by downstream users. These must be _exactly_ the artifacts from the RC that passed. Please note that currently, only Yetus PMC members have write access to this space. If you are not yet on the PMC, please ask t [...]
 
         $ svn co https://dist.apache.org/repos/dist/release/yetus/ yetus-dist-release
@@ -525,6 +458,7 @@ Once a release candidate obtains majority approval from the PMC, there are sever
         $ svn add 0.7.0
         $ svn commit -m "Publish Apache Yetus 0.7.0"
     It may take up to 24 hours for the artifacts to make their way to the various mirrors. You should not announce the release until after this period.
+1. Add the release to the ASF reporter tool. To make our project reports for the ASF Board easier, you should include the release in the [Apache Committee Report Helper website](https://reporter.apache.org/addrelease.html?yetus). Be sure to use the date release artifacts first were pushed to the distribution area, which should be the same release date as in JIRA. Note that this website is only available to PMC members. If you are not yet in the PMC, please ask them to add the release inf [...]
 1. Remove candidates from the staging area. Once you have moved the artifacts into the distribution area, they no longer need to be in the staging area and should be cleaned up as a courtesy to future release managers.
 
         $ svn co https://dist.apache.org/repos/dist/dev/yetus/ yetus-dist-dev
@@ -556,44 +490,6 @@ Once a release candidate obtains majority approval from the PMC, there are sever
 1. Mark JIRA version as released. Browse to the [project version management page for the YETUS JIRA tracker](https://issues.apache.org/jira/plugins/servlet/project-config/YETUS/versions). Mouse over the version you are managing, click on the gear in the far right and select Release.
 1. Delete staging branch. Now that there is an immutable tag for the release, all commits leading up to that release will be maintained by git. Should we need a future maintenance release after this version, we can reestablish the branch based off of the release tag.
         $ git push origin :YETUS-XXX
-1. Update the Mac OS X Homebrew Formula:
-
-   ```bash
-   $ vim Formula/yetus.rb
-   $ # change URL point to the new version
-   $ # update the sha256. e.g., shasum -a 256 bin.gz
-   $ # test the formula:
-   $ brew install --build-from-source Formula/yetus.rb
-    # or if you already have it installed:
-   $ brew upgrade --build-from-source Formula/yetus.rb
-   ```
-
-1. Update the documentation in the git main branch for the new release.  Remove the oldest release and add the latest.
-
-   ```bash
-   $ cd asf-site-src
-   $ # Add the release to the releases data file
-   $ vim data/versions.yml
-   $ vim data/htaccess.yml
-   $ vim pom.xml
-   $ # add the two stanzas
-   $ git add -p
-   $ git add asf-site-src/pom.xml
-   $ git commit
-   ```
-
-   - Example commit message:
-
-   ```text
-   YETUS-XXX. add release 0.7.0.
-
-   - list in releases
-   - remove 0.4.0, add 0.7.0 to pom.xml
-   ```
-
-1. You should then post this patch for review. Once you've gotten feedback, it's fine to push the patch to the ASF source repo immediately so long as the updated website is not published.
-1. Publish website updates. After the 24 hour window needed for the release artifacts to make their way to the variety of mirrors, you should render the website and publish it using the instructions found in [Maintaining the Yetus Website](../website).
-1. Verify that https://yetus.apache.org/latest.tgz and https://yetus.apache.org/latest.tgz.asc download the newly released version.
 1. Remove old releases from the distribution area. The ASF distribution area should only contain the most recent release for actively developed branches If your release is a maintenance release, delete the prior release. If your release marks the end of maintenance for an earlier minor or major release line, you should delete those versions from the distribution area.
 1. Draft an announcement email. The announcement email should briefly describe our project and provide links to our artifacts and documentation. For example,
         Subject: [ANNOUNCE] Apache Yetus 0.7.0 release
@@ -656,7 +552,77 @@ Once a release candidate obtains majority approval from the PMC, there are sever
         Meg Smith
         Apache Yetus PMC
     If you'd like feedback on the draft, feel free to post it for review on your release issue.
-1. Send announcement emails. After the 24 hour window needed for the release artifacts to make their way to the variety of mirrors, you should send the announcement email. The email should come from your apache.org email address and at a minimum should go to the dev@yetus.apache.org list. For details see [the ASF Release Policy section How Should Releases Be Announced?](https://www.apache.org/dev/release.html#release-announcements). Additionally, you may want to send the announcement to  [...]
+1. Wait 24 hours for mirrors to get properly updated.
+
+### Documentation
+
+1. Update the documentation in the git main branch for the new release.  Remove the oldest release and add the latest.
+
+   ```bash
+   $ release/update-doc-versions.sh --version=<x.y.z -- version WITHOUT the rel/!>
+   $ git add -p
+   $ git add asf-site-src/pom.xml
+   $ git commit
+   ```
+
+   - Example commit message:
+
+   ```text
+   YETUS-XXX. add release 0.7.0.
+
+   - list in releases
+   - remove 0.4.0, add 0.7.0 to pom.xml
+   ```
+
+1. You should then post this patch for review. Once you've gotten feedback, it's fine to push the patch to the ASF source repo immediately so long as the updated website is not published.
+1. 24 hours after the distribution repo has been updated, publish website updates. See [Maintaining the Yetus Website](../website).
+1. Verify that https://yetus.apache.org/latest.tgz and https://yetus.apache.org/latest.tgz.asc download the newly released version.
+
+### Homebrew
+
+24 Hours after the distribution repo has been updated, update Homebrew to point to the new release:
+
+1. Update the `yetus-homebrew` repo by using the release script:
+
+  ```bash
+  $ ./release.sh YETUS-XXX <x.y.z -- version WITHOUT the rel/!>
+  ```
+
+1. Test the formula:
+
+  ```bash
+   $ # test the formula:
+   $ brew install --build-from-source Formula/yetus.rb
+    # or if you already have it installed:
+   $ brew upgrade --build-from-source Formula/yetus.rb
+   ```
+
+1. If all looks good, push it live.
+
+### Github Marketplace Action
+
+24 Hours after the distribution repo has been updated, update the Github Marketplace.
+
+1. Update the `yetus-test-patch-action` repo by using the release script to create a branch which will then tag that branch:
+
+  ```bash
+  $ ./release.sh YETUS-XXX <x.y.z -- version WITHOUT the rel/!>
+  ```
+
+1. Verify the branch and the tag match and that the container version matches the Apache Yetus release.
+1. Go to [Draft a release](https://github.com/aw-was-here/yetus-test-patch-action/releases/new?marketplace=true)
+1. Type the tag that you just pushed into the 'tag' box.
+1. Use categories 'Code quality' and 'Continuous integration'
+1. Release Title should reflect the version
+1. Describe this release should be a cut-down version of the anouncement email (drop SHA and direct download links. main page, github actions, and release notes should be mentioned)
+1. Mark 'This is a pre-release'
+1. Verify everything looks good.
+1. Publish release
+
+### Make it Official
+
+1. Did you wait 24 hours for the release artifacts to get everywhere?
+1. Send announcement emails. The email should come from your apache.org email address and at a minimum should go to the dev@yetus.apache.org list. For details see [the ASF Release Policy section How Should Releases Be Announced?](https://www.apache.org/dev/release.html#release-announcements). Additionally, you may want to send the announcement to the development lists of downstream projects we know are using Yetus components.
 1. Send tweet. Once the message to dev@yetus.apache.org has made it to the public archive, you should draft a tweet with a link to the announcement. You should use the ASF link shortener and a descriptive name. For example, the 0.7.0 release could use
 
         Apache Yetus 0.7.0 has been released:
diff --git a/release/build-and-sign.sh b/release/build-and-sign.sh
new file mode 100755
index 0000000..9b0326b
--- /dev/null
+++ b/release/build-and-sign.sh
@@ -0,0 +1,286 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# SHELLDOC-IGNORE
+
+
+this="${BASH_SOURCE-$0}"
+thisdir=$(cd -P -- "$(dirname -- "${this}")" >/dev/null && pwd -P)
+
+pushd "${thisdir}/.." >/dev/null || exit 1
+
+if [[ ! -d precommit ]]; then
+  echo "ERROR: Unsure about directory structure."
+  exit 1
+fi
+
+#shellcheck source=precommit/src/main/shell/core.d/00-yetuslib.sh
+. precommit/src/main/shell/core.d/00-yetuslib.sh
+
+BINDIR=$(yetus_abs "${thisdir}")
+BASEDIR=$(yetus_abs "${BINDIR}/..")
+
+PARAMS=("$@")
+
+echo_and_redirect()
+{
+  declare logfile=$1
+  shift
+
+  # to the screen
+  echo "cd $(pwd)"
+  echo "${*} > ${logfile} 2>&1"
+
+  yetus_run_and_redirect "${logfile}" "${@}"
+}
+
+set_defaults()
+{
+  # Where our artifacts are located
+  ARTIFACTS_DIR=${BASEDIR}/yetus-dist/target/artifacts
+
+  # deploy to maven staging repo
+  DEPLOY=false
+
+  GPG=$(command -v gpg)
+  GPGAGENT=$(command -v gpg-agent)
+
+  LOGDIR="/tmp/build-log"
+
+  PUBKEYFILE="https://downloads.apache.org/yetus/KEYS"
+
+  SIGN=false
+}
+
+
+big_console_header()
+{
+  declare text="$*"
+  declare spacing=$(( (75+${#text}) /2 ))
+
+  printf '\n\n'
+  echo "============================================================================"
+  echo "============================================================================"
+  printf '%*s\n'  ${spacing} "${text}"
+  echo "============================================================================"
+  echo "============================================================================"
+  printf '\n\n'
+}
+
+startgpgagent()
+{
+  if [[ "${SIGN}" = true ]]; then
+    if [[ -n "${GPGAGENT}" && -z "${GPG_AGENT_INFO}" ]]; then
+      echo "starting gpg agent"
+      echo "default-cache-ttl 36000" > "${LOGDIR}/gpgagent.conf"
+      echo "max-cache-ttl 36000" >> "${LOGDIR}/gpgagent.conf"
+      # shellcheck disable=2046
+      eval $("${GPGAGENT}" --daemon \
+        --options "${LOGDIR}/gpgagent.conf" \
+        --log-file="${LOGDIR}/create-release-gpgagent.log")
+      GPGAGENTPID=$(pgrep "${GPGAGENT}")
+      GPG_AGENT_INFO="$HOME/.gnupg/S.gpg-agent:$GPGAGENTPID:1"
+      export GPG_AGENT_INFO
+    fi
+
+    if [[ -n "${GPG_AGENT_INFO}" ]]; then
+      echo "Warming the gpg-agent cache prior to calling maven"
+      # warm the agent's cache:
+      touch "${LOGDIR}/warm"
+      "${GPG}" --use-agent --armor --output "${LOGDIR}/warm.asc" --detach-sig "${LOGDIR}/warm"
+      rm "${LOGDIR}/warm.asc" "${LOGDIR}/warm"
+    else
+      SIGN=false
+      yetus_error "ERROR: Unable to launch or acquire gpg-agent. Disable signing."
+    fi
+  fi
+}
+
+stopgpgagent()
+{
+  if [[ -n "${GPGAGENTPID}" ]]; then
+    kill "${GPGAGENTPID}"
+  fi
+}
+
+usage()
+{
+  yetus_add_option "--asfrelease" "Make an ASF release"
+  yetus_add_option "--deploy" "Deploy Maven artifacts using ~/.m2/settings.xml"
+  yetus_add_option "--logdir=[path]" "Path to store logs"
+  yetus_add_option "--sign" "Use .gnupg dir to sign the artifacts and jars"
+  yetus_generic_columnprinter "${YETUS_OPTION_USAGE[@]}"
+  yetus_reset_usage
+}
+
+option_parse()
+{
+  declare i
+
+  for i in "$@"; do
+    case ${i} in
+      --asfrelease)
+        ASFRELEASE=true
+        SIGN=true
+        DEPLOY=true
+      ;;
+      --deploy)
+        DEPLOY=true
+      ;;
+      --help)
+        usage
+        exit
+      ;;
+      --logdir=*)
+        LOGDIR=${i#*=}
+      ;;
+      --sign)
+        SIGN=true
+      ;;
+    esac
+  done
+
+  if [[ ! -d "${HOME}/.gnupg" ]]; then
+    yetus_error "ERROR: No .gnupg dir. Disabling signing capability."
+    SIGN=false
+  fi
+
+  if [[ "${SIGN}" = true ]]; then
+    if [[ -n "${GPG_AGENT_INFO}" ]]; then
+      echo "NOTE: Using existing gpg-agent. If the default-cache-ttl"
+      echo "is set to less than ~20 mins, maven commands will fail."
+    elif [[ -z "${GPGAGENT}" ]]; then
+      yetus_error "ERROR: No gpg-agent. Disabling signing capability."
+      SIGN=false
+    fi
+  fi
+
+  if [[ "${DEPLOY}" = true && ! -f "${HOME}/.m2/settings.xml" ]]; then
+    yetus_error "ERROR: No ~/.m2/settings.xml file, cannot deploy Maven artifacts."
+    exit 1
+  fi
+
+  if [[ "${ASFRELEASE}" = true ]]; then
+    if [[ "${SIGN}" = false ]]; then
+      yetus_error "ERROR: --asfrelease requires --sign. Exiting."
+      exit 1
+    fi
+  fi
+}
+
+makearelease()
+{
+  declare target="install"
+
+  if [[ "${DEPLOY}" = true ]]; then
+    target="deploy"
+  fi
+
+  if [[ "${SIGN}" = true ]]; then
+    signflags=("-Psign" "-Dgpg.useagent=true")
+  fi
+
+  # let's start at the root
+  pushd "${BASEDIR}" >/dev/null || exit 1
+
+  mkdir -p "${LOGDIR}"
+
+  big_console_header "Cleaning the Source Tree"
+
+  # git clean to clear any remnants from previous build
+  echo_and_redirect "${LOGDIR}/git_clean.log" git clean -xdf
+
+  echo_and_redirect "${LOGDIR}/mvn_clean.log" mvn --batch-mode clean
+
+  big_console_header "Apache RAT Check"
+
+  # Create RAT report
+  echo_and_redirect "${LOGDIR}/mvn_apache_rat.log" mvn --batch-mode apache-rat:check
+
+  big_console_header "Maven Build and Install"
+
+  echo_and_redirect "${LOGDIR}/mvn_${target}.log" \
+    mvn --batch-mode "${target}" \
+      "${signflags[@]}" \
+      -DskipTests
+
+  big_console_header "Maven Site"
+
+  echo_and_redirect "${LOGDIR}/mvn_site.log" \
+    mvn --batch-mode site site:stage </dev/null
+}
+
+function signartifacts
+{
+  declare i
+  declare ret
+
+  if [[ "${SIGN}" = false ]]; then
+    echo ""
+    echo "Remember to sign the artifacts before staging them on the open"
+    echo ""
+    return
+  fi
+
+  big_console_header "Signing the release"
+
+  pushd "${ARTIFACTS_DIR}" > /dev/null || exit 1
+  for i in *; do
+    gpg --use-agent --armor --output "${i}.asc" --detach-sig "${i}"
+    gpg --print-mds "${i}" >"${i}".mds
+    sha512sum --tag "${i}" > "${i}.sha512"
+  done
+
+  popd > /dev/null || exit 1
+
+  if [[ "${ASFRELEASE}" = true ]]; then
+    echo "Fetching the Apache Yetus KEYS file..."
+    curl -L "${PUBKEYFILE}" -o "${BASEDIR}/target/KEYS"
+    gpg --import --trustdb "${BASEDIR}/target/testkeysdb" "${BASEDIR}/target/KEYS"
+    for i in "${ARTIFACTS_DIR}"/*gz; do
+      gpg --verify --trustdb "${BASEDIR}/target/testkeysdb" \
+        "${i}.asc" "${i}"
+      ret=$?
+      if [[ ${ret} != 0 ]]; then
+        yetus_error "ERROR: GPG key is not present in ${PUBKEYFILE}."
+        yetus_error "ERROR: This MUST be fixed. Exiting."
+        exit 1
+      fi
+    done
+  fi
+}
+
+set_defaults
+
+option_parse "${PARAMS[@]}"
+
+startgpgagent
+
+makearelease
+releaseret=$?
+
+stopgpgagent
+
+if [[ ${releaseret} == 0 ]]; then
+  echo
+  echo "Congratulations, you have successfully built the release"
+  echo "artifacts for Apache Yetus ${YETUS_VERSION}"
+  echo
+  echo "The artifacts for this run are available at ${ARTIFACTS_DIR}:"
+  ls -1 "yetus-dist/target/artifacts"
+
+  echo
+fi
diff --git a/release/initial-patches.sh b/release/initial-patches.sh
new file mode 100755
index 0000000..861e2ba
--- /dev/null
+++ b/release/initial-patches.sh
@@ -0,0 +1,165 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# SHELLDOC-IGNORE
+
+this="${BASH_SOURCE-$0}"
+thisdir=$(cd -P -- "$(dirname -- "${this}")" >/dev/null && pwd -P)
+
+pushd "${thisdir}/.." >/dev/null || exit 1
+
+if [[ ! -d precommit ]]; then
+  echo "ERROR: Unsure about directory structure."
+  exit 1
+fi
+
+#shellcheck source=precommit/src/main/shell/core.d/00-yetuslib.sh
+. precommit/src/main/shell/core.d/00-yetuslib.sh
+
+BINDIR=$(yetus_abs "${thisdir}")
+BASEDIR=$(yetus_abs "${BINDIR}/..")
+STARTING_BRANCH=main
+
+USER_NAME=${SUDO_USER:=$USER}
+USER_ID=$(id -u "${USER_NAME}")
+pushd "${BASEDIR}" >/dev/null || exit 1
+
+usage()
+{
+  yetus_add_option "--jira=<issue>" "[REQUIRED] Path to use to store release bits"
+  yetus_add_option "--startingbranch=<git ref>" "Make an ASF release"
+  yetus_add_option "--version=[version]" "Use an alternative version string"
+  yetus_generic_columnprinter "${YETUS_OPTION_USAGE[@]}"
+  yetus_reset_usage
+}
+
+option_parse()
+{
+  declare i
+
+  for i in "$@"; do
+    case ${i} in
+      --jira=*)
+        JIRAISSUE=${i#*=}
+      ;;
+      --help)
+        usage
+        exit
+      ;;
+      --startingbranch=*)
+        STARTING_BRANCH=${i#*=}
+      ;;
+      --version=*)
+        NEW_BRANCH_VERSION=${i#*=}
+      ;;
+    esac
+  done
+
+  if [[ -z "${JIRAISSUE}" ]]; then
+    usage
+    exit 1
+  fi
+}
+
+docker_run() {
+  docker run -i \
+    -v "${PWD}:/src" \
+    -v "${HOME}/.m2:${HOME}/.m2" \
+    -u "${USER_ID}" \
+    -e "HOME=${HOME}" \
+    -w /src \
+    "apache/yetus:main" \
+    "$@"
+}
+
+cleanup() {
+  git checkout --force "${STARTING_BRANCH}"
+  git branch -D "${JIRAISSUE}-release"
+  exit 1
+}
+
+determine_versions() {
+  declare major
+  declare minor
+  declare micro
+  declare microinc
+
+  OLD_BRANCH_VERSION=$(docker_run mvn -Dmaven.repo.local="${HOME}/.m2" help:evaluate -Dexpression=project.version -q -DforceStdout)
+
+  if [[ ${OLD_BRANCH_VERSION} =~ -SNAPSHOT ]]; then
+    if [[ -n "${NEW_BRANCH_VERSION}" ]]; then
+      OLD_BRANCH_VERSION="${NEW_BRANCH_VERSION}"
+    else
+      NEW_BRANCH_VERSION=${OLD_BRANCH_VERSION//-SNAPSHOT}
+    fi
+    major=$(echo "${OLD_BRANCH_VERSION}" | cut -d. -f1)
+    minor=$(echo "${OLD_BRANCH_VERSION}" | cut -d. -f2)
+    ((minor=minor+1))
+    NEW_MAIN_VERSION="${major}.${minor}.0-SNAPSHOT"
+  elif [[ -z "${NEW_BRANCH_VERSION}" ]]; then
+    major=$(echo "${OLD_BRANCH_VERSION}" | cut -d. -f1)
+    minor=$(echo "${OLD_BRANCH_VERSION}" | cut -d. -f2)
+    micro=$(echo "${OLD_BRANCH_VERSION}" | cut -d. -f3)
+    ((microinc=micro+1))
+    NEW_BRANCH_VERSION="${major}.${minor}.${microinc}"
+  fi
+}
+
+update_version() {
+  declare oldversion=${1//\./\\.}
+  declare newversion=$2
+
+  # *MOST* systems have sed -i these days
+  while read -r file; do
+    sed -i "s,${oldversion},${newversion},g" "${file}"
+  done < <( find . -name 'pom.xml')
+}
+
+option_parse "$@"
+
+trap cleanup INT QUIT TRAP ABRT BUS SEGV TERM ERR
+
+set -x
+
+git clean -xdf
+
+docker_run mvn -Dmaven.repo.local="${HOME}/.m2" clean
+
+git fetch origin
+git checkout --force "${STARTING_BRANCH}"
+git fetch origin
+if [[ ! "${STARTING_BRANCH}" =~ rel ]]; then
+  git rebase "origin/${STARTING_BRANCH}"
+fi
+
+determine_versions
+
+git checkout -b "${JIRAISSUE}-release"
+
+update_version "${OLD_BRANCH_VERSION}" "${NEW_BRANCH_VERSION}"
+
+git commit -a -m "${JIRAISSUE}. Stage version ${NEW_BRANCH_VERSION}"
+
+if [[ -n "${NEW_MAIN_VERSION}" ]]; then
+
+  git checkout -b "${JIRAISSUE}-${STARTING_BRANCH}"
+  update_version "${OLD_BRANCH_VERSION}" "${NEW_MAIN_VERSION}"
+fi
+
+git checkout "${JIRAISSUE}-release"
+echo "Source tree is now in ${JIRAISSUE}-release"
+popd >/dev/null || exit 1
diff --git a/release/update-doc-versions.sh b/release/update-doc-versions.sh
new file mode 100755
index 0000000..4a906a1
--- /dev/null
+++ b/release/update-doc-versions.sh
@@ -0,0 +1,180 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# SHELLDOC-IGNORE
+
+this="${BASH_SOURCE-$0}"
+thisdir=$(cd -P -- "$(dirname -- "${this}")" >/dev/null && pwd -P)
+
+pushd "${thisdir}/.." >/dev/null || exit 1
+
+if [[ ! -d precommit ]]; then
+  echo "ERROR: Unsure about directory structure."
+  exit 1
+fi
+
+#shellcheck source=precommit/src/main/shell/core.d/00-yetuslib.sh
+. precommit/src/main/shell/core.d/00-yetuslib.sh
+
+BINDIR=$(yetus_abs "${thisdir}")
+BASEDIR=$(yetus_abs "${BINDIR}/..")
+
+
+usage()
+{
+  yetus_add_option "--version=<version>" "Version to process"
+  yetus_generic_columnprinter "${YETUS_OPTION_USAGE[@]}"
+  yetus_reset_usage
+}
+
+option_parse()
+{
+  declare i
+
+  for i in "$@"; do
+    case ${i} in
+      --help)
+        usage
+        exit
+      ;;
+      --VERSION=*)
+        VERSION=${i#*=}
+      ;;
+    esac
+  done
+
+  if [[ -z "${VERSION}" ]]; then
+    usage
+    exit 1
+  fi
+
+  MAJORVERSION=$(echo "${VERSION}" | cut -d. -f1)
+  MINORVERSION=$(echo "${VERSION}" | cut -d. -f2)
+  #MICROVERSION=$(echo "${VERSION}" | cut -d. -f3)
+}
+
+update_versions()
+{
+  declare newfile=/tmp/versionsedit.$$
+  declare found=false
+  declare ver
+  declare vermajor
+  declare verminor
+  declare -a versions
+  declare produced=false
+
+  ## NOTE: $REPLY, the default for read, is used
+  ## here because it will maintain any leading spaces!
+  ## if read is given a variable, then IFS manipulation
+  ## will be required!
+
+  while read -r; do
+    if [[ ${found} == false && "${REPLY}" != releases: ]]; then
+      echo "${REPLY}" >> "${newfile}"
+    elif [[ "${REPLY}" == releases: ]]; then
+      echo "${REPLY}" >> "${newfile}"
+      found=true
+    else
+      ver=${REPLY##* }
+      ver=${ver//\'/}
+      vermajor=$(echo "${ver}" | cut -d. -f1)
+      verminor=$(echo "${ver}" | cut -d. -f2)
+
+      # Don't keep matching major.minor:
+      if [[ "${vermajor}" == "${MAJORVERSION}" && "${verminor}" == "${MINORVERSION}" ]]; then
+        continue
+      fi
+      versions+=("${ver}")
+    fi
+  done < "${BASEDIR}"/asf-site-src/data/versions.yml
+
+  versions+=("${VERSION}")
+
+  while [[ ${#versions[@]} -gt 3 ]]; do
+    # array slice off the first element
+    versions=("${versions[@]:1}")
+  done
+
+  for ver in "${versions[@]}"; do
+    echo "  - '${ver}'" >> "${newfile}"
+  done
+
+  mv "${newfile}" "${BASEDIR}"/asf-site-src/data/versions.yml
+
+
+  ## NOTE: $REPLY, the default for read, is used
+  ## here because it will maintain any leading spaces!
+  ## if read is given a variable, then IFS manipulation
+  ## will be required!
+
+  found=false
+  produced=false
+  while read -r; do
+    if [[ "${REPLY}" =~ AUTOMATED_EDIT_BEGIN ]]; then
+      echo "${REPLY}" >> "${newfile}"
+      found=true
+    elif [[ "${REPLY}" =~ AUTOMATED_EDIT_END ]]; then
+      echo "${REPLY}" >> "${newfile}"
+      found=false
+    elif [[ ${found} == false ]]; then
+      echo "${REPLY}" >> "${newfile}"
+    elif [[ "${produced}" == true ]]; then
+      continue
+    elif [[ "${found}" == true ]]; then
+      for ver in "${versions[@]}"; do
+        cat << EOF >> "${newfile}"
+          <execution>
+            <id>${ver}</id>
+            <phase>pre-site</phase>
+            <goals>
+              <goal>symlink</goal>
+            </goals>
+            <configuration>
+              <target>../../target/${ver}</target>
+              <newLink>\${basedir}/source/documentation/${ver}</newLink>
+            </configuration>
+          </execution>
+          <execution>
+            <id>${ver}.html.md</id>
+            <phase>pre-site</phase>
+            <goals>
+              <goal>symlink</goal>
+            </goals>
+            <configuration>
+              <target>../../target/${ver}.html.md</target>
+              <newLink>\${basedir}/source/documentation/${ver}.html.md</newLink>
+            </configuration>
+          </execution>
+EOF
+      done
+      produced=true
+    fi
+  done < "${BASEDIR}"/asf-site-src/pom.xml
+
+  mv "${newfile}" "${BASEDIR}"/asf-site-src/pom.xml
+
+}
+
+update_htaccess()
+{
+  sed -E -i "s,[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+,${VERSION},g" "${BASEDIR}"/asf-site-src/data/htaccess.yml
+}
+
+option_parse "$@"
+
+update_versions
+update_htaccess