Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 48 additions & 15 deletions Makefile.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ const OPEN_SOURCE_LICENSES = [
/Public Domain/u, /LGPL/u, /Python/u, /BlueOak/u
];

const MAIN_GIT_BRANCH = "main";

//------------------------------------------------------------------------------
// Data
//------------------------------------------------------------------------------
Expand All @@ -74,6 +76,8 @@ const NODE = "node ", // intentional extra space
TEST_FILES = "\"tests/{bin,conf,lib,tools}/**/*.js\"",
PERF_ESLINTRC = path.join(PERF_TMP_DIR, "eslint.config.js"),
PERF_MULTIFILES_TARGET_DIR = path.join(PERF_TMP_DIR, "eslint"),
CHANGELOG_FILE = "./CHANGELOG.md",
VERSIONS_FILE = "./docs/src/_data/versions.json",

/*
* glob arguments with Windows separator `\` don't work:
Expand All @@ -97,6 +101,14 @@ function execSilent(cmd) {
return exec(cmd, { silent: true }).stdout;
}

/**
* Gets name of the currently checked out Git branch.
* @returns {string} Name of the currently checked out Git branch.
*/
function getCurrentGitBranch() {
return execSilent("git branch --show-current").trim();
}

/**
* Generates a release blog post for eslint.org
* @param {Object} releaseInfo The release metadata.
Expand Down Expand Up @@ -313,14 +325,18 @@ function updateVersions(oldVersion, newVersion) {
/**
* Updates the changelog, bumps the version number in package.json, creates a local git commit and tag,
* and generates the site in an adjacent `website` folder.
* @param {string} [prereleaseId] The prerelease identifier (alpha, beta, etc.). If `undefined`, this is
* @param {Object} options Release options.
* @param {string} [options.prereleaseId] The prerelease identifier (alpha, beta, etc.). If `undefined`, this is
* a regular release.
* @param {string} options.packageTag Tag that should be added to the package submitted to the npm registry.
* @returns {void}
*/
function generateRelease(prereleaseId) {
function generateRelease({ prereleaseId, packageTag }) {
echo(`Current Git branch: ${getCurrentGitBranch()}`);

const oldVersion = require("./package.json").version;

ReleaseOps.generateRelease(prereleaseId);
ReleaseOps.generateRelease(prereleaseId, packageTag);
const releaseInfo = JSON.parse(cat(".eslint-release-info.json"));

echo("Generating site");
Expand All @@ -335,7 +351,9 @@ function generateRelease(prereleaseId) {
docsPackage.version = releaseInfo.version;
fs.writeFileSync(docsPackagePath, `${JSON.stringify(docsPackage, null, 4)}\n`);

updateVersions(oldVersion, releaseInfo.version);
if (getCurrentGitBranch() === MAIN_GIT_BRANCH) {
updateVersions(oldVersion, releaseInfo.version);
}

echo("Updating commit with docs data");
exec("git add docs/ && git commit --amend --no-edit");
Expand All @@ -351,17 +369,32 @@ function publishRelease() {
ReleaseOps.publishRelease();
const releaseInfo = JSON.parse(cat(".eslint-release-info.json"));

/*
* for a pre-release, push to the "next" branch to trigger docs deploy
* for a release, push to the "latest" branch to trigger docs deploy
*/
if (isPreRelease(releaseInfo.version)) {
exec("git push origin HEAD:next -f");
} else {
exec("git push origin HEAD:latest -f");
}
const docsSiteBranch = releaseInfo.packageTag === "maintenance"
? `v${semver.major(releaseInfo.version)}.x`
: releaseInfo.packageTag; // "latest" or "next"

echo(`Updating docs site branch: ${docsSiteBranch}`);
exec(`git push origin HEAD:${docsSiteBranch} -f`);

publishSite();

// Update changelog and list of versions on the main branch
if (getCurrentGitBranch() !== MAIN_GIT_BRANCH) {
echo(`Updating changelog and versions on branch: ${MAIN_GIT_BRANCH}`);

exec(`git checkout ${MAIN_GIT_BRANCH} --force`);

fs.writeFileSync(CHANGELOG_FILE, `${releaseInfo.markdownChangelog}${cat(CHANGELOG_FILE)}`);

const versions = JSON.parse(cat(VERSIONS_FILE));

versions.items.find(({ branch }) => branch === docsSiteBranch).version = releaseInfo.version;
fs.writeFileSync(VERSIONS_FILE, `${JSON.stringify(versions, null, 4)}\n`);

exec(`git add ${CHANGELOG_FILE} ${VERSIONS_FILE}`);
exec(`git commit -m "chore: updates for v${releaseInfo.version} release"`);
exec("git push origin HEAD");
}
}

/**
Expand Down Expand Up @@ -1022,6 +1055,6 @@ target.perf = function() {
});
};

target.generateRelease = () => generateRelease();
target.generatePrerelease = ([prereleaseType]) => generateRelease(prereleaseType);
target.generateRelease = ([packageTag]) => generateRelease({ packageTag });
target.generatePrerelease = ([prereleaseId]) => generateRelease({ prereleaseId, packageTag: "next" });
target.publishRelease = publishRelease;
41 changes: 41 additions & 0 deletions docs/src/maintain/manage-releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,47 @@ In rare cases, a second patch release might be necessary if the release is known

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.
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
"lint:fix:docs:js": "trunk check -y --ignore=** --ignore=!docs/**/*.js -a --flter=eslint && trunk check -y --ignore=** --ignore=!docs/**/*.js",
"release:generate:alpha": "node Makefile.js generatePrerelease -- alpha",
"release:generate:beta": "node Makefile.js generatePrerelease -- beta",
"release:generate:latest": "node Makefile.js generateRelease",
"release:generate:latest": "node Makefile.js generateRelease -- latest",
"release:generate:maintenance": "node Makefile.js generateRelease -- maintenance",
"release:generate:rc": "node Makefile.js generatePrerelease -- rc",
"release:publish": "node Makefile.js publishRelease",
"test": "node Makefile.js test",
Expand Down Expand Up @@ -136,7 +137,7 @@
"eslint-config-eslint": "file:packages/eslint-config-eslint",
"eslint-plugin-eslint-plugin": "^6.0.0",
"eslint-plugin-yml": "^1.14.0",
"eslint-release": "^3.2.2",
"eslint-release": "^3.3.0",
"eslint-rule-composer": "^0.3.0",
"eslump": "^3.0.0",
"esprima": "^4.0.1",
Expand Down
Loading