Skip to content

Commit ff5dfa4

Browse files
authored
Merge pull request #744 from TheRestartProject/RES-1995_map_of_groups
RES-1995 rework groups page to have a map of groups
2 parents cc229a7 + 399ed7d commit ff5dfa4

100 files changed

Lines changed: 4377 additions & 4432 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.circleci/config.yml

Lines changed: 82 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,163 @@
11
version: 2.1
22

3-
jobs:
4-
build:
5-
machine:
6-
image: ubuntu-2204:current
7-
resource_class: large
8-
environment:
9-
- TZ: "UTC"
10-
3+
# Shared setup steps via CircleCI reusable command.
4+
# Both jobs need their own Docker environment (CircleCI jobs can't share Docker).
5+
commands:
6+
setup_docker:
117
steps:
128
- checkout
13-
14-
# Install Task
9+
1510
- run:
1611
name: Install Task
1712
command: |
1813
sudo sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
1914
task --version
2015
21-
# Set up environment file
2216
- run:
2317
name: Setup environment
2418
command: |
2519
cp .env.example .env
26-
27-
# Configure for Docker Compose setup
2820
sed -i 's/DB_HOST=.*$/DB_HOST=restarters_db/g' .env
2921
sed -i 's/DB_DATABASE=.*$/DB_DATABASE=restarters_db_test/g' .env
3022
sed -i 's/DB_USERNAME=.*$/DB_USERNAME=restarters/g' .env
3123
sed -i 's/DB_PASSWORD=.*$/DB_PASSWORD=s3cr3t/g' .env
32-
33-
# Configure Discourse integration
3424
sed -i 's/FEATURE__DISCOURSE_INTEGRATION=.*$/FEATURE__DISCOURSE_INTEGRATION=true/g' .env
3525
sed -i 's/DISCOURSE_URL=.*$/DISCOURSE_URL=http:\/\/restarters_discourse/g' .env
3626
sed -i 's/DISCOURSE_APIKEY=.*$/DISCOURSE_APIKEY=fb71f38ca2b8b7cd6a041e57fd8202c9937088f0ecae7db40722bd758dda92fc/g' .env
3727
sed -i 's/DISCOURSE_APIUSER=.*$/DISCOURSE_APIUSER=someuser/g' .env
38-
39-
# Configure for testing
4028
sed -i 's/APP_DEBUG=.*$/APP_DEBUG=false/g' .env
4129
sed -i 's/SESSION_DOMAIN=.*$/SESSION_DOMAIN=localhost/g' .env
4230
sed -i 's/HONEYPOT_DISABLE=.*$/HONEYPOT_DISABLE=TRUE/g' .env
4331
sed -i 's/APP_URL=.*$/APP_URL=http:\/\/localhost:8001/g' .env
44-
45-
# Add environment variables from CircleCI
4632
echo "" >> .env
4733
echo "GOOGLE_API_CONSOLE_KEY=$GOOGLE_API_CONSOLE_KEY" >> .env
4834
echo "MAPBOX_TOKEN=$MAPBOX_TOKEN" >> .env
4935
50-
# Start Docker services using Task
36+
- restore_cache:
37+
keys:
38+
- composer-v2-{{ checksum "composer.lock" }}
39+
- composer-v2-
40+
41+
- restore_cache:
42+
keys:
43+
- node-modules-v1-{{ checksum "package-lock.json" }}
44+
- node-modules-v1-
45+
46+
- run:
47+
name: Build frontend assets
48+
command: |
49+
npm install --legacy-peer-deps
50+
npm run build
51+
no_output_timeout: 15m
52+
53+
- save_cache:
54+
key: node-modules-v1-{{ checksum "package-lock.json" }}
55+
paths:
56+
- node_modules
57+
5158
- run:
5259
name: Start Docker services
5360
command: |
54-
# Set environment variable for CircleCI detection
5561
export CIRCLECI=true
56-
# Enable Docker Compose bake for build optimization
5762
export COMPOSE_BAKE=true
58-
# Start all services using Task
5963
task docker:up-all
6064
no_output_timeout: 10m
6165

