MiniCI
Simple minimalist framework to run CI-like checks on local machine, used by Erebos projects.
The code can be downloaded here:
git clone https://code.erebosprotocol.net/minici
from a mirror on github:
git clone https://github.com/roman-smrz/minici
or from Hackage:
Installation
Debian
For installation and updates using apt, new repository can be added by
creating a file named /etc/apt/sources.list.d/erebos.sources:
Types: deb
URIs: https://repo.erebosprotocol.net/debian/
Suites: DIST
Components: main
Signed-By: /etc/apt/keyrings/erebos.gpg
Where DIST needs to be changed to the distribution codename: bookworm,
trixie or forky.
Download and install the repository key:
# wget -O /etc/apt/keyrings/erebos.gpg https://repo.erebosprotocol.net/erebos.gpg
Update apt database and install minici:
# apt update
# apt install minici
Binary release
Prebuilt binary with minimal dependencies — apart from the git command,
which needs to be installed for most of the functionality — is available for
64bit Linux:
The archive there contains executable that can be run from any location:
$ tar xzf minici-0.1.9_linux_amd64.tar.gz
$ ./minici-0.1.9_linux_amd64/minici --version
MiniCI version 0.1.9
To build from source, use the cabal tool either within the source directory:
$ tar xzf minici-0.1.9.tar.gz
$ cd minici-0.1.9
$ cabal install
or to automatically download the source from Hackage:
$ cabal install minici
Readme
MiniCI runs jobs defined in the minici.yaml file in the root of the project
(on the same level as the .git directory). With that, minici invocation can
execute the jobs for local commits that are not yet in upstream (remote) branch
or for any manually given commit range.
Job definition
The basic top-level elements of the YAML file are job <name> defining steps
to perform the job and potentially listing artifacts produced or required.
Example:
job build:
shell: |
./configure
make
artifact bin:
path: build/example
job test:
uses:
- build.bin
shell: |
./build/example test
Each job is a map with the following attributes:
shell- Shell script to perform the job.
artifact <name>-
Defines artifact
<name>produced by this job. Is itself defined as a dictionary. artifact <name>.path- Path to the produced artifact file, relative to the root of the project.
uses-
List of artifact required for this job, in the form
<job>.<artifact>. checkout- List of repositories to checkout into the work directory before starting the job (see below). If not specified, the default repository (containing the YAML file) will be checked out to the root of the work directory.
publish- List of artifacts (produced by this or other jobs) to publish to specified destinations (see below).
Usage
To run jobs for a git commit range:
minici run <commit>..<commit>
or:
minici run --range=<commit>..<commit>
To run jobs for commits that are in local <branch>, but not yet in its upstream:
minici run --since-upstream=<branch>
For current branch, the name can be omitted:
minici run
To run selected jobs with the current working tree, including uncommitted changes, list the job names on command line:
minici run <job name> [<job name> ...]
To watch changes on given <branch> and run jobs for each new commit:
minici run --new-commits-on=<branch>
To watch new tags and run jobs for each tag matching given pattern:
minici run --new-tags=<pattern>
The above options --range, --since-upstream, etc can be arbitrarily combined.
Explicit script file
Normally, minici uses the minici.yaml file from the repository in the current working directory;
the path to a repository used can also be specified on the command line before the command (e.g. run).
That path must contain a slash character to disambiguate it from a command name, e.g.:
minici ../path/to/some/other/repo run some_job
Whether using the implicit repository or one specified on the command line, when
executing jobs for a range of commits, minici uses the minici.yaml file
version from each individual commit. So for example, running:
minici run HEAD~5..HEAD
can execute different jobs for each commit, if the job file was changed in each of the last five commits.
To force usage of particular version of minici.yaml file, explicit path to that file can be given:
minici ./minici.yaml run HEAD~5..HEAD
In this case, the jobs specified in the current version of minici.yaml will
be used for all of the five commits.
Additional repositories and checkouts
Jobs can also use repositories other than the default one (which contains the minici.yaml file).
The additional repositories need to be declared at the top level of the minici.yaml file as:
repo <name>:
path: <path/to/repository> (optional, only relevant for explicit script file)
The path of a repository <name> can be given (or overridden) on command line by passing argument in the form --repo=<name>:<path> before the command name.
To explicitly set what repositories to check out, set the list in the checkout element of the job definition:
job some_job:
checkout:
- repo: some_repo
dest: destination/path
...
The elements of the checkout list are dictionaries with following elements:
repo-
Name of the repo to checkout from. If not given, the default repo (containing the
minici.yamlfile) is used. dest- Path within the work directory to use for the checkout. If not given, the root of the work directory is used.
subtree- If provided, checkout only given subtree of the repository. If the given path does not exist within a particular commit, the checkout and the whole job fail.
All checkouts are performed before running the script given in the shell element.
If no checkout list is given, the whole default repo is checked out to the root of the work directory.
Destinations
Apart from a recipe, a job can also contain instructions to publish artifacts to given destinations. The artifacts can be produced either by the publishing job or other jobs, and the destination must be declared at the top of the job file:
destination <name>:
url: <destination url> (optional, only relevant for explicit script file)
Note: only local filesystem path is currently supported as url.
The URL of a destination <name> can be given (or overridden) on command line by passing argument in the form --destination=<name>:<url> before the command name.
The artifacts to publish are then given in the publish list of a job definition:
job publish_something:
publish:
- to: some_destination
artifact: other_job.some_artifact
Elements of the publish list are dictionaries with following elements:
to- Name of the destinations to publish to.
artifact-
Artifact to publish—either
<artifact-name>if produced by this job, or<job-name>.<artifact-name>if produced by other job. path- Path within the destination to publish this artifact to. If not given, artifact path from the work directory is used.
Roadmap
0.1.10
0.1.x
0.2.0
0.2.x
Backlog
Changelog
0.1.9 – 2025-12-29
- Reuse job status and artifacts from previous runs
- Added
--rerun-*command-line options to configure which jobs should be rerun - Job section to publish artifacts to specified destination
- Accept literal text block for the
shellsection - Prepare used artifacts for the
shellcommand
0.1.8 – 2025-07-06
- Added
shellcommand to open a shell prepared for given job - Support whole directories as artifacts
- Automatically run dependencies of jobs specified on command line
- Fix getting (sub)directory in a bare repository
0.1.7 – 2025-05-28
- Added
logcommand to show job log - Added
extractcommand to extract artifacts - Added
--terminal-outputand--log-outputoptions to set output style - Run jobs by specifying full job id or reference
0.1.6 – 2025-03-30
- Added
jobidcommand resolving job reference to canonical ID - Fix copying of used artifacts to appropriate working directory
0.1.5 – 2025-03-20
- Accept job file path on command line
- Added
checkoutcommand - Reference and checkout other repositories from job file
- Accept names of jobs to run as command-line arguments
0.1.4 – 2025-02-04
- Fix invocation of
minici runwithout arguments - Fix that empty temporary dir was not deleted in some cases
- Add explicit
--since-upstreamoption for theruncommand
0.1.3 – 2025-01-25
- Run jobs based on configuration in associated commit
- Configurable number of concurrently running jobs (using
-joption) - Concurrently run jobs for multiple commits
- Properly cancel and clean up jobs on user interrupt
- Added
--new-commits-onand--new-tagsoptions forruncommand to dynamically generate jobs based on branch/tags changes - Support for GHC up to 9.12
0.1.2 – 2024-07-30
- Explicit run command
- Support for GHC up to 9.10
0.1.1 – 2023-04-25
- Support for GHC 9.2
- Added
-Vcommand-line switch to show version.
0.1.0 – 2023-02-04
- First version.