Skip to content

Latest commit

 

History

History
370 lines (259 loc) · 20.4 KB

RELEASING.md

File metadata and controls

370 lines (259 loc) · 20.4 KB

THIS IS WORK IN PROGRESS

General: Releasing repositories by tag

As of 2022 all repository in the Play Framework GitHub organization are released by tag... This is released from the main branch from 2.9.0 forward. Unless an older version needs patching, then it must be released from the maintenance branch, for instance 2.8.x branch. If there is no maintenance branch for the release that needs patching, create it from the tag.

Cutting the release

Requires contributor access

  • Check the draft release notes to see if everything is there
  • Wait until the main build finished after merging the last PR
  • Update the draft release with the next tag version (eg. 2.9.0), title and release description
  • Check that GitHub Actions release build has executed successfully (GitHub will start a CI build for the new tag and publish artifacts to Sonatype)

Requires Sonatype access

Check Maven Central

Play Core Repository Release Procedure

Before the release

Issues and pull request triage

See if there are issues that need triage and are possibly related to the upcoming release. This is mainly important if you are doing a minor or major release.

Release tracking issue

Create a new release tracking issue.

Intro

When cutting a release of Play, you need to make the following decision:

  • Does this release of Play require releasing the modules that depend on it, e.g. play-grpc and play-slick. For a typical minor release, it would not. For a major release, and often for pre releases of major releases, the answer is yes.

Prerequisites

As of 2022 all repositories in the Play Framework organization are released by tag. That means the sonatype credentials are set up at the GitHub organization level. To release from older branches however you might still have to release from your machine, that's why you have to set up the sonatype credentials locally. See here how that is done (either by setting credentials +=... or using the env variable).

If something goes wrong

The release process pushes all artifacts to maven central and "promote" them automatically.

If the build fails during or after the promotion of maven central artifacts, there is no going back. Published artifacts are immutable, they find their way into CDNs, into caches on developer machines, and if there are two different versions of the same artifact out there, this can cause big problems. Your only option is to fix the problem, and attempt another release of the next version. Remember, version numbers are cheap.

If the build failed during or before the publishing of artifacts, but not after maven central promotion, you can drop the maven central staging repository. This can either be done through their corresponding web interfaces, or by using the sonatypeDrop sbt commands.

The most common failure is a request timeout. Typically, you can see in the logs that all artifacts have been uploaded and the build fails with a timeout while closing the repository or promoting it. If that's the case, the easiest solution is to close and promote by hand on Sonatype.

Before you release Play

Check when was the last time scala-steward ran on the repository and consider updating the dependencies yourself. Have a look in the .scala-steward.conf.

Take this with a grain of salt. It's good and nice to have a release with the latest dependencies, but dependency updates at the last minute can come with surprises.

Releasing Play

Step 0 - Release projects that Play depends on (play-json, play-ws, twirl)

Prepare the branch for each project:

  • Look for PRs that should be merged.
  • Look at status:needs-backport issues/PRs (including closed ones).
  • Look at issues/PRs tagged milestone version (including closed ones).
  • Update any dependencies that are needed.
  • Update any upstream projects (e.g make sure new play-ws is using new play-json)

May need to release these projects: play-json, play-ws, twirl

When ready:

  • If the project already has set up sbt-ci-release:
    • Make sure you are on the latest HEAD of the branch you want to release
    • Tag the version you want to release: git tag -s x.y.z
    • Push the tag to the upstream repo.
    • In the GitHub user interface, check "Publish" action, it will publish the release.
  • If you release from an older branch that has no sbt-ci-release set up yet:
    • Make sure you are using JDK8 to build and release!
    • Checkout the branch you want to release and check that the commit you want to release has a green build in CI
    • Tag the commit, eg: (git tag -s x.y.z). The projects are using sbt-dynver, so tagging first is important in order to get the right version number. The projects are NOT using tag prefixes (eg: v1.0.2), they use 1.0.2 instead. Watch-out, don't be mislid by twirl and play-ws. They do have tags prefixed by a v, but the dynver config is requiring the new tags to NOT have a prefix.
    • Run sbt release
    • At the end of the release, you must push the tag.
    • Check the correcponding release page in GitHub, adapt the release notes as needed and published it.

Step 1 - Release Play itself

Prepare the branch:

  • Look for PRs that should be merged.
  • Look at status:needs-backport issues/PRs (including closed ones). If you are releasing an older version of Play, look at the status:needs-backport-x.x label too.
  • Look at issues/PRs tagged milestone version (including closed ones).
  • Updated any dependencies that are needed (e.g. Dependencies.scala).
  • Do a local build or the appropriate snapshot and use the local-test.sh from play-samples for a final round of tests.

