1+ # GitLab CI for Moodle — mirrors typical GitHub Actions pipeline
2+ # - Runs PHP unit tests against MySQL and PostgreSQL
3+ # - Runs Behat features (headless Chrome)
4+ # - Uses Node.js version from .nvmrc when present, otherwise falls back to latest LTS
5+ #
6+ # Notes:
7+ # 1) Set the following CI/CD variables in your project/group for reliable runs:
8+ # - APP_BASE_URL → e.g. http://localhost:8000 (used by Behat)
9+ # - PHP_VERSION → optional, e.g. 8.2 (selects image tag below if you change it)
10+ # - MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD (optional; defaults used below)
11+ # - POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD (optional; defaults used below)
12+ # 2) This pipeline starts a PHP built‑in server for Behat. For large suites you may prefer Apache/Nginx containers.
13+ # 3) If you have a .nvmrc at repo root, that version will be used. Otherwise latest LTS Node is installed.
14+ #
15+ # You can further tune PHP extensions/images to match your production matrix.
16+
17+ stages :
18+ - prepare
19+ - phpunit
20+ - behat
21+
22+ .default-variables : &default-variables
23+ # Keep Composer non‑interactive
24+ COMPOSER_NO_INTERACTION : " 1"
25+ COMPOSER_CACHE_DIR : " $CI_PROJECT_DIR/.cache/composer"
26+ NPM_CONFIG_CACHE : " $CI_PROJECT_DIR/.cache/npm"
27+ APP_BASE_URL : " http://127.0.0.1:8000"
28+ # Default DB creds for MySQL service
29+ MYSQL_DATABASE : " moodle"
30+ MYSQL_USER : " moodle"
31+ MYSQL_PASSWORD : " moodle"
32+ # Default DB creds for Postgres service
33+ POSTGRES_DB : " moodle"
34+ POSTGRES_USER : " moodle"
35+ POSTGRES_PASSWORD : " moodle"
36+ # PHPUnit parallelism (tune for your runners)
37+ PHPUNIT_PARALLEL : " 2"
38+
39+ .default-image : &default-image
40+ image : " edbizarro/gitlab-ci-pipeline-php:8.2"
41+
42+ .caches : &caches
43+ cache :
44+ key : " $CI_JOB_NAME"
45+ paths :
46+ - .cache/composer/
47+ - vendor/
48+ - node_modules/
49+ policy : pull-push
50+
51+ .before-script-base : &before-script-base
52+ - php -v
53+ - composer --version
54+ # --- Install nvm and select Node from .nvmrc (or latest LTS if missing) ---
55+ - export NVM_DIR="$CI_PROJECT_DIR/.nvm"
56+ - curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
57+ - . "$NVM_DIR/nvm.sh"
58+ - |
59+ if [ -f .nvmrc ]; then
60+ echo "Using Node version from .nvmrc: $(cat .nvmrc)"
61+ nvm install
62+ nvm use
63+ else
64+ echo "No .nvmrc found; using latest LTS Node"
65+ nvm install --lts
66+ nvm use --lts
67+ fi
68+ - node -v && npm -v
69+ # --- Install PHP and JS deps ---
70+ - composer install --prefer-dist --no-progress --no-interaction
71+ - |
72+ if [ -f package-lock.json ] || [ -f npm-shrinkwrap.json ]; then
73+ npm ci
74+ else
75+ npm install
76+ fi
77+ # Create writable dirs commonly needed by Moodle
78+ - mkdir -p "$CI_PROJECT_DIR"/{moodledata,report}
79+
80+ # Helper to generate a minimal config.php suitable for tests.
81+ # Adjust CFG settings if your project requires special paths/plugins.
82+ .make-config-php : &make-config-php |
83+ cat > config.php <<'PHP'
84+ <?php
85+ // Auto-generated by CI for testing only.
86+ if (!getenv('DBTYPE')) { $_ENV['DBTYPE'] = 'mysqli'; }
87+ $dbtype = getenv('DBTYPE') ? : ' mysqli' ;
88+ $dblibrary = 'native';
89+ $dbhost = getenv('DBHOST') ? : ($dbtype === 'pgsql' ? 'postgres' : 'mysql');
90+ $dbname = getenv('DBNAME') ? : ' moodle' ;
91+ $dbuser = getenv('DBUSER') ? : ' moodle' ;
92+ $dbpass = getenv('DBPASS') ? : ' moodle' ;
93+ $dbprefix = 'mdl_';
94+ $wwwroot = getenv('APP_BASE_URL') ? : ' http://127.0.0.1:8000' ;
95+ $dataroot = __DIR__ . '/moodledata';
96+ $directorypermissions = 02777;
97+ $CFG = new stdClass();
98+ $CFG->dbtype = $dbtype;
99+ $CFG->dblibrary = $dblibrary;
100+ $CFG->dbhost = $dbhost;
101+ $CFG->dbname = $dbname;
102+ $CFG->dbuser = $dbuser;
103+ $CFG->dbpass = $dbpass;
104+ $CFG->prefix = $dbprefix;
105+ $CFG->wwwroot = $wwwroot;
106+ $CFG->dataroot = $dataroot;
107+ $CFG->directorypermissions = $directorypermissions;
108+ $CFG->debug = E_ALL | E_STRICT;
109+ $CFG->debugdisplay = 1;
110+ require_once(__DIR__ . '/lib/setup.php');
111+ PHP
112+
113+ prepare :
114+ stage : prepare
115+ << : *default-image
116+ variables :
117+ << : *default-variables
118+ << : *caches
119+ script :
120+ - *before-script-base
121+ rules :
122+ - if : ' $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"'
123+
124+ phpunit:mysql :
125+ stage : phpunit
126+ << : *default-image
127+ variables :
128+ << : *default-variables
129+ DBTYPE : " mysqli"
130+ DBHOST : " mysql"
131+ DBNAME : " $MYSQL_DATABASE"
132+ DBUSER : " $MYSQL_USER"
133+ DBPASS : " $MYSQL_PASSWORD"
134+ MYSQL_ROOT_PASSWORD : " root"
135+ services :
136+ - name : mysql:8
137+ alias : mysql
138+ command : ["--default-authentication-plugin=mysql_native_password", "--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]
139+ << : *caches
140+ script :
141+ - *before-script-base
142+ - *make-config-php
143+ # Init PHPUnit (creates test tables etc.)
144+ - php admin/tool/phpunit/cli/init.php
145+ # Run tests in parallel if supported
146+ - vendor/bin/phpunit --configuration=phpunit.xml.dist --testsuite core --colors=always -v
147+
148+ phpunit:pgsql :
149+ stage : phpunit
150+ << : *default-image
151+ variables :
152+ << : *default-variables
153+ DBTYPE : " pgsql"
154+ DBHOST : " postgres"
155+ DBNAME : " $POSTGRES_DB"
156+ DBUSER : " $POSTGRES_USER"
157+ DBPASS : " $POSTGRES_PASSWORD"
158+ services :
159+ - name : postgres:16
160+ alias : postgres
161+ variables :
162+ POSTGRES_DB : " $POSTGRES_DB"
163+ POSTGRES_USER : " $POSTGRES_USER"
164+ POSTGRES_PASSWORD : " $POSTGRES_PASSWORD"
165+ << : *caches
166+ script :
167+ - *before-script-base
168+ - *make-config-php
169+ - php admin/tool/phpunit/cli/init.php
170+ - vendor/bin/phpunit --configuration=phpunit.xml.dist --testsuite core --colors=always -v
171+
172+ behat :
173+ stage : behat
174+ << : *default-image
175+ variables :
176+ << : *default-variables
177+ DBTYPE : " mysqli"
178+ DBHOST : " mysql"
179+ DBNAME : " $MYSQL_DATABASE"
180+ DBUSER : " $MYSQL_USER"
181+ DBPASS : " $MYSQL_PASSWORD"
182+ MOODLE_WWWROOT : " $APP_BASE_URL"
183+ BEHAT_FEATURE_RUNNER : " vendor/bin/behat"
184+ # Behat integration config
185+ BEHAT_FAILDIFF : " $CI_PROJECT_DIR/report/behat-fails"
186+ services :
187+ - name : mysql:8
188+ alias : mysql
189+ command : ["--default-authentication-plugin=mysql_native_password", "--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]
190+ - name : selenium/standalone-chrome:4.25.0
191+ alias : selenium
192+ << : *caches
193+ script :
194+ - *before-script-base
195+ - *make-config-php
196+ # Start PHP built-in server to serve Moodle to Selenium
197+ - php -S 0.0.0.0:8000 -t public >/dev/null 2>&1 &
198+ - sleep 5
199+ # Prepare Behat (updates database and config for Behat testing)
200+ - php admin/tool/behat/cli/init.php
201+ # Variables for Behat/Moodle integration
202+ - export BEHAT_WD_HOST=http://selenium:4444/wd/hub
203+ - export BEHAT_SELENIUM2_URL=$BEHAT_WD_HOST
204+ # Run Behat; adjust profiles or tags as needed for your project
205+ - vendor/bin/behat --colors -vv --config "${CI_PROJECT_DIR}/behat.yml" || vendor/bin/behat --colors -vv --rerun
206+ artifacts :
207+ when : always
208+ paths :
209+ - report/
210+ - moodledata/behat/*/faildump/
211+ expire_in : 7 days
212+ rules :
213+ - if : ' $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"'
0 commit comments