Skip to content
Makefile + Docker = CI Pipeline
Shell Makefile Other
Branch: master
Clone or download
rosineygp test: increase code coverage (#47)
improvement of test add more uses case.
Latest commit e6fca26 Jan 14, 2020
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci feat: re-think job behaviour (#36) Jan 5, 2020
.github/workflows fix: issues showed in codefactor (#42) Jan 8, 2020
examples fix: alter variable JOB_NAME to MKDKR_JOB_NAME (#38) Jan 5, 2020
generator Fix template filename (#13) Dec 16, 2019
media
test test: increase code coverage (#47) Jan 15, 2020
.gitignore chore: add commit lint (#32) Jan 4, 2020
.gitlab-ci.yml feat: re-think job behaviour (#36) Jan 5, 2020
.mkdkr refactor: isolated ifs to one function (#46) Jan 11, 2020
.surgeignore
.travis.yml feat: re-think job behaviour (#36) Jan 5, 2020
Dockerfile fix: issues showed in codefactor (#42) Jan 8, 2020
LICENSE Create LICENSE Dec 12, 2019
Makefile test: increase code coverage (#47) Jan 15, 2020
README.md test: improve test report (#43) Jan 8, 2020
_config.yml Set theme jekyll-theme-cayman Dec 29, 2019
commitlint.config.js chore: add commit lint (#32) Jan 4, 2020
package.json

README.md

mkdkr

Build Status pipeline status CircleCI GitHub license GitHub release kcov CodeFactor

mkdkr = Makefile + Docker

Super small and powerful framework for build CI pipeline, scripted with Makefile and isolated with docker.

  • Dependencies: [ make, docker, bash ]
  • Two files only (Makefile and .mkdkr), less garbage on your repo
  • All power of make, docker and bash
  • Shipping and switch among CI engines like Circle CI, GitHub Actions, Gitlab-ci, Jenkins, Travis.. and more
  • Clean and elegant code syntax

Table of contents

Usage

Installation

# Download .mkdkr
curl https://raw.githubusercontent.com/rosineygp/mkdkr/master/.mkdkr > .mkdkr

# not required, but can be used as template
curl https://raw.githubusercontent.com/rosineygp/mkdkr/master/examples/simple.mk > Makefile

Makefile

Create a file with name Makefile and paste the following content

# Required header
.EXPORT_ALL_VARIABLES:
.ONESHELL:
SHELL = /bin/bash

define . =
	source .mkdkr
	$(eval MKDKR_JOB_NAME=$(shell source .mkdkr; .... $(@)))
	trap '.' EXIT
endef
# end of header

job:                                # job name
	@$(.)                       # required: load mkdkr and create unique job name
	... alpine                  # create a docker container using alpine image
	.. echo "hello mkdkr!"      # execute a command inside container

# if you want to test it remove all comments of job

Execute

# execute
make job

Result

# output
... job alpine            # creating a docker container using alpine image
cdab4af95cec...           # docker container id
.. echo hello mkdkr!      # execute command inside container
hello mkdkr!              # output of command
.                         # destroy all containers related of this job
cdab4af95cec              # id(s) of container(s) removed

Reason

Build pipeline for a dedicated platform can take a lot of time to learn and test, with mkdkr you can test all things locally and run it in any pipeline engine like Jenkins, Actions, Gitlab-ci and others.

standards

Dot Functions

ATTENTION: All functions are represented with .(s) It creates a beautiful code style like yaml, indents are not required.

job:
	....
	...
	..
	.

yes, just dots

•••• 4 dots

[auto] Create a unique job name.

Parameters:

  • String, MKDKR_JOB_NAME: If not exist set a MKDKR_JOB_NAME otherwise return current MKDKR_JOB_NAME.

Return:

  • String, MKDKR_JOB_NAME

Automatically load after call @$(.).

Usage

.... my-awesome-job		# name a job

••• 3 dots

[optional**] Create a docker container, it can set as simple job, service or privileged job.

Parameters:

  • String, ACTION: Actions is the mode that container will run it can be a:
    • job [default]: simple docker container
    • service: is like a job, but run in detached mode
    • privileged: is a job but with docker socket access

if any action was passed, it will be a job

  • String, IMAGE *: any docker image name
  • String|Array, ARGS: additional docker init args like (--cpus 1 --memory 64MB)

Return:

  • String, Container Id

Usage

... job alpine                  # simple job
... ubuntu:18.04                # if it's a job, pass action [job] is not required
... centeos:7 \
    --cpus 2 \
    --memory 1024MB \
    -e PASSWORD=$$PASSWORD      # container parameters
... service nginx               # create a service
... privileged docker:19        # create a job with docker demon access

** Required when is a service or a privileged container

•• 2 dots

[required] Execute a command inside docker container [job or privileged].

Parameters:

  • String|Array, command: any sh command eg. 'apk add nodejs'

Return:

  • String, Command(s) output

Usage

.. apk add curl                # run a command inside container
.. ls -la > myfile             # run a command inside container and redirect output to host
.. 'ls -la > myfile'           # run a command inside container and redirect output to container
.. 'apt-get update && \
    apt-get install -y curl'   # just need '' cause && redirect outside container

• 1 dot

[optional] Destroy all containers initialized in a job.

At end of job it is called implicitly.

Parameters:

  • None

Return:

  • String, Container Id

Usage

.   # Kill 'Em All

Examples

Simple

simple:
	@$(.)
	... job alpine
	.. echo "hello mkdkr!"

Is possible to mix images during job, see in example

Makefile

Service

service:
	@$(.)
	... service nginx
	... alpine --link service_$$MKDKR_JOB_NAME:nginx
	.. apk add curl
	.. curl -s nginx

Makefile

DIND

Privileged job

dind:
	@$(.)
	... privileged docker:19
	.. docker build -t rosiney/pylint .

Makefile

Escapes

pipes:
	@$(.)
	... ubuntu:18.04
	.. "find . -iname '*.mk' -type f -exec cat {} \; | grep -c escapes"

More examples at file

Makefile

Shell

Switch to another shell

shell:
	@$(.)
	... ubuntu
	export MKDKR_SHELL=bash
	.. 'echo $$0'

More examples at file

Trap

Prevent keep container running when after error or exit.

broken:
	@$(.)
	... service nginx
	... alpine
	.. ps -ef

Job finished without call ., now trap close it correctly.

Makefile

Implicit Job

When start a new job if action passed, it will create a container as a simple job.

implicit-job:
	@$(.)
	... alpine --memory 32MB
	.. echo "hello nano job"

implicit='Less code!'

Makefile

Pipeline

Group of jobs for parallel and organization execution

pipeline:
	make test -j 3	# parallel execution
	make build
	make pack
	make deploy

Makefile

Generators

Create a scaffold to another pipeline engine.

External pipeline:

Gitlab CI

gitlab:
	@$(.)
	... rosiney/mkdkr
	.. gitlab-ci \
		lint=shellcheck \
		scenarios=simple,service,dind > .gitlab-ci.yml

Parameters:

  • String(key)=String(job),String(job),... The name of key is the stage and the job(s) is the values separated by comma.
  • Ex. test=lint,syntax build=gcc deploy=k8s
  • Avoid spaces, slashes or symbols it will keep compatibility with pipeline vendors.

Environment Variables

Name Default Description
MKDKR_TTL 3600 The time limit to a job or service run
MKDKR_SHELL sh Change to another shell eg. bash, csh
MKDKR_JOB_NAME* (job|service)_target-name_(uuid) Unique job name, used as container name suffix
  • to overwrite the values use: export <var>=<value>
  • * auto generated
You can’t perform that action at this time.