When ready:

  • If releasing 2.9 or newer:
    • Tag the version you want to release: git tag -s x.y.z
    • Push the tag to the upstream repo.
    • In the GitHub user interface, check "Publish" action, it will publish the release.
  • If releasing from 2.8.x:
    • Make sure you are using JDK8 to build and release.
    • Ccheckout the branch you want to release and check that the commit you want to release has a green build in CI
    • Tag the commit, eg: (git tag -s x.y.z). The projects are using sbt-dynver, so tagging first is important in order to get the right version number. Play is NOT using tag prefixes (eg: v1.0.2), it uses 1.0.2 instead and dynver is configured as such.
    • Run sbt -J-XX:ReservedCodeCacheSize=512m release
    • At the end of the release, you must push the tag.
  • Check the corresponding release page in GitHub, adapt the release notes as needed and published it.

Once Play is released, you need to wait 10 minutes or so for a Maven central sync before you can perform any of the remaining tasks.

Verification: You can check that the artifacts are available at Maven Central under play_<scalaversion>. You can see the staged artifacts here on OSS Sonatype. E.g. here is a search for Play 2.8.18 artifacts.

Warning: After pushing the a tag to GitHub, a GitHub actions workflow will be trigger.

Step 2 - Release external modules

This includes the modules:

  • play-slick
  • play-ebean
  • scalatestplus-play
  • play-grpc

Only release these if they need to be released, generally for minor Play releases, there's no reason to cut a new release of these, these libraries are free to have their own release cycle.

Note: since we update omnidoc and the Play templates and seeds people reading the docs or starting a new project will automatically see and use the latest minor versions of all modules, even if we don't patch all modules directly to update dependencies.

You may need to bump the Play version in the external module, do this, commit, and depending on how major the version bump is, push directly to the repo or go through a pull request. Once that is done, to release:

For play-slick and scalatestplus-play:

  • Make sure you are using JDK8 to build and release
  • Checkout the branch you want to release and check that the commit you want to release has a green build in CI
  • Tag the commit, eg: (git tag -s x.y.z). The projects are using sbt-dynver, so tagging first is important is important in order to get the right version number. The projects are NOT using tag prefixes (eg: v1.0.2), they use 1.0.2 instead.
  • Run sbt release
  • At the end of the release, you must push the tag.
  • Check the correcponding release page in GitHub, adapt the release notes as needed and published it.

TODO: all of the above should soon become obsolete. All that process should be run by the CI build.

Again, you will need to wait 10 minutes or so for a Maven central sync before you can perform any of the remaining tasks. In the meantime you can see the staged artifacts here on OSS Sonatype. E.g. here is a search for Play 2.8.18 artifacts: https://oss.sonatype.org/#nexus-search;gav~com.typesafe.play~~2.8.18~~

Verification: You can check that the artifacts are available at Maven Central under <library>_<scalaversion> or <sbt-plugin>_2.12_1.0:

Verification: when you run sbt new playframework/play-{scala,java}-seed.g8 it should pick up the new version on Maven. Try the templates out. You may need to update them if they don't work with the new version of Play.

Step 3 - omnidoc

Warning: This is a compulsory step and the version X.Y.Z of omnidoc released here must match the version X.Y.Z of Play released in step 1 above.

Omnidoc builds Play's documentation from all the current versions of Play and its modules. To understand what omnidoc really does under the covers, read the README. Note that once omnidoc completed, you will have the docs on the machine where you run the command and you still need to push them to play-generated-docs (next step).

In the omnidoc build file for the branch of Play that you are releasing:

  1. Update the Play version to the version of Play that you just released, and also
  2. Update any external modules to their latest version that is compatible with that version of Play.

Here's an example update to the omnidoc 2.8.x branch.

$ git diff
diff --git a/project/OmnidocBuild.scala b/project/OmnidocBuild.scala
-  val playVersion       = sys.props.getOrElse("play.version",       "2.8.0")
+  val playVersion       = sys.props.getOrElse("play.version",       "2.8.1")

Push this changes directly to GitHub (no need for a pull request).

To tag omnidoc:

  • For Play 2.9 we do not need to publish artifacts anymore:
    • Just create a tag by using git tag -s or the GitHub UI. Make sure you are on the correct branch (where you just set the correct versions described above)
    • After the tag was pushed, there will be NO GitHub actions ci workflow run anymore because we do not need to publish artifacts.
    • Now locally: Make sure you checked out the tag you just created, make sure the working directoy is clean, so sbt version display the version nice (without -SNAPSHOT etc.)
    • Run sbt +publishLocal
    • Continue with the play generated docs step below.
  • For Play 2.8.x you still have to release by hand and actually publish artifacts:
    • make sure you are using JDK8 to build and release
    • checkout the branch you want to release and check that the commit you want to release has a green build in CI
    • DO NOT create a tag. Omnidoc does not have a version.sbt file and also does not use sbt-dynver. It gets its version from Play.
    • run sbt release
    • at the end of the release, the commit will be tagged and you must push the tag.
    • Verification: check that the artifacts are available at Maven Central under play-omnidoc_<scalaversion>. It may take a few minutes. https://repo1.maven.org/maven2/com/typesafe/play/

Once that is done, you can update the docs on playframework.com, by running:

Checkout https://github.com/playframework/play-generated-docs and switch to the branch you are releasing.

