Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
b7a810f
WIP Change CircleCI to use Docker Compose.
edwh Jun 23, 2025
fc72393
WIP Change CircleCI to use Docker Compose.
edwh Jun 23, 2025
45e3b7d
WIP Change CircleCI to use Docker Compose.
edwh Jun 23, 2025
650691a
WIP Change CircleCI to use Docker Compose.
edwh Jun 23, 2025
d5b4cbc
WIP Change CircleCI to use Docker Compose.
edwh Jun 23, 2025
62b4404
WIP Change CircleCI to use Docker Compose.
edwh Jun 23, 2025
a35e09f
WIP Change CircleCI to use Docker Compose.
edwh Jun 23, 2025
f3629b8
WIP Change CircleCI to use Docker Compose.
edwh Jun 23, 2025
baa2b14
WIP Change CircleCI to use Docker Compose.
edwh Jun 23, 2025
5818a40
WIP Change CircleCI to use Docker Compose.
edwh Jun 23, 2025
e1dcf20
WIP Change CircleCI to use Docker Compose.
edwh Jun 23, 2025
b3ced01
We are using MySQL 8, so up the Docker Compose version. Also update …
edwh Jul 8, 2025
6b40f1f
Fail Docker startup on error.
edwh Jul 8, 2025
a3b6462
Migration creates TRIGGERs which are no longer used and require permi…
edwh Jul 8, 2025
34f58f4
Phpunit tests failing.
edwh Jul 8, 2025
5b76d7b
pcntl_signal not found.
edwh Jul 8, 2025
6df44bf
Handle test user already existing.
edwh Jul 8, 2025
1cf62fc
Phpunit tests failing.
edwh Jul 8, 2025
3136622
Phpunit tests failing.
edwh Jul 8, 2025
0e49551
Make docker_run wait for DB to be available before proceeding.
edwh Jul 8, 2025
0277f5e
Make docker_run wait for DB to be available before proceeding.
edwh Jul 8, 2025
bcad74f
Make docker_run wait for DB to be available before proceeding.
edwh Jul 8, 2025
865054f
Make docker_run wait for DB to be available before proceeding.
edwh Jul 8, 2025
7e8e1c4
Make docker_run wait for DB to be available before proceeding.
edwh Jul 8, 2025
4ed2803
Make docker_run wait for DB to be available before proceeding.
edwh Jul 8, 2025
07b8d46
PHPUnit test fails.
edwh Jul 8, 2025
0c8d1e7
PHPUnit test fails.
edwh Jul 14, 2025
549f769
PHPUnit test fails.
edwh Jul 14, 2025
3a0eb95
Use --teamcity on phpunit to make it easier to spot failing tests on …
edwh Jul 14, 2025
84d625b
Exclude NotificationsTest which is failing with a facade error which …
edwh Jul 14, 2025
f45f2ac
Possible fix for MenusTest.
edwh Jul 14, 2025
bdbc4d2
Possible fix for NotificationsTest.
edwh Jul 21, 2025
63650e2
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
a647963
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
b6787e4
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
47841d2
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
6491750
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
8a59106
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
fe86bf0
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
c607c94
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
17b35d2
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
929bb56
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
a99c4ce
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
0eaac9c
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
4200338
WIP Change CircleCI to use Docker Compose.
edwh Jul 21, 2025
5e12183
WIP Change CircleCI to use Docker Compose.
edwh Jul 22, 2025
77b85d1
WIP Change CircleCI to use Docker Compose.
edwh Jul 28, 2025
dc36058
WIP Change CircleCI to use Docker Compose.
edwh Jul 28, 2025
fb87c63
WIP Change CircleCI to use Docker Compose.
edwh Jul 28, 2025
2ebc05c
WIP Change CircleCI to use Docker Compose.
edwh Jul 28, 2025
768af48
WIP Change CircleCI to use Docker Compose.
edwh Jul 28, 2025
eac2dcc
WIP Change CircleCI to use Docker Compose.
edwh Jul 28, 2025
e160612
WIP Change CircleCI to use Docker Compose.
edwh Jul 28, 2025
74d3892
WIP Change CircleCI to use Docker Compose.
edwh Jul 28, 2025
7cd0678
WIP Change CircleCI to use Docker Compose.
edwh Jul 28, 2025
61879fc
WIP Change CircleCI to use Docker Compose.
edwh Jul 28, 2025
28adb19
WIP Change CircleCI to use Docker Compose.
edwh Jul 28, 2025
43f93db
WIP Change CircleCI to use Docker Compose.
edwh Jul 28, 2025
3325d09
WIP Change CircleCI to use Docker Compose.
edwh Jul 31, 2025
087b1ce
WIP Change CircleCI to use Docker Compose.
edwh Aug 1, 2025
9d342b3
WIP Change CircleCI to use Docker Compose.
edwh Aug 1, 2025
fdb5c6c
WIP Change CircleCI to use Docker Compose.
edwh Aug 1, 2025
1a4b573
WIP Change CircleCI to use Docker Compose.
edwh Aug 1, 2025
f58a84f
WIP Change CircleCI to use Docker Compose.
edwh Aug 1, 2025
4569846
WIP Change CircleCI to use Docker Compose.
edwh Aug 1, 2025
cbbc5ba
Merge branch 'refs/heads/develop' into RES-2026_circleci_docker_compose
edwh Sep 17, 2025
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
469 changes: 221 additions & 248 deletions .circleci/config.yml

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,7 @@ npm test
- Only translate fr and fr-BE

