Skip to content

Commit 8c9100d

Browse files
authored
Merge pull request #80 from itk-dev/feature/5566_maintenance_contract-by-martin
Feature/5566 maintenance contract by martin
2 parents f4c8520 + 4985f7b commit 8c9100d

35 files changed

Lines changed: 994 additions & 177 deletions

.env

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,8 @@ VAULT_SECRET_ID="CHANGE_ME_IN_LOCAL_ENV"
6363

6464
# The number of old results for each server/result-type combination
6565
APP_KEEP_RESULTS=5
66+
67+
###> economics ###
68+
APP_ECONOMICS_URI=https://economics.itkdev.dk
69+
APP_ECONOMICS_API_KEY=changeme
70+
###< economics ###

.github/workflows/doctrine.yaml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: Doctrine
2+
3+
env:
4+
COMPOSE_USER: root
5+
6+
on:
7+
pull_request:
8+
push:
9+
branches:
10+
- main
11+
- develop
12+
13+
jobs:
14+
validate-doctrine-schema:
15+
name: Validate Doctrine Schema
16+
runs-on: ubuntu-latest
17+
env:
18+
APP_ENV: prod
19+
20+
steps:
21+
- uses: actions/checkout@v6
22+
23+
- name: Create docker network
24+
run: |
25+
docker network create frontend
26+
27+
- name: Run Composer Install
28+
run: |
29+
docker compose run --rm phpfpm composer install
30+
31+
- name: Run Doctrine Migrations
32+
run: |
33+
docker compose run --rm phpfpm bin/console doctrine:migrations:migrate --no-interaction
34+
35+
- name: Setup messenger "failed" doctrine transport to ensure db schema is updated
36+
run: |
37+
docker compose run --rm phpfpm bin/console messenger:setup-transports failed
38+
39+
- name: Validate Doctrine schema
40+
run: |
41+
docker compose run --rm phpfpm bin/console doctrine:schema:validate
42+
43+
load-fixtures:
44+
name: Load Doctrine fixtures
45+
runs-on: ubuntu-latest
46+
47+
steps:
48+
- uses: actions/checkout@v6
49+
50+
- name: Create docker network
51+
run: |
52+
docker network create frontend
53+
54+
- name: Run Composer Install
55+
run: |
56+
docker compose run --rm phpfpm composer install --no-interaction
57+
58+
- name: Run Doctrine Migrations
59+
run: |
60+
docker compose run --rm phpfpm bin/console doctrine:migrations:migrate --no-interaction
61+
62+
- name: Load fixtures
63+
run: |
64+
docker compose run --rm phpfpm composer fixtures

.github/workflows/pr.yaml

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,6 @@ name: Review
33
env:
44
COMPOSE_USER: runner
55
jobs:
6-
validate-doctrine-schema:
7-
runs-on: ubuntu-latest
8-
name: Validate Doctrine Schema
9-
steps:
10-
- name: Checkout
11-
uses: actions/checkout@v6
12-
13-
- name: Create docker network
14-
run: docker network create frontend
15-
16-
- name: Install and validate
17-
run: |
18-
docker compose up --detach
19-
docker compose exec phpfpm composer install --no-interaction
20-
docker compose exec phpfpm bin/console doctrine:migrations:migrate --no-interaction
21-
docker compose exec phpfpm bin/console messenger:setup-transports failed
22-
docker compose exec phpfpm bin/console doctrine:schema:validate
23-
246
phpstan:
257
runs-on: ubuntu-latest
268
name: PHPStan
@@ -65,23 +47,6 @@ jobs:
6547
# fail_ci_if_error: true
6648
# flags: unittests
6749

