Skip to content
This repository has been archived by the owner on Mar 28, 2020. It is now read-only.
/ DotNetCoreBuildServer Public archive

DotNetCoreBuildServer is a build system based on .NET Core with Slack integration

License

Notifications You must be signed in to change notification settings

KonH/DotNetCoreBuildServer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DotNetCoreBuildServer

DotNetCoreBuildServer is a build system based on .NET Core (netstandard2.0). It allows you to run batch of actions (check/copy directory/files, run external tools) and collect results in a simple way. Also, it provides Slack integration using SlackBotNet by jweber.

Configuration

Project config

Server config based on .json file in given format:

{
	"builds": "pathToBuildConfigDirectory"
}

If you need Slack integration, add these lines:

{
	...
	"slack_token": "bot_token",
	"slack_hub": "channel_or_user_name"
}

Slack token you can get in team dashboard after adding new bot, slack hub can be #channelName or @userName, and after that you can control your bot in this channel or direct messages with user.

Any other parts of project config are optional and used as replacers. For example, you have "root" in project config:

{
	...
	"root": "pathToYourProject"
}

After it, you can use {root} in build tasks:

{
	"path": "{root}/subDirectory"
}

Also, your server name is already added to available replacers as "serverName".

Build config

Build configs are placed to one directory, specified in "builds" in project config. One .json file per build.

Build config looks like this:

{
	"short_description": "Short description of this Build config",
	"long_description": "Detailed description of this Build config",
	"args_description": ["arg_0 description", ... "arg_N description"],
	"args": [
		"arg_0", "arg_1", ... "arg_N"	
	],
	"args_check": [
		"", "", ... ""	
	],
	"log_file": "path_to_logfile",
	"tasks": [
		{
			"task_name": {
				"command_name": {
					"command_arg_0": "value_0",
					"command_arg_1": "value_1",
					...
					"command_arg_N": "value_N"
				}
			}
		}
	]
}

"short_description" is an optional summary of this Build config. It will be shown on "help list" command output.

"long_description" is an optional description of this Build config. It will be shown on "help build_config_name" command output.

"args_description" is an optional array of Build config's arguments descriptions. These descriptions will be shown on "help build_config_name" command output.

"args_check" is optional and it is a array of regex's, args is checked against them before build.

"log_file" is optional, in this file full build output will be redirected.

Any command has "message" and "result", "message" is full output, "result" can contain short info (see "run" task). You can get these values using {taskName:message} and {taskName:result} in next tasks parameter values.

Full list of commands you can see at Tasks section.

Also, you can look at full example here.

Sub-builds

You can include one build into another build using this syntax in task list:

{
	"_build": 
		"sub_build_name": {
			"arg_0": "arg_value_0",
			...
		}
 }

All tasks in sub build will be inserted in position of "_build" task.

It allow you to re-use tasks and avoid code redundancy.

If build args and sub-build args is the same, you can skip it and provide specific args only (which is not included in build args).

Task parallelism

You can mark several tasks (one by one) as "parallel". This tasks run simultaneously and next execution is continued when all this tasks is done.

{
	"task_a": {
		...,
		"parallel": "true"
	},
	"task_b": {
		...,
		"parallel": "true"
	},
	"task_c": {
		...
	}
 }

In example above "task_a" and "task_b" start at same time, "task_c" started after "task_a" and "task_b" is done.

Also, you can setup parallel queues using "parallel_queue" parameter (it is used if value > 0):

{
   "task_a": {
   	...,
   	"parallel": "true",
   	"parallel_queue": "1"
   },
   "task_b": {
   	...,
   	"parallel": "true",
   	"parallel_queue": "2"
   },
   "task_c": {
   	...,
   	"parallel": "true",
   	"parallel_queue": "2"
   }
}

In this case: "task_a" and "task_b" started simultaneously, "task_c" started after "task_b" and execution goes next after "task_a" and "task_c" is done.

Start

You need dotnet runtime installed. Next steps is osX based, but Windows is also supported:

git clone https://github.com/KonH/DotNetCoreBuildServer.git
cd DotNetCoreBuildServer
dotnet restore
dotnet publish -c RELEASE

Next, you need to run server:

cd ConsoleClient/bin/Release/netcoreapp1.1/
dotnet ConsoleClient.dll -server=serverName -config=configName

Where:

  • serverName - your server name
  • configName - path to .json project config (you can set several config files, but at least one is required)

After that, your server is ready to use and works before you decide to stop it.

Usage

You can control your server with commands described below:

- "status" - current server status
- "buildName arg0 arg1 ... argN" - start build with given parameters
- "abort" - stop current build immediately
- "help" - show this message
- "help list" - show list of all builds available
- "stop" - stop server