## Development Warnings
- Don't try to test changes when you're running on Windows.
- Don't try to test changes when you're running on Windows.

## Workflow Guidelines
- When you create files, add them to git
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@ RUN apt-get update && \
unzip \
npm \
vim \
netcat-openbsd \
default-mysql-client \
postgresql-client && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Install Playwright system dependencies
# We need to install @playwright/test first to get the install-deps command
RUN npm install -g @playwright/test && \
npm install -g jest-junit && \
npx playwright install-deps && \
npm uninstall -g @playwright/test

ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/download/2.7.31/install-php-extensions /usr/local/bin/

RUN install-php-extensions \
Expand All @@ -23,6 +31,9 @@ RUN install-php-extensions \
xmlrpc \
xdebug \
intl \
exif \
pcntl \
curl \
gd

# Install composer. Don't run composer install yet - see docker_run.sh
Expand Down
107 changes: 104 additions & 3 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,19 @@

env:
UID:
sh: id -u
sh: |
if command -v id >/dev/null 2>&1; then
id -u
else
echo "1000"
fi
GID:
sh: id -g
sh: |
if command -v id >/dev/null 2>&1; then
id -g
else
echo "1000"
fi

vars:
DOCKER_CMD:
Expand Down Expand Up @@ -159,4 +169,95 @@
task docker:run:artisan -- migrate

cmds:
- docker exec -it restarters php artisan "{{ .CLI_ARGS }}"
- docker exec -it restarters php artisan "{{ .CLI_ARGS }}"

docker:wait-for-services-*:
desc: Wait for Docker services to be ready and responding for a given profile (Usage - task docker:wait-for-services-[core|debug|discourse|all])
summary: |
Wait for Docker services to be ready by checking their health endpoints.
This task will check that services are listening on their ports and returning
plausible responses before proceeding, but only for the services in the specified profile.

For just the core services, use:
task docker:wait-for-services-core

To include debug tools (phpMyAdmin, Mailhog), use:
task docker:wait-for-services-debug

To include Discourse services, use:
task docker:wait-for-services-discourse

To wait for all services, use:
task docker:wait-for-services-all

The task checks:
- Core profile: MySQL database, Restarters web app
- Debug profile: Core + phpMyAdmin, Mailhog
- Discourse profile: Core + Discourse, PostgreSQL, Redis, Sidekiq
- All profile: All services

requires: *PROFILE_REQUIRES

vars: *PROFILE_VARS

