Skip to content

Commit 4b3b587

Browse files
committed
Merge develop into RES-1995_map_of_groups (resolves conflict from #744 revert; keep PR content)
# Conflicts: # resources/js/components/GroupsPage.vue # resources/js/components/GroupsRequiringModeration.vue # resources/js/store/groups.js # tests/Integration/grouptags.test.js
2 parents d9c127b + 78282c1 commit 4b3b587

96 files changed

Lines changed: 4055 additions & 4013 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: 61 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,163 +1,147 @@
11
version: 2.1
22

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:
3+
jobs:
4+
build:
5+
machine:
6+
image: ubuntu-2204:current
7+
resource_class: large
8+
environment:
9+
- TZ: "UTC"
10+
711
steps:
812
- checkout
9-
13+
14+
# Install Task
1015
- run:
1116
name: Install Task
1217
command: |
1318
sudo sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
1419
task --version
1520
21+
# Set up environment file
1622
- run:
1723
name: Setup environment
1824
command: |
1925
cp .env.example .env
26+
27+
# Configure for Docker Compose setup
2028
sed -i 's/DB_HOST=.*$/DB_HOST=restarters_db/g' .env
2129
sed -i 's/DB_DATABASE=.*$/DB_DATABASE=restarters_db_test/g' .env
2230
sed -i 's/DB_USERNAME=.*$/DB_USERNAME=restarters/g' .env
2331
sed -i 's/DB_PASSWORD=.*$/DB_PASSWORD=s3cr3t/g' .env
32+
33+
# Configure Discourse integration
2434
sed -i 's/FEATURE__DISCOURSE_INTEGRATION=.*$/FEATURE__DISCOURSE_INTEGRATION=true/g' .env
2535
sed -i 's/DISCOURSE_URL=.*$/DISCOURSE_URL=http:\/\/restarters_discourse/g' .env
2636
sed -i 's/DISCOURSE_APIKEY=.*$/DISCOURSE_APIKEY=fb71f38ca2b8b7cd6a041e57fd8202c9937088f0ecae7db40722bd758dda92fc/g' .env
2737
sed -i 's/DISCOURSE_APIUSER=.*$/DISCOURSE_APIUSER=someuser/g' .env
38+
39+
# Configure for testing
2840
sed -i 's/APP_DEBUG=.*$/APP_DEBUG=false/g' .env
2941
sed -i 's/SESSION_DOMAIN=.*$/SESSION_DOMAIN=localhost/g' .env
3042
sed -i 's/HONEYPOT_DISABLE=.*$/HONEYPOT_DISABLE=TRUE/g' .env
3143
sed -i 's/APP_URL=.*$/APP_URL=http:\/\/localhost:8001/g' .env
44+
45+
# Add environment variables from CircleCI
3246
echo "" >> .env
3347
echo "GOOGLE_API_CONSOLE_KEY=$GOOGLE_API_CONSOLE_KEY" >> .env
3448
echo "MAPBOX_TOKEN=$MAPBOX_TOKEN" >> .env
3549
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-
50+
# Start Docker services using Task
5851
- run:
5952
name: Start Docker services
6053
command: |
54+
# Set environment variable for CircleCI detection
6155
export CIRCLECI=true
56+
# Enable Docker Compose bake for build optimization
6257
export COMPOSE_BAKE=true
58+
# Start all services using Task
6359
task docker:up-all
6460
no_output_timeout: 10m
6561

62+
# Wait for services to be ready (includes build completion and restart detection)
6663
- run:
6764
name: Wait for services
6865
command: |
6966
task docker:wait-for-services-all
7067
71-
- save_cache:
72-
key: composer-v2-{{ checksum "composer.lock" }}
73-
paths:
74-
- vendor
75-
68+
# Setup database and application
7669
- run:
7770
name: Setup application
7871
command: |
72+
# Grant timezone access - run directly on MySQL container
7973
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)
8077
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
8180
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
8283
docker exec restarters php artisan l5-swagger:generate
8384
85+
# Setup Discourse API
8486
- run:
8587
name: Setup Discourse
8688
command: |
89+
# Add API key to Discourse - run directly on PostgreSQL container
8790
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
8893
docker exec restarters php artisan discourse:setting personal_message_enabled_groups 10
8994
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-
95+
# Run PHPUnit tests
10196
- run:
10297
name: Run PHPUnit tests
10398
command: |
104-
mkdir -p /tmp/test-results/phpunit
99+
# Run PHPUnit tests using Task for consistency with local development
105100
task docker:test:phpunit
101+
# Copy test results to host
106102
docker cp restarters:/tmp/phpunit-results.xml /tmp/test-results/phpunit/results.xml
107103
no_output_timeout: 45m
108104

105+
# Run Jest tests
109106
- run:
110107
name: Run Jest tests
111108
command: |
112-
mkdir -p /tmp/test-results/jest
109+
# Run Jest tests using Task for consistency with local development
113110
task docker:test:jest
111+
# Copy test results to host if they exist
114112
docker cp restarters:/tmp/test-results/junit.xml /tmp/test-results/jest/junit.xml || echo "Jest results not found, skipping"
115113
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-
114+
# Run main Playwright tests (excluding autocomplete)
133115
- run:
134116
name: Run main Playwright tests
135117
command: |
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
118+
# Run Playwright tests using Task for consistency with local development
140119
task docker:test:playwright
141-
EXIT_CODE=$?
142-
kill $KEEPALIVE_PID 2>/dev/null || true
143-
exit $EXIT_CODE
144-
no_output_timeout: 30m
120+
no_output_timeout: 10m
145121

122+
# Copy test results and artifacts
146123
- run:
147124
name: Copy Playwright artifacts
148125
command: |
149-
mkdir -p /tmp/test-results/playwright /tmp/test-results/logs
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
150131
docker exec restarters_playwright bash -c "ls -la /tmp/test-results/* || echo 'No playwright directories found'"
151-
docker cp restarters_playwright:/tmp/test-results/. /tmp/test-results/playwright/ || echo "Playwright results not 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
152137
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"
155138
when: always
156139

140+
# Store artifacts
157141
- store_artifacts:
158142
path: /tmp/test-results
159143
destination: playwright-test-results
160-
144+
161145
- store_test_results:
162146
path: /tmp/test-results
163147

@@ -198,18 +182,13 @@ jobs:
198182
workflows:
199183
build-and-deploy:
200184
jobs:
201-
- test-php:
202-
filters:
203-
branches:
204-
ignore: production
205-
- test-playwright:
185+
- build:
206186
filters:
207187
branches:
208188
ignore: production
209189
- deploy-fly-dev:
210190
requires:
211-
- test-php
212-
- test-playwright
191+
- build
213192
filters:
214193
branches:
215194
only: develop

Dockerfile

Lines changed: 3 additions & 7 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.4-fpm
2+
FROM php:8.2-fpm
33

44
# Install dependencies
55
RUN apt-get update && \
@@ -22,15 +22,11 @@ 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.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
25+
ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/download/2.7.31/install-php-extensions /usr/local/bin/
3126

3227
RUN install-php-extensions \
3328
pdo_mysql \
29+
bcmath \
3430
zip \
3531
xmlrpc \
3632
xdebug \

Dockerfile.fly

Lines changed: 3 additions & 5 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.4-cli AS builder
4+
FROM php:8.2-cli AS builder
55

66
# Install system dependencies for building
77
RUN apt-get update && apt-get install -y --no-install-recommends \
@@ -16,7 +16,6 @@ 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
2019

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

2625
WORKDIR /build
2726

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

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

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

Taskfile.yml

Lines changed: 6 additions & 9 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 tests/bootstrap.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 vendor/autoload.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,17 +264,13 @@ 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"
273267
- docker exec restarters bash -c "sed -i 's/APP_DEBUG=.*$/APP_DEBUG=false/g' /var/www/.env"
274268
- docker exec restarters bash -c "sed -i 's/QUEUE_CONNECTION=.*/QUEUE_CONNECTION=sync/g' /var/www/.env"
275269
- docker exec restarters bash -c "sed -i 's/MAIL_MAILER=.*/MAIL_MAILER=log/g' /var/www/.env"
276270
- |
277-
echo "Building assets for production..."
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"
278274
docker exec restarters bash -c "rm -f /var/www/public/hot && npm run build"
279275
- |
280276
# Ensure Playwright browsers are installed (handles version mismatches)
@@ -285,10 +281,11 @@ tasks:
285281
export PLAYWRIGHT_TEST=true
286282
export PLAYWRIGHT_DEBUG=true
287283
export PWTEST_SKIP_TEST_OUTPUT=0
284+
export DEBUG=playwright
288285
export PLAYWRIGHT_BASE_URL=http://restarters_nginx
289286
export PW_TEST_HTML_REPORT_OPEN=never
290287
export FORCE_COLOR=1
291-
stdbuf -oL -eL npx playwright test --reporter=list,html
288+
stdbuf -oL -eL npx playwright test --reporter=html
292289
"
293290
294291
docker:wait-for-services-*:

app/Device.php

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

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

0 commit comments

Comments
 (0)