The source code is on GitHub so I will only make a quick walk-through here.
The script
- Get the last commit message (including hash). Following conventional commits specification, decide whether version number should be increased. If yes:
- calculate the next version and
- get the list of changed projects. For each of the changed projects get the last two commits and:
- ensure that the hash of project last commit is equal to the hash of the last commit (in case rush indicates the change, but the files were not included in the last commit) and
- ensure that the last two commit messages are not equal.
- If the above is true, generate change files based on the commits. Append the change file to the last commit using
--amend
Importing modules installed by autoinstaller
Importing modules installed by the rush-changemanager autoinstaller requires a path to the node_modules.
//...
const node_modules = path.join(__dirname, '..', 'autoinstallers/rush-changemanager/node_modules');
const rushLib = require(path.join(node_modules, '@microsoft/rush-lib'));
const rushCore = require(path.join(node_modules, '@rushstack/node-core-library'));
const gitlog = require(path.join(node_modules, 'gitlog')).default;
const recommendedBump = require(path.join(node_modules, 'recommended-bump'));
Rush custom commands: execute custom script with autoinstaller dependencies.
Recommended bump
To generate change files for commit types fix:
, feat:
and BREAKING CHANGE (if the commit has a footer BREAKING CHANGE:
, or appends a !
after the type/scope), retrieve the last commit using gitlog
, and parse it using recommendedBump
.
const options = {
repo: repoPath,
file: repoPath,
number: 1,
fields: ["subject", "body", "rawBody", "authorEmail", "hash"]
}
const lastCommit = gitlog(options);
//fix, feat or BREAKING?
const { increment } = recommendedBump([lastCommit[0].rawBody]);
Get changed projects
If the last commit should trigger change file generation, retrieve the names and folder paths of the changed projects using ProjectChangeAnalyzer
.
Important: ProjectChangeAnalyzer API is provided as a preview and may change. Use at your own risk.
const projectAnalyzer = new rushLib.ProjectChangeAnalyzer(rushConfiguration);
const terminal = new rushCore.Terminal(new rushCore.ConsoleTerminalProvider({ verboseEnabled: false }));
const changedProjects = await projectAnalyzer.getChangedProjectsAsync({
//...
});
Are the changed projects included in the last commit?
Retrieve the last two commits for each changed projects. This allows verifying that:
- the specific project was included in the last commit, and
- the last two commit messages are different.
If everything checks, the change files are generated using ChangeManager
class. After their content is set based on the parsed commit messages, they are committed to the repo.
async function getChangedProjectNamesAsync(rushConfiguration) {
const changedProjects = await projectAnalyzer.getChangedProjectsAsync({
targetBranchName: getCurrentBranch() , //detect current branch
//...
});
changedProjects.forEach(project => {
rushProjects.set(project.packageName, project.projectFolder);
});
return rushProjects;
}
//...
getChangedProjectNamesAsync(rushConfiguration).then((rushProjects) => {
rushProjects.forEach((value, key) => {
const result = parseRecentCommits(key, value, lastCommitInfo, rushConfiguration.rushJsonFolder);
if (result) {
generateChangeFile(rushConfiguration, result);
executeCommand(`git add ${rushConfiguration.changesFolder}`);
executeCommandAsync(`git commit --no-edit --no-verify --amend `);
}
});
Git hooks
To generate the change files after git commit
, use the post-commit
git hook, which is is invoked after a commit is made.
common\git-hooks\post-commit
#!/bin/sh
node common/scripts/install-run-rush.js changefiles
Run rush install
for Rush to .git/hooks/post-commit
rush install
Testing
When testing, make sure to edit files belonging to a project managed by rush. Changes will not be detected otherwise.
Next steps
This is by far not a finished product. For example, when retrieving changed projects I don't evaluate shouldPublish
or versionPolicy.exemptFromRushChange
.
Source Code
You may find the source code on GitHub.
Top comments (0)