62-
# Wait for services to be ready (includes build completion and restart detection)
6366
- run:
6467
name: Wait for services
6568
command: |
6669
task docker:wait-for-services-all
6770
68-
# Setup database and application
71+
- save_cache:
72+
key: composer-v2-{{ checksum "composer.lock" }}
73+
paths:
74+
- vendor
75+
6976
- run:
7077
name: Setup application
7178
command: |
72-
# Grant timezone access - run directly on MySQL container
7379
docker exec restarters_db mysql -u root -ps3cr3t -e "GRANT SELECT ON mysql.time_zone_name TO 'restarters'@'%';"
74-
75-
# Setup additional configuration needed for CI (most setup already done by docker_run.sh)
76-
# Set MySQL function creators using session variable (compatible with MySQL 5.7)
7780
docker exec restarters_db mysql -u root -ps3cr3t -e "SET GLOBAL log_bin_trust_function_creators = 1;"
78-
79-
# Disable ONLY_FULL_GROUP_BY for compatibility with getItemTypes() query
8081
docker exec restarters_db mysql -u root -ps3cr3t -e "SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));"
81-
82-
# Generate additional Laravel artifacts for testing
8382
docker exec restarters php artisan l5-swagger:generate
8483
85-
# Setup Discourse API
8684
- run:
8785
name: Setup Discourse
8886
command: |
89-
# Add API key to Discourse - run directly on PostgreSQL container
9087
docker exec postgresql psql -U postgres -c "INSERT INTO api_keys (id, user_id, created_by_id, created_at, updated_at, allowed_ips, hidden, last_used_at, revoked_at, description, key_hash, truncated_key) VALUES (1, NULL, 1, '2021-10-25 13:56:20.033338', '2021-10-25 13:56:20.033338', NULL, false, NULL, NULL, 'Restarters', 'd89e9dfacfb611fbaf004807648187ce7ed474df44dcb0ada230fab5c8dd6a5b', '9fd7');" bitnami_discourse
91-
92-
# Configure Discourse settings
9388
docker exec restarters php artisan discourse:setting personal_message_enabled_groups 10
9489
95-
# Run PHPUnit tests
90+
jobs:
91+
test-php:
92+
machine:
93+
image: ubuntu-2204:current
94+
resource_class: large
95+
environment:
96+
- TZ: "UTC"
97+
98+
steps:
99+
- setup_docker
100+
96101
- run:
97102
name: Run PHPUnit tests
98103
command: |
99-
# Run PHPUnit tests using Task for consistency with local development
104+
mkdir -p /tmp/test-results/phpunit
100105
task docker:test:phpunit
101-
# Copy test results to host
102106
docker cp restarters:/tmp/phpunit-results.xml /tmp/test-results/phpunit/results.xml
103107
no_output_timeout: 45m
104108

105-
# Run Jest tests
106109
- run:
107110
name: Run Jest tests
108111
command: |
109-
# Run Jest tests using Task for consistency with local development
112+
mkdir -p /tmp/test-results/jest
110113
task docker:test:jest
111-
# Copy test results to host if they exist
112114
docker cp restarters:/tmp/test-results/junit.xml /tmp/test-results/jest/junit.xml || echo "Jest results not found, skipping"
113115
114-
# Run main Playwright tests (excluding autocomplete)
116+
- store_artifacts:
117+
path: /tmp/test-results
118+
destination: test-results-php
119+
120+
- store_test_results:
121+
path: /tmp/test-results
122+
123+
test-playwright:
124+
machine:
125+
image: ubuntu-2204:current
126+
resource_class: large
127+
environment:
128+
- TZ: "UTC"
129+
130+
steps:
131+
- setup_docker
132+
115133
- run:
116134
name: Run main Playwright tests
117135
command: |
118-
# Run Playwright tests using Task for consistency with local development
136+
mkdir -p /tmp/test-results/playwright /tmp/test-results/logs
137+
( while true; do sleep 60; echo "[ci-keepalive] $(date -u +%H:%M:%S)"; done ) &
138+
KEEPALIVE_PID=$!
139+
trap "kill $KEEPALIVE_PID 2>/dev/null || true" EXIT
119140
task docker:test:playwright
120-
no_output_timeout: 10m
141+
EXIT_CODE=$?
142+
kill $KEEPALIVE_PID 2>/dev/null || true
143+
exit $EXIT_CODE
144+
no_output_timeout: 30m
121145

122-
# Copy test results and artifacts
123146
- run:
124147
name: Copy Playwright artifacts
125148
command: |
126-
# Create test results directory on host
127-
mkdir -p /tmp/test-results/playwright
128-
mkdir -p /tmp/test-results/logs
129-
130-
# List what's available in the playwright container
149+
mkdir -p /tmp/test-results/playwright /tmp/test-results/logs
131150
docker exec restarters_playwright bash -c "ls -la /tmp/test-results/* || echo 'No playwright directories found'"
132-
133-
# Copy test results and artifacts from playwright container to host
134-
docker cp restarters_playwright:/tmp/test-results/. /tmp/test-results/playwright/ || echo "Playwright HTML report not found"
135-
136-
# Copy Vite log from restarters container for debugging
151+
docker cp restarters_playwright:/tmp/test-results/. /tmp/test-results/playwright/ || echo "Playwright results not found"
137152
docker cp restarters:/tmp/vite.log /tmp/test-results/logs/vite.log || echo "Vite log not found"
153+
docker logs restarters > /tmp/test-results/logs/restarters.log 2>&1 || echo "Could not capture restarters logs"
154+
docker exec restarters bash -c "tail -300 /var/www/storage/logs/laravel.log 2>/dev/null" > /tmp/test-results/logs/laravel.log || echo "No laravel log found"
138155
when: always
139156

