Skip to content

Commit

Permalink
🔨 Move to changeset (#5241)
Browse files Browse the repository at this point in the history
**Description**

<!-- Please provide a short description and potentially linked issues
justifying the need for this PR -->

Move from the built-in release mechanisms provided within yarn berry to
the ones of changeset.

<!-- * Your PR is fixing a bug or regression? Check for existing issues
related to this bug and link them -->
<!-- * Your PR is adding a new feature? Make sure there is a related
issue or discussion attached to it -->

<!-- You can provide any additional context to help into understanding
what's this PR is attempting to solve: reproduction of a bug, code
snippets... -->

**Checklist** — _Don't delete this checklist and make sure you do the
following before opening the PR_

- [x] The name of my PR follows [gitmoji](https://gitmoji.dev/)
specification
- [x] My PR references one of several related issues (if any)
- [x] New features or breaking changes must come with an associated
Issue or Discussion
- [x] My PR does not add any new dependency without an associated Issue
or Discussion
- [x] My PR includes bumps details, please run `yarn bump` and flag the
impacts properly
- [x] My PR adds relevant tests and they would have failed without my PR
(when applicable)

<!-- More about contributing at
https://github.com/dubzzz/fast-check/blob/main/CONTRIBUTING.md -->

**Advanced**

<!-- How to fill the advanced section is detailed below! -->

- [x] Category: 🔨 New tool for PR
- [x] Impacts: New way to manage declaration of bumps

<!-- [Category] Please use one of the categories below, it will help us
into better understanding the urgency of the PR -->
<!-- * ✨ Introduce new features -->
<!-- * 📝 Add or update documentation -->
<!-- * ✅ Add or update tests -->
<!-- * 🐛 Fix a bug -->
<!-- * 🏷️ Add or update types -->
<!-- * ⚡️ Improve performance -->
<!-- * _Other(s):_ ... -->

<!-- [Impacts] Please provide a comma separated list of the potential
impacts that might be introduced by this change -->
<!-- * Generated values: Can your change impact any of the existing
generators in terms of generated values, if so which ones? when? -->
<!-- * Shrink values: Can your change impact any of the existing
generators in terms of shrink values, if so which ones? when? -->
<!-- * Performance: Can it require some typings changes on user side?
Please give more details -->
<!-- * Typings: Is there a potential performance impact? In which cases?
-->
  • Loading branch information
dubzzz authored Aug 25, 2024
1 parent 1baccc5 commit 94d5d57
Show file tree
Hide file tree
Showing 7 changed files with 609 additions and 82 deletions.
11 changes: 11 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.0.2/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["@fast-check/examples", "website"]
}
18 changes: 0 additions & 18 deletions .github/workflows/build-status.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,6 @@ jobs:
check-latest: true
- name: Ensure no dedupe required
run: yarn dedupe --check
all_version_bump_declared:
name: 'All version bump declared'
needs: warmup_yarn_cache
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' && github.event.pull_request.user.login != 'renovate[bot]'
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
fetch-depth: 0
- name: Using Node v20.x
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version: '20.x'
cache: 'yarn'
cache-dependency-path: yarn.lock
check-latest: true
- name: Ensure versions have been properly bumped
run: yarn version check
package_quality:
name: 'Package quality'
needs: warmup_yarn_cache
Expand Down
75 changes: 40 additions & 35 deletions .github/workflows/scripts/generate-changelog.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-check
const {
promises: { readFile, writeFile },
promises: { readFile, writeFile, rm },
existsSync,
} = require('fs');
const path = require('path');
Expand Down Expand Up @@ -189,45 +189,36 @@ function isInitialTag(tagName) {
return tagName.endsWith('v0.0.0');
}

/**
* Extract the kind of release
* @param {string} oldTagName
* @param {string} newTagName
* @returns {'major'|'minor'|'patch'}
*/
function extractReleaseKind(oldTagName, newTagName) {
const oldTagVersion = extractMajorMinorPatch(oldTagName);
const newTagVersion = extractMajorMinorPatch(newTagName);
const releaseKind =
newTagVersion.major !== oldTagVersion.major
? 'major'
: newTagVersion.minor !== oldTagVersion.minor
? 'minor'
: 'patch';
return releaseKind;
}

/**
* @returns {Promise<{branchName:string, commitName:string, errors:string[], changelogs: string[]}>}
*/
async function run() {
const allErrors = [];

// Get packages to be bumped via yarn
const { stdout: yarnOut } = await execFile('yarn', ['version', 'apply', '--all', '--dry-run', '--json']);
const allBumps = yarnOut
.split('\n')
.filter((line) => line.trim().length !== 0)
.map((line) => JSON.parse(line));
// Get packages to be bumped via changeset
const temporaryChangelogFile = 'changelog.json';
await execFile('yarn', ['changeset', 'status', `--output=${temporaryChangelogFile}`]);
const temporaryChangelogFileContentBuffer = await readFile(temporaryChangelogFile);
const temporaryChangelogFileContent = JSON.parse(temporaryChangelogFileContentBuffer.toString());
await rm(temporaryChangelogFile);
// Array of {name, type, oldVersion, newVersion, changesets}
const allBumps = await Promise.all(
temporaryChangelogFileContent.releases
.filter((entry) => entry.type !== 'none')
.map(async (entry) => {
// Extracting the location of the package from the workspace
const { stdout: packageLocationUnsafe } = await execFile('yarn', ['workspace', entry.name, 'exec', 'pwd']);
const packageLocation = packageLocationUnsafe.split('\n')[0].trim();
return { ...entry, packageLocation };
}),
);

for (const packageBump of allBumps) {
const { oldVersion, newVersion, cwd: packageLocation, ident: packageName } = packageBump;
for (const { oldVersion, newVersion, name: packageName, type: releaseKind, packageLocation } of allBumps) {
console.debug(`[debug] Checking ${packageName} between version ${oldVersion} and version ${newVersion}`);

// Extract metas for changelog
const oldTag = computeTag(oldVersion, packageName);
const newTag = computeTag(newVersion, packageName);
const releaseKind = extractReleaseKind(oldTag, newTag);
console.debug(`[debug] Checking ${packageName} between tag ${oldTag} and tag ${newTag}`);
const { breakingSection, newFeaturesSection, maintenanceSection, errors } = await extractAndParseDiff(
oldTag,
Expand Down Expand Up @@ -274,16 +265,30 @@ async function run() {
const previousContent = existsSync(changelogPath) ? await readFile(changelogPath) : '';
await writeFile(changelogPath, `${body}\n\n${releaseKind !== 'patch' ? `---\n\n` : ''}${previousContent}`);
await execFile('git', ['add', changelogPath]);
}

// Bump towards latest version and add files for upcoming commit
await execFile('yarn', ['version', 'apply', '--all']);
for (const packageBump of allBumps) {
const { cwd: packageLocation } = packageBump;
// Update the package.json
await execFile('npm', ['--no-git-tag-version', '--workspaces-update=false', 'version', releaseKind], {
cwd: packageLocation,
});
const packageJsonPath = path.join(packageLocation, 'package.json');
await execFile('git', ['add', packageJsonPath]);
}
await execFile('git', ['add', '.yarn/versions']);

// Force yarn reinstall
await execFile('yarn');
await execFile('git', ['add', 'yarn.lock']);

// Drop all changesets
const alreadyDeleted = new Set();
for (const { changesets } of allBumps) {
for (const changeset of changesets) {
if (alreadyDeleted.has(changeset)) {
continue;
}
alreadyDeleted.add(changeset);
await execFile('git', ['rm', `.changeset/${changeset}.md`]);
}
}

// Create another branch and commit on it
const branchName = `changelog-${Math.random().toString(16).substring(2)}`;
Expand All @@ -294,7 +299,7 @@ async function run() {

// Compute the list of all impacted changelogs
const changelogs = allBumps
.map((b) => b.cwd.substring(process.cwd().length + 1).replace(/\\/g, '/'))
.map((b) => b.packageLocation.substring(process.cwd().length + 1).replace(/\\/g, '/'))
.map(
(packageRelativePath) =>
`https://github.com/dubzzz/fast-check/blob/${branchName}/${packageRelativePath}/CHANGELOG.md`,
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.changeset/
.yarn/
packages/*/coverage/
packages/*/dist/
Expand Down
4 changes: 0 additions & 4 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,4 @@ enableGlobalCache: true
enableScripts: false
nodeLinker: pnp
enableHardenedMode: false

changesetIgnorePatterns:
- '**/*.spec.{js,ts}'

yarnPath: .yarn/releases/yarn-4.4.1.cjs
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
"lint": "eslint . --fix",
"lint:check": "eslint .",
"publint:all": "yarn workspaces foreach --all -pvi --no-private exec publint --strict",
"bump": "yarn version check --interactive",
"bump": "changeset",
"pack:all": "yarn workspaces foreach --all -pvi --no-private pack --out package.tgz",
"unpack:all": "yarn workspaces foreach --all -pvi --no-private exec tar -xf package.tgz --strip-components=1 --exclude='package/package.json'"
},
"devDependencies": {
"@changesets/cli": "^2.27.7",
"@eslint/js": "^9.9.0",
"@fast-check/packaged": "*",
"@typescript-eslint/utils": "^7.18.0",
Expand Down
Loading

0 comments on commit 94d5d57

Please sign in to comment.