CI Reference Workflow for Mint

Before implementing a CI workflow, see the getting started guide.

In general, most Mint workflows for CI are structured like this:

  • install system packages
  • clone the code repository
  • install programming languages
  • install packages via the package manager
  • run tests, linters, etc.

Hypothetical Project

Here is a hypothetical Mint configuration file for a Node.js project.

You can name this file whatever you want in the .mint directory, but it's common to name it .mint/ci.yml

on:
  github:
    pull_request:
      init:
        commit-sha: ${{ event.github.pull_request.pull_request.head.sha }}

tasks:
  - key: system-packages
    run: |
      sudo apt-get update
      sudo apt-get install jq
      sudo apt-get clean

  - key: code
    call: mint/git-clone 1.2.2
    with:
      repository: https://github.com/YOUR_ORG/YOUR_REPO.git
      ref: ${{ init.commit-sha }}
      github-access-token: ${{ secrets.YOUR_ORG_CLONE_TOKEN }}

  - key: node
    call: mint/install-node 1.0.6
    with:
      node-version: 20.12.1

  - key: npm-install
    use: [system-packages, code, node]
    run: npm install
    filter:
      - package.json
      - package-lock.json

  - key: lint
    use: npm-install
    run: npm run lint

  - key: test
    use: npm-install
    run: npm run test

Init Params

When working on defining a Mint workflow, it's most productive to use the CLI to kick off runs. That way, you can avoid the overhead of having to push to test changes.

Typically, you can look up the latest commit on main and test using that.

For example, if the latest commit is ec6f4ed13a6562317311b6c8470e049ac6f39285, you would run:

mint run --file .mint/ci.yml --init commit-sha=ec6f4ed13a6562317311b6c8470e049ac6f39285 --open

You could also do this dynamically:

mint run --file .mint/ci.yml --init commit-sha=$(git rev-parse origin/main) --open

See the documentation on init params.

Event Triggers

This example runs on the pull request trigger, but you could also run it based on a push trigger:

on:
  github:
    push:
      init:
        commit-sha: ${{ event.github.push.head_commit.id }}

See the documentation on event triggers.

System Packages

- key: system-packages
  run: |
    sudo apt-get update
    sudo apt-get install jq
    sudo apt-get clean

In this example, system-packages arbitrarily installs jq.

We then defined the npm-install task to use system-packages:

- key: npm-install
  use: [system-packages, code, node]
  run: npm install
  filter:
    - package.json
    - package-lock.json

It's unlikely in this example that jq is actually required for npm-install to succeed, so the npm-install task may just look like:

- key: npm-install
  use: [code, node]
  run: npm install
  filter:
    - package.json
    - package-lock.json

However, if you need any development packages installed, like libsqlite3-dev, then you may need to depend on system-packages for your package manager installation task to succeed.

Cloning the Repository

- key: code
  call: mint/git-clone 1.2.2
  with:
    repository: https://github.com/YOUR_ORG/YOUR_REPO.git
    ref: ${{ init.commit-sha }}
    github-access-token: ${{ secrets.YOUR_ORG_CLONE_TOKEN }}

This task uses the git-clone leaf to clone the repository.

The github-access-token is using a vault secret automatically managed by Mint. It will be available once you install the GitHub Mint app.

If you're cloning a public repository, then you do not need to specify a github-access-token at all.

If you're working with a different version control provider, you can also clone by specifying an ssh-key. For more details, see the git-clone leaf documentation.

Programming Language Install

Several Mint leaves are available to install programming languages: go, node, python, and ruby.

Most of them accept specifying the version of the language to install, like we showed in the Node.js example:

- key: node
  call: mint/install-node 1.0.6
  with:
    node-version: 20.12.1

However, you may want to configure the version of the language to install based on a file checked into your code repository. In that case, you would need to add use code to the task definition. Additionally, you'd want to add a filter so that your task will be cached effectively.

- key: node
  call: mint/install-node 1.0.6
  use: code
  with:
    node-version-file: .node-version
  filter:
    - .node-version

Package Manager

Most package managers have simple interfaces for installing packages, so Mint does not provide leaves to manage this part of the setup.

- key: npm-install
  use: [system-packages, code, node]
  run: npm install
  filter:
    - package.json
    - package-lock.json

You will want to use a filter so that you packager manager install can be cached.

Docker Services

If you need to run a database or other service for your tests to succeed, you'll need to add background processes to your test task.

Multiple Languages

Of course, you can also install multiple programming languages.

tasks:
  - key: node
    call: mint/install-node 1.0.6
    with:
      node-version: 20.12.1

  - key: npm-install
    use: [system-packages, code, node]
    run: npm install
    filter:
      - package.json
      - package-lock.json

  - key: ruby
    call: mint/install-ruby 1.0.9
    with:
      ruby-version: 3.3.0

  - key: bundle-install
    use: ruby
    run: bundle install
    filter:
      - Gemfile
      - Gemfile.lock

  - key: has-node-and-ruby
    use: [npm-install, ruby-install]
    run: ...

In this example, has-node-and-ruby will have both node and ruby available to it. This may be common for running things like system tests that utilize both runtimes.