140-
# Store artifacts
141157
- store_artifacts:
142158
path: /tmp/test-results
143159
destination: playwright-test-results
144-
160+
145161
- store_test_results:
146162
path: /tmp/test-results
147163

@@ -182,13 +198,18 @@ jobs:
182198
workflows:
183199
build-and-deploy:
184200
jobs:
185-
- build:
201+
- test-php:
202+
filters:
203+
branches:
204+
ignore: production
205+
- test-playwright:
186206
filters:
187207
branches:
188208
ignore: production
189209
- deploy-fly-dev:
190210
requires:
191-
- build
211+
- test-php
212+
- test-playwright
192213
filters:
193214
branches:
194215
only: develop

Dockerfile

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# This is the docker for restarters. It's used from docker-compose.
2-
FROM php:8.2-fpm
2+
FROM php:8.4-fpm
33

44
# Install dependencies
55
RUN apt-get update && \
@@ -22,11 +22,15 @@ RUN npm install -g @playwright/test && \
2222
npx playwright install-deps && \
2323
npm uninstall -g @playwright/test
2424

25-
ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/download/2.7.31/install-php-extensions /usr/local/bin/
25+
ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/download/2.11.1/install-php-extensions /usr/local/bin/
26+
27+
# bcmath via PHP's own docker-php-ext-install — install-php-extensions
28+
# trips over a pre-existing libbcmath/src/.libs directory in some PHP 8.4
29+
# base image variants ("mkdir: cannot create directory ...: File exists").
30+
RUN docker-php-ext-install bcmath
2631

2732
RUN install-php-extensions \
2833
pdo_mysql \
29-
bcmath \
3034
zip \
3135
xmlrpc \
3236
xdebug \

Dockerfile.fly

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# =============================================================================
22
# Stage 1: Build assets (Node + Composer)
33
# =============================================================================
4-
FROM php:8.2-cli AS builder
4+
FROM php:8.4-cli AS builder
55

66
# Install system dependencies for building
77
RUN apt-get update && apt-get install -y --no-install-recommends \
@@ -16,6 +16,7 @@ RUN pecl install channel://pecl.php.net/xmlrpc-1.0.0RC3 && docker-php-ext-enable
1616

1717
# Install composer
1818
COPY --from=composer/composer:2-bin /composer /usr/bin/composer
19+
ENV COMPOSER_ALLOW_SUPERUSER=1
1920

2021
# Install Node 18
2122
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
@@ -24,8 +25,9 @@ RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
2425

2526
WORKDIR /build
2627

27-
# Copy composer files first for layer caching
28+
# Copy composer files and patches for layer caching
2829
COPY composer.json composer.lock ./
30+
COPY patches/ ./patches/
2931
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist
3032

3133
# Copy package files for npm layer caching
@@ -62,7 +64,7 @@ RUN rm -f .env
6264
# =============================================================================
6365
# Stage 2: Production image (Nginx + PHP-FPM + Supervisord + Cron)
6466
# =============================================================================
65-
FROM php:8.2-fpm
67+
FROM php:8.4-fpm
6668

6769
# yesterday mode adds mariadb-server (co-located DB for restored snapshots).
6870
ARG STARTUP_SCRIPT=startup.sh

