<!--
 Licensed to the Hipparchus project under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The Hipparchus project 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

      https://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.
-->
# Release Guide

Releasing a new version of Hipparchus is not an easy process. Here are
some steps that have been used in the past. They can be used as
guidelines to avoid forgetting something.

You can also use the `release.sh` shell script to perform some of
the commands depicted here.

## Prerequisites

In order to sign the binary releases, one has to create (once) a GPG
signing key. This can be done on Linux-type using the command:

    gpg --full-generate-key

Once the key has been generated, it should be registered on the
Hipparchus server so users would be able to download it from
[https://www.hipparchus.org/KEYS](https://www.hipparchus.org/KEYS). Ask
on the Hipparchus forum or on the GitHub discussion so the project
team can add it.

## Prepare Git branch for release

Release will be performed on a dedicated branch, not directly on
main. So a new branch must be created as follows and used for
everything else:

    git branch release-X.Y
    git checkout release-X.Y

## Change library version number

The pom.xml files (both the top level one in the aggregator and the lower level
ones for the various modules) contain the version number of the library. During
development, this version number has the form `X.Y-SNAPSHOT`. For release, the
`-SNAPSHOT` part must be removed. On a system with Unix utilities, you can do
it with the single following line:

    for pom in pom.xml hipparchus-*/pom.xml ; do sed -i 's,-SNAPSHOT,,' $pom ; done

Commit the change:

    git add pom.xml hipparchus-*/pom.xml
    git commit -m "Dropped -SNAPSHOT in version number for official release."

This step is performed by the `release.sh` shell script.

## Update maven plugins versions

Release is a good opportunity to update the maven plugin versions. They are all
gathered at one place, in a set of properties in `hipparchus-parent/pom.xml`,
in a set of properties:

    <!-- Project specific plugin versions -->

    <hipparchus.spotbugs-maven-plugin.version>4.7.3.4</hipparchus.spotbugs-maven-plugin.version>
    <hipparchus.jacoco-maven-plugin.version>0.8.9</hipparchus.jacoco-maven-plugin.version>
    <hipparchus.maven-assembly-plugin.version>3.5.0</hipparchus.maven-assembly-plugin.version>
    ...

You can find the latest version of the plugins using the search feature at
[https://central.sonatype.com/search](https://central.sonatype.com/search).
The properties name all follow the pattern `hipparchus.some-plugin-name.version`, the plugin
name should be used in the web form to check for available versions.

Beware that in some cases, the latest version cannot be used due to incompatibilities.

Beware also that some plugins use configuration files that may need update too. This is
typically the case with `maven-checkstyle-plugin` and `maven-pmd-plugin`. The
`src/conf/checkstyle.xml` and `src/conf/pmd-ruleset` files may need to be checked.

Before committing these changes, you have to check that everything works. So run
the following command:

    LANG=C mvn -Prelease site site:stage

If something goes wrong, either fix it by changing the plugin configuration or
roll back to an earlier version of the plugin.

Browse the generated site starting at page `target/staging/index.html`.
Beware not to use `target/site/index.html` because it only contains
the top level part of the site, not the modules. The `target/staging`
directory which was generated by the `site:stage` part of the command gathers
everything in one place.

When everything runs fine and the generated site is OK, then you can commit the changes:

    git add hipparchus-parent/pom.xml src/conf/checkstyle.xml src/conf/pmd-ruleset.xml
    git commit -m "Updated maven plugins versions."

## Creating release notes

The release notes are created automatically using the `maven-changes-plugin`.

Some preparation is needed as Hipparchus is a multi-module product and this is not
managed directly by the plugin.

The first step is to finalize the modules `hipparchus-x/src/changes/changes.xml` files.
The release date and description, which are often only set to `TBD` during development,
must be set to appropriate values. The release date at this step is only a guess three or
four days in the future, in order to take into account the 72 hours release vote delay. If some
modules had no changes at all, it is still worth adding a new `<release>` entry for the
version, if the `hipparchus-core` module itself changed, as all other modules depend on
it. It also simplifies management for users, as for any X.Y version released, all modules
will have such a version number.

The second step to perform is to gather the entries from the modules
`hipparchus-x/src/changes/changes.xml` files into the aggregator
file `src/changes/changes.xml`. Forgetting this step would imply the release notes are
incomplete as only this file is parsed during release notes generation.

The third step to perform is to run the following commands (don't forget to replace
X.Y by the correct version number):

    mkdir -p hipparchus-parent/src/changes
    cp src/changes/* hipparchus-parent/src/changes/
    mvn -Dversion=X.Y changes:announcement-generate -pl hipparchus-parent
    cp hipparchus-parent/target/announcement/release-notes.vm RELEASE-NOTES.txt
    rm -rf hipparchus-parent/src

After these commands have been run, the `RELEASE-NOTES.txt` file has been updated
automatically. It should be reviewed and edited manually to improve readability
(mainly whitespaces, indentation and lines wrapping) and then committed:

    git add RELEASE-NOTES.txt src/changes/changes.xml hipparchus-*/src/changes/changes.xml
    git commit -m "Updated release notes."

This third step is performed by the `release.sh` shell script (but the first two
steps must be performed manually).

## Updating documentation

Several files must be updated to take into account the new version:

|            file name             |           usage            |                                     required update                                                    | 
|----------------------------------|----------------------------|--------------------------------------------------------------------------------------------------------|
| `hipparchus-*/src/site/site.xml` | site structure and menus   | Add an entry in the menu for X.Y API docs (don't remove the existing entries for previous versions!)   |
| `src/site/site.xml         `     | site structure and menus   | Add an entry in the menu for X.Y API docs (don't remove the existing entries for previous versions!)   |
| `src/site/markdown/index.md`     | site home page             | Update the text about the latest available version, including important changes from RELEASE-NOTES.txt |
| `src/site/markdown/downloads.md` | downloads links            | Add a table with the links for files of the new versions, don't forget the date in the table caption   |
| `README.md`                      | introduction for new users | Use the latest version number in the example property myprojectname.hipparchus.version                 |
Documentation files to update

Once the files have been updated, commit the changes:

    git add hipparchus-*/src/site/site.xml src/site/site.xml src/site/markdown/*.md README.md
    git commit -m "Updated documentation for the release."

## Tag and sign the git repository

When all previous steps have been performed, the local git repository holds the final state
of the sources and build files for the release. It must be tagged and the tag must be signed.
Note that before the vote is finished, the tag can only signed with a `-RCx` suffix to denote
Release Candidate. The final tag without the `-RCx` suffix will be put once the vote succeeds,
on the same commit (which will therefore have two tags). Tagging and signing is done using the
following command, with `-RCn` replaced with the Release Candidate number:

    git tag X.Y-RCn -s -u key-ID -m "Release Candidate n for version X.Y."

The key ID is the 16 hexadecimal digits representing the manager keyID. This key ID should be
available in the [https://www.hipparchus.org/KEYS](https://www.hipparchus.org/KEYS) file.

The tag should be verified using command:

    git tag -v X.Y-RCn

## Pushing the branch and the tag

When the tag is ready, the branch and the tag must be pushed to GitHub so everyone can
review it:

    git push --tags origin release-X.Y

## Generating signed artifacts

In order to upload the generated artifacts to SonaType OSS site, an account must have been
set up and the corresponding credentials must be set in the `servers` section of the
`$HOME/.m2/settings.xml` file, using an id of `ossrh`:

    <servers>
      <server>
        <id>ossrh</id>
        <username>the user name to connect to the OSS site</username>
        <password>the encrypted password</password>
      </server>
    </servers>

In order to sign the generated artifacts, the `gpg` key ID must be configured properly
for maven to pick it. This can be done by adding a property that will be triggered
automatically as follows in the `profiles` section of the `$HOME/.m2/settings.xml` file:

    <profiles>
      <profile>
         <id>hipparchus-gpg-settings</id>
         <activation>
           <file>
             <exists>${basedir}/hipparchus-core</exists>
           </file>
         </activation>
         <properties>
           <gpg.keyname>the 16 hexadecimal digits representing the manager keyID</gpg.keyname>
         </properties>
       </profile>
     </profiles>

When these settings have been set up, generating the artifacts is done by running the following commands:

    mvn clean
    mvn deploy -DskipStagingRepositoryClose=true -Prelease

During the generation, maven will trigger gpg which will ask the user for the pass phrase to
access the signing key.

A huge number of files will be uploaded to SonaType server, some of which we do not really
release. So once the commands ends, you will have to log into SonaType OSS site
[https://oss.sonatype.org/](https://oss.sonatype.org/), check the staging repository and
remove all the artifacts related to `hipparchus-aggregator` and
`hipparchus-coverage` modules by right-clicking and selecting "delete".
When the artifacts are considered OK, the repository must be closed so it is ready for the
upcoming vote for the release.

This step is performed by the `release.sh` shell script, except the closing of the OSS repository,
removing the spurious artifacts.

## Uploading non-maven artifacts

The non-maven artifacts are the web site and the source and binary archives.

In addition to generate the maven artifacts and upload them, the command from the previous step
also generated the source and binary release files we provide directly at the Hipparchus site in
the downloads pages. Archives in both `.zip` and `.tar.bz2` formats are created for sources and
binaries, as well as their signatures but missing the checksums. The checksums must be generated
manually using the command:

    for f in target/hipparchus-*.zip target/hipparchus-*.tar.bz2 ; do md5sum < $f > $f.md5 ; done

The 12 files (`hipparchus-X.Y-bin.zip`, `hipparchus-X.Y-bin.zip.asc`, `hipparchus-X.Y-bin.zip.md5`,
`hipparchus-X.Y-bin.tar.bz2`, `hipparchus-X.Y-bin.tar.bz2.asc`, `hipparchus-X.Y-bin.tar.bz2.md5`,
`hipparchus-X.Y-src.zip`, `hipparchus-X.Y-src.zip.asc`, `hipparchus-X.Y-src.zip.md5`,
`hipparchus-X.Y-src.tar.bz2`, `hipparchus-X.Y-src.tar.bz2.asc`, `hipparchus-X.Y-src.tar.bz2.md5`) must
be uploaded manually to the Hipparchus site (in a new `staging/downloads` directory) so people
can review them.

The site is generated locally using:

    LANG=C mvn site site:stage

Once generated, the site can be archived and uploaded to the Hipparchus site:

    cd target/staging
    tar cjf ../www-X.Y.hipparchus.org.tar.bz2 .

This archive content must be extracted in the `staging` directory that already contains the
`downloads` directory with the 12 files uploaded just before.

## Prepare the site for the release

When the `staging` directory is ready, the Apache server configuration
must be updated to allow this directory to be served (it is not served
when no vote is going on). This server configuration file is located
in the `/etc/apache2/sites-enabled` folder. The `#` comment marker in
front of the line that references the staging directory must be
removed, the file must be saved and the `apache2ctl restart` command
must be run to relaunch the Apache server.

## Calling for the vote

Everything is now ready so the developers and PMC can vote for the release. Create a
new topic in the developers category of the forum with a subject line of the form:

    [VOTE] Releasing hipparchus X.Y from release candidate n

and a content of the form:

    This is a VOTE in order to release version X.Y of the Hipparchus library.
    Version X.Y is a maintenance release.


    Highlights in the X.Y release are:
      - feature 1 description
      ...
      - feature n description

    The release candidate n can be found on the GitHub repository as
    tag X.Y-RCn in the release-X.Y branch.

    Source and binary archives are available using the staged web
    site downloads page at
    <https://hipparchus.org/staging/downloads.html>.

    Note that the index page at /downloads does not show the X.Y release,
    as it has not been voted yet.

    The release notes can be read here:
    <https://hipparchus.org/staging/changes-report.html>.

    Maven artifacts are available at
    <https://oss.sonatype.org/content/repositories/orghipparchus-xxxx/>.

    The votes will be tallied in 72 hours for now, on 20yy-mm-ddThh:mm:00Z (this is UTC time).

## After the vote

If the vote fails, the maven artifacts must be removed from OSS site by dropping the repository
and non-maven artifacts must be removed from the `staging` directory in the Hipparchus site.
Then a new release candidate must be created, with a new number, a new tag and new artifacts.
Another vote is needed for this new release candidate.

### Tagging the released version

As the vote passed, a final signed tag must be added to the succeeding release candidate,
verified and pushed:

    git tag X.Y -s -u key-ID -m "Version X.Y."
    git tag -v X.Y
    git push --tags

### Merging the release version into main

After the release branch has been completed, it should be merged back
to the main branch:

    git checkout main
    git merge --no-ff release-X.Y
    git push

### Releasing maven artifacts on SonaType

In order to publish the maven artifacts, one should log into SonaType OSS site
[https://oss.sonatype.org/](https://oss.sonatype.org/), select the
staging repository and press the "Release" button in the top menu.

### Releasing source artifacts on GitHub

In order to publish the source artifacts, one should log to GitHub, go
to the
[https://github.com/Hipparchus-Math/hipparchus/releases/](https://github.com/Hipparchus-Math/hipparchus/releases/)
page and declare the new release.

### Finalize the site after the successful vote

The non-maven artifacts must also be published on the Hipparchus
server by moving them from the `staging` repository to the general
repository. Beware to create a new `www-X.Y.hipparchus.org` directory
for the site and link the latest version to it. This allows older
versions to be kept available if needed. A dedicated `apidocs-X.Y`
folder must also be set up with a copy of the
`www-X.Y.hipparchus.org/apidocs` directory. Here again, it allows
older versions to still be available online.

The Apache server configuration must be updated to forbid serving the
now unused `staging` directory, and to add an alias for the new
`apidocs-X.Y` folder. Once again, this is done by editing the Apache
configuration file in the `/etc/apache2/sites-enabled` folder, saving
it and running `apache2ctl restart`.

### Announcing the release

The last step is to announce the release by creating a new topic in the announcements category of the forum.

## Preparing next version

The `pom.xml` must be updated with the `-SNAPSHOT`flag for the next release number on the develop branch.
On a system with Unix utilities, you can do it with the single following line:

    git checkout develop
    git merge --no-ff release-X.Y
    for pom in pom.xml hipparchus-*/pom.xml ; do sed -i 's,<version>X.Y</version>,<version>X.Z-SNAPSHOT</version>,' $pom ; done

Commit the change:

    git add pom.xml hipparchus-*/pom.xml
    git commit -m "Preparing development of next version."
    git push
