# Release Process

This document outlines the release process for NGINX Gateway Fabric (NGF).

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
## Table of Contents

- [Versioning](#versioning)
- [Release Planning and Development](#release-planning-and-development)
- [Releasing](#releasing)
  - [Major or Minor Release](#major-or-minor-release)
  - [Patch Release](#patch-release)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Versioning

NGF uses semantic versioning for its releases. For more information, see https://semver.org.

> Major version zero `(0.Y.Z)` is reserved for development, anything MAY change at any time. The public API is not stable.

## Release Planning and Development

The features that will go into the next release are reflected in the
corresponding [milestone](https://github.com/nginx/nginx-gateway-fabric/milestones). Refer to
the [Issue Lifecycle](/ISSUE_LIFECYCLE.md) document for information on issue creation and assignment to releases.

## Releasing

Note: in the instructions below, `X` stands for the major version, `Y` -- minor, `Z` -- patch.

### Major or Minor Release

A Major or minor introduces new features.

To create a new release, follow these steps:

1. Create an issue to define and track release-related activities. Choose a title that follows the
   format `Release X.Y.Z`.
2. Stop merging any new work into the main branch.
3. Create a release branch following the `release-X.Y` naming convention.
4. Once the release branch pipeline completes, run tests using the `release-X.X-rc` images that are pushed to Github (for example, `release-1.3-rc`).
   1. Kick off the [longevity tests](https://github.com/nginx/nginx-gateway-fabric/blob/main/tests/README.md#longevity-testing) for both OSS and Plus. You'll need to create two clusters and VMs for this. Before running, update your `vars.env` file with the proper image tag and prefixes. NGF and nginx images will be available from `ghcr.io`, and nginx plus will be available in GCP (`us-docker.pkg.dev/<GCP_PROJECT_ID>/nginx-gateway-fabric/nginx-plus`). These tests need to run for 4 days before releasing. The results should be committed to the main branch and then cherry-picked to the release branch.
   2. Kick off the [NFR workflow](https://github.com/nginx/nginx-gateway-fabric/actions/workflows/nfr.yml) in the browser. For `image_tag`, use `release-X.X-rc`, and for `version`, use the upcoming `X.Y.Z` NGF version. Run the workflow on the new release branch. This will run all of the NFR tests which are automated and open a PR with the results files when it is complete. Review this PR and make any necessary changes before merging. Once merged, be sure to cherry-pick the commit to the main branch as well (the original PR targets the release branch).
5. Run the [Release PR](https://github.com/nginx/nginx-gateway-fabric/actions/workflows/release-pr.yml) workflow to update the repo files for the release. Then there are a few manual steps to complete:
   1. Update the [README](/README.md) to include information about the release.
   2. Update the [changelog](/CHANGELOG.md). There is going to be a new blank section generated by the automation that needs to be adjusted accordingly.
      - At the top there will be a list of all PRs that are labeled with `release-notes`.
      The changelog includes only important (from the user perspective)
      changes to NGF. This is in contrast with the autogenerated full changelog, which is created in the next
      step. As a starting point, copy the important features, bug fixes, and dependencies from the autogenerated
      draft of the full changelog. This draft can be found under
      the [GitHub releases](https://github.com/nginx/nginx-gateway-fabric/releases) after the release branch is
      created. If included, use the Release Notes specified in a PR.
      - If the supported Gateway API minor version has changed since the last release, add a note to the release notes explaining if the previous version is no longer supported.
      - Merge the release PR once it has received all necessary approvals.
6. Ensure you are on the latest version of the release branch and are up-to-date on all commits, then create and push the release tag in the format `vX.Y.Z`.

   ```shell
   git tag vX.Y.Z
   git push upstream vX.Y.Z
   ```

   As a result, the CI/CD pipeline will:
   - Build NGF, NGINX and NGINX Plus container images with the release tag `X.Y.Z` and push them to the registries.
   - Package and publish the Helm chart to the registry.
   - Create a GitHub release with an autogenerated changelog and attached release artifacts.
7. Prepare and merge a PR into the main branch to update with similar information that you did in the release branch docs PR. Specifically:
    1. [README](/README.md) to include the information about the latest release.
    2. [changelog](/CHANGELOG.md).
    3. Helm chart `version` field.
    4. `GW_API_PREV_VERSION` in tests Makefile, if necessary.
    5. Any references in the docs to the previous release.
    6. Any installation instructions to ensure that the supported Gateway API and NGF versions are correct. Specifically, helm README.
8. Prepare and merge a PR into the main branch of the [documentation repository](https://github.com/nginx/documentation) from the relevant release branch, such as `ngf-release-2.0`.
   - In the NGF repo, run `make generate-api-docs` and copy the generated file from `docs/api/content.md` into the documentation repo to `content/ngf/reference/api.md`.
   - Update the HTML file located at `layouts/shortcodes/version-ngf.html` with the latest version. Ensure you do not add an empty line to the file.
   - Documentation is built and deployed automatically from `main`, and will trigger when merging to it.
   - Create a new branch for the next release version, in the format `ngf-release-<i>.<i>`, substituting the *i* placeholders for major and minor version numbers.
9. Close the issue created in Step 1.
10. Ensure that the [associated milestone](https://github.com/nginx/nginx-gateway-fabric/milestones) is closed.
11. Verify that published artifacts in the release can be installed properly.
12. Submit the `conformance-profile.yaml` artifact from the release to the [Gateway API repo](https://github.com/kubernetes-sigs/gateway-api/tree/main/conformance/reports).
    - Create a fork of the repository
    - Name the file based on the requirements of the [README](https://github.com/kubernetes-sigs/gateway-api/blob/main/conformance/reports/README.md). Update the README in the ngf directory and update the site source if necessary (see following example).
    - Open a PR. [Example](https://github.com/kubernetes-sigs/gateway-api/pull/3149)
      If it's your first time submitting a PR, you will need to sign a CLA using F5, Inc. as the organization.

### Patch Release

A patch release is for an important fix that cannot wait the next major/minor release.

To create a new release, follow these steps:

1. Create an issue to define and track release-related activities. Choose a title that follows the
   format `Release X.Y.Z`.
2. If the fix applies to both the latest release and the main branch, then:
   1. Prepare and merge a fix PR into the in the main branch.
   2. Prepare and merge a fix PR (with a cherry-pick commit) into the existing release branch.
3. Alternatively, if the fix only applies to the latest release, prepare and merge a fix PR into the existing release
   branch.
4. Test the release branch for release-readiness.
5. If a problem is found, return to Step 2.
6. Follow Steps 5-7 from the [Major or Minor Release](#major-or-minor-release) section.
7. Prepare and merge a PR into the main branch of the [documentation repository](https://github.com/nginx/documentation) to update the NGF version in `layouts/shortcodes/version-ngf.html`. If any of our APIs have changed, in the NGF repo, run `make generate-api-docs` and copy the generated file from `docs/api/content.md` into the documentation repo to `content/ngf/reference/api.md`.