cmds:
- |
# Cross-platform sleep function
cross_platform_sleep() {
if command -v sleep >/dev/null 2>&1; then
sleep "$1"
elif command -v powershell >/dev/null 2>&1; then
powershell -Command "Start-Sleep -Seconds $1"
else
# Fallback using ping (works on most systems)
ping -n $(($1 + 1)) 127.0.0.1 >/dev/null 2>&1 || ping -c $1 127.0.0.1 >/dev/null 2>&1
fi
}

# Generic wait function that takes: service_name, check_command, max_attempts, sleep_interval
wait_for_service() {
local service_name="$1"
local check_command="$2"
local max_attempts="$3"
local sleep_interval="$4"

echo "Waiting for $service_name..."
local attempt=0
while [ $attempt -lt $max_attempts ]; do
if eval "$check_command" >/dev/null 2>&1; then
echo "✓ $service_name is ready"
return 0
fi
echo " $service_name not ready, waiting... (attempt $((attempt + 1))/$max_attempts)"
cross_platform_sleep "$sleep_interval"
attempt=$((attempt + 1))
done
echo "❌ $service_name failed to start after $max_attempts attempts"
exit 1
}

echo "Waiting for services in profile: {{.PROFILE}}"
echo ""

# Wait for core services (always needed)
wait_for_service "MySQL database" "docker exec restarters_db mysqladmin ping -h localhost -u root -ps3cr3t --silent" 60 5

Check failure

Code scanning / SonarCloud

MySQL database passwords should not be disclosed High

Make sure this MySQL database password gets changed and removed from the code. See more on SonarQube Cloud
wait_for_service "Restarters web application" "curl -f -s http://localhost:8001" 120 5

# Wait for debug services (if in debug or all profile)
{{- if or (eq .PROFILE "debug") (eq .PROFILE "all") }}
wait_for_service "phpMyAdmin" "curl -f -s http://localhost:8002" 60 5
wait_for_service "Mailhog" "curl -f -s http://localhost:8025" 60 5
{{- else }}
echo "✓ phpMyAdmin not in profile {{.PROFILE}}, skipping"
echo "✓ Mailhog not in profile {{.PROFILE}}, skipping"
{{- end }}

# Wait for discourse services (if in discourse or all profile)
{{- if or (eq .PROFILE "discourse") (eq .PROFILE "all") }}
wait_for_service "PostgreSQL" "docker exec postgresql pg_isready -U postgres" 60 5
wait_for_service "Discourse" "curl -f -s http://localhost:8003" 120 10
{{- else }}
echo "✓ PostgreSQL not in profile {{.PROFILE}}, skipping"
echo "✓ Discourse not in profile {{.PROFILE}}, skipping"
{{- end }}
- echo "🎉 All services in profile {{.PROFILE}} are ready!"
44 changes: 33 additions & 11 deletions app/Device.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ class Device extends Model implements Auditable

use \OwenIt\Auditing\Auditable;
protected $table = 'devices';

