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

feat: actions check.php and basecheck.php separation, audit, static build, cachebust test #1381

Draft
wants to merge 17 commits into
base: master
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
50 changes: 50 additions & 0 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Audit

on: [pull_request]

env:
WEBAPP_NAME: ninjawars # set this to your application's name
WEBAPP_PACKAGE_PATH: "." # set this to the path to your web app project, defaults to the repository root
NODE_VERSION: "16.13.1" # set this to the node version to use
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_READ_TOKEN }}
CI: false
jobs:
lighthouseci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: ${{ env.NODE_VERSION }}
#always-auth: true
#registry-url: "https://npm.pkg.github.com"
- name: Yarn packages audit
run: yarn npm audit
continue-on-error: true
- name: Install, configure, install the lighthouse auditor
run: |
# Check the node version
node --version
corepack enable
# corepack enable should have made this unnecessary
# Install the project, then...
# yarn workspaces run init-project
yarn init-project
yarn install --immutable
# I guess even with corepack the yarn install is still required?
#yarn bootstrap
- name: Build
run: |
# Stop eslint from failing the build
rm .eslintrc.json
yarn build
- name: Audit URLs using Lighthouse
uses: treosh/lighthouse-ci-action@v8
with:
urls: |
http://localhost:7474/
http://localhost:7474/intro
budgetPath: ./.budget.json # test performance budgets
uploadArtifacts: true # save results as an action artifacts
temporaryPublicStorage: true # upload lighthouse report to the temporary storage
5 changes: 5 additions & 0 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ jobs:
# Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit"
# Docs: https://getcomposer.org/doc/articles/scripts.md

- name: Run build
run: |
ln -s ./resources.build.php ./deploy/resources.php
make build

- name: Run test suite
run: |
ln -s ./resources.build.php ./deploy/resources.php
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,5 @@ karma.conf.js
.php-cs-fixer.cache
deploy/www/index.html
deploy/www/intro.html
deploy/www/login.html
deploy/www/signup.html
47 changes: 47 additions & 0 deletions .lighthouserc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module.exports = {
ci: {
collect: {
staticDistDir: 'deploy/www',
isSinglePageApplication: true,
numberOfRuns: 1
},
upload: {
// target: 'filesystem'
target: 'temporary-public-storage'
},
assert: {
"preset": "lighthouse:no-pwa", // Change this to "lighthouse:recommended" when we move to a PWA in the future
assertions: {
"maskable-icon": "off",
"service-worker": "off",
"tap-targets": "off",
"apple-touch-icon": "off",
"first-contentful-paint": ['warn', { minScore: 0.9 }],
"interactive": ['warn', { minScore: 0.9 }],
"last-contentful-paint": ['warn'],
"largest-contentful-paint": ['warn'],
"first-meaningful-paint": ['warn'],
"label": ['warn'],
"max-potential-fid": ['warn', { minScore: 0.9 }],
//"render-blocking-resources": ['warn', { minScore: 0.4 }],
"speed-index": ['warn', { minScore: 0.9 }],
"mainthread-work-breakdown": ['warn', { minScore: 0.9 }],
"legacy-javascript": ['warn', { auditRan: 1 }],
"duplicated-javascript": ['warn'],
"unused-javascript": ['warn', { maxLength: 4 }],
"unminified-javascript": ['warn'],
"uses-long-cache-ttl": ['warn', { maxLength: 13 }],
"uses-rel-preconnect": ['warn'],
"render-blocking-resources": ['error', { maxLength: 2 }],
"font-size": ['warn'],
"bootup-time": ['warn', { minScore: 0.65 }],
"button-name": ['warn', { minScore: 0.65 }],
"link-name": ['warn', { minScore: 0.65 }],
"color-contrast": ['warn', { minScore: 0.65 }],
"robots-txt": ['warn'],
"first-cpu-idle": ['warn', { minScore: 0.85 }],
"meta-description": ['warn'],
}
},
}
}
13 changes: 12 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,21 @@ endif

