Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
3d33d70
First (incomplete) version of git-restart
Jul 23, 2018
5edb020
Added more info to the .gemspec
Xasin Jul 23, 2018
d36b7b6
Renamed specification.rb to task.rb, began working on the logic
Xasin Jul 23, 2018
3dba00a
First version of the single task execution thread
Xasin Jul 24, 2018
97a2cb4
Simplified code execution significantly
Xasin Jul 25, 2018
6cf7489
Added proper start/stop/join commands
Xasin Jul 25, 2018
e1cfa3f
Added better status reporting
Xasin Jul 25, 2018
d54763c
Added more possible config options
Xasin Jul 25, 2018
2bcdb11
Added Guard and a test for GitRestart::Task
Xasin Jul 25, 2018
b08882e
Fixed class-wide `branch` and `modified` getter/setter
Xasin Jul 25, 2018
ed608e2
Added "triggered" option vs. "active", added `watch` and `on_branch`
Xasin Jul 25, 2018
cdb81a4
Added tests for all!
Xasin Jul 25, 2018
e45bd54
Began working on the runner file
Jul 26, 2018
b39d2ce
Added a proper error class for validation errors
Xasin Jul 26, 2018
a8a3853
Reworked the trigger mechanism to be dynamic
Xasin Jul 26, 2018
2f2257a
Better integration with the Runner class
Xasin Jul 26, 2018
f83e941
Rewrote to use the new integration of the runner class
Xasin Jul 26, 2018
b875eca
TOWARDS OUR GOAL, FELLOW FRIENDS
Xasin Jul 26, 2018
04c9a7e
Unified how tasks are stopped
Xasin Jul 30, 2018
d5f2f09
Added a task thread
Xasin Jul 30, 2018
45c6aee
Used _switch_to for all necessary actions
Xasin Jul 30, 2018
62b1db4
Test files! :D
Xasin Jul 30, 2018
a8c1ab2
Fixed wrong require statements
Xasin Jul 30, 2018
23e6914
Test file changes
Xasin Jul 30, 2018
45f2d6a
Debug messages
Xasin Jul 30, 2018
6358786
MOAR debug >:C
Xasin Jul 30, 2018
3d64805
'scuse the debug >.>
Xasin Jul 30, 2018
c521f86
Fixed check of `if(@branches)` to `not branches.empty?`
Xasin Jul 30, 2018
5b837f0
Fixed wrong argument order for `find`
Xasin Jul 30, 2018
07355fd
Fixed forgotten `split!`
Xasin Jul 30, 2018
43402b0
Slight tweak to the TestTask file
Xasin Jul 30, 2018
0c10807
Fixed missing PID-clear after task completion
Xasin Jul 30, 2018
edf50b3
Fixed wrong hash index used for commit selection
Xasin Jul 30, 2018
ac3f2dc
GitTask fixes
Xasin Jul 30, 2018
29f57b5
Whoopsie, shouldn't have been added!
Xasin Jul 30, 2018
d711a7d
Tried adding a self-testing script
Xasin Aug 2, 2018
701fe11
Changed error type fetch
Xasin Aug 2, 2018
5c7ef03
Testing with proper task name >.>
Xasin Aug 2, 2018
d3600a0
Forgot to enable error reporting
Xasin Aug 2, 2018
08bb3cc
Small changes, we'll see
Xasin Aug 2, 2018
c469828
Forgot to initialize lastStatus
Xasin Aug 2, 2018
cb7ba3b
Task needn't run if no targets are specified
Xasin Aug 2, 2018
4eea66f
Improvements to the trigger RegExp mechanism
Xasin Aug 2, 2018
56b4fdc
Added abort_on_exception and a dummy "update_status"
Xasin Aug 2, 2018
abda99f
Forgot to require minitest/autorun
Xasin Aug 2, 2018
3f04f83
Why wasn't this staged o.o'
Xasin Aug 2, 2018
8df629b
Reenabled log redirection
Xasin Aug 2, 2018
bff440d
Small delay might improve console output
Xasin Aug 2, 2018
e52ac89
This might work a bit better >.<
Xasin Aug 2, 2018
0d413e2
We only need the basename here, not the full name!
Xasin Aug 2, 2018
c47f182
Added a first version of the git-restart executable
Aug 6, 2018
6f340f2
Gemspec update to include executable
Aug 6, 2018
9360566
Improved usage of the git gem
Aug 6, 2018
78b4bb4
Slowly removing debugs :D
Aug 6, 2018
3e6aae7
Adding support for octokit
Aug 6, 2018
80f83dd
Added ci_task for tasks that shall always run
Aug 6, 2018
91213bc
Improved restart behavior
Aug 6, 2018
cd3101f
Added executable flags
Aug 6, 2018
a68f142
Merge branch 'master' into GIT_RESTART
Xasin Aug 6, 2018
8803277
Updated gemspec a bit, and fixed wrong REF
Xasin Aug 14, 2018
6f35005
Merge branch 'GIT_RESTART' of github.com:XasWorks/XasCode into GIT_RE…
Xasin Aug 14, 2018
5f543a3
Added the option of specifying task and runner files
Aug 17, 2018
3822e7d
Added reset before checkout and at_exit
Aug 17, 2018
1075c80
Merge branch 'GIT_RESTART' of github.com:XasWorks/XasCode into GIT_RE…
Aug 17, 2018
30d29c1
Added `current_commit` for later functions
Aug 28, 2018
10f5339
Added support for "above-dir" triggers
Aug 28, 2018
f2b8736
Logfiles in /tmp/ and proper status reporting!
Aug 28, 2018
285a2ec
Version bump
Aug 28, 2018
28aef24
Removed some derpy files
Xasin Aug 28, 2018
a2343b2
Allowed for any file to be loaded
Xasin Aug 28, 2018
1c0b4fa
Fixes for the new status message generation
Xasin Aug 28, 2018
ed71b6b
Testing of the new status message
Xasin Aug 28, 2018
b5a7aeb
Version bump
Xasin Aug 28, 2018
295b80b
Added gitignore for yard
Xasin Sep 3, 2018
02e4912
Added first GitRun task set
Xasin Sep 3, 2018
279d0c1
Merge branch 'master' into GIT_RESTART
Xasin Sep 3, 2018
bdcfc1b
incorrect setting of ci_task
Xasin Sep 3, 2018
f02bc60
Small fix to message name generation
Xasin Sep 3, 2018
562fcac
Merge branch 'GIT_RESTART' of github.com:XasWorks/XasCode into GIT_RE…
Xasin Sep 3, 2018
be05ded
Change to work with "Ruby/.gittask"
Xasin Sep 3, 2018
4bd6d8b
First batch of documentation, yay!
Xasin Sep 3, 2018
f848ed8
Added MQTT Task file
Xasin Sep 5, 2018
6c48af9
Added properly functioning test sequence
Xasin Sep 5, 2018
cbd3078
Final bunch of documentation written, README remains
Xasin Sep 5, 2018
9df8905
Tiny private
Xasin Sep 5, 2018
c3febff
Version boomp
Xasin Sep 5, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Ruby/.gitrun
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

$XAS_CI = true;

$runner = GitRestart::Runner.new do |r|
r.name = "XasStart CI";
r.repo = "XasWorks/XasCode";

r.mqtt = "mqtt://xasin.hopto.org";
r.octokit = Octokit::Client.new(netrc: true);

r.start_on = r.current_branch();
end
2 changes: 2 additions & 0 deletions Ruby/GitRestart/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.yardoc
doc
11 changes: 11 additions & 0 deletions Ruby/GitRestart/.gittask
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

GitRestart::Task.new do |t|
t.ci_task = true;
t.name = "GitRestart Task"

t.report_status = true;

t.active = true;

t.targets << "ruby tests/tc_task.rb"
end
9 changes: 9 additions & 0 deletions Ruby/GitRestart/Guardfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

# with Minitest::Unit
guard :minitest,
test_folders: ['tests'],
test_file_patterns: ["tc_*.rb"] do

watch(%r{^lib/git-restart/([^/]+)\.rb}) { |m| "tests/tc_#{m[1]}.rb"}
watch(%r{^tests/tc_(.*).rb})
end
22 changes: 22 additions & 0 deletions Ruby/GitRestart/bin/git-restart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/ruby

require 'mqtt/sub_handler.rb'
require 'git-restart/runner.rb'

puts "Starting runner ..."

$taskfiles = Array.new();
target = ".gitrun"
ARGV.each do |t|
if(t =~ /\.gitrun$/)
target = t;
else
$taskfiles << t;
end
end

raise ArgumentError, "No valid runner file specified!" unless File.exist? target

load target

GitRestart::Task.runner.mqtt.lockAndListen
27 changes: 27 additions & 0 deletions Ruby/GitRestart/git-restart.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Gem::Specification.new do |s|
s.name = 'git-restart'
s.version = '0.1.0'
s.summary = '(Re)start scripts and monitor them on a GitHub push'
s.description = 'This gem can be used to (re)start scripts whenever a GitHub push event is recorded.
The exit status of scripts can be monitored, and a failure can be sent back, making this capable of running simple tests too!'
s.authors = ['Xasin']

s.files = [ 'bin/git-restart',
'lib/git-restart/runner.rb',
'lib/git-restart/task.rb']

s.executables << 'git-restart'


s.homepage =
'https://github.com/XasWorks/XasCode/tree/master/Ruby/GitRestart'
s.license = 'GPL-3.0'

s.add_runtime_dependency "mqtt-sub_handler", "~> 0.1"
s.add_runtime_dependency "git", "~> 1.4"
s.add_runtime_dependency "octokit", "~> 4.0"

s.add_development_dependency "minitest"
s.add_development_dependency "guard"
s.add_development_dependency "guard-minitest"
end
237 changes: 237 additions & 0 deletions Ruby/GitRestart/lib/git-restart/runner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@

require 'mqtt/sub_handler'

require 'git'
require 'octokit'

require_relative "task.rb"

module GitRestart
class Runner
# Sets a name for this Runner, used for reporting to GitHub
attr_accessor :name

# Which repository to listen to. Uses "Owner/Repo" syntax.
attr_accessor :repo
# A white- and blacklist of branches. If neither are specified, all are used.
# If the whitelist is used, only it is considered.
attr_accessor :branches, :exclude_branches
# Which branch to start on.
# This not only makes the system switch branch, but it will also execute
# ALL active tasks. Very useful for auto-updating servers.
attr_accessor :start_on
# A list of tasks that this Runner will actually look at.
# If nil, all tasks are allowed.
attr_accessor :allowed_tasks

attr_reader :next_tasks
attr_reader :current_task_file

# The MQTT::SubHandler to use to listen to GitHub updates.
# Can be specified as either MQTT::SubHandler class or String, the latter
# will be interpreted as URI
attr_reader :mqtt
# Octokit to use for optional status reporting
attr_accessor :octokit

# @return [String] Full SHA of the current commit
def current_commit()
@git.object("HEAD").sha;
end
# @return [String] Name of the current branch
def current_branch()
@git.current_branch();
end
# @return [Array<String>] A list of all files that were modified in the commit we are checking
def current_modified()
@current_modified;
end

def initialize(fileList = nil)
raise ArgumentError, "File list needs to be nil or an Array!" unless (fileList.is_a? Array or fileList.nil?)

GitRestart::Task.runner = self;

@allowed_tasks = Array.new();
@allowed_tasks << fileList if(fileList);
@allowed_tasks << $taskfiles unless($taskfiles.empty?)

@current_tasks = Hash.new();
@next_tasks = Hash.new();

@branches = Array.new();
@exclude_branches = Array.new();

@branchQueue = Queue.new();

@git = Git.open(".");

yield(self);

@allowed_tasks.flatten!

@listenedSub = @mqtt.subscribe_to "GitHub/#{@repo}" do |data|
begin
data = JSON.parse(data, symbolize_names: true);
rescue
next;
end

next unless data[:branch];
if(not @branches.empty?)
next unless @branches.include? data[:branch];
elsif(not @exclude_branches.empty?)
next if @exclude_branches.include? data[:branch];
end

@branchQueue << data;
end

autostart();
_start_task_thread();

at_exit {
_stop_all_tasks();
}
end

# Update the GitHub status for the task of given name, with optional status message
# Only prints a line if no octokit is specified
def update_status(name, newStatus, message = nil)
puts "Task #{name} assumed a new status: #{newStatus}#{message ? " MSG:#{message}" : ""}"

return unless @octokit;

begin
@octokit.create_status(@repo, current_commit(), newStatus, {
context: "#{name}/#{name}".gsub(" ", "_"),
description: message,
})
rescue
end
end

# Start the task responsible for queueing and executing the individual
# task stop, branch switch, task start cycles
def _start_task_thread()
@taskThread = Thread.new do
loop do
newData = @branchQueue.pop;

@current_modified = newData[:touched];
_switch_to(newData[:branch], newData[:head_commit]);
end
end.abort_on_exception = true;
end
private :_start_task_thread

# Stop all tasks of the given hash, not list. Waits for them to stop.
def _stop_tasks(taskList)
taskList.each do |name, t|
t.stop();
end
taskList.each do |name, t|
t.join();
@current_tasks.delete(name);
end
end
private :_stop_tasks
def _stop_all_tasks()
_stop_tasks(@current_tasks);
end
private :_stop_all_tasks
# Stop all tasks that have marked themselves as affected by the
# current set of file-changes. This way, applications are only
# restarted when their own files have been altered.
def _stop_triggered_tasks()
_stop_tasks(@current_tasks.select {|k,v| v.triggered?});
end
private :_stop_triggered_tasks

# Scan through the file-tree for .gittask files, or use the @allowed_tasks
# list of tasks.
def _generate_next_tasks()
puts "Generating new tasks..."
@next_tasks = Hash.new();

taskFiles = `find ./ -nowarn -iname "*.gittask"`
[taskFiles.split("\n"), @allowed_tasks].flatten.each do |t|
puts "Looking at: #{t}"
t.gsub!(/^\.\//,"");
@current_task_file = t;

unless(@allowed_tasks.empty?)
next unless @allowed_tasks.include? @current_task_file
end

begin
load(t);
rescue ScriptError, StandardError
update_status("File #{t}", :failure, "File could not be parsed!")
puts("File #{t} could not be loaded!");
rescue GitRestart::TaskValidityError
update_status("File #{t}", :failure, "Task-file not configured properly!")
puts("Task-File #{t} is not configured properly!");
end
end

puts "Finished loading! Next tasks: #{@next_tasks.keys}"
end
private :_generate_next_tasks

# Start all new tasks that have marked themselves as affected by the current
# set of filechanges
def _start_next_tasks()
_generate_next_tasks();

puts "\nStarting next tasks!"
@next_tasks.each do |name, t|
next unless t.active;
next unless t.triggered?

t.start();
@current_tasks[name] = t;
end
end
private :_start_next_tasks

# Perform an entire cycle of git fetch & checkout, stop tasks, pull, restart.
# *CAUTION* A HARD RESET IS USED HERE
def _switch_to(branch, commit = nil)
puts "\n\nSwitching to branch: #{branch}#{commit ? ",commit: #{commit}" : ""}"

begin
@git.fetch();
rescue
end

if(branch != current_branch())
_stop_all_tasks();
else
_stop_triggered_tasks();
end
@git.reset_hard();
@git.checkout(branch);
@git.merge("origin/#{branch}");

@git.reset_hard(commit);

_start_next_tasks();
end
private :_switch_to

def autostart()
return unless @start_on;
@branchQueue << {branch: @start_on};
end
private :autostart

def mqtt=(mqtt)
if(mqtt.is_a? String)
@mqtt = MQTT::SubHandler.new(mqtt);
else
@mqtt = mqtt;
end
end
end
end
Loading