Taskfile.yml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ tasks:
225225
else
226226
echo "Running on CircleCI - skipping database reset (handled by CI setup)"
227227
fi
228-
- docker exec -e COVERALLS_REPO_TOKEN="$COVERALLS_REPO_TOKEN" restarters bash -c "export XDEBUG_MODE=coverage; ./vendor/bin/phpunit -d memory_limit=1024M --bootstrap vendor/autoload.php --coverage-clover tests/clover.xml --log-junit /tmp/phpunit-results.xml --configuration ./phpunit.xml --teamcity {{ .CLI_ARGS }}"
228+
- docker exec -e COVERALLS_REPO_TOKEN="$COVERALLS_REPO_TOKEN" restarters bash -c "export XDEBUG_MODE=coverage; ./vendor/bin/phpunit -d memory_limit=1024M --bootstrap tests/bootstrap.php --coverage-clover tests/clover.xml --log-junit /tmp/phpunit-results.xml --configuration ./phpunit.xml --teamcity {{ .CLI_ARGS }}"
229229
- |
230230
if [ ! -z "$COVERALLS_REPO_TOKEN" ]; then
231231
echo "Uploading coverage to Coveralls..."
@@ -264,13 +264,17 @@ tasks:
264264
# Create test data for group tags tests (NC user, host user, network, group)
265265
docker exec restarters php artisan tinker --execute='$nc = App\User::firstOrCreate(["email"=>"nc@test.net"], ["name"=>"NC User","password"=>Hash::make("passw0rd"),"consent_past_data"=>"2021-01-01","consent_future_data"=>"2021-01-01","consent_gdpr"=>"2021-01-01"]); $nc->role=6; $nc->save(); $host = App\User::firstOrCreate(["email"=>"host@test.net"], ["name"=>"Host User","password"=>Hash::make("passw0rd"),"consent_past_data"=>"2021-01-01","consent_future_data"=>"2021-01-01","consent_gdpr"=>"2021-01-01"]); $host->role=3; $host->save(); $network = App\Network::where("name","Test London")->first(); if (!$network) { $network = new App\Network(); $network->name="Test London"; $network->shortname="testlondon"; $network->description="Test network"; $network->default_language="en"; $network->save(); } DB::table("user_network")->insertOrIgnore(["user_id"=>$nc->id,"network_id"=>$network->id]); $group = App\Group::firstOrCreate(["name"=>"Tag Test Group"], ["website"=>"https://test.example.com","location"=>"London","area"=>"London","postcode"=>"SW1A 1AA","latitude"=>51.5,"longitude"=>-0.1,"free_text"=>"Test group","approved"=>true]); DB::table("group_network")->insertOrIgnore(["group_id"=>$group->idgroups,"network_id"=>$network->id]); DB::table("users_groups")->insertOrIgnore(["user"=>$host->id,"group"=>$group->idgroups,"role"=>3,"status"=>1]); echo "Group tags test data: NC=".$nc->id." Host=".$host->id." Network=".$network->id." Group=".$group->idgroups;' || true
266266
- docker exec restarters bash -c "sed -i 's/.throttle:api.,//g' /var/www/app/Http/Kernel.php"
267+
- |
268+
# Stop Vite dev server BEFORE modifying .env.
269+
# Vite v4 crashes with ERR_INVALID_ARG_TYPE when it detects .env changes mid-run;
270+
# killing it first prevents the crash from corrupting the build environment.
271+
echo "Stopping Vite dev server..."
272+
docker exec restarters bash -c "ps aux | grep 'node.*vite' | grep -v grep | awk '{print \$2}' | xargs -r kill -9 || true"
267273
- docker exec restarters bash -c "sed -i 's/APP_DEBUG=.*$/APP_DEBUG=false/g' /var/www/.env"
268274
- docker exec restarters bash -c "sed -i 's/QUEUE_CONNECTION=.*/QUEUE_CONNECTION=sync/g' /var/www/.env"
269275
- docker exec restarters bash -c "sed -i 's/MAIL_MAILER=.*/MAIL_MAILER=log/g' /var/www/.env"
270276
- |
271-
# Stop Vite dev server and build assets for production
272-
echo "Stopping Vite dev server and building assets..."
273-
docker exec restarters bash -c "ps aux | grep 'node.*vite' | grep -v grep | awk '{print \$2}' | xargs -r kill || true"
277+
echo "Building assets for production..."
274278
docker exec restarters bash -c "rm -f /var/www/public/hot && npm run build"
275279
- |
276280
# Ensure Playwright browsers are installed (handles version mismatches)
@@ -281,11 +285,10 @@ tasks:
281285
export PLAYWRIGHT_TEST=true
282286
export PLAYWRIGHT_DEBUG=true
283287
export PWTEST_SKIP_TEST_OUTPUT=0
284-
export DEBUG=playwright
285288
export PLAYWRIGHT_BASE_URL=http://restarters_nginx
286289
export PW_TEST_HTML_REPORT_OPEN=never
287290
export FORCE_COLOR=1
288-
stdbuf -oL -eL npx playwright test --reporter=html
291+
stdbuf -oL -eL npx playwright test --reporter=list,html
289292
"
290293
291294
docker:wait-for-services-*:

app/Device.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,11 @@ public function uWasteDiverted()
355355
{
356356
$wasteDiverted = 0;
357357

358-
if ($this->isFixed() && $this->deviceCategory->isUnpowered()) {
358+
$unpowered = \Cache::remember('category-unpowered-' . $this->category, 60, function() {
359+
return $this->deviceCategory->isUnpowered();
360+
});
361+
362+
if ($this->isFixed() && $unpowered) {
359363
if ($this->estimate > 0) {
360364
$wasteDiverted = $this->estimate;
361365
} else {

0 commit comments

Comments
 (0)