---
title: Manage Releases
eleventyNavigation:
    key: manage releases
    parent: maintain eslint
    title: Manage Releases
    order: 4
---

Releases are when a project formally publishes a new version so the community can use it. There are two types of releases:

- Regular releases that follow [semantic versioning](https://semver.org/) and are considered production-ready.
- Prereleases that are not considered production-ready and are intended to give the community a preview of upcoming changes.

## Release Manager

One member of the Technical Steering Committee (TSC) is assigned to manage each scheduled release. The release manager is determined at the TSC meeting the day before the release.

The release manager is responsible for:

1. The scheduled release on Friday.
1. Monitoring issues over the weekend.
1. Determining if a patch release is necessary on Monday.
1. Publishing the patch release (if necessary).

The release manager should seek input from the whole team on the Monday following a release to double-check if a patch release is necessary.

The release manager needs to have access to ESLint's two-factor authentication for npm in order to do a release.

## Release Communication

Each scheduled release is associated with an autogenerated release issue ([example](https://github.com/eslint/eslint/issues/18151)). The release issue is the source of information for the team about the status of a release and contains a checklist that the release manager should follow.

## Process

On the day of a scheduled release, the release manager should follow the steps in the release issue.

All release-related communications occur in a thread in the `#team` channel on Discord.

On the Monday following the scheduled release, the release manager needs to determine if a patch release is necessary. A patch release is considered necessary if any of the following occurred since the scheduled release:

- A regression bug is causing people's lint builds to fail when it previously passed.
- Any bug that is causing a lot of problems for users (frequently happens due to new functionality).

The patch release decision should be made as early on Monday as possible. If a patch release is necessary, then follow the same steps as the scheduled release process.

In rare cases, a second patch release might be necessary if the release is known to have a severe regression that hasn't been fixed by Monday. If this occurs, the release manager should announce the situation on the release issue, and leave the issue open until all patch releases are complete. However, it's usually better to fix bugs for the next release cycle rather than doing a second patch release.

After the patch release has been published (or no patch release is necessary), close the release issue and inform the team that they can start merging in semver-minor changes again.

### Release Parameters

The following tables show examples of the option to select as `RELEASE_TYPE` when starting `eslint-js Release` (the `@eslint/js` package release) and `eslint Release` (the `eslint` package release) jobs on Jenkins to release a new version with the latest features. In both jobs, `main` should be selected as `RELEASE_BRANCH`.

| **HEAD Version** | **Desired Next Version** | **`eslint-js Release`<br>`RELEASE_TYPE`** |
| :--------------: | :----------------------: | :---------------------------------------: |
|     `9.25.0`     |         `9.25.1`         |                  `patch`                  |
|     `9.25.0`     |         `9.26.0`         |                  `minor`                  |
|     `9.25.0`     |     `10.0.0-alpha.0`     |                 `alpha.0`                 |
| `10.0.0-alpha.0` |     `10.0.0-alpha.1`     |                  `alpha`                  |
| `10.0.0-alpha.1` |     `10.0.0-beta.0`      |                  `beta`                   |
| `10.0.0-beta.0`  |     `10.0.0-beta.1`      |                  `beta`                   |
| `10.0.0-beta.1`  |      `10.0.0-rc.0`       |                   `rc`                    |
|  `10.0.0-rc.0`   |      `10.0.0-rc.1`       |                   `rc`                    |
|  `10.0.0-rc.1`   |         `10.0.0`         |                  `major`                  |

| **HEAD Version** | **Desired Next Version** | **`eslint Release`<br>`RELEASE_TYPE`** |
| :--------------: | :----------------------: | :------------------------------------: |
|     `9.25.0`     |   `9.25.1` or `9.26.0`   |                `latest`                |
|     `9.25.0`     |     `10.0.0-alpha.0`     |                `alpha`                 |
| `10.0.0-alpha.0` |     `10.0.0-alpha.1`     |                `alpha`                 |
| `10.0.0-alpha.1` |     `10.0.0-beta.0`      |                 `beta`                 |
| `10.0.0-beta.0`  |     `10.0.0-beta.1`      |                 `beta`                 |
| `10.0.0-beta.1`  |      `10.0.0-rc.0`       |                  `rc`                  |
|  `10.0.0-rc.0`   |      `10.0.0-rc.1`       |                  `rc`                  |
|  `10.0.0-rc.1`   |         `10.0.0`         |                `latest`                |

When releasing a new version of the previous major line, the option to select as `RELEASE_TYPE` depends on whether the HEAD version is a prerelease or not. In both jobs, the corresponding development branch (for example, `v9.x-dev`) should be selected as `RELEASE_BRANCH`.

| **HEAD Version** | **Previous Major Line Version** | **Desired Next Version** | **`eslint-js Release`<br>`RELEASE_TYPE`** |
| :--------------: | :-----------------------------: | :----------------------: | :---------------------------------------: |
| `10.0.0-alpha.0` |            `9.25.0`             |         `9.25.1`         |                  `patch`                  |
| `10.0.0-alpha.0` |            `9.25.0`             |         `9.26.0`         |                  `minor`                  |
|     `10.0.0`     |            `9.25.0`             |         `9.25.1`         |            `maintenance.patch`            |
|     `10.0.0`     |            `9.25.0`             |         `9.26.0`         |            `maintenance.minor`            |

| **HEAD Version** | **Previous Major Line Version** | **Desired Next Version** | **`eslint Release`<br>`RELEASE_TYPE`** |
| :--------------: | :-----------------------------: | :----------------------: | :------------------------------------: |
| `10.0.0-alpha.0` |            `9.25.0`             |   `9.25.1` or `9.26.0`   |                `latest`                |
|     `10.0.0`     |            `9.25.0`             |   `9.25.1` or `9.26.0`   |             `maintenance`              |

## Emergency Releases

An emergency release is unplanned and isn't the regularly scheduled release or the anticipated patch release.

In general, we try not to do emergency releases. Even if there is a regression, it's best to wait until Monday to see if any other problems arise so a patch release can fix as many issues as possible.

The only real exception is if ESLint is completely unusable by most of the current users. For instance, we once pushed a release that errored for everyone because it was missing some core files. In that case, an emergency release is appropriate.

## Troubleshooting

### `npm publish` returns a 404

This typically happens due to a permission error related to the npm token.

- `release-please` uses a granular access token that expires after a year. This token is tied to the `eslintbot` npm account and needs to be regenerated every year in March. If the access token is expired, `npm publish` returns a 404.
- Jenkins uses a classic access token without an expiration date, but it does require a 2FA code to publish. If the 2FA code is incorrect, then `npm publish` returns a 404.