68-
fixtures:
69-
runs-on: ubuntu-latest
70-
name: Load fixtures
71-
steps:
72-
- name: Checkout
73-
uses: actions/checkout@v6
74-
75-
- name: Create docker network
76-
run: docker network create frontend
77-
78-
- name: Load fixtures
79-
run: |
80-
docker compose up --detach
81-
docker compose exec phpfpm composer install --no-interaction
82-
docker compose exec phpfpm bin/console doctrine:migrations:migrate --no-interaction
83-
docker compose exec phpfpm composer fixtures
84-
8550
build-assets:
8651
runs-on: ubuntu-latest
8752
name: Build assets

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
- [#80](https://github.com/itk-dev/devops_itksites/pull/80) 5566: Service agreements
11+
- Add security contract entity with crud controller
12+
- Add Abstract full crud controller and extend on it in some cases
13+
- Add economics service and sync action/command for service agreement synchronization
1014
- [#81](https://github.com/itk-dev/devops_itksites/pull/81) 5564: Asset Mapper migration
1115
- Add Symfony Asset Mapper bundle and importmap
1216
- Add Renovate auto-patch + auto-release pipeline (Phase 1 fork validation)

config/packages/framework.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ framework:
1313
#esi: true
1414
#fragments: true
1515

16+
http_client:
17+
scoped_clients:
18+
economics.client:
19+
base_uri: '%env(APP_ECONOMICS_URI)%'
20+
scope: '%env(APP_ECONOMICS_URI)%'
21+
headers:
22+
x-api-key: '%env(APP_ECONOMICS_API_KEY)%'
23+
1624
when@test:
1725
framework:
1826
test: true
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DoctrineMigrations;
6+
7+
use Doctrine\DBAL\Schema\Schema;
8+
use Doctrine\Migrations\AbstractMigration;
9+
10+
/**
11+
* Auto-generated Migration: Please modify to your needs!
12+
*/
13+
final class Version20260520101548 extends AbstractMigration
14+
{
15+
public function getDescription(): string
16+
{
17+
return '';
18+
}
19+
20+
public function up(Schema $schema): void
21+
{
22+
// this up() migration is auto-generated, please modify it to your needs
23+
$this->addSql('CREATE TABLE security_contract (id BINARY(16) NOT NULL, created_at DATETIME NOT NULL, modified_at DATETIME NOT NULL, created_by VARCHAR(255) DEFAULT \'\' NOT NULL, modified_by VARCHAR(255) DEFAULT \'\' NOT NULL, economics_id INT NOT NULL, project_name VARCHAR(255) NOT NULL, client_name VARCHAR(255) DEFAULT NULL, hosting_provider VARCHAR(255) DEFAULT NULL, document_url VARCHAR(255) DEFAULT NULL, monthly_price DOUBLE PRECISION DEFAULT NULL, valid_from DATE DEFAULT NULL, valid_to DATE DEFAULT NULL, active TINYINT NOT NULL, eol TINYINT NOT NULL, leantime_url VARCHAR(255) DEFAULT NULL, client_contact_name VARCHAR(255) DEFAULT NULL, client_contact_email VARCHAR(255) DEFAULT NULL, dedicated_server TINYINT NOT NULL, server_size VARCHAR(255) DEFAULT NULL, git_repos LONGTEXT DEFAULT NULL, system_owner_notices JSON DEFAULT NULL, project_tracker_key VARCHAR(255) DEFAULT NULL, quarterly_hours DOUBLE PRECISION DEFAULT NULL, cybersecurity_price DOUBLE PRECISION DEFAULT NULL, cybersecurity_note LONGTEXT DEFAULT NULL, UNIQUE INDEX UNIQ_8AE4AF8B4416F7E8 (economics_id), PRIMARY KEY (id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci`');
24+
}
25+
26+
public function down(Schema $schema): void
27+
{
28+
// this down() migration is auto-generated, please modify it to your needs
29+
$this->addSql('DROP TABLE security_contract');
30+
}
31+
}

phpstan.dist.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
parameters:
22
level: 6
3+
# Require a reason on every @phpstan-ignore so the next reader knows
4+
# why a check was suppressed. https://phpstan.org/user-guide/ignoring-errors#requiring-comments-for-@phpstan-ignore
5+
reportIgnoresWithoutComments: true
36
paths:
47
- bin/
58
- config/
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace App\Command;
4+
5+
use App\Service\ServiceAgreementSyncService;
6+
use Symfony\Component\Console\Attribute\AsCommand;
7+
use Symfony\Component\Console\Command\Command;
8+
use Symfony\Component\Console\Input\InputInterface;
9+
use Symfony\Component\Console\Output\OutputInterface;
10+
use Symfony\Component\Console\Style\SymfonyStyle;
11+
12+
#[AsCommand(
13+
name: 'app:economics:sync-agreements',
14+
description: 'Sync service agreements from Economics',
15+
)]
16+
class SyncServiceAgreementsCommand extends Command
17+
{
18+
public function __construct(
19+
private readonly ServiceAgreementSyncService $syncService,
20+
) {
21+
parent::__construct();
22+
}
23+
24+
protected function execute(InputInterface $input, OutputInterface $output): int
25+
{
26+
$io = new SymfonyStyle($input, $output);
27+
28+
try {
29+
$count = $this->syncService->syncAll();
30+
31+
$io->success(sprintf('Synced %d service agreements successfully.', $count));
32+
} catch (\Throwable $e) {
33+
$io->error($e->getMessage());
34+
35+
return Command::FAILURE;
36+
}
37+
38+
return Command::SUCCESS;
39+
}
40+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace App\Controller\Admin;
4+
5+
use App\Trait\ExportCrudControllerTrait;
6+
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
7+
use EasyCorp\Bundle\EasyAdminBundle\Config\ActionGroup;
8+
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
9+
use EasyCorp\Bundle\EasyAdminBundle\Config\Assets;
10+
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
11+
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
12+
13+
abstract class AbstractFullCrudController extends AbstractCrudController
14+
{
15+
use ExportCrudControllerTrait;
16+
17+
#[\Override]
18+
public function configureCrud(Crud $crud): Crud
19+
{
20+
return $crud->showEntityActionsInlined();
21+
}
22+
23+
#[\Override]
24+
public function configureActions(Actions $actions): Actions
25+
{
26+
// Remove default actions
27+
$actions
28+
->remove(Crud::PAGE_INDEX, Action::EDIT)
29+
->remove(Crud::PAGE_INDEX, Action::DELETE);
30+
31+
// Re-add default actions as grouped action.
32+
$groupedDefaultActions = ActionGroup::new('default', 'Default')
33+
->addMainAction(
34+
Action::new('show', 'Show')
35+
->linkToCrudAction(Action::DETAIL)
36+
)
37+
->addAction(
38+
Action::new('edit', 'Edit')
39+
->linkToCrudAction(Action::EDIT)
40+
->setIcon('fa fa-edit')
41+
)
42+
->addDivider()
43+
->addAction(
44+
Action::new('delete', 'Delete')
45+
->linkToCrudAction(Action::DELETE)
46+
->setIcon('fa fa-trash')
47+
->setCssClass('btn-danger text-danger')
48+
);
49+
50+
return $actions
51+
->add(Crud::PAGE_INDEX, $groupedDefaultActions)
52+
->add(Crud::PAGE_INDEX, $this->createExportAction())
53+
->update(Crud::PAGE_INDEX, Action::NEW,
54+
static fn (Action $action) => $action->setIcon('fa fa-plus')
55+
)
56+
;
57+
}
58+
59+
#[\Override]
60+
public function configureAssets(Assets $assets): Assets
61+
{
62+
return $assets
63+
->addWebpackEncoreEntry('easyadmin');
64+
}
65+
}

src/Controller/Admin/DashboardController.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function index(): Response
3737
public function configureDashboard(): Dashboard
3838
{
3939
return Dashboard::new()
40-
->setTitle('<img src="/img/itk-sites-logo.png" width="170px" alt="ITK sites">')
40+
->setTitle('<img src="/img/itk-sites-logo.png" width="170px" alt="ITK sites logo">')
4141
->setFaviconPath('img/favicon.ico')
4242
->renderContentMaximized();
4343
}
@@ -52,6 +52,7 @@ public function configureMenuItems(): iterable
5252
yield MenuItem::linkTo(DomainCrudController::class, 'Domains', 'fas fa-link');
5353
yield MenuItem::linkTo(OIDCCrudController::class, 'OIDC', 'fas fa-key');
5454
yield MenuItem::linkTo(ServiceCertificateCrudController::class, 'Service certificates', 'fas fa-lock');
55+
yield MenuItem::linkTo(SecurityContractCrudController::class, 'Service Agreements', 'fas fa-file-contract');
5556
yield MenuItem::section('Dependencies');
5657
yield MenuItem::linkTo(PackageCrudController::class, 'Packages', 'fas fa-cube');
5758
yield MenuItem::linkTo(PackageVersionCrudController::class, 'Package Versions', 'fas fa-cubes');

0 commit comments

Comments
 (0)