Skip to content
Open
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
63 changes: 63 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: CI

on:
pull_request:
push:
branches: [main]

jobs:
php-lint:
name: PHP lint (phpcs + syntax)
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, intl, pdo_mysql
coverage: none
tools: composer:v2

- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"

- name: Cache composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-

- name: Install composer dependencies
run: composer install --prefer-dist --no-progress --no-interaction

- name: Run phpcs (CakePHP coding standard)
run: composer cs-check

- name: PHP syntax check (php -l)
run: |
set -e
find src tests config templates -type f -name '*.php' -print0 \
| xargs -0 -n1 -P4 php -l > /dev/null

yaml-lint:
name: YAML lint
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install yamllint
run: pip install --quiet yamllint

- name: Lint workflow and config YAML
run: yamllint -d relaxed .github/ config/
2 changes: 1 addition & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: CD

# Controls when the action will run. Triggers the workflow on push or pull request

Check warning on line 3 in .github/workflows/main.yaml

View workflow job for this annotation

GitHub Actions / YAML lint

3:81 [line-length] line too long (82 > 80 characters)
# events but only for the main branch
on:
push:
Expand All @@ -8,13 +8,13 @@
main
]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel

Check warning on line 11 in .github/workflows/main.yaml

View workflow job for this annotation

GitHub Actions / YAML lint

11:81 [line-length] line too long (88 > 80 characters)
jobs:
database:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job

Check warning on line 17 in .github/workflows/main.yaml

View workflow job for this annotation

GitHub Actions / YAML lint

17:81 [line-length] line too long (82 > 80 characters)
steps:
- name: Checkout repository
uses: actions/checkout@v2
Expand Down Expand Up @@ -42,9 +42,9 @@
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job

Check warning on line 45 in .github/workflows/main.yaml

View workflow job for this annotation

GitHub Actions / YAML lint

45:81 [line-length] line too long (82 > 80 characters)
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it

Check warning on line 47 in .github/workflows/main.yaml

View workflow job for this annotation

GitHub Actions / YAML lint

47:81 [line-length] line too long (85 > 80 characters)
- uses: actions/checkout@v2

# Runs a single command using the runners shell
Expand All @@ -54,4 +54,4 @@
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SERVER_USERNAME }}
password: ${{ secrets.SERVER_PASSWORD }}
script: cd ${{ secrets.PROJECT_PATH }} && git pull
script: cd ${{ secrets.PROJECT_PATH }} && git pull
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,16 @@ This repository contains the source-code for the new webpage of IO500. It is mad
## Contributions

Feel free to contribute to this page by forking and making a merge request. You can find more information on how to contribute in the Wiki.

## Running checks locally

CI runs the same checks on every pull request. To reproduce them locally before pushing:

```bash
composer install # one-time, pulls phpcs and the CakePHP codesniffer
composer cs-check # PHP coding standard (CakePHP)
find src tests config templates -name '*.php' -print0 | xargs -0 -n1 php -l # PHP syntax
yamllint -d relaxed .github/ config/ # YAML
```

`composer cs-fix` will auto-fix most coding-standard violations.
8 changes: 8 additions & 0 deletions config/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,14 @@
]
);

$builder->connect(
'/plots/data.json',
[
'controller' => 'Listings',
'action' => 'plotsData',
]
);

