Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions etc/db-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,11 @@
description: Time in seconds after an external contest source reader last checked in before showing its status as `critical`.
regex: /^\d+$/
error_message: A non-negative number is required.
- name: check_new_version
type: bool
default_value: false
public: false
description: Automatically check for new DOMjudge release?
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
description: Automatically check for new DOMjudge release?
description: Automatically check and notify for new DOMjudge releases?

- name: adminer_enabled
type: bool
default_value: false
Expand Down
3 changes: 2 additions & 1 deletion webapp/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@
"twig/extra-bundle": "^3.5",
"twig/markdown-extra": "^3.5",
"twig/string-extra": "^3.5",
"twig/twig": "^3.6"
"twig/twig": "^3.6",
"z4kn4fein/php-semver": "^3.0"
},
"require-dev": {
"ext-dom": "*",
Expand Down
58 changes: 56 additions & 2 deletions webapp/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions webapp/src/Service/DOMJudgeService.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Exception;
use InvalidArgumentException;
use Psr\Log\LoggerInterface;
use ReflectionClass;
Expand All @@ -63,6 +64,7 @@
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Twig\Environment;
use z4kn4fein\SemVer\Version;
use ZipArchive;

class DOMJudgeService
Expand Down Expand Up @@ -107,6 +109,8 @@
protected string $projectDir,
#[Autowire('%domjudge.vendordir%')]
protected string $vendorDir,
#[Autowire('%domjudge.version%')]
protected readonly string $domjudgeVersion,
) {}

