Skip to content

Commit

Permalink
Create sandbox environment
Browse files Browse the repository at this point in the history
  • Loading branch information
RichardDavies authored and BTS eGov committed Apr 11, 2024
1 parent 208d432 commit 4bb98ad
Show file tree
Hide file tree
Showing 14 changed files with 373 additions and 0 deletions.
56 changes: 56 additions & 0 deletions sandbox.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Sandbox Environment

## Description

The `sandbox` branch creates a long-living multidev that provides a permanently available sandbox environment that mirrors production where editors can safely practice and use the CMS without fear of messing up the live site.

This environment can be used for guided training classes, self learning, or experimentation, etc.

## Environment Updates

### Code Syncing

This environment should be a replica of the live site so it needs to be updated as part of the deployment process in order to stay in sync with the live site.

This happens automatically thanks to a Pantheon Quicksilver script that runs on deployments to Live and triggers a GitHub action that rebases the sandbox branch with master.

If you need to do this manually, run these commands to update this branch:

```
git checkout sandbox
git rebase origin/master
git push -f
```

If the master branch is already ahead of the Live site, you'll need to find the commit ID belonging to the Live site deployment. This can be found in the Code section of the Pantheon dashboard. (Ignore the first "CircleCI deployment" commit&mdash;it's the second commit ID you want.) Use this rebase command instead of the above one: `git rebase <commit-ID>`

### Content Syncing

The database content also needs to be periodically updated by cloning the database from Live. (Please note that this will destroy any existing "test content" previously created on the site.)

This happens automatically thanks to a CircleCI trigger that is scheduled to run every Monday morning. This runs the "Update Sandbox Database" CircleCI workflow which executes a Terminus command to clone the Live database to Sandbox, runs `drush deploy`, reindexes Solr, and executes a Percy test that adds the sandbox alert notification to the site.

If you need to do this manually, follow these steps:

1. Run `lando terminus env:clone-content employees.live sandbox --db-only`
2. Run `lando terminus drush employees.sandbox deploy`
3. Reindex the Solr index(es)
4. Create and publish an informational `Sandbox Site` alert with the following text:

```This sandbox site is a copy of employees.portland.gov and is intended to provide a safe environment for editor training classes, self learning, or experimentation, etc. Changes made here will not affect the live site and cannot be imported into the live site.```

## Sandbox Branch Code Changes

This branch should only have one code change from the `master` branch:
* `sandbox.md` (This file)

Sometimes due to certain types of code changes in master, the automated rebase that keeps this branch's code up to date with master doesn't work perfectly and this branch ends up with inadvertent additional code changes to other files besides `sandbox.md`. Sometimes these extra changes will cause Sandbox builds to fail.

If the Sandbox PR in Github shows that there are more than one files changed, you need to do the following manual cleaup steps in VS Code to remove these extraneous code changes:

1. Run `git checkout sandbox`
2. Run `git pull --rebase`
3. In the VS Code source control panel, click the &hellip; "More actions" icon and select Commit->Undo Last Commit
4. The source control panel will now show all of the changed files under the "Staged Changes" section. Click the &mdash; icon next to each file to unstage all changes except `sandbox.md`. This moves the changed files to the "Changes" section.
5. Click the &#8634; icon to discard all of the changes in the "Changes" section. This should leave the future commit with only one staged change: `sandbox.md`. Commit the change.
6. Run `git push -f`
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

namespace Drupal\portland_groups\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityFormBuilderInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\group\Entity\Controller\GroupContentController;
use Drupal\group\Entity\GroupInterface;
use Drupal\group\Plugin\GroupContentEnablerManagerInterface;
use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\group\Entity\GroupContentType;
use Drupal\node\Entity\NodeType;
use Drupal\media\Entity\MediaType;

use Drupal\Core\Config\Entity;
use Symfony\Component\HttpKernel;
use Drupal\Core\Plugin;

