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

VACMS-16851: cms next gh worfklow comms #17991

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
<?php

namespace Drupal\va_gov_content_release\Form;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Site\Settings;
use Drupal\va_gov_build_trigger\Traits\RunsDuringBusinessHours;
use GuzzleHttp\ClientInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Provides a VA.gov Content Release form.
*/
class ContentReleaseStatusForm extends FormBase {
use RunsDuringBusinessHours;

// @todo Need proper permissions and token sorted out.
// I tested on my personal repo with a personal token.
const OWNER = 'department-of-veterans-affairs';
const REPO = 'next-build';
const WORKFLOW_ID = 'content_release.yml';

/**
* The http client service.
*
* @var \GuzzleHttp\Client
*/
private ClientInterface $httpClient;

/**
* The Drupal settings service.
*
* @var \Drupal\Core\Site\Settings
*/
private Settings $settings;

/**
* The Content Release Status Form constructor.
*
* @param \Drupal\Core\Site\Settings $settings
* The settings service.
* @param \GuzzleHttp\ClientInterface $client
* The http client service.
* @param \Drupal\Component\Datetime\TimeInterface $time
* The time service.
* @param \Drupal\Core\Datetime\DateFormatterInterface $dateFormatter
* The date formatter service.
*/
public function __construct(Settings $settings, ClientInterface $client, TimeInterface $time, DateFormatterInterface $dateFormatter) {
$this->settings = $settings;
$this->httpClient = $client;
$this->time = $time;
$this->dateFormatter = $dateFormatter;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('settings'),
$container->get('http_client'),
$container->get('datetime.time'),
$container->get('date.formatter'),
);
}

/**
* {@inheritdoc}
*/
public function getFormId(): string {
return 'va_gov_content_release_next_simple';
}

/**
* {@inheritdoc}
*
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function buildForm(
array $form,
FormStateInterface $form_state
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [PHP_CodeSniffer] <Drupal.Functions.MultiLineFunctionDeclaration.MissingTrailingComma> reported by reviewdog 🐶
Multi-line function declarations must have a trailing comma after the last parameter

): array {

// Make a call to GitHub using http_client service to check workflow runs.
$response = $this->httpClient->request('GET',
'https://api.github.com/repos/' . self::OWNER . '/' . self::REPO . '/actions/workflows/' . self::WORKFLOW_ID . '/runs');
$data = json_decode($response->getBody()->getContents());

// Get the latest run.
$latest_run = $data->workflow_runs[0];
// Get last run.
$last_run = $data->workflow_runs[1];
// Get start of the run.
$start = $latest_run->run_started_at;
// Calculate the duration of the run so far.
$duration = (time() - strtotime($start));

$form['content_release_status_block'] = [
'#theme' => 'status_report_grouped',
'#grouped_requirements' => [
[
'title' => $this->t('Latest Content Release Run'),
'type' => 'content-release-status',
'items' => [
'last_run' => [
'title' => $this->t('Previous Build Status'),
'value' => $last_run->status,
],
'status' => [
'title' => $this->t('Current Build Status'),
'value' => $latest_run->status,
],
'run_start' => [
'title' => $this->t('Last Run Start Time'),
'value' => date('Y-m-d H:i:s', strtotime($start)),
],
'duration' => [
'title' => $this->t('Duration'),
'value' => gmdate('H:i:s', $duration),
],
'during_business_hours' => [
'title' => $this->t('During Business Hours'),
'value' => $this->isCurrentlyDuringBusinessHours() ? 'Yes' : 'No',
],
],
],
],
];

$form['request_release'] = [
'#type' => 'fieldset',
'#title' => $this->t('Request Content Release'),
];

$message = <<<HTML
<ul>
<li>Refresh the page to update the Content Release Status information.</li>
<li>Any content you set to Published will go live once the release is finished.</li>
<li>You cannot release content manually during business hours so the release button is disabled during those times.</li>
</ul>
<hr>
HTML;

// Add markup for a message before the form fields.
$form['request_release']['message'] = [
'#markup' => $message,
];

$form['request_release']['acknowledgement'] = [
'#type' => 'checkbox',
'#title' => $this->t('I understand that all VA content set to Published will go live once the release is finished.'),
'#required' => TRUE,
'#disabled' => $this->isCurrentlyDuringBusinessHours(),
];

$form['request_release']['actions'] = [
'#type' => 'actions',
'#disabled' => $this->isCurrentlyDuringBusinessHours(),
'submit' => [
'#type' => 'submit',
'#value' => $this->t('Release Content Request'),
],
];

return $form;
}

/**
* {@inheritdoc}
*
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function submitForm(
array &$form,
FormStateInterface $form_state
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [PHP_CodeSniffer] <Drupal.Functions.MultiLineFunctionDeclaration.MissingTrailingComma> reported by reviewdog 🐶
Multi-line function declarations must have a trailing comma after the last parameter

): void {

try {
// Trigger the content release.
$this->httpClient->request('POST',
'https://api.github.com/repos/' . self::OWNER . '/' . self::REPO . '/actions/workflows/' . self::WORKFLOW_ID . '/dispatches',
[
'headers' => [
'Accept' => 'application/vnd.github.v3+json',
// @todo Replace with proper token.
'Authorization' => 'token ' . $this->settings->get('va_cms_bot_github_auth_token'),
],
'json' => [
'ref' => 'main',
// Can add 'inputs' => [] to the workflow, if needed.
],
]);
}
catch (Exception $exception) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[PHPStan] reported by reviewdog 🐶
Caught class Drupal\va_gov_content_release\Form\Exception not found.

$this->messenger()->addError($this->t('There was an error triggering the content release.'));
// @todo Add more logging?
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,11 @@ va_gov_content_release.frontend_version_autocomplete:
_format: json
requirements:
_permission: "va gov deploy content build"

va_gov_content_release.check_status_form:
path: '/admin/content/deploy/check-status'
defaults:
_title: 'Content Release Status'
_form: '\Drupal\va_gov_content_release\Form\ContentReleaseStatusForm'
requirements:
_permission: 'va gov deploy content build'
46 changes: 46 additions & 0 deletions scripts/continuous_build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env bash

# This script is used to build the project continuously.
# The project is build on GitHub using a Workflow.

# The continuous build only runs during business hours.
export TZ="America/New_York"
echo "Current time: $(date)"
if [ $(date +%u) -lt 6 ] && [ $(date +%H) -ge 8 ] && [ $(date +%H) -lt 20 ]; then
echo "It is during business hours. Proceeding with the build."
else
echo "It is not during business hours. Exiting build."
exit 0
fi

# Make request to Github to check if a workflow is running.
# If a workflow is running, then exit the script.
# If no workflow is running, then build the project.
OWNER="department-of-veterans-affairs"
REPO="next-build"
WORKFLOW_ID="content_release.yml"

# Get the Content Release workflow status.
WORKFLOW_STATUS=$(curl -L \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/runs | jq '.workflow_runs[0].status' | tr -d '"')
echo "Workflow status: ${WORKFLOW_STATUS}"

if [ "$WORKFLOW_STATUS" == "in_progress" ]; then
echo "Workflow is running. Exiting the script."
exit 0
else
echo "Workflow is not running. Building the project."
fi

# Make call to trigger the workflow.
# The workflow is triggered by making a POST request to the GitHub API.
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${GH_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/dispatches \
-d '{"ref":"main"}'

Loading