build: dep
mkdir -p $(JS)
@echo "Don't forget to update nginx configs as necessary."
@echo "Including updating the php to retain login sessions longer."
cp -pn ./deploy/resources.build.php ./deploy/resources.php || true
echo "Note that this does not overwrite existing resources.php"
echo "Check that the webserver user has permissions to the script!"
@ln -sf "$(RELATIVE_COMPONENTS)jquery/jquery.min.js" "$(JS)"
@ln -sf "$(RELATIVE_COMPONENTS)jquery/jquery.min.map" "$(JS)"
@ln -sf "$(RELATIVE_COMPONENTS)jquery-timeago/jquery.timeago.js" "$(JS)"
@ln -sf "$(RELATIVE_COMPONENTS)jquery-linkify/jquery.linkify.js" "$(JS)"
@ln -sf "$(RELATIVE_VENDOR)twbs/bootstrap/dist/css/bootstrap.min.css" "$(CSS)"
@ln -sf "$(RELATIVE_VENDOR)twbs/bootstrap/dist/js/bootstrap.min.js" "$(JS)"
make check-base
php deploy/www/intro-controller.php > deploy/www/intro.html
php deploy/www/front-controller.php > deploy/www/index.html
@echo "Built front controller to static deploy/www/index.html file and deploy/www/intro.html file"
rm -rf ./deploy/templates/compiled/* ./deploy/templates/cache/*
mkdir -p ./deploy/templates/compiled ./deploy/templates/cache ./deploy/resources/logs/
chmod -R ugo+rwX ./deploy/templates/compiled ./deploy/templates/cache
Expand All @@ -45,6 +54,9 @@ dep:

check: pre-test

check-base:
php deploy/checkbase.php

js-deps:
node -v
corepack enable
Expand Down Expand Up @@ -142,7 +154,6 @@ check-for-syntax-errors:
@find "./deploy/www/" -name "*.php" -exec php -l {} \;|grep -v "No syntax errors" || true

test-unit: check-for-syntax-errors

@$(TEST_RUNNER) $(CC_FLAG) --testsuite Unit

test-quick: check-for-syntax-errors
Expand Down
29 changes: 6 additions & 23 deletions deploy/check.php
Original file line number Diff line number Diff line change
@@ -1,39 +1,22 @@
<?php

require_once(realpath(__DIR__).'/resources.php');
// This file is very raw to be about as simple as possible of an app status check
ob_start();
assert(defined('WEB_ROOT'));
assert(defined('DEBUG'));
assert(defined('ROOT'));
assert(defined('SERVER_ROOT'));
assert(defined('DATABASE_PASSWORD'));
assert('' !== WEB_ROOT);
assert('http:///' !== WEB_ROOT);

// Check for webserver root configuration
$out = ob_get_contents();
ob_end_clean();
echo $out;

require(SERVER_ROOT.'lib/base.inc.php');
require_once(VENDOR_ROOT.'autoload.php');
require_once(realpath(__DIR__) . '/resources.php');
require_once(realpath(__DIR__) . '/checkbase.php');

// Check for database
$connected = (bool) query_item('select 1 from players limit 1');
$is_superuser = (bool) query_item('select usesuper from pg_user where usename = CURRENT_USER;') === true;

function passfail($passed, $pass, $fail) {
$messaging = ($passed ? '[PASSING]: Reason '.$pass : '[FAILING]: Reason '.$fail);
function passfailB($passed, $pass, $fail) {
$messaging = ($passed ? '[PASSING]: Reason ' . $pass : '[FAILING]: Reason ' . $fail);
echo "$messaging\n";
return $passed;
}

// Executing and outputing checks, to try to run all before final return
$outcomes = [
passfail(empty($out), 'WEB ROOT was configured as '.WEB_ROOT, 'No web root seems to be configured '.WEB_ROOT),
passfail($connected, 'Able to connect and list a player from the players table of the database', 'Unable to select from players table of the database'),
passfail(!$is_superuser, 'Connected to database as appropriate user level', 'Connected as database superuser, you want to connect as a lower permission role')
passfailB($connected, 'Able to connect and list a player from the players table of the database', 'Unable to select from players table of the database'),
passfailB(!$is_superuser, 'Connected to database as appropriate user level', 'Connected as database superuser, you want to connect as a lower permission role')
];

return (($outcomes[0] && $outcomes[1] && $outcomes[2]) ? 0 : 1); // Reversed logic due to linux script return values expected
33 changes: 33 additions & 0 deletions deploy/checkbase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

require_once(realpath(__DIR__) . '/resources.php');
// This file is very raw to be about as simple as possible of an app status check
ob_start();
assert(defined('WEB_ROOT'));
assert(defined('DEBUG'));
assert(defined('ROOT'));
assert(defined('SERVER_ROOT'));
assert(defined('DATABASE_PASSWORD'));
assert('' !== WEB_ROOT);
assert('http:///' !== WEB_ROOT);

// Check for webserver root configuration
$out = ob_get_contents();
ob_end_clean();
echo $out;

require(SERVER_ROOT . 'lib/base.inc.php');
require_once(VENDOR_ROOT . 'autoload.php');

function passfail($passed, $pass, $fail) {
$messaging = ($passed ? '[PASSING]: Reason ' . $pass : '[FAILING]: Reason ' . $fail);
echo "$messaging\n";
return $passed;
}

// Executing and outputing checks, to try to run all before final return
$outcomes = [
passfail(empty($out), 'WEB ROOT was configured as ' . WEB_ROOT, 'No web root seems to be configured ' . WEB_ROOT),
];

return (($outcomes[0]) ? 0 : 1); // Reversed logic due to linux script return values expected
18 changes: 9 additions & 9 deletions deploy/conf/nw.local.nginx
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ server {
try_files $uri =404;
}

location = /intro {
add_header X-Frame-Options SAMEORIGIN;
try_files intro.html =404;
}

location = / {
add_header X-Frame-Options SAMEORIGIN;
try_files index.html =404;
}
#location = /intro {
# add_header X-Frame-Options SAMEORIGIN;
# try_files intro.html =404;
#}

#location = / {
# add_header X-Frame-Options SAMEORIGIN;
# try_files index.html =404;
#}

location / {
#default fallback of everything else block
Expand Down
2 changes: 1 addition & 1 deletion deploy/lib/extensions/Nmail.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public function send() {

//Optionally add any attachments
// ->attach(Swift_Attachment::fromPath('my-document.pdf'))
;
;

if ($this->reply_to) {
$this->message->setReplyTo($this->reply_to);
Expand Down
2 changes: 1 addition & 1 deletion deploy/lib/plugins/function.cachebust.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
function smarty_function_cachebust($p_params) {
$file = ROOT."/www/$p_params[file]";

if (is_file($file)) {
if (is_file($file) && HASH_ASSET_PATHS) {
$mtime = filemtime($file);
$pathParts = pathinfo($p_params['file']);
return $pathParts['dirname'].'/'.$pathParts['filename'].".$mtime.".$pathParts['extension'];
Expand Down
15 changes: 8 additions & 7 deletions deploy/resources.build.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
define('DATABASE_USE_PASSWORD', false); // *** Whether to specify password to pdo at all. Generally true only on live
define('DATABASE_USE_PORT', false); // *** Whether to specify port to pdo at all. Generally true only on live
define('DATABASE_USE_HOST', false); // *** Whether to specify HOST to pdo at all. Generally true only on live
define('DATABASE_HOST', "localhost"); // *** The host to connect to for the database, localhost by default
define('DATABASE_PORT', "5432"); // *** The port number to connect on.
define('DATABASE_USER', "postgres"); // *** The user that should connect to the database
define('DATABASE_PASSWORD', "unused_in_build"); // *** The password for the database connection, trust on dev
define('DATABASE_NAME', "nw"); // *** The name of the database to connect to, nw on dev
define('OFFLINE', false); // *** Controls if remote or local resources are used
define('DATABASE_HOST', "localhost"); // *** The host to connect to for the database, localhost by default
define('DATABASE_PORT', "5432"); // *** The port number to connect on.
define('DATABASE_USER', "postgres"); // *** The user that should connect to the database
define('DATABASE_PASSWORD', "unused_in_build"); // *** The password for the database connection, trust on dev
define('DATABASE_NAME', "nw"); // *** The name of the database to connect to, nw on dev
define('OFFLINE', true); // *** Controls if remote or local resources are used
define('HASH_ASSET_PATHS', false); // *** Controls if cachebusting hash strings for assets like images are used
define('DEBUG', true); // *** Shorter debugging constant name, set as false on live.
define('SERVER_ROOT', realpath(__DIR__).'/'); // *** The root deployment directory of the game
// Generally for the install purposes the SERVER_ROOT should correspond to /srv/ninjawars/deploy/
Expand All @@ -28,7 +29,7 @@
define('FACEBOOK_APP_ID', '30479872633'); // Non-confidential id for the facebook app
define('FACEBOOK_APP_SECRET', 'mooMooIAmACow'); // Secret! string for facebook login auth stuff.

define('TRAP_ERRORS', true); // Whether to use the global error handler & oops page, true on live.
define('TRAP_ERRORS', false); // Whether to use the global error handler & oops page, true on live.

define('TEMPLATE_LIBRARY_PATH', SERVER_ROOT.'vendor/smarty/smarty/libs/Smarty.class.php'); // Path to Smarty 3

Expand Down
3 changes: 2 additions & 1 deletion deploy/resources.template.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
define('DATABASE_USER', __DB_USER__); // *** The user that should connect to the database
define('DATABASE_NAME', __DB_NAME__); // *** The name of the database to connect to
define('DATABASE_PASSWORD', __DB_PASS__); // *** The password for the database connection
define('OFFLINE', __OFFLINE__); // *** Controls if remote or local resources are used
define('OFFLINE', __OFFLINE__); // *** Controls if remote or local resources are used
define('HASH_ASSET_PATHS', true); // *** Controls if cachebusting hash strings for assets like images are used
define('DEBUG', __DEBUG__); // *** Shorter debugging constant name, set as false on live.
define('SERVER_ROOT', __SERVER_ROOT__); // *** The root deployment directory of the game
// Generally for the install purposes the SERVER_ROOT should correspond to /srv/ninjawars/deploy/
Expand Down
2 changes: 1 addition & 1 deletion deploy/tests/functional/test_ratchets.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class TestRatchets:
and checks the overall SLOC of the project
'''
control_php = 37
www_php = 1
www_php = 4
plus_minus = 6
''' Rough file counts in pertinent directories '''

Expand Down
6 changes: 3 additions & 3 deletions deploy/tests/unit/SmartyPluginUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ class SmartyPluginUnitTest extends \PHPUnit\Framework\TestCase {
public const URL = 'https://localhost.com/go/?query=string';

public function testCachebustPositive() {
$result = smarty_function_cachebust(['file'=>self::EXISTING_FILE]);
$this->assertNotEquals(self::EXISTING_FILE, $result);
$this->assertGreaterThan(strlen(self::EXISTING_FILE), strlen($result));
$result = smarty_function_cachebust(['file' => self::EXISTING_FILE]);
$this->assertNotEmpty($result);
$this->assertStringContainsString(self::EXISTING_FILE, $result);
}

public function testCachebustNegative() {
Expand Down
45 changes: 45 additions & 0 deletions deploy/www/intro-controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

require_once(dirname(__DIR__ . '..') . '/lib/base.inc.php');

use Pimple\Container;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use NinjaWars\core\RouteNotFoundException;
use NinjaWars\core\Router;
use NinjaWars\core\environment\RequestWrapper;
use NinjaWars\core\data\Player;
use NinjaWars\core\extensions\SessionFactory;

// setup our runtime environment
require_once(LIB_ROOT . 'environment/bootstrap.php');

try {
$container = new Container();

$container['current_player'] = function ($c) {
$player_id = SessionFactory::getSession()->get('player_id');
return $player_id ? Player::find($player_id) : null;
};

$container['session'] = function ($c) {
return SessionFactory::getSession();
};

// Update the activity of the page viewer in the database.
RequestWrapper::init();

// get the request information to parse the route
$response = Router::route(Request::create(
'/intro',
'GET',
), $container);

if ($response instanceof Response) {
$response->send();
} else {
throw new \RuntimeException('Route returned something other than a Response');
}
} catch (RouteNotFoundException $e) {
Router::respond404();
}
Loading