/**
* Returns responses for 'group_node' GroupContent routes.
*/
class PortlandGroupContentController extends GroupContentController {

/**
* {@inheritdoc}
*/
public function addPage(GroupInterface $group, $create_mode = FALSE) {

$build = GroupContentController::addPage($group, $create_mode);

// Do not interfere with redirects.
if (!is_array($build)) {
return $build;
}

// Overwrite the label and description for all of the displayed bundles.
$storage_handler = $this->entityTypeManager->getStorage('node_type');
$page_bundles = $this->addPageBundles($group, $create_mode);
// NOTE: ksort is working here, but bundle types are still displayed out of order.
// there must be some other sorting process that occurs after this point.
ksort($page_bundles);
// we need the $build['#bundles'] array to be sorted the same as $page_bundles, but it's
// being handed to us sorted by plugin_id, which doens't map well to the bundle machine names.
// we need to build a new array based on the foreach order below.
$new_bundles = [];
foreach ($page_bundles as $plugin_id => $bundle_name) {
// Don't process Media types. They are handled by PortlanMediaController next door.
if(strpos($plugin_id, 'group_media:') === 0) {
unset($build['#bundles'][$bundle_name]);
continue;
}
if (!empty($build['#bundles'][$bundle_name])) {
$plugin = $group->getGroupType()->getContentPlugin($plugin_id);
$bundle_label = $storage_handler->load($plugin->getEntityBundle())->label();
$bundle_id = $storage_handler->load($plugin->getEntityBundle())->id();
$bundle_desc = \Drupal::config('node.type.' . $bundle_id)->get('description');
$t_args = ['%node_type' => $bundle_label];

$new_bundles[$bundle_name] = $build['#bundles'][$bundle_name];
$new_bundles[$bundle_name]['label'] = $bundle_label;
$new_bundles[$bundle_name]['description'] = $bundle_desc;
// build custom link text; this overrides the link text created in the GroupNodeDeriver
$new_bundles[$bundle_name]['add_link']->setText(t('Add ' . $bundle_label));
}
}

$build['#bundles'] = $new_bundles;
return $build;
}

/**
* The _title_callback for the entity.group_content.create_form route.
*
* @param \Drupal\group\Entity\GroupInterface $group
* The group to create the group content in.
* @param string $plugin_id
* The group content enabler to create content with.
*
* @return string
* The page title.
*/
public function createFormTitle(GroupInterface $group, $plugin_id) {
/** @var \Drupal\group\Plugin\GroupContentEnablerInterface $plugin */
$plugin = $group->getGroupType()->getContentPlugin($plugin_id);
$entity_type = $plugin->getEntityTypeId();
switch ($entity_type) {
case "media":
$content_type = MediaType::load($plugin->getEntityBundle());
break;
case "node":
$content_type = NodeType::load($plugin->getEntityBundle());
break;
default:
$content_type = "undefined";
}
$return = $this->t('Create @name in @group', ['@name' => $content_type->label(), '@group' => $group->label()]);
return $return;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
uuid: 26523f2b-d87d-4147-8cef-aec58afcf91c
langcode: en
status: true
dependencies:
config:
- field.storage.group.field_has_contracts
- group.type.employee
id: group.employee.field_has_contracts
field_name: field_has_contracts
entity_type: group
bundle: employee
label: 'Has Contracts'
description: ''
required: false
translatable: false
default_value:
-
value: 0
default_value_callback: ''
settings:
on_label: 'Yes'
off_label: 'No'
field_type: boolean
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
uuid: 03df5b6a-2f36-41fc-9241-7f502a0024c4
langcode: en
status: true
dependencies:
module:
- field_permissions
- group
third_party_settings:
field_permissions:
permission_type: custom
id: group.field_has_contracts
field_name: field_has_contracts
entity_type: group
type: boolean
settings: { }
module: core
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false
17 changes: 17 additions & 0 deletions web/sites/default/config/group.role.employee-1ab877bcd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
uuid: b9f42175-d143-4db1-856e-43ab16a7cfd4
langcode: en
status: true
dependencies:
config:
- group.type.employee
enforced:
config:
- user.role.content_lead
id: employee-1ab877bcd
label: 'Content Lead'
weight: -7
internal: true
audience: outsider
group_type: employee
permissions_ui: false
permissions: { }
17 changes: 17 additions & 0 deletions web/sites/default/config/group.role.employee-3e5cf4b4d.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
uuid: f8a46374-5d12-4931-abe3-4ecc75459576
langcode: en
status: true
dependencies:
config:
- group.type.employee
enforced:
config:
- user.role.311_support_agent
id: employee-3e5cf4b4d
label: '311 Support Agent'
weight: -4
internal: true
audience: outsider
group_type: employee
permissions_ui: false
permissions: { }
17 changes: 17 additions & 0 deletions web/sites/default/config/group.role.employee-631a7fe0a.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
uuid: db73e9e0-34fe-4118-8821-a6cb5e41fdd2
langcode: en
status: true
dependencies:
config:
- group.type.employee
enforced:
config:
- user.role.311_lead
id: employee-631a7fe0a
label: '311 Lead'
weight: -3
internal: true
audience: outsider
group_type: employee
permissions_ui: false
permissions: { }
17 changes: 17 additions & 0 deletions web/sites/default/config/group.role.employee-855450a16.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
uuid: 66fbc858-d1cc-470c-90ce-f05f0d8909f7
langcode: en
status: true
dependencies:
config:
- group.type.employee
enforced:
config:
- user.role.publisher
id: employee-855450a16
label: Publisher
weight: -5
internal: true
audience: outsider
group_type: employee
permissions_ui: false
permissions: { }
17 changes: 17 additions & 0 deletions web/sites/default/config/group.role.employee-a416e6833.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
uuid: 8fd2b688-c9a4-4757-9e94-e095e8e710d3
langcode: en
status: true
dependencies:
config:
- group.type.employee
enforced:
config:
- user.role.administrator
id: employee-a416e6833
label: 'Site Administrator'
weight: -6
internal: true
audience: outsider
group_type: employee
permissions_ui: false
permissions: { }
17 changes: 17 additions & 0 deletions web/sites/default/config/group.role.private-1ab877bcd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
uuid: 90debd6f-0edc-4edc-a265-40f8395484b6
langcode: en
status: true
dependencies:
config:
- group.type.private
enforced:
config:
- user.role.content_lead
id: private-1ab877bcd
label: 'Content Lead'
weight: -7
internal: true
audience: outsider
group_type: private
permissions_ui: false
permissions: { }
17 changes: 17 additions & 0 deletions web/sites/default/config/group.role.private-3e5cf4b4d.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
uuid: df5977ae-1801-4cc7-96f8-c1212e556639
langcode: en
status: true
dependencies:
config:
- group.type.private
enforced:
config:
- user.role.311_support_agent
id: private-3e5cf4b4d
label: '311 Support Agent'
weight: -4
internal: true
audience: outsider
group_type: private
permissions_ui: false
permissions: { }
17 changes: 17 additions & 0 deletions web/sites/default/config/group.role.private-631a7fe0a.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
uuid: daa9595a-0fd4-4f78-a8cc-a593f0fabbea
langcode: en
status: true
dependencies:
config:
- group.type.private
enforced:
config:
- user.role.311_lead
id: private-631a7fe0a
label: '311 Lead'
weight: -3
internal: true
audience: outsider
group_type: private
permissions_ui: false
permissions: { }
17 changes: 17 additions & 0 deletions web/sites/default/config/group.role.private-855450a16.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
uuid: ccd16f26-a25d-4029-9341-fe4190d08ea8
langcode: en
status: true
dependencies:
config:
- group.type.private
enforced:
config:
- user.role.publisher
id: private-855450a16
label: Publisher
weight: -5
internal: true
audience: outsider
group_type: private
permissions_ui: false
permissions: { }
17 changes: 17 additions & 0 deletions web/sites/default/config/group.role.private-a416e6833.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
uuid: 474a1a90-c157-411d-aafd-ad18b9fd0953
langcode: en
status: true
dependencies:
config:
- group.type.private
enforced:
config:
- user.role.administrator
id: private-a416e6833
label: 'Site Administrator'
weight: -6
internal: true
audience: outsider
group_type: private
permissions_ui: false
permissions: { }

0 comments on commit 4bb98ad

Please sign in to comment.