/**
* Check if we're running in CircleCI environment
*/
private static function isCircleCI()
{
return env('CIRCLECI', false) || env('CI', false);
}
protected $primaryKey = 'iddevices';
/**
* The attributes that are mass assignable.
Expand Down Expand Up @@ -269,9 +277,13 @@ public function eCo2Diverted($emissionRatio, $displacementFactor)
if ($this->category == env('MISC_CATEGORY_ID_POWERED') && $this->estimate > 0) {
$footprint = $this->estimate * $emissionRatio;
} else {
$footprint = \Cache::remember('category-' . $this->category, 15, function() {
return $this->deviceCategory;
})->footprint;
if (self::isCircleCI()) {
$footprint = $this->deviceCategory->footprint;
} else {
$footprint = \Cache::remember('category-' . $this->category, 15, function() {
return $this->deviceCategory;
})->footprint;
}
}
}

Expand Down Expand Up @@ -305,17 +317,25 @@ public function eWasteDiverted()
{
$ewasteDiverted = 0;

$powered = \Cache::remember('category-powered-' . $this->category, 15, function() {
return $this->deviceCategory->powered;
});
if (self::isCircleCI()) {
$powered = $this->deviceCategory->powered;
} else {
$powered = \Cache::remember('category-powered-' . $this->category, 15, function() {
return $this->deviceCategory->powered;
});
}

if ($this->isFixed() && $powered) {
if ($this->category == env('MISC_CATEGORY_ID_POWERED') && $this->estimate > 0) {
$ewasteDiverted = $this->estimate;
} else {
$category = \Cache::remember('category-' . $this->category, 15, function() {
return $this->deviceCategory;
});
if (self::isCircleCI()) {
$category = $this->deviceCategory;
} else {
$category = \Cache::remember('category-' . $this->category, 15, function() {
return $this->deviceCategory;
});
}

$ewasteDiverted = $category->weight;
}
Expand Down Expand Up @@ -454,7 +474,7 @@ public static function getItemTypes()
// used by the item types.
//
// This is slow and the results don't change much, so we use a cache.
if (Cache::has('item_types')) {
if (!self::isCircleCI() && Cache::has('item_types')) {
$types = Cache::get('item_types');
} else {
$types = DB::select(DB::raw("
Expand Down Expand Up @@ -485,7 +505,9 @@ public static function getItemTypes()
AND LENGTH(t.item_type) > 0
GROUP BY t.item_type, t.powered;
"));
\Cache::put('item_types', $types, 24 * 3600);
if (!self::isCircleCI()) {
\Cache::put('item_types', $types, 24 * 3600);
}
}

return $types;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,6 @@ public function up()
DB::table('devices')
->where('repair_status', 0)
->update(['repair_status_str' => 'Unknown']);
DB::unprepared("CREATE TRIGGER `repair_status_str_up`
BEFORE UPDATE ON `devices` FOR EACH ROW
SET NEW.repair_status_str = CASE
WHEN NEW.repair_status = 1 THEN 'Fixed'
WHEN NEW.repair_status = 2 THEN 'Repairable'
WHEN NEW.repair_status = 3 THEN 'End of life'
ELSE 'Unknown'
END;
");
DB::unprepared("CREATE TRIGGER `repair_status_str_in`
BEFORE INSERT ON `devices` FOR EACH ROW
SET NEW.repair_status_str = CASE
WHEN NEW.repair_status = 1 THEN 'Fixed'
WHEN NEW.repair_status = 2 THEN 'Repairable'
WHEN NEW.repair_status = 3 THEN 'End of life'
ELSE 'Unknown'
END;
");
}

/**
Expand All @@ -60,8 +42,6 @@ public function up()
*/
public function down()
{
DB::unprepared('DROP TRIGGER IF EXISTS `repair_status_str_in`');
DB::unprepared('DROP TRIGGER IF EXISTS `repair_status_str_up`');
if (Schema::hasColumn('devices', 'repair_status_str')) {
Schema::table('devices', function (Blueprint $table) {
$table->dropColumn('repair_status_str');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
DB::unprepared('DROP TRIGGER IF EXISTS `repair_status_str_in`');
DB::unprepared('DROP TRIGGER IF EXISTS `repair_status_str_up`');
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
}
};
5 changes: 2 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@
# TODO This is stock Discourse - no theme. Would be nice to have the theme, but that doesn't matter so far as
# testing the integration.

version: '3'

services:
# Core services - always enabled
restarters:
Expand All @@ -93,6 +91,7 @@ services:
SERVICE_TAGS: dev
UID: ${UID}
GID: ${GID}
CIRCLECI: ${CIRCLECI:-false}
working_dir: /var/www
volumes:
# We share the current folder into /var/www. This means code changes on the host will get picked up
Expand All @@ -119,7 +118,7 @@ services:

restarters_db:
profiles: ["core", "debug", "discourse"]
image: mysql:5.7.33
image: mysql:8.0
container_name: restarters_db
restart: unless-stopped
tty: true
Expand Down
Loading