/**
Expand Down Expand Up @@ -1671,4 +1675,59 @@
->getQuery()
->getResult();
}

public function checkNewVersion(): string|false {
Copy link
Member

Choose a reason for hiding this comment

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

nit: add a comment what this function should return

if (!$this->config->get('check_new_version')) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (!$this->config->get('check_new_version')) {
if (!$this->config->get('check_new_version', false)) {

return false;
}

Check failure on line 1682 in webapp/src/Service/DOMJudgeService.php

View workflow job for this annotation

GitHub Actions / phpcs

Closing brace indented incorrectly; expected 8 spaces, found 4

Check failure on line 1682 in webapp/src/Service/DOMJudgeService.php

View workflow job for this annotation

GitHub Actions / phpcs

Line indented incorrectly; expected 8 spaces, found 4

Check failure on line 1682 in webapp/src/Service/DOMJudgeService.php

View workflow job for this annotation

GitHub Actions / phpcs

Spaces must be used to indent lines; tabs are not allowed
$versionLocalString = explode("/", str_replace("DEV", "-prerelease", $this->domjudgeVersion))[0];
$versionLocal = Version::parse($versionLocalString, false);
Copy link
Member

Choose a reason for hiding this comment

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

Why tarball in the user agent and not DOMjudge like we do when shadowing?

Copy link
Member Author

Choose a reason for hiding this comment

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

We also wanted to know which installmethods are out there, so next step is a config variable but I had no idea on how to set that (yet) I suspect a make option..

$versionUrl = 'https://versions.domjudge.org';
$options = ['http' => ['method' => 'GET', 'header' => "User-Agent: tarball/" . $versionLocalString . "\r\n"]];
$context = stream_context_create($options);
$response = @file_get_contents($versionUrl, false, $context);
if ($response === false) {

Check failure on line 1689 in webapp/src/Service/DOMJudgeService.php

View workflow job for this annotation

GitHub Actions / phpcs

Line indented incorrectly; expected 8 spaces, found 4

Check failure on line 1689 in webapp/src/Service/DOMJudgeService.php

View workflow job for this annotation

GitHub Actions / phpcs

Spaces must be used to indent lines; tabs are not allowed
return false;
}

Check failure on line 1691 in webapp/src/Service/DOMJudgeService.php

View workflow job for this annotation

GitHub Actions / phpcs

Closing brace indented incorrectly; expected 4 spaces, found 8
$versions = json_decode($response, true);
Copy link
Member

Choose a reason for hiding this comment

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

nit: add a comment to explain what format you expect the server to return

/* Steer towards to the latest patch first

Check failure on line 1693 in webapp/src/Service/DOMJudgeService.php

View workflow job for this annotation

GitHub Actions / phpcs

Whitespace found at end of line
* the user can see on the website if there is a new Major/minor themselves
* otherwise the latest minor, or Major release. So the user might make the upgrade path:
* DJ6.0.0 -> DJ6.0.6 -> DJ6.6.0 -> DJ9.0.0 instead of
* -> DJ6.0.[1..6] -> DJ6.[1..6] -> DJ[7..9].0.0
Copy link
Member

Choose a reason for hiding this comment

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

This whole loop could also be done by sorting the versions lexicographically and taking the next one higher than the local version. This could replace all three checks?

Copy link
Member Author

@vmcj vmcj Aug 23, 2025

Choose a reason for hiding this comment

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

Wouldn't that give the path over all patches, minor plus patches in that minor etc?

Basically the 2nd path I mentioned.

Copy link
Member

@nickygerritsen nickygerritsen Aug 23, 2025

Choose a reason for hiding this comment

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

Ah yeah you might be right but we could solve that by only exposing specific versions on the versions site?

Copy link
Member Author

Choose a reason for hiding this comment

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

Even if the array would only the latest patch release per M.m release we would still need to filter somewhere.

But I get the point that we should do something smarter so the code is less duplicated.

Copy link
Member Author

@vmcj vmcj Aug 24, 2025

Choose a reason for hiding this comment

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

We still need the loop as at best we can only clean the list to always have the highest patch version in the list,

We could ofcourse do this math on the version site and basically only let the server do a lookup there so:
{'1.1.5': '1.5.5',
'1.2.3': '1.2.5',
'1.5.5': '5.5.5'}
where 5 is always the highest version in that release.

But that also feels expensive, it just removes the calculation to another server.

I did some cleanup though and I think this is already more what you want. Although I'm not 100% if it will now not also alert for the current version.

Copy link
Member

Choose a reason for hiding this comment

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

Should we not return just the newest version here?

*/
$latestPatchString = $versionLocal;
if (isset($versions[$versionLocal->getMajor()][$versionLocal->getMinor()])) {
$latestPatchString = Version::rsortString($versions[$versionLocal->getMajor()][$versionLocal->getMinor()])[0];
$latestPatch = Version::parse($latestPatchString);
if (Version::compare($versionLocal, $latestPatch) < 0) {
return $latestPatchString;
}
}
$latestMinorString = $versionLocal;
if (isset($versions[$versionLocal->getMajor()])) {
$highestMinorInMajor = array_keys($versions[$versionLocal->getMajor()]);
rsort($highestMinorInMajor);
$latestMinorString = Version::rsortString($versions[$versionLocal->getMajor()][$highestMinorInMajor[0]])[0];
$latestMinor = Version::parse($latestMinorString);
if (Version::compare($versionLocal, $latestMinor) < 0) {
return $latestMinorString;
}
}
$latestMajorString = $versionLocal;
try {
$highestMajor = array_keys($versions);
rsort($highestMajor);
$highestMinorInMajor = array_keys($versions[$highestMajor[0]]);
rsort($highestMinorInMajor);
$latestMajorString = Version::rsortString($versions[$highestMajor[0]][$highestMinorInMajor[0]])[0];
$latestMajor = Version::parse($latestMajorString);
if (Version::compare($versionLocal, $latestMajor) < 0) {
return $latestMajorString;
}
} catch (Exception $e) {
return false;
}
return false;
}
}
1 change: 1 addition & 0 deletions webapp/src/Twig/TwigExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ public function getGlobals(): array
'doc_links' => $this->dj->getDocLinks(),
'allow_registration' => $selfRegistrationCategoriesCount !== 0,
'enable_ranking' => $this->config->get('enable_ranking'),
'new_version_available' => $this->dj->checkNewVersion(),
'editor_themes' => [
'vs' => ['name' => 'Visual Studio (light)'],
'vs-dark' => ['name' => 'Visual Studio (dark)'],
Expand Down
7 changes: 7 additions & 0 deletions webapp/templates/jury/menu.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@
</li>
</ul>
{% endif %}
{% if new_version_available %}
<ul class="navbar-nav">
<li class="nav-item nav-link">
<i class="fa-solid fa-ship fa-2x"></i> New release {{ new_version_available }} available.
Copy link
Member

Choose a reason for hiding this comment

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

Add link?

Copy link
Member Author

Choose a reason for hiding this comment

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

To do that I need to make it unraw, I'll need @nickygerritsen for that if we want this.

</li>
</ul>
{% endif %}

<ul class="navbar-nav ml-auto">

Expand Down
Loading