Releasing PLC4X
TL/DR
Please be sure to execute the release with a Java version 11 or the Karaf feature tests will not run. |
-
Update the
RELEASE_NOTES
-
Check year in
NOTICE
-
Create release branch:
mvn release:branch -P with-c,with-dotnet,with-go,with-java,with-python,enable-all-checks -DbranchName=rel/{current-short-version}
-
Add a new section to the
RELEASE_NOTES
ondevelop
-
Prepare the release:
mvn release:prepare -P with-c,with-dotnet,with-go,with-java,with-python,enable-all-checks
-
Perform the release:
mvn clean release:perform
-
Close the staging repo on
Nexus
-
Stage the release artifacts in
SVN
-
Vote on the mailing list
-
Move RC to the release section of
SVN
-
Remove old releases in
SVN
-
Release staging repo on
Nexus
-
Add the version to the DOAP file on
develop
-
Update Download site
-
Update GitHub Issues
-
Merge back release version to
release
branch -
Send announce email
Preparing your system for being able to release
Be sure you are using a JDK and not a JRE, or the release will fail because the release can’t execute the javadoc executable.
|
As part of the release process, Maven will upload maven release artifacts to a so-called staging repository.
This can be thought of as an ad-hoc Maven repository that contains only the artifacts for one release. This helps reviewers to see what’s in the convenience maven package and to release that to the public repos with one click.
In order to be allowed to upload artifacts, your account has to be enabled for this, and you have to tell Maven about your credentials.
In order to do this, you should provide these credentials via .m2/settings.xml
.
So if you don’t already have one, you should create a .m2
directory in your user home and inside that create a settings.xml
file with at least this content:
<?xml version="1.0" encoding="UTF-8"?> <settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <servers> <!-- Apache Repo Settings --> <server> <id>apache.snapshots.https</id> <username>{user-id}</username> <password>{user-pass}</password> </server> <server> <id>apache.releases.https</id> <username>{user-id}</username> <password>{user-pass}</password> </server> </servers> </settings>
This tells maven to use above credentials as soon as a repository with the id apache.snapshots.https
or apache.releases.https
is being used.
For a release all you need is the releases
repo, but it is good to have the other in place as it enables you to also deploy SNAPSHOTs from your system.
There repos are defined in the apache
parent pom and is identical for all Apache projects.
Additionally, all artifacts are automatically signed by the release build. In order to be able to do this you need to set up GPG.
The key being used to sign the artifacts will have to be linked to your Apache E-Mail ({apache-id}@apache.org) and verified by at least one fellow Apache committer (Ideally more) that have trusted keys themselves.
Usually for this you have to get in touch - in real life - with any Apache committer with a trusted key.
Attending an ApacheCon
is usually a great way to do this as usually every ApacheCon has a Key Signing event
in its schedule.
He can then sign your key and hereby enable you to sign Apache release artifacts.
There’s a detailed description here.
However, in contrast to that documentation, upload your key to the following servers: pool.sks-keyservers.net and keyserver.ubuntu.com as these are the ones Nexus is checking.
|
If you happen to have multiple keys, adding the following profile to your settings.xml
should help:
<profile> <id>apache-release</id> <properties> <gpg.keyname>5C60D6B9</gpg.keyname><!-- Your GPG Keyname here --> <!-- Use an agent: Prevents being asked for the password during the build --> <gpg.useagent>true</gpg.useagent> <gpg.passphrase>topsecret-password</gpg.passphrase> </properties> </profile>
Currently, there is a Java-Version sweet-spot for being able to release all modules and that is Java 11.
So be sure to set Java 11
as the java version used to do the release.
Also, at least Maven 3.6
is required for CMake.
Ideally use the Maven-Wrapper to ensure the Maven version fits the build.
On some systems (mainly Mac) gpg signing can result in errors like:
In this case adding the following helps: export GPG_TTY=$(tty)
|
Preparing the codebase for a release
Usually you will have to update the RELEASE_NOTES document to the new version.
I would suggest doing this prior to the branch as otherwise you will definitely have to port it back to develop
.
So remove the SNAPSHOT
and (Unreleased)
markers from the file and add missing parts.
Also, if you are doing the first release in a new year, it is advisable to search for the old year and check if any occurrences are ok the way they are.
Usually the NOTICE
file has to be adjusted.
Creating a release branch
According to SemVer, we have: Major, Minor and Bugfix releases.
For each new Major and Minor release we create a new branch at the beginning of a code-freeze phase.
So if currently the project version in develop is 0.13.0-SNAPSHOT
, we create a branch rel/{current-short-version}
.
When creating the branch is exactly the moment in which the version in develop
is incremented to the next minor version.
This can and should be automated by the maven-release-plugin
.
Per default the plugin will ask for the working copy version during the build execution.
This is the version the develop
branch will be changed to.
In contrast to normal builds, it is important to enable all profiles when creating the branch as only this way will all modules versions be updated. Otherwise, the non-default modules on develop will reference the old version which will cause problems when building.
mvn release:branch -P with-c,with-dotnet,with-go,with-java,with-python,enable-all-checks -DbranchName=rel/{minor-version}
Per default the plugin suggests the next bugfix version as working version, however we want it to use the next minor version.
So in case of preparing the release branch for 0.13.0-SNAPSHOT
the command would be the following:
mvn release:branch -P with-c,with-dotnet,with-go,with-java,with-python,enable-all-checks -DbranchName=rel/{current-short-version}
The plugin will then aks for the version:
What is the new working copy version for "PLC4X"? (org.apache.plc4x:plc4x-parent) {current-next-incremental-version}-SNAPSHOT: : {current-next-minor-version}-SNAPSHOT
Here the suggested default has to be manually overridden.
This step now should perform quite quickly as no build and no tests are involved.
However, in the end the versions of the develop
branch are updated and a new rel/{current-short-version}
branch is created.
Preparing develop
for the next iteration
Now is a good time to add a new section to the RELEASE_NOTES
document for the new SNAPSHOT
version.
Here comes a template:
============================================================== (Unreleased) Apache PLC4X {current-next-minor-version}-SNAPSHOT ============================================================== New Features ------------ Incompatible changes -------------------- Bug Fixes --------- // Rest of the file
Also be sure to do a quick full-text-search to check if the version was updated correctly everywhere.
If you find anything here, you will need to pay attention during the release. |
Release stabilization phase
Now usually comes a phase in which last tests and checks should be performed.
If any problems are found, they have to be fixed in the release branch.
Changes should either be re applied in develop
or cherry-picked
, however merging things back can cause a lot of problems, and we no longer have the same versions.
Preparing a release
Same as with creating the branch it is important to enable all profiles when creating the branch as only this way will all modules versions be updated. Otherwise, the non-default modules on develop will reference the old version which will cause problems when building. For people building with some additional profiles from the source release will be impossible.
As especially when switching a lot between different branches, it is recommended to do a clean checkout of the repository. Otherwise, a lot of directories can be left over, which would be included in the source-release zip. In order to prepare a release-candidate, the first step is switching to the corresponding release-branch.
After that, the following command will to all preparation steps for the release:
mvn release:prepare -P with-c,with-dotnet,with-go,with-java,with-python,enable-all-checks
(The -P with-c,with-dotnet,with-go,with-java,with-python,enable-all-checks
tells maven to activate the all profiles that partition the build and makes sure the versions of all modules are updated as part of the release)
In general the plugin will now ask you 3 questions:
-
The version we want to release as (It will suggest the version you get by omitting the
-SNAPSHOT
suffix) -
The name of the tag the release commit will be tagged with in the SCM (Name it
v{release-version}
(v0.13.0
in our case) -
The next development version (The version present in the pom after the release) (
{current-next-bugfix-version}
in our case)
Usually for 1 and 3 the defaults are just fine, make sure the tag name is correct as this usually is different.
What the plugin now does, is automatically execute the following operations:
-
Check we aren’t referencing any
SNAPSHOT
dependencies. -
Update all pom versions to the release version.
-
Run a build with all tests
-
Commit the changes (commit message:
[maven-release-plugin] prepare release v0.13.0
) -
Push the commit
-
Tag the commit
-
Update all poms to the next development version.
-
Commit the changes (commit message:
[maven-release-plugin] prepare for next development iteration
) -
Push the commit
However, this just prepared the git repository for the release, we have to perform the release to produce and stage the release artifacts.
Please verify the git repository at: https://gitbox.apache.org/repos/asf?p=plc4x.git is in the correct state. Please select the release branch and verify the commit log looks similar to this
It is important that the commit with the message "[maven-release-plugin] prepare release v{release-version}" is tagged with the release tag (in this case v0.13.0)
If you check the commit itself, it should mainly consist of version updates like this:
The root pom has a few more changes, but in general this should be what you are seeing.
After that should come a second commit:
This now updates the versions again, but this time from the release version to the one we selected for the next development iteration (in this case 0.3.1-SNAPSHOT)
If the commit history doesn’t look like this, something went wrong. |
What if something goes wrong?
If something goes wrong, you can always execute:
mvn release:rollback -P with-c,with-dotnet,with-go,with-java,with-python,enable-all-checks
It will change the versions back and commit and push things.
Also, should you check if you have any uncommitted changes (as our code-generation can make git think they are "dirty")
However, it will not delete the tag in GIT (locally and remotely). So you have to do that manually or use a different tag next time.
Performing a release
This is done by executing another goal of the maven-release-plugin
:
mvn clean release:perform
The clean is only for making sure there is no artifacts in target directly, but only in target/checkout/target .
|
This executes automatically as all information it requires is located in the release.properties
file the prepare
-goal prepared.
The first step is that the perform
-goal checks out the previously tagged revision into the root modules target/checkout
directory.
Here it automatically executes a maven build (You don’t have to do this, it’s just that you know what’s happening):
mvn deploy -P apache-release
As the apache-release
profile is also activated, this builds and tests the project as well as creates the JavaDocs, Source packages and signs each of these with your PGP key.
We are intentionally not adding the other profiles, as these either produce binary artifacts that usually only work on the system they were compiled on (C++, .Net) or we haven’t found a good way to distribute them via Maven yet (Python).
As this time the build is building with release versions, Maven will automatically choose the release url for deploying artifacts.
The way things are set up in the apache parent pom, is that release artifacts are deployed to a so-called staging repository
.
You can think of a staging repository
as a dedicated repository created on the fly as soon as the first artifact comes in.
After the build you will have a nice and clean Maven repository at https://repository.apache.org/ that contains only artifacts from the current build.
After the build it is important to log in to Nexus
at https://repository.apache.org/, select Staging Repositories
and find the repository with the name: orgapacheplc4x-{somenumber}
.
Select that and click on the Close
button.
Now Nexus will do some checks on the artifacts and check the signatures.
As soon as it’s finished, we are done on the Maven side and ready to continue with the rest of the release process.
A release build also produces a so-called source-assembly
zip.
This contains all sources of the project and will be what’s actually the release from an Apache point of view and will be the thing we will be voting on.
This file will also be signed and SHA512
hashes will be created.
Staging a release
Each new release and release-candidate has to be staged in the Apache SVN under:
The directory structure of this directory is as follows:
./KEYS ./0.13.0/ ./0.13.0/rc1 ./0.13.0/rc1/README ./0.13.0/rc1/RELEASE_NOTES ./0.13.0/rc1/apache-plc4x-0.13.0-source-release.zip ./0.13.0/rc1/apache-plc4x-0.13.0-source-release.zip.asc ./0.13.0/rc1/apache-plc4x-0.13.0-source-release.zip.sha512
You can generally import the stuff, by preparing a directory structure like above locally and then using svn import
to do the importing:
cd ./{current-full-version} svn import rc1 https://dist.apache.org/repos/dist/dev/plc4x/{current-full-version}/rc1 -m"Staging of rc1 of PLC4X {current-full-version}"
The KEYS
file contains the PGP public key which belongs to the private key used to sign the release artifacts.
If this is your first release be sure to add your key to this file. For the format have a look at the file itself. It should contain all the information needed.
Be sure to stage exactly the README
and RELEASE_NOTES
files contained in the root of your project.
Ideally you just copy them there from there.
All three -source-relese.zip
artifacts should be located in the directory: target/checkout/target
After committing these files to SVN you are ready to start the vote.
Starting a vote on the mailing list
After staging the release candidate in the Apache SVN, it is time to actually call out the vote.
For this we usually send two emails. The following would be the one used to do our first TLP release:
E-Mail Topic: [VOTE] Apache PLC4X 0.13.0 RC1 Message: Apache PLC4X 0.13.0 has been staged under [2] and it’s time to vote on accepting it for release. All Maven artifacts are available under [1]. Voting will be open for 72hr. A minimum of 3 binding +1 votes and more binding +1 than binding -1 are required to pass. Release tag: v0.13.0 Hash for the release tag: {replacethiswiththerealgitcommittag} Per [3] "Before voting +1 PMC members are required to download the signed source code package, compile it as provided, and test the resulting executable on their own platform, along with also verifying that the package meets the requirements of the ASF policy on releases." You can achieve the above by following [4]. [ ] +1 accept (indicate what you validated - e.g. performed the non-RM items in [4]) [ ] -1 reject (explanation required) [1] https://repository.apache.org/content/repositories/orgapacheplc4x-{somefourdigitnumber} [2] https://dist.apache.org/repos/dist/dev/plc4x/0.13.0/rc1 [3] https://www.apache.org/dev/release.html#approving-a-release [4] https://cwiki.apache.org/confluence/display/PLC4X/Validating+a+staged+Release
As it is sometimes to do the vote counting, if voting and discussions are going on in the same thread, we send a second email:
E-Mail Topic: [DISCUSS] Apache PLC4X 0.13.0 RC1 Message: This is the discussion thread for the corresponding VOTE thread. Please keep discussions in this thread to simplify the counting of votes. If you have to vote -1 please mention a brief description on why and then take the details to this thread.
Now we have to wait 72 hours till we can announce the result of the vote.
This is an Apache policy to make it possible for anyone to participate in the vote, no matter where that person lives and not matter what weekends or public holidays might currently be.
The vote passes, if at least 3 +1
votes are received and more +1
are received than -1
.
After the 72-hour minimum wait period is over and we have fulfilled the requirement of at least 3 +1 votes and more +1 than -1, a final reply is sent to the vote thread with a prefix of [RESULT]
in the title in which the summary of the vote is presented in an aggregated form.
E-Mail Topic: [RESULT] [VOTE] Apache PLC4X 0.13.0 RC1 Message: So, the vote passes with {number of +1 votes} +1 votes by PMC members {number of +1 votes from non-pmc members} +1 vote by a non PMC member.
Releasing after a successful vote
As soon as the votes are finished, and the results were in favor of a release, the staged artifacts can be released. This is done by moving them inside the Apache SVN.
svn move -m "Release Apache PLC4X 0.13.0" \ https://dist.apache.org/repos/dist/dev/plc4x/0.13.0/rc1 \ https://dist.apache.org/repos/dist/release/plc4x/0.13.0
This will make the release artifacts available and will trigger them being copied to mirror sites.
This is also the reason why you should wait at least 24 hours before sending out the release notification emails.
Going back for a new release candidate
If however for some reason it is needed to prepare a new RC for the release. Please follow these steps:
-
Set the versions of the release branch to the previous version by using the
versions:set
plugin:mvn versions:set -DprocessAllModules=true -P with-c,with-dotnet,with-go,with-java,with-python,enable-all-checks
-
Delete the tag locally:
git tag -d v{current-full-version}
-
Delete the tag remotely:
git push --delete origin v{current-full-version}
-
Commit all changes
-
Drop the staging repo at https://repository.apache.org
-
Delete the previous RC in SVN
svn rm https://dist.apache.org/repos/dist/dev/plc4x/0.9.0/rc1 -m"Removed rc1 of PLC4x 0.9.0"
-
Reply to the
VOTE
and theDISCUSS
announcing the vote has been cancelled and explain why and that you’re going to start a new RC soon. Ideally prefix the title of the Emails with[CANCELLED]
After this you should be ready to start a new RC.
Cleaning up older release versions
As a lot of mirrors are serving our releases, it is the Apache policy to clean old releases from the repo if newer versions are released.
This can be done like this:
svn delete https://dist.apache.org/repos/dist/release/plc4x/{current-full-version}/ -m"deleted version {current-full-version}"
After this https://dist.apache.org/repos/dist/release/plc4x should only contain the latest release directory.
Releasing the Maven artifacts
Probably the simplest part is releasing the Maven artifacts.
In order to do this, the release manager logs into Nexus at https://repository.apache.org/, selects the staging repository and clicks on the Release
button.
This will move all artifacts into the Apache release repository and delete the staging repository after that.
All release artifacts released to the Apache release repo, will automatically be synced to Maven central.
Add the version to the DOAP file
Now that the release is out, in the develop
branch, update the DOAP
file for plc4x.
This is found at:
src/site/resources-filtered/plc4x-doap.rdf
Please add the just released version to the top of the versions.
This file is needed for Apache’s tooling to automatically keep track of project release activity, and we use this internally too to automatically update the documentation to always reference the latest released version automatically.
Merge back release version to release
branch
The release
branch should always point to the last released version.
This has to be done with git
git checkout release git merge v0.13.0
When there are conflicts it could help to use the theirs
merge strategy, i.e.,
git merge -X theirs v0.13.0
Possibly a manual conflict resolution has to be done afterwards. After that, changes need to be pushed.
Updating GitHub Issues
-
Set the released version to "released" and set the "release-date"
-
Add the next version to the versions.
Update the download site
The URL http://plc4x.apache.org/users/download.html has to be changed, and the current release has to be listed there.
This is done by changing the download.adoc
under src/site/users/
(in the develop branch, as this is where the site is generated from!)
-
Copy the last release down to Previous Releases
-
Point the download links of the last release to archive, e.g.
http://archive.apache.org/dist/plc4x/0.13.0/apache-plc4x-0.13.0-source-release.zip
-
Add the new Release under Current Releases and change all links. Note: Please add an anchor for the toc
-
Update the sections for the changes according to the RELEASE_NOTES from the release Note: Transfer all to ascii-doc notation to ensure correct rendering of the site Also remove the JIRA TICKET ids in Front
Notifying the world
Make sure you have given the Apache mirrors time to fetch the release files by waiting at least 24 hours after moving the release candidate to the release part of the SVN.
After that it is time to announce your release to the world:
From: your apache email address To: announce@apache.org CC: dev@plc4x.apache.org E-Mail Topic: [ANNOUNCE] Apache PLC4X 0.13.0 released Message: The Apache PLC4X team is pleased to announce the release of Apache PLC4X 0.13.0 PLC4X is a set of libraries for communicating with industrial programmable logic controllers (PLCs) using a variety of protocols but with a shared API. The current release contains drivers able to communicate with industrial PLCs using one of the following protocols: * AB-ETH * Beckhoff ADS * CanOpen * EtherNet/IP / EIP * Firmata * KNXNet/IP * Modbus * OPC UA * Siemens S7 (0x32) Beyond that we also provide integration modules for the following Apache projects and frameworks: * Apache Calcite * Apache Camel * Apache Edgent (Incubating / Retired) * Apache Kafka (Kafka Connect) * Apache NiFi * Logstash It also provides an `OPC UA Server` which can act as a bridge between legacy systems and OPC UA. Visit the Apache PLC4X website [1] for general information or the downloads page [2] for release notes and download information. Regards, The Apache PLC4X team [1] http://plc4x.apache.org [2] http://plc4x.apache.org/users/download.html
It is important to note that you have to send this email from your apache email address, or it will be rejected. This wasn’t very simple for me to set up. A general description can be found here: https://reference.apache.org/committer/email Here’s what I did in Google Mail to allow sending of emails: https://gmail.googleblog.com/2009/07/send-mail-from-another-address-without.html Note … you will be able to select the alternate sending address if you click into the recipients line of a new email (Not very intuitive).
After that email is out the door, you’re done. Congrats!