A task runner for repositories
·
Report Bug
·
Request Feature
·
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.
npm i @beuluis/repository-runner
-
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
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'])],
},
],
});
-
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. Usesnpm ci
oryarn install --frozen-lockfile
under the hood.
-
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.
-
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.
-
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.
-
run
- Function that gets called during runtime. -
title
- Tasks title to be used in reports.
report
- Function to be called after the run is done.
-
repository
- Name of reference repository. -
error
- Error string of repository result.
or
-
repository
- Name of reference repository. -
branchReports
- List of branch reports. See BranchReport.
-
branch
- Name of reference branch. -
error
- Error string of branch result.
or
-
branch
- Name of reference branch. -
taskReports
- List of task reports. See TaskReport.
-
taskTitle
- Title of reference task. -
error
- Error string of task result.
or
-
taskTitle
- Title of reference task. -
output
- Output string of task result.
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.
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.
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
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.