/*
* ...and connect the rest of 'Pages' controller's URLs.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
use Cake\Datasource\FactoryLocator;
use Cake\Error\Middleware\ErrorHandlerMiddleware;
use Cake\Http\BaseApplication;
use Cake\Http\MiddlewareQueue;
use Cake\Http\Middleware\BodyParserMiddleware;
use Cake\Http\Middleware\CsrfProtectionMiddleware;
use Cake\Http\Middleware\SecurityHeadersMiddleware;
use Cake\Http\MiddlewareQueue;
use Cake\ORM\Locator\TableLocator;
use Cake\Routing\Middleware\AssetMiddleware;
use Cake\Routing\Middleware\RoutingMiddleware;
Expand Down
101 changes: 91 additions & 10 deletions src/Controller/ListingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ public function list($bof = null, $url = null)
$release = $this->Listings->Releases->find('all')
->contain([
'Listings' => [
'Types',
'sort'=> [
'Types.position' => 'ASC'
]
'Types',
'sort' => [
'Types.position' => 'ASC',
],
],
])
->where([
Expand Down Expand Up @@ -68,8 +68,8 @@ public function list($bof = null, $url = null)
'Submissions' => [
'Releases',
'Questionnaires' => [
'ReproducibilityScores'
]
'ReproducibilityScores',
],
],
])
->where([
Expand All @@ -83,6 +83,87 @@ public function list($bof = null, $url = null)
$this->set('submissions', $this->paginate($submissions, $settings));
}

/**
* Data feed for the client-side plotly charts under /submissions/{graphs,ior,mdtest,pfind}.
*
* Returns a JSON array of one row per ListingsSubmissions entry in the "io500"
* Types listing across all released BoFs, with only the columns the 18 charts
* in webroot/js/plots.js need (x-axis grouping, tooltip text, y-values).
*
* Adding a new release to the database is enough to make its data appear
* in the plots — no script run, no commit of regenerated HTML.
*
* @return \Cake\Http\Response
*/
public function plotsData()
{
$rows = $this->Listings->ListingsSubmissions->find('all')
->contain([
'Listings' => ['Types', 'Releases'],
'Submissions',
])
->where([
'Types.url' => 'io500',
'Releases.release_date <=' => date('Y-m-d'),
])
->order([
'Releases.release_date' => 'ASC',
'ListingsSubmissions.score' => 'DESC',
])
->all();

// Build a set of (submission_id, release_acronym) pairs that appear
// in any production listing, so each io500 row can be tagged.
$productionRows = $this->Listings->ListingsSubmissions->find('all')
->contain([
'Listings' => ['Types', 'Releases'],
])
->where([
'Types.url' => 'production',
'Releases.release_date <=' => date('Y-m-d'),
])
->all();
$productionSet = [];
foreach ($productionRows as $pr) {
$productionSet[$pr->submission_id . '|' . $pr->listing->release->acronym] = true;
}

$payload = [];
foreach ($rows as $ls) {
$s = $ls->submission;
$acronym = $ls->listing->release->acronym;
$payload[] = [
'list_name' => $acronym,
'is_production' => isset($productionSet[$ls->submission_id . '|' . $acronym]),
'information_system' => $s->information_system,
'information_filesystem_type' => $s->information_filesystem_type,
'information_institution' => $s->information_institution,
'score' => $ls->score,
'io500_bw' => $s->io500_bw,
'io500_md' => $s->io500_md,
'ior_easy_write' => $s->ior_easy_write,
'ior_easy_read' => $s->ior_easy_read,
'ior_hard_write' => $s->ior_hard_write,
'ior_hard_read' => $s->ior_hard_read,
'mdtest_easy_write' => $s->mdtest_easy_write,
'mdtest_easy_stat' => $s->mdtest_easy_stat,
'mdtest_easy_delete' => $s->mdtest_easy_delete,
'mdtest_hard_write' => $s->mdtest_hard_write,
'mdtest_hard_read' => $s->mdtest_hard_read,
'mdtest_hard_stat' => $s->mdtest_hard_stat,
'mdtest_hard_delete' => $s->mdtest_hard_delete,
'find_easy' => $s->find_easy,
];
}

$this->autoRender = false;

return $this->response
->withType('application/json')
->withHeader('Cache-Control', 'public, max-age=600')
->withStringBody(json_encode($payload));
}

/**
* Download method
*
Expand Down Expand Up @@ -112,10 +193,10 @@ public function download($bof = null, $url = null)
],
])
->where([
'Releases.release_date <=' => date('Y-m-d')
'Releases.release_date <=' => date('Y-m-d'),
])
->order([
'Releases.release_date' => 'DESC'
'Releases.release_date' => 'DESC',
])
->first();

Expand Down Expand Up @@ -150,7 +231,7 @@ public function download($bof = null, $url = null)
'Releases.acronym' => strtoupper($bof),
])
->order([
'Releases.release_date' => 'DESC'
'Releases.release_date' => 'DESC',
])
->first();

Expand All @@ -168,7 +249,7 @@ public function download($bof = null, $url = null)
'ListingsSubmissions.listing_id' => $listing->id,
])
->order([
'ListingsSubmissions.score' => 'DESC'
'ListingsSubmissions.score' => 'DESC',
]);

$records = [];
Expand Down
Loading
Loading