In play-generated-docs checkout and after switching the branch, eg: 2.8.x, run the following:

rm -rf api/java
rm -rf api/scala
rm -rf manual
rm -rf confs

Followed by...

cp -r <path-to-omnidoc>/target/scala-2.13/omnidoc/javadoc api/java
cp -r <path-to-omnidoc>/target/scala-2.13/omnidoc/scaladoc api/scala
cp -r <path-to-omnidoc>/target/scala-2.13/omnidoc/playdoc/manual manual
cp -r <path-to-omnidoc>/target/scala-2.13/omnidoc/playdoc/confs confs

Where <path-to-omnidoc> is the path to the omnidoc repo in your machine that you just released.

In play-generated-docs

git add --all
git commit -m "Documentation for <tag>"
git push origin <branch>
git tag -sm "Version <tag>" <tag>
git push origin <tag>

Where <tag> is the version you are releasing, eg: 2.8.11 and branch is the branch you are updating eg: 2.8.x

Verification: check there is a new tag <tag> at https://github.com/playframework/play-generated-docs project. It should be on top of https://github.com/playframework/play-generated-docs/releases. The website should pick this tagged version of the generated docs up to 10 minutes later. You can check that then using the following URL pattern: https://www.playframework.com/documentation/<tag>/Home. For example https://www.playframework.com/documentation/2.7.2/Home.

Step 4 - Update play-samples

Update the Play version (and other released artifacts) in any of the play-example projects.

Verification: The sample repository builds can be seen at https://github.com/playframework/play-samples/actions/workflows/build-test.yml. Make sure the build is green and then merge the pull request. Only continue the release procedure if the samples pass the test! If they don't it's an indicator the relase might break existing applications!

Step 5 - Update playframework.com

These are the steps to update https://playframework.com website.

Update .version in play-generated-docs

If you are releasing a MAJOR version, review the contents of .version in play-generated-docs before updating the site.

Update playReleases.json and changelog.md

Update playReleases.json and changelog.md in playframework.com website git repository.

Note that the changelog should be updated describing all milestone/release candidates for the same release collectively. In addition the playReleases.json should be updated with the development releases in place i.e. you don't need to publish information on both an M1 and an M2 release. If the release is for the latest stable or development version, upgrade the website itself to use that version.

Deploy the website changes

Commit and push your changes.

NOTE: you will need a distinct SSH public key for this. Talk to Matthias or someone from the steering committee if you don't have access.

To set up your public key:

  1. Ask someone else from Play team to give you access the Play secrets.
  2. Download the PEM file and log into the machine:
ssh -i PlayProd2015.pem [email protected]
  1. cd playframework.com
  2. git pull
  3. sbt stage
  4. Restart the linux service: sudo systemctl restart playframework.service

Verification: Check that https://www.playframework.com/changelog contains the new release and also if the previous release moved to https://www.playframework.com/releases.

Step 6 - Announce

  1. If the release contains security fixes post an update on https://groups.google.com/g/play-framework-security
  2. Publish the release on https://github.com/playframework/playframework/releases. There should be a release draft already.
    • Make sure to check [x] Create a discussion for this release before publishing the release!
  3. Tweet about the new release: https://twitter.com/playframework/
  4. Post in the LinkedIn group: https://www.linkedin.com/groups/3818467/
  5. Post an (email) update on the Play Open Collective page: https://opencollective.com/playframework#category-CONNECT
  6. Post an (email) update in the GitHub Sponsors Dashboard https://github.com/sponsors/playframework/dashboard/updates (private link)
  7. Post on Scala Reddit https://www.reddit.com/r/scala/

Tip: This shouldn't be necessary anymore because release drafter already adds all the author itself to the release notes, which will the display nicely at the bottom of a release. In case you want to list all the authors that contributed to a release you can use:

git fetch --tags && git shortlog -s 2.8.0..2.8.1 | cut -c8- | sort

Verification:

Step 7 - Post release tasks

  1. Close the milestone for the release you just made
  2. Create a new milestone for the next release
  3. Move issues and pull requests from the old milestone to the new one if necessary

sbt-web plugins release procedure

Prerequisites

Github

You'll need the write access to the sbt-web plugin's Github repo. The easiest way to do this is to be added to the sbt-web team: https://github.com/orgs/sbt/teams/sbt-web. You can then see all the repos you can publish to (with the playframework sonatype user): https://github.com/orgs/sbt/teams/sbt-web/repositories

In addtion the playframework sonatype user can also publish releases for https://github.com/sbt/sbt-eclipse. You have to join the sbteclipse team for that: https://github.com/orgs/sbt/teams/sbteclipse

PGP key

  1. You'll need to set up a PGP key so that sbt release can sign the artifacts. Signing is done with sbt-pgp. Read the docs there if you need more info.

Process

  1. Run sbt release
  2. Answer all prompts with defaults - you'll need to provide your PGP passphrase too
  3. After publish has finished update the project's README.md to show the latest version. You can do this with Github's online editor and push it.