Stacks#
Which scripts run which kind of project. Each one takes -h or --help and
prints its options and exit codes. The full list is in the
command reference.
Two kinds of runner:
- CI runners (
ci_wp_*,ci_laravel.sh,ci_django.sh,ci_pimcore_bundle_check.sh,ci_gitleaks_report.sh) run the same way in CI and on a laptop. ci-helpers workflows call them. - Local runners (
ci_node.sh,ci_go.sh,ci_python.sh,ci_flutter.sh,ci_gradle.sh,ci_security.sh) run the steps in a pinned Docker image for local use. They exit 1 underCI=true. Thelocal_test_*.shscripts run the same checks on the host, and the git hooks call them.
| Stack | Scripts | Guide |
|---|---|---|
| WordPress | ci_wp_build.sh, ci_wp_phpunit.sh, ci_wp_plugin_check.sh |
below |
| Laravel and PHP | ci_laravel.sh, local_test_php.sh |
Usage |
| Pimcore | ci_pimcore_bundle_check.sh |
below |
| Django | ci_django.sh |
Usage |
| Python | ci_python.sh, local_test_python.sh, ps/scripts/ci_python.ps1 |
Usage |
| Node | ci_node.sh, local_test_node.sh, ps/scripts/ci_node.ps1 |
below |
| Go | ci_go.sh, local_test_go.sh, ps/scripts/ci_go.ps1 |
below |
| Rust | local_test_rust.sh, ps/scripts/ci_rust.ps1 |
below |
| Flutter | ci_flutter.sh, local_test_flutter.sh |
below |
| Android and Gradle | ci_gradle.sh, local_test_gradle.sh, generate-android-keystore.sh |
below |
| iOS | ci_ios.sh |
macOS, iOS and bash 3.2 |
| Security scans | ci_security.sh, ci_gitleaks_report.sh, foxguard_report.sh |
Security gates |
| Packages | build_deb_artifacts.sh, build_rpm_artifacts.sh, build_arch_artifacts.sh, build_brew_tarball.sh |
Packaging |
WordPress#
Three scripts cover a plugin: build the package, run its PHPUnit suite, and run WordPress plugin-check against it. They run unchanged in CI and on a laptop.
Build the package: ci_wp_build.sh#
Stages what ships into <out-dir>/<slug>/ and zips it as
<out-dir>/<slug>-<version>.zip.
scripts/ci_wp_build.sh --workdir . --out-dir build
scripts/ci_wp_build.sh --workdir . --slug my-plugin --zip false
- Production dependencies:
composer install --no-dev --optimize-autoloader --prefer-dist(--composer-command, empty skips it). - Front-end assets:
npm ci && npm run buildwhenpackage.jsonexists (--asset-command, empty skips it). - Excludes come from
.distignore(or--exclude-from). Without one, a default list drops.git,node_modules,tests, PHPUnit and PHPCS config, lock files andbuild, and the log names it..gitand.distignoreare always excluded. - The version comes from the
Version:header of the file withPlugin Name:, unless--versionis given. --php-imageand--node-imagerun those steps in a container, so a laptop needs neither toolchain. The image must have bash.- A symlink that leaves the plugin or points at nothing fails the build (exit 1). Links inside the plugin become regular files.
--out-dirmay be inside the plugin; it is left out of the package. It may not be the plugin directory or contain it (exit 2).
Exit codes: 0 built; 1 a packaging step failed; 2 bad arguments; N a failing composer or asset command's own code.
Run the tests: ci_wp_phpunit.sh#
Provisions the WordPress test library and core from one wordpress-develop
release, writes wp-tests-config.php, and runs the plugin's tests. A plugin
needs no bin/install-wp-tests.sh of its own.
# start a database in Docker, and remove it afterwards
scripts/ci_wp_phpunit.sh --workdir . --db-image mysql:8.0 --wp-version 6.5
# a database that already exists, as in a CI service container
scripts/ci_wp_phpunit.sh --workdir . --db-host 127.0.0.1 --db-port 3306
--wp-versiontakesX.Y.Z,X.Y(the newest release of that minor) orlatest.--wp-tests-dirand--wp-core-dirare removed and rewritten, so each must be an absolute path with no.or..component that is not, and does not contain, the plugin, the working directory or$HOME(symlinks are resolved first). Defaults:/tmp/wordpress-tests-lib,/tmp/wordpress.--skip-provision truereuses a library already there.--php-imageruns the tests in that image. The database must then be one a container can reach.--multisite 1runs the suite as multisite.
Exit codes: 0 passed; 1 the database did not start or provisioning failed; 2 bad arguments; N the test command's own code.
Run plugin-check: ci_wp_plugin_check.sh#
Starts WordPress from the caller's Docker Compose file, installs it, activates
the plugin, installs the
plugin-check plugin, and runs
wp plugin check. Reports land in --out-dir as plugin-check.json and
meta-check.json.
scripts/ci_wp_plugin_check.sh \
--compose-file test/docker-compose.yml \
--plugin-slug my-plugin \
--plugin-src . \
--exclude-directories "vendor,node_modules,test" \
--fail-on-findings true
- The compose file is the caller's. It needs a database, a WordPress and a
WP-CLI service (
--db-service,--wordpress-service,--wpcli-service). The plugin source path reaches it in thePLUGIN_SRCvariable (--plugin-src-env). --php-lint-command,--phpcs-warning-commandand--phpunit-commandrun on the host first. PHPCS warnings never fail the run.- Findings fail the run only with
--fail-on-findings true(exit 4). The default reports them and exits 0. --multisiteand--activate-networkdefault totrue.--cleanup falsekeeps the containers for inspection.
Exit codes: 0 clean or report-only; 1 the database did not become ready;
2 bad arguments; 4 errors found, or plugin-check unavailable, with
--fail-on-findings true; 5 a report could not be parsed; N a failing lint,
PHPUnit or setup command's own code. More on the excludes in
Usage.
Pimcore#
ci_pimcore_bundle_check.sh checks a Pimcore bundle. Optional host-side lint,
PHPCS and PHPUnit commands run first, after composer install on the host.
Then composer install, PHPCS, PHPStan and PHPUnit run inside the PHP service
of the caller's compose file.
scripts/ci_pimcore_bundle_check.sh \
--compose-file test/docker-compose.yml \
--phpstan-command "vendor/bin/phpstan analyse"
Findings fail the run by default (--fail-on-findings true, exit 1).
Node, Go and Rust#
scripts/ci_node.sh --workdir web # install, lint, test, build in Docker
scripts/ci_go.sh --skip-build # lint and test in Docker
bash scripts/local_test_node.sh --quick # the same checks on the host
bash scripts/local_test_go.sh --quick
bash scripts/local_test_rust.sh --quick # rustup's stable, not the first cargo on PATH
Each --skip-* flag drops one step, and --no-docker runs on the host. There
is no Bash ci_rust.sh: local_test_rust.sh is the Rust gate.
ps/scripts/ci_node.ps1, ci_go.ps1 and ci_rust.ps1 run the same checks
natively on Windows, or in Docker Desktop with -UseDocker. More in
Git hook setup and local test runners.
Mobile#
scripts/ci_flutter.sh --workdir app # analyze, test, build
scripts/ci_gradle.sh --workdir android # build, test, lint, detekt
bash scripts/local_test_gradle.sh --dir android --android
bash scripts/generate-android-keystore.sh ./release.jks
scripts/ci_ios.sh --skip-build # macOS with Xcode only
ci_ios.sh runs on the host and exits 3 anywhere without Xcode. The adb,
android, flutter, gradle, ios and screencap modules hold the functions
these scripts use; see the API index.