-
-
Notifications
You must be signed in to change notification settings - Fork 11
183 lines (163 loc) · 7.57 KB
/
Copy pathdocker-test.yml
File metadata and controls
183 lines (163 loc) · 7.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
name: 🐳 Docker Test Environment
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
docker-test:
name: Build & Verify Docker Environment
runs-on: ubuntu-latest
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v5
- name: 🐳 Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: 📄 Prepare environment files
run: |
# Create .env from the template 'env' file
cp env .env
# Configure for Docker CI environment.
#
# The app and PHPUnit need SEPARATE schemas. ci4ms:setup migrates the whole
# schema into the app's database, and PHPUnit then migrates again into its
# own — pointing both at ci4ms_test made every DB-backed test die with
# "Table 'ci4ms_users' already exists". The tests group must keep a name
# containing "ci4ms_test": CIUnitTestCase guards refuse to run otherwise.
cat >> .env << 'EOF'
CI_ENVIRONMENT=development
app.baseURL='http://localhost/'
database.default.hostname=db
database.default.database=ci4ms_app
database.default.username=ci4ms_user
database.default.password=ci4ms_pass
database.default.DBDriver=MySQLi
database.default.DBPrefix=ci4ms_
database.default.port=3306
database.tests.hostname=db
database.tests.database=ci4ms_test
database.tests.username=ci4ms_user
database.tests.password=ci4ms_pass
database.tests.DBDriver=MySQLi
database.tests.DBPrefix=ci4ms_
database.tests.port=3306
encryption.key=hex2bin:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
EOF
# Prepare Routes file from default template
cp app/Config/DefaultRoutes.php app/Config/Routes.php
- name: 🔨 Build and start Docker containers
run: docker compose up -d --build
- name: ⏳ Wait for MariaDB to be ready
run: |
echo "Waiting for MariaDB..."
for i in $(seq 1 30); do
if docker exec ci4ms_db healthcheck.sh --connect --innodb_initialized 2>/dev/null; then
echo "✅ MariaDB is ready!"
break
fi
echo "Attempt $i/30 - waiting..."
sleep 5
done
# The compose file only creates ci4ms_test (used by PHPUnit); the app needs
# its own schema so the two never migrate over each other.
docker exec ci4ms_db mariadb -u root -pci4ms_secret -e \
"CREATE DATABASE IF NOT EXISTS ci4ms_app CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; \
GRANT ALL ON ci4ms_app.* TO 'ci4ms_user'@'%'; FLUSH PRIVILEGES;"
# Final verification
docker exec ci4ms_db mariadb -u ci4ms_user -pci4ms_pass -e "SELECT 1;" ci4ms_test
docker exec ci4ms_db mariadb -u ci4ms_user -pci4ms_pass -e "SELECT 1;" ci4ms_app
echo "✅ Database connection verified."
- name: 📦 Install Composer dependencies
run: docker exec ci4ms_app composer install --no-interaction --prefer-dist --optimize-autoloader
- name: 📂 Set file permissions
run: |
docker exec ci4ms_app chmod -R 775 writable
docker exec ci4ms_app chown -R www-data:www-data writable
docker exec ci4ms_app mkdir -p writable/backups writable/cache writable/logs writable/session
docker exec ci4ms_app mkdir -p public/media/.tmb public/media/.trash
docker exec ci4ms_app chmod -R 775 public/media
- name: 🗄️ Run migrations & seed default data
run: |
if docker exec ci4ms_app php spark ci4ms:setup \
--fname=CI \
--sname=Test \
--username=admin \
--email=admin@ci4ms.test \
--password=Test1234! \
--baseUrl=http://localhost/ \
--siteName="CI4MS Test"; then
echo "✅ Setup completed."
else
echo "❌ Setup failed."
exit 1
fi
- name: 📂 Re-apply permissions after setup
run: |
# ci4ms:setup runs as root through docker exec, so everything it creates
# under writable/ (log file, session, cache) is owned by root. Apache runs
# as www-data and then cannot even append to its own error log, which is
# why a failing request used to leave no trace in the CI4 log at all.
docker exec ci4ms_app chown -R www-data:www-data writable
docker exec ci4ms_app chmod -R 775 writable
- name: 🧹 PHP syntax check
run: |
echo "Running PHP syntax check..."
ERRORS=$(docker exec ci4ms_app find app modules -name "*.php" -exec php -l {} \; 2>&1 | grep -c "Parse error" || true)
if [ "$ERRORS" -gt 0 ]; then
echo "❌ Found $ERRORS syntax errors!"
docker exec ci4ms_app find app modules -name "*.php" -exec php -l {} \; 2>&1 | grep "Parse error"
exit 1
fi
echo "✅ No PHP syntax errors found."
- name: 🌐 Check HTTP response (Homepage)
run: |
sleep 3
# Keep the body instead of discarding it. ci4ms:setup rewrites .env with
# CI_ENVIRONMENT=production, so this is usually the generic error page —
# but it still distinguishes an application error from a proxy/Apache one,
# and the CI4 log (readable now that permissions are re-applied) carries
# the stack trace.
STATUS=$(curl -s -o /tmp/home.html -w "%{http_code}" http://localhost)
echo "HTTP Status: $STATUS"
# 200 = page rendered, 302 = redirect, 401 = auth required (all mean app is running)
if [ "$STATUS" -eq 200 ] || [ "$STATUS" -eq 302 ] || [ "$STATUS" -eq 401 ]; then
echo "✅ Application is responding correctly."
else
echo "❌ Unexpected HTTP status: $STATUS"
echo "=== RESPONSE BODY ==="
sed -e 's/<[^>]*>//g' /tmp/home.html | grep -v '^[[:space:]]*$' | head -60
exit 1
fi
- name: 🔒 Check backend responds
run: |
STATUS=$(curl -s -o /tmp/backend.html -w "%{http_code}" -L http://localhost/backend)
echo "Backend HTTP Status: $STATUS"
# 200 = login page, 302 = redirect to login, 401 = auth required (all valid)
if [ "$STATUS" -eq 200 ] || [ "$STATUS" -eq 302 ] || [ "$STATUS" -eq 401 ]; then
echo "✅ Backend is responding correctly."
else
echo "❌ Backend unexpected status: $STATUS"
echo "=== RESPONSE BODY ==="
sed -e 's/<[^>]*>//g' /tmp/backend.html | grep -v '^[[:space:]]*$' | head -60
exit 1
fi
- name: 🧪 Run PHPUnit tests (if available)
run: |
docker exec ci4ms_app vendor/bin/phpunit --no-coverage
- name: 📋 Show container logs on failure
if: failure()
run: |
echo "=== APP LOGS ==="
docker compose logs app
echo ""
echo "=== DB LOGS ==="
docker compose logs db
echo ""
echo "=== CI4 LOG ==="
# Glob rather than guess today's date: the runner's date and the
# container's can differ, and a run spanning midnight writes two files.
docker exec ci4ms_app sh -c 'ls -la writable/logs/ 2>/dev/null; cat writable/logs/log-*.log 2>/dev/null' \
|| echo "No CI4 log file found."
- name: 🛑 Stop and clean up containers
if: always()
run: docker compose down -v