Build process

Build tasks executed in described order, if one task failed, all next tasks are skipped. If build is done, last "message" is shown. If build is failed, full execution log is shown.

Slack integration usage

Using Slack integration, you can execute the same commands, when you mention your bot (at first word int your message). So, if you write in specific room:

@buildbot myBuild 1.0.0

It is recognized as:

myBuild 1.0.0

And build is started (if exists).

In any server response you can see server name:

konh [5:55 PM] 
@buildbot status

buildbotAPP [5:55 PM] 
[testServer]
 Server 0.1.0.0
Is busy: True
Services:
- ConsoleService
- SlackService
Builds:
- dev_build (tag)

You can use several servers (as many as you want), but if you don't need to duplicate builds, use unique build names at those servers (e.g. two servers: 'osxServer' and 'winServer', with builds: ['osx.x64'] and ['win.x32', 'win.x64'] respectively). Or you can start some builds with "check" command to execute them on concrete server.

Limitations

  • One build per time
  • You can stop current build on server, but it actually stops after current task is ended

Tasks

Run

  • Command output is shown as "message"
  • If "logfile" exists, "message" does not contain actual message, but contains path to log
  • To catch errors using non-zero exit code, use "error_exit_code"
  • To catch errors in output, use "error_regex"
  • To convert message to short "result", use "result_regex" (also, you can set "result_right_to_left" to "true" if you need to catch last match instead of first)
  • If application which you call can't write to stdout and support only external log files, you can enable "is_external_log" (optional) and provide log path to app and "log_file". When execution is done, log file will be processed as usual
  • If "warning_timeout" is set (in format: "10s", "5m", "1h") and NotificationService is active, you get notified if operation takes longer time to execute
{
	"task_name": {
		"run": {
			"path": "path_or_command",
			"args": "arguments",
			"work_dir": "work_directory",
			"error_regex": "regex_to_catch_errors",
			"error_exit_code": "true",
			"log_file": "path_to_logfile",
			"is_external_log": "false"
		}
	}
}

Examples:

{
	"fetch_last_repo": {
		"run": {
			"path": "git",
			"args": "fetch --all",
			"work_dir": "{root}/git_repo",
			"error_regex": "(error|fatal)"
		}
	}
}
{
	"upload_build": {
		"run": {
			"path": "svn",
			"args": "commit -m \"Build for {tag}.\"",
			"work_dir": "{root}/local_svn",
			"error_regex": "(error|Commit failed)",
			"log_file": "{root}/upload_log.txt",
			"result_regex": "(?<=Committed revision )([0-9]*)"
		}
	}
}

Print

{
	"task_name": {
		"print": {
			"message": "some_text"
		}
	}
}

Example:

{
	"build_report": {
		"print": {
			"message": "Build result rev.{upload_build:result}"
		}
	}
}

You can place this task as last place and collect all required data in its "message".

Check

You can check any values to given condition, if "silent" is set to "true", full build log is skipped:

"task_name": {
	"check": {
		"condition": "condition",
		"value": "{replacer}",
		"silent": "true"
	}
}

Example (next tasks run only on server with name = testServer, or failed without full log):

"only_on_testServer": {
	"check": {
		"condition": "testServer",
		"value": "{serverName}",
		"silent": "true"
	}
}

Check file exist/check dir exist

Failed, if file doesn't exist

{
	"task_name": {
		"check_file_exist": {
			"path": "path_to_file"
		}
	}
}
{
	"task_name": {
		"check_dir_exist": {
			"path": "path_to_dir"
		}
	}
}

Delete file/delete dir

Failed only if "if_exist": "true"

{
	"task_name": {
		"delete_file": {
			"path": "path_to_file",
			"if_exist": "true"
		}
	}
}
{
	"task_name": {
		"delete_dir": {
			"path": "path_to_dir",
			"if_exist": "true"
		}
	}
}

Copy file/copy dir

If you set "if_exist" : "false" (optional), operation will be ignored when source file isn't exist (by default it cause error):

{
	"task_name": {
		"copy_file": {
			"from": "fromPath",
			"to": "toPath",
			"if_exist" : "true"
		}
	}
}
{
	"task_name": {
		"copy_dir": {
		"if_exist" : "false"
			"from": "fromPath",
			"to": "toPath",
			"if_exist" : "true"
		}
	}
}

Make file/make dir

Make new directory:

{
	"task_name": {
		"make_dir": {
			"path": "pathToDir"
		}
	}
}

Make new file with given content (optional):

{
	"task_name": {
		"make_file": {
			"path": "pathToFile",
			"content": "fileContent"
		}
	}	
}

About

DotNetCoreBuildServer is a build system based on .NET Core with Slack integration

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages