Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add configurable and extensible git hooks #1

Open
wants to merge 49 commits into
base: 7.x-3.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
c00f59c
Issue #2897894: Add configurable "Git Hooks" to site nodes:
jonpugh Jul 27, 2017
4039f49
If user's don't select anything, set to "none" so that the task uses …
jonpugh Jul 27, 2017
d5aff35
Issue #2897894: Get list of site aliases using _drush_sitealias_find_…
jonpugh Jul 28, 2017
efb86a8
Issue #2897894: Add a post hosting checkout and pull hook to queue pl…
jonpugh Jul 28, 2017
0027e84
Unset hooks value when skip_hooks is enabled.
jonpugh Jul 28, 2017
69099a6
Issue #2897894: Add hooks form elements to Git Pull task form.
jonpugh Jul 28, 2017
5d7d155
Issue #2897894: Add hooks container element so that we can hide it wh…
jonpugh Jul 28, 2017
8931f7e
Merge branch '7.x-3.x' into 2897894-git-hooks
jonpugh Aug 31, 2017
4b2bb77
Merge branch '7.x-3.x' into 2897894-git-hooks
jonpugh Sep 8, 2017
0e922c1
Display enabled git hooks.
jonpugh Sep 8, 2017
25bcf0c
Set property git_hooks in platform as well.
jonpugh Sep 8, 2017
b4786e8
Apply git_hooks property to platform as well.
jonpugh Sep 8, 2017
9ade4a8
Don't show the hook if it's not set to run.
jonpugh Sep 8, 2017
bc3e09d
Move field validation to common module.
jonpugh Sep 8, 2017
4689195
Show a message if there are no hooks.
jonpugh Sep 8, 2017
96eeebf
If not allowed to override hooks, set a hidden form value so hooks ar…
jonpugh Sep 8, 2017
f291bd3
Add missing quotes
helmo Sep 8, 2017
5468707
Do not consider deleted and disabled sites when running hooks
helmo Nov 22, 2017
2fd4ba5
whitespace fixes
helmo Nov 22, 2017
55edade
remove unused placeholder
helmo Nov 23, 2017
063371d
If the path of the repo already exists, check to make sure the git re…
jonpugh Dec 19, 2017
fcec6a2
Use 'success' as the drush log type.
jonpugh Dec 19, 2017
e4cd4ee
Merge branch '7.x-3.x' into 2897894-git-hooks
jonpugh Dec 19, 2017
1c3ffc5
Look for composer.json file and run composer install if present.
jonpugh Dec 19, 2017
a308c8c
Merge branch '7.x-3.x' into 2897894-git-hooks
jonpugh Dec 19, 2017
694665e
Use hook_name as array key for easy lookups.
jonpugh Dec 19, 2017
13ae63b
- Add "Composer install" as a git hook.
jonpugh Dec 19, 2017
983d5bb
Remove composer install on verify task.
jonpugh Jan 29, 2018
27f2338
Better form desscription.
jonpugh Jan 29, 2018
1c79c11
Typo
jonpugh Jan 29, 2018
693c6c2
Issue #2897894: Add "git hooks" to allow extensible reactions to Git …
jonpugh Jan 29, 2018
10be3a1
If there are no git hooks, label "none"
jonpugh Jan 29, 2018
1d24d36
Add api docs
helmo Jan 30, 2018
79d244d
Now that issue is fixed, putting back the repo delete function https:…
jonpugh Jan 30, 2018
5d71050
Merge branch '7.x-3.x' into 2897894-git-hooks
jonpugh Jan 31, 2018
92d3bc4
Allow repo_url and git_ref to be NULL in hook_schema.
jonpugh Feb 14, 2018
aba8f81
Fix checks to load or save data by creating a method to check if the …
jonpugh Feb 14, 2018
71918ee
Change how forms are generated: if verified, set as value so data is …
jonpugh Feb 15, 2018
83aefd8
Remove composer install git hook. Provision now runs it automatically…
jonpugh Feb 15, 2018
d75017f
Fix lost repo_path value on platform submit.
jonpugh Feb 15, 2018
3b864df
Fix output on form and node view for sites. Set repo_path to the sit…
jonpugh Feb 15, 2018
7ec6e37
Look for active verify task. If there is one, block access to form el…
jonpugh Feb 15, 2018
98ec24f
Custom revert of 13ae63bd5742a94333d96547a5e23648f3b6bce1
jonpugh Feb 16, 2018
4c010a8
Add .travis.yml file and .travis.make file for building the drupal co…
jonpugh Feb 16, 2018
bc0a253
Add a --help call to debug.
jonpugh Feb 16, 2018
528faff
Use hosting-git-tests branch.
jonpugh Feb 16, 2018
6295e6f
Changing docker compose command signature
jonpugh Feb 16, 2018
e8b3fef
For now, add chmod 777 to composer.lock.
jonpugh Feb 16, 2018
f77a671
Merge branch '2897894-git-hooks' of github.com:aegir-project/hosting_…
jonpugh Feb 16, 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
15 changes: 15 additions & 0 deletions .travis.make
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
core = 7.x
api = 2

projects[drupal][type] = "core"

# Load 3.x branch of hostmaster.
projects[hostmaster][type] = "profile"
projects[hostmaster][version] = "3.x"

# Override source of hosting module download.
# .travis.yml puts hosting module at /source/hosting_git
projects[hosting_git][type] = "module"
projects[hosting_git][subdir] = "aegir"
projects[hosting_git][download][type] = "copy"
projects[hosting_git][download][url] = "/source/hosting_git"
49 changes: 49 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
language: generic

sudo: required

env:
globaL:
- DOCKER_VERSION=1.11.2-0~trusty
- DOCKER_COMPOSE_VERSION=1.7.1
- AEGIR_HOSTING_VERSION=7.x-3.x
- AEGIR_TESTS_VERSION=hosting-git-tests

#env:
# - test: Ubuntu 14.04 Apache
# distribution: ubuntu
# version: 14.04
# init: /sbin/init
# run_opts: ""

addons:
hosts:
- aegir.travis
- sitetest.aegir.travis

services:
- docker

before_install:
# Show travis build dir variable.
- echo $TRAVIS_BUILD_DIR

# Get test scripts
- git clone http://github.com/aegir-project/tests.git /home/travis/build/aegir-project/tests
- cd /home/travis/build/aegir-project/tests
- git checkout $AEGIR_TESTS_VERSION

# Run prepare scripts.
- cd /home/travis/build/aegir-project/tests/travis
- sudo bash prepare-docker.sh
- bash prepare-testenv.sh
- sudo chmod 777 ../composer.lock

script:

# Tests are included in the docker-compose.yml file in the tests repo.
- docker-compose run --help
- sudo docker-compose -f docker-compose-hostmaster.yml run
-e AEGIR_MAKEFILE=/source/hosting_git/.travis.make
-v $TRAVIS_BUILD_DIR:/source/hosting_git
hostmaster
14 changes: 12 additions & 2 deletions checkout/drush/provision_git_checkout.drush.inc
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@
* Implementation of hook_drush_command().
*/
function provision_git_checkout_drush_command() {

$hooks = provision_git_hooks();
$available_hooks = implode(', ', array_keys($hooks));

$items['provision-git-checkout'] = array(
'description' => 'Git checkout a branch or tag in a specified location.',
'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
'arguments' => array(
'git_ref' => dt('Parameter for the git checkout command'),
),
'options' => array(
'new_branch' => "Optional: If the branch doesn't exist, create it. Equivalent to git checkout -b branchname"
)
'new_branch' => "Optional: If the branch doesn't exist, create it. Equivalent to git checkout -b branchname",
'hooks' => "Override the hooks to run after git checkout. Separate with a comma. Available hooks include ". $available_hooks

),
);
return $items;
}
Expand Down Expand Up @@ -77,6 +83,10 @@ function drush_provision_git_checkout($git_ref = '') {
* Implements drush_hook_post_COMMAND().
*/
function drush_provision_git_checkout_post_provision_git_checkout() {

// Run all hooks on updated sites
provision_git_run_git_hooks();

// Re-verify the site, this corrects the file permission when necessary.
$options = array();
$target = d()->uri;
Expand Down
46 changes: 46 additions & 0 deletions checkout/hosting_git_checkout.module
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,52 @@ function hosting_task_git_checkout_form($node) {
'#weight' => '-1',
'#default_value' => TRUE,
);
$form['skip_hooks'] = array(
'#title' => t('Skip git hooks'),
'#description' => t("Do not run git hooks after running git checkout.") . ' <em>' . t('Warning: This may result in an unstable site if a database update is required') . '</em>',
'#type' => 'checkbox',
'#weight' => '0',
'#default_value' => FALSE,
'#access' => variable_get('hosting_git_allow_skip_hooks', FALSE),
);
$form['git_hooks'] = array(
'#title' => t('Git Hooks'),
'#weight' => '1',
'#type' => 'checkboxes',
'#default_value' => $node->git['git_hooks'],
'#access' => variable_get('hosting_git_allow_task_override_hooks', FALSE),
'#options' => hosting_git_get_hook_options(),
'#states' => array(
'invisible' => array(
':input[name="parameters[skip_hooks]"]' => array('checked' => TRUE),
),
),
'#element_validate' => array(
'hosting_git_hooks_implode'
)
);

$form['hooks'] = array(
'#type' => 'container',
'#states' => array(
'invisible' => array(
':input[name="parameters[skip_hooks]"]' => array('checked' => TRUE),
),
),
);

// Invoke hook_hosting_git_hooks().
$hooks = module_invoke_all('hosting_git_hooks');
foreach ($hooks as $name => $hook) {
$name = ucfirst($name);
$items[] = "<label>$name:</label> " . $hook['description'];
}
$form['hooks']['hooks_display'] = array(
'#type' => 'item',
'#title' => t('Git Hooks'),
'#markup' => theme('item_list', array('items' => $items)),
'#access' => !variable_get('hosting_git_allow_task_override_hooks', FALSE),
);

return $form;
}
2 changes: 2 additions & 0 deletions drush/Provision/Service/git.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ static function subscribe_platform($context) {
$context->setProperty('repo_path');
$context->setProperty('deploy_from_git');
$context->setProperty('git_ref');
$context->setProperty('git_hooks');
}

static function subscribe_site($context) {
$context->setProperty('repo_url');
$context->setProperty('deploy_from_git');
$context->setProperty('git_ref');
$context->setProperty('git_hooks');
}

}
148 changes: 146 additions & 2 deletions drush/provision_git.drush.inc
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,8 @@ function drush_provision_git_provision_verify_validate() {
case 'platform':
default:
$context_type = 'Platform';
$repo_path = d()->root;
$path_exists = provision_file()->exists(d()->root)->status();
$repo_path = d()->repo_path;
$path_exists = provision_file()->exists(d()->repo_path)->status();
break;
}
// If the platform path doesn't exist, we will clone it.
Expand All @@ -380,6 +380,25 @@ function drush_provision_git_provision_verify_validate() {
drush_log(dt("$context_type path does not exist. Invoking provision-git-clone."), 'ok');
provision_backend_invoke(d()->name, 'provision-git-clone');
}

// Path already exists: check if remotes match.
else {
// If our repo_url is not found as a remote, show a warning.
drush_shell_cd_and_exec($repo_path, 'git remote -v');
$output = drush_shell_exec_output();
if (strpos(implode(',', $output), d()->repo_url) === FALSE) {
drush_log(dt('The git repository located at !path did not have the repository !remote set as a remote. Please check the platform repo URL and git remotes and try again.', [
'!path' => $repo_path,
'!remote' => d()->repo_url,
]), 'warning');
}
else {
drush_log(dt('Clone of !remote found at !path. Continuing verification.', [
'!path' => $repo_path,
'!remote' => d()->repo_url,
]), 'success');
}
}
}
else {
// Check to see if we can puick up on existing Git info.
Expand Down Expand Up @@ -501,3 +520,128 @@ function provision_git_provision_services() {
provision_git_register_autoload();
return array('git' => NULL);
}

/**
* Load all available git hooks.
* @return mixed
*/
function provision_git_hooks() {
// Invoke hook_provision_git_hooks().
$hooks = drush_command_invoke_all('provision_git_hooks');
return $hooks;
}

/**
* Implements hook_provision_git_hooks();
* @return array
*/
function provision_git_provision_git_hooks() {
return array(
'update' => 'provision-update',
'cache' => 'provision-flush_cache',
'registry' => 'provision-rebuild_registry',
'revert' => 'provision-features_revert_all',
);
}

/**
* Run all drush commands listed in the 'git_hooks' property of the drush alias.
*
* If run when a platform is active,
*/
function provision_git_run_git_hooks() {

if (drush_get_option('skip-hooks', FALSE)) {
drush_log('Skipping git hooks, as requested. Be aware the site might need database updates.', 'ok');
return;
}

// Run post-git-pull hooks.
$sites = array();
if (d()->type == 'site') {
$sites[] = d()->name;
}
elseif (d()->type == 'platform') {

// Get a list of all that use this platform.
$aliases_files = _drush_sitealias_find_alias_files();
$aliases = array();
foreach ($aliases_files as $filename) {
if ((@include $filename) === FALSE) {
drush_log(dt('Cannot open alias file "!alias", ignoring.', array('!alias' => realpath($filename))), LogLevel::BOOTSTRAP);
continue;
}
}

foreach ($aliases as $alias_name => $alias) {
// If the alias is a site and platform is a match, load it into our sites list.
if (isset($alias['context_type']) && $alias['context_type'] == 'site' && $alias['platform'] == d()->name) {

// Use the URI as the key to prevent duplicate sites. Project aliases get included.
// I'm using URI as the value as well because DevShop writes additional aliases which are copies. We want to be sure to use the Aegir-generated alias name
$sites[$alias['uri']] = $alias['uri'];
}
}

drush_log(dt('Found %num sites on this platform: %sites', array(
'%num' => count($sites),
'%sites' => implode(', ', $sites),
)), 'ok');
}

drush_log(dt('Running git hooks for %num sites.', array(
'%num' => count($sites),
)), 'ok');

$hook_commands = provision_git_hooks();
foreach ($sites as $site) {
// @TODO: Gotta figure out a way to put this in the Git service.
if (is_array(d($site)->git_hooks)) {

// Allow overriding what hooks to run on the command line.
$hooks = drush_get_option('hooks', d($site)->git_hooks);
if (is_string($hooks)) {
$hooks = explode(',', $hooks);
}
$hooks = array_intersect($hooks, array_keys($hook_commands));

if (empty($hooks)) {
drush_log(dt('No hooks to invoke on site %site. Check drush context.', array(
'%site' => $site,
)), 'ok');
}
elseif (drush_get_option('hooks')) {
drush_log(dt('hooks option detected: Running %num git hooks on site %site: %hooks.', array(
'%num' => count($hooks),
'%hooks' => implode(', ', $hooks),
'%site' => $site,
)), 'ok');
}
else {
drush_log(dt('Using default git hooks for the site %site: %hooks.', array(
'%num' => count($hooks),
'%hooks' => implode(', ', $hooks),
'%site' => $site,
)), 'ok');
}

foreach ($hooks as $hook) {
drush_log(dt('Invoking git hook "%hook" on site %site: %command', array(
'%site' => $site,
'%hook' => $hook,
'%command' => $hook_commands[$hook],
)), 'ok');
provision_backend_invoke($site, $hook_commands[$hook]);
}

if (empty(d($site)->git_hooks)) {
drush_log(dt('No hooks to invoke. Check drush context.'), 'ok');
}
}
else {
drush_log(dt('No hooks to invoke in site %site.', array(
'%site' => $site,
)), 'ok');
}
}
}
44 changes: 40 additions & 4 deletions hosting_git.admin.inc
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,55 @@
*/
function hosting_git_settings_form() {
$form = array();
$form['deploy'] = array(

$form['hooks'] = array(
'#type' => 'fieldset',
'#title' => t('Git Hooks'),
);
$form['hooks']['hosting_git_default_hooks'] = array(
'#type' => 'checkboxes',
'#title' => t('Default git hooks:'),
'#description' => t('Choose the default hooks to use for new sites and platforms.'),
'#options' => hosting_git_get_hook_options(),
'#default_value' => variable_get('hosting_git_default_hooks', ['update', 'cache']),
);
$form['hooks']['hosting_git_allow_skip_hooks'] = array(
'#type' => 'checkbox',
'#title' => t('Allow users to skip git hooks when running Git Checkout or Git Pull.'),
'#default_value' => variable_get('hosting_git_allow_skip_hooks', FALSE),
);
$form['hooks']['hosting_git_allow_task_override_hooks'] = array(
'#type' => 'checkbox',
'#title' => t('Allow users to change git hooks when running Git Checkout or Git Pull.'),
'#default_value' => variable_get('hosting_git_allow_task_override_hooks', FALSE),
);
$form['sites'] = array(
'#type' => 'fieldset',
'#title' => t('Deploy from Git'),
'#title' => t('Sites'),
);
$form['deploy']['hosting_git_allow_deploy_site'] = array(
$form['sites']['hosting_git_allow_deploy_site'] = array(
'#type' => 'checkbox',
'#title' => t('Allow deploying sites from git repositories.'),
'#default_value' => variable_get('hosting_git_allow_deploy_site', TRUE),
);
$form['deploy']['hosting_git_allow_deploy_platform'] = array(
$form['sites']['hosting_git_allow_hooks_site'] = array(
'#type' => 'checkbox',
'#title' => t('Allow sites to have configurable git hooks.'),
'#default_value' => variable_get('hosting_git_allow_hooks_site', TRUE),
);
$form['platforms'] = array(
'#type' => 'fieldset',
'#title' => t('Platforms'),
);
$form['platforms']['hosting_git_allow_deploy_platform'] = array(
'#type' => 'checkbox',
'#title' => t('Allow deploying platforms from git repositories.'),
'#default_value' => variable_get('hosting_git_allow_deploy_platform', TRUE),
);
$form['platforms']['hosting_git_allow_hooks_platform'] = array(
'#type' => 'checkbox',
'#title' => t('Allow platforms to have configurable git hooks.'),
'#default_value' => variable_get('hosting_git_allow_hooks_platform', TRUE),
);
return system_settings_form($form);
}
Loading