repository-runner
A task runner for repositories
·
Report Bug
·
Request Feature
·
About The Project
A task runner to run tasks on repositories and matching branches. Reporting the collected results.
It makes sure not to override local changes and goes back to the previous checked out branch.
Installation
npm i @beuluis/repository-runner
Usage
-
Create a node project. You can use TypeScript if you wish.
-
Define a main bin
-
Call the runner helper function and start configure your setup
-
You can package your project and run it via npx
or you can just run the bin locally
Functions
Runner helper function
Runner helper function accepts RunnerConfig as parameter.
Example:
#!/usr/bin/node
import { resolve } from 'path';
import { runner, buildInReporters, buildInTasks } from '@beuluis/repository-runner';
void runner({
reporters: [
buildInReporters.jsonReporter(resolve(process.cwd(), 'out')),
buildInReporters.markdownReporter(resolve(process.cwd(), 'out')),
],
repositoriesDirectory: resolve('/Users/HelloWorld/workspaces'),
branchRegex: /(.*?)/u,
repositories: [
{
repository: 'testRepo1',
tasks: [buildInTasks.commandTask('echo', ['hello'])],
},
{
repository: 'testRepo2',
branchRegex: /^feature\/.*/u,
tasks: [
buildInTasks.installNodeDependenciesTask(),
buildInTasks.dryMergeTask('master'),
],
},
{
repository: 'testRepo3',
prepareTasks: [buildInTasks.commandTask('docker-compose', ['up', '--build', '-d'])],
tasks: [
buildInTasks.installNodeDependenciesTask('yarn'),
buildInTasks.commandTask('npm', ['run', 'test:cov']),
{
title: 'Awesome task',
run: async (repositoriesDirectory: string) => {
console.log(`what ever you want in ${repositoriesDirectory}`);
},
},
],
cleanupTasks: [buildInTasks.commandTask('docker-compose', ['down'])],
},
],
});
Build in tasks
-
buildInTasks.commandTask(command: string, args?: string[], reportStdout = true)
- Run a command with the current repository as pwd. Optional reports stdout back in the task report.
-
buildInTasks.dryMergeTask(targetBranch = 'main')
- Tries a dry run merge with the configured branch.
-
buildInTasks.installNodeDependenciesTask(packageManager: 'npm' | 'yarn' = 'npm')
- Installs dependencies with the configured package manager. Uses npm ci
or yarn install --frozen-lockfile
under the hood.
Build in reporters
-
buildInReporters.markdownReporter(outputDirectory: string, filename = 'report')
- Writes report markdown files to the configured output directory.
-
buildInReporters.jsonReporter(outputDirectory: string, filename = 'report')
- Writes report JSON files to the configured output directory.
Interfacess
RunnerConfig
-
branchRegex
- Regex used to match branches to run tasks.
-
concurrent
- Run repositories in concurrent mode. If number is passed this number will be used as maximum.
-
reporters
- Array of objects with the Reporter interface. See Reporter
-
repositories
- Repositories to run. See RepositoryTasks.
-
repositoriesDirectory
- Repositories directory where the repositories are located.
RepositoryTasks
-
branchRegex
- Overrides the global regex.
-
repository
- Repository name to look up in repositoriesDirectory.
-
tasks
- List of tasks to run on all matches branches. See Task.
-
prepareTasks
- List of tasks to run after all branch tasks. Run once after all branches in repository. See Task.
-
cleanupTasks
- List of tasks to run before all branch tasks. Run once before all branches in repository. See Task.
Task
Reporter
report
- Function to be called after the run is done.
RepositoryReport
or
BranchReport
or
TaskReport
or
Write custom tasks
To provide a custom task you can implement a class or object according to the Task and pass it in the tasks
property of the RepositoryTasks interface.
Write custom reporter
To provide a custom reporter you can implement a class or object according to the Reporter and pass it in the reporter
property of the RunnerConfig interface.
Principles
Runners
A runner is responsible to run all defined tasks on the context 'section'.
As example the repositoryRunner
is run per repository and the branchRunner
per branch.
An configuration like this:
├── repo1
│ ├── branch 1
│ └── branch 2
└── repo2
├── branch 1
└── branch 2
Would result in something like this:
├── repositoryRunner for repo 1
│ ├── branchRunner for branch 1
│ └── branchRunner for branch 2
└── repositoryRunner for repo 2
├── branchRunner for branch 1
└── branchRunner for branch 2
Reporting
All runners care about the reports of there own context 'section' and combine them of the results of the triggered runners. You can say the reports bubble up to the upper layers.
The report order goes as follows:
taskRunner
-> branchRunner
-> repositoryRunner
-> index function
After all reports are collected they get passed to the configured reporters. These reporters can do whatever they want with the reports. They can write them to files, pass them to an API, or trigger scripts, whatever their heart desires.
TODO
Contributing
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Contact
Luis Beu - me@luisbeu.de