|
1 | 1 | version: 2.1 |
2 | 2 |
|
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: |
11 | 7 | steps: |
12 | 8 | - checkout |
13 | | - |
14 | | - # Install Task |
| 9 | + |
15 | 10 | - run: |
16 | 11 | name: Install Task |
17 | 12 | command: | |
18 | 13 | sudo sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin |
19 | 14 | task --version |
20 | 15 |
|
21 | | - # Set up environment file |
22 | 16 | - run: |
23 | 17 | name: Setup environment |
24 | 18 | command: | |
25 | 19 | cp .env.example .env |
26 | | - |
27 | | - # Configure for Docker Compose setup |
28 | 20 | sed -i 's/DB_HOST=.*$/DB_HOST=restarters_db/g' .env |
29 | 21 | sed -i 's/DB_DATABASE=.*$/DB_DATABASE=restarters_db_test/g' .env |
30 | 22 | sed -i 's/DB_USERNAME=.*$/DB_USERNAME=restarters/g' .env |
31 | 23 | sed -i 's/DB_PASSWORD=.*$/DB_PASSWORD=s3cr3t/g' .env |
32 | | - |
33 | | - # Configure Discourse integration |
34 | 24 | sed -i 's/FEATURE__DISCOURSE_INTEGRATION=.*$/FEATURE__DISCOURSE_INTEGRATION=true/g' .env |
35 | 25 | sed -i 's/DISCOURSE_URL=.*$/DISCOURSE_URL=http:\/\/restarters_discourse/g' .env |
36 | 26 | sed -i 's/DISCOURSE_APIKEY=.*$/DISCOURSE_APIKEY=fb71f38ca2b8b7cd6a041e57fd8202c9937088f0ecae7db40722bd758dda92fc/g' .env |
37 | 27 | sed -i 's/DISCOURSE_APIUSER=.*$/DISCOURSE_APIUSER=someuser/g' .env |
38 | | - |
39 | | - # Configure for testing |
40 | 28 | sed -i 's/APP_DEBUG=.*$/APP_DEBUG=false/g' .env |
41 | 29 | sed -i 's/SESSION_DOMAIN=.*$/SESSION_DOMAIN=localhost/g' .env |
42 | 30 | sed -i 's/HONEYPOT_DISABLE=.*$/HONEYPOT_DISABLE=TRUE/g' .env |
43 | 31 | sed -i 's/APP_URL=.*$/APP_URL=http:\/\/localhost:8001/g' .env |
44 | | - |
45 | | - # Add environment variables from CircleCI |
46 | 32 | echo "" >> .env |
47 | 33 | echo "GOOGLE_API_CONSOLE_KEY=$GOOGLE_API_CONSOLE_KEY" >> .env |
48 | 34 | echo "MAPBOX_TOKEN=$MAPBOX_TOKEN" >> .env |
49 | 35 |
|
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 | + |
51 | 58 | - run: |
52 | 59 | name: Start Docker services |
53 | 60 | command: | |
54 | | - # Set environment variable for CircleCI detection |
55 | 61 | export CIRCLECI=true |
56 | | - # Enable Docker Compose bake for build optimization |
57 | 62 | export COMPOSE_BAKE=true |
58 | | - # Start all services using Task |
59 | 63 | task docker:up-all |
60 | 64 | no_output_timeout: 10m |
61 | 65 |
|
62 | | - # Wait for services to be ready (includes build completion and restart detection) |
63 | 66 | - run: |
64 | 67 | name: Wait for services |
65 | 68 | command: | |
66 | 69 | task docker:wait-for-services-all |
67 | 70 |
|
68 | | - # Setup database and application |
| 71 | + - save_cache: |
| 72 | + key: composer-v2-{{ checksum "composer.lock" }} |
| 73 | + paths: |
| 74 | + - vendor |
| 75 | + |
69 | 76 | - run: |
70 | 77 | name: Setup application |
71 | 78 | command: | |
72 | | - # Grant timezone access - run directly on MySQL container |
73 | 79 | 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) |
77 | 80 | 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 |
80 | 81 | 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 |
83 | 82 | docker exec restarters php artisan l5-swagger:generate |
84 | 83 |
|
85 | | - # Setup Discourse API |
86 | 84 | - run: |
87 | 85 | name: Setup Discourse |
88 | 86 | command: | |
89 | | - # Add API key to Discourse - run directly on PostgreSQL container |
90 | 87 | 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 |
93 | 88 | docker exec restarters php artisan discourse:setting personal_message_enabled_groups 10 |
94 | 89 |
|
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 | + |
96 | 101 | - run: |
97 | 102 | name: Run PHPUnit tests |
98 | 103 | command: | |
99 | | - # Run PHPUnit tests using Task for consistency with local development |
| 104 | + mkdir -p /tmp/test-results/phpunit |
100 | 105 | task docker:test:phpunit |
101 | | - # Copy test results to host |
102 | 106 | docker cp restarters:/tmp/phpunit-results.xml /tmp/test-results/phpunit/results.xml |
103 | 107 | no_output_timeout: 45m |
104 | 108 |
|
105 | | - # Run Jest tests |
106 | 109 | - run: |
107 | 110 | name: Run Jest tests |
108 | 111 | command: | |
109 | | - # Run Jest tests using Task for consistency with local development |
| 112 | + mkdir -p /tmp/test-results/jest |
110 | 113 | task docker:test:jest |
111 | | - # Copy test results to host if they exist |
112 | 114 | docker cp restarters:/tmp/test-results/junit.xml /tmp/test-results/jest/junit.xml || echo "Jest results not found, skipping" |
113 | 115 |
|
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 | + |
115 | 133 | - run: |
116 | 134 | name: Run main Playwright tests |
117 | 135 | 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 |
119 | 140 | 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 |
121 | 145 |
|
122 | | - # Copy test results and artifacts |
123 | 146 | - run: |
124 | 147 | name: Copy Playwright artifacts |
125 | 148 | 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 |
131 | 150 | 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" |
137 | 152 | 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" |
138 | 155 | when: always |
139 | 156 |
|
140 | | - # Store artifacts |
141 | 157 | - store_artifacts: |
142 | 158 | path: /tmp/test-results |
143 | 159 | destination: playwright-test-results |
144 | | - |
| 160 | + |
145 | 161 | - store_test_results: |
146 | 162 | path: /tmp/test-results |
147 | 163 |
|
@@ -182,13 +198,18 @@ jobs: |
182 | 198 | workflows: |
183 | 199 | build-and-deploy: |
184 | 200 | jobs: |
185 | | - - build: |
| 201 | + - test-php: |
| 202 | + filters: |
| 203 | + branches: |
| 204 | + ignore: production |
| 205 | + - test-playwright: |
186 | 206 | filters: |
187 | 207 | branches: |
188 | 208 | ignore: production |
189 | 209 | - deploy-fly-dev: |
190 | 210 | requires: |
191 | | - - build |
| 211 | + - test-php |
| 212 | + - test-playwright |
192 | 213 | filters: |
193 | 214 | branches: |
194 | 215 | only: develop |
|
0 commit comments