3 # vim: expandtab sw=4 ts=4 sts=4:
7 if [ -n "$GATEWAY_INTERFACE" ] ; then
8 echo 'Can not invoke as CGI!'
12 # More documentation about making a release is available at:
13 # https://wiki.phpmyadmin.net/pma/Releasing
15 # Fail on undefined variables
20 KITS
="all-languages english source"
21 COMPRESSIONS
="zip-7z txz tgz"
22 # The version series this script is allowed to handle
37 while [ $# -gt 0 ] ; do
57 if [ -z "$branch" ] ; then
65 echo " create-release.sh <version> <from_branch> [--tag] [--stable] [--test] [--ci]"
67 echo "If --tag is specified, release tag is automatically created (use this for all releases including pre-releases)"
68 echo "If --stable is specified, the STABLE branch is updated with this release"
69 echo "If --test is specified, the testsuite is executed before creating the release"
70 echo "If --ci is specified, the testsuite is executed and no actual release is created"
73 echo " create-release.sh 2.9.0-rc1 QA_2_9"
74 echo " create-release.sh 2.9.0 MAINT_2_9_0 --tag --stable"
79 if [ -z "$version" ] ; then
80 version
=`echo $1 | tr -d -c '0-9a-z.+-'`
81 if [ "x$version" != "x$1" ] ; then
82 echo "Invalid version: $1"
85 elif [ -z "$branch" ] ; then
86 branch
=`echo $1 | tr -d -c '/0-9A-Za-z_-'`
87 if [ "x$branch" != "x$1" ] ; then
88 echo "Invalid branch: $1"
92 echo "Unknown parameter: $1!"
99 if [ -z "$version" -o -z "$branch" ] ; then
100 echo "Branch and version have to be specified!"
104 # Checks whether remote branch has local tracking branch
105 ensure_local_branch
() {
106 if ! git branch |
grep -q '^..'"$1"'$' ; then
107 git branch
--track $1 origin
/$1
111 # Marks current head of given branch as head of other branch
112 # Used for STABLE tracking
116 echo "* Marking release as $rel_branch"
117 ensure_local_branch
$rel_branch
118 git checkout
$rel_branch
119 git merge
-s recursive
-X theirs
$branch
123 cleanup_composer_vendors
() {
124 echo "* Cleanup of composer packages"
126 vendor
/phpmyadmin
/sql-parser
/tests
/ \
127 vendor
/phpmyadmin
/sql-parser
/tools
/ \
128 vendor
/phpmyadmin
/sql-parser
/src
/Tools
/ \
129 vendor
/phpmyadmin
/sql-parser
/locale
/sqlparser.pot \
130 vendor
/phpmyadmin
/sql-parser
/locale
/*/LC_MESSAGES
/sqlparser.po \
131 vendor
/phpmyadmin
/sql-parser
/bin
/ \
132 vendor
/phpmyadmin
/sql-parser
/phpunit.xml.dist \
133 vendor
/phpmyadmin
/motranslator
/phpunit.xml.dist \
134 vendor
/phpmyadmin
/motranslator
/tests
/ \
135 vendor
/phpmyadmin
/shapefile
/codecov.yml \
136 vendor
/phpmyadmin
/shapefile
/phpunit.xml.dist \
137 vendor
/phpmyadmin
/shapefile
/tests
/ \
138 vendor
/phpmyadmin
/shapefile
/examples
/ \
139 vendor
/phpmyadmin
/shapefile
/data
/ \
140 vendor
/phpmyadmin
/shapefile
/phpstan-baseline.neon \
141 vendor
/phpmyadmin
/shapefile
/phpstan.neon.dist \
142 vendor
/phpmyadmin
/twig-i18n-extension
/README.rst \
143 vendor
/phpmyadmin
/twig-i18n-extension
/phpunit.xml.dist \
144 vendor
/phpmyadmin
/twig-i18n-extension
/test
/ \
145 vendor
/phpseclib
/phpseclib
/phpseclib
/File
/ \
146 vendor
/phpseclib
/phpseclib
/phpseclib
/Math
/ \
147 vendor
/phpseclib
/phpseclib
/phpseclib
/Net
/ \
148 vendor
/phpseclib
/phpseclib
/phpseclib
/System
/ \
149 vendor
/phpseclib
/phpseclib
/appveyor.yml \
150 vendor
/phpseclib
/phpseclib
/.github \
151 vendor
/symfony
/cache
/Tests
/ \
152 vendor
/symfony
/service-contracts
/Test
/ \
153 vendor
/symfony
/expression-language
/Tests
/ \
154 vendor
/symfony
/expression-language
/Resources
/ \
155 vendor
/symfony
/dependency-injection
/Loader
/schema
/dic
/services
/services-1.0.xsd \
156 vendor
/tecnickcom
/tcpdf
/examples
/ \
157 vendor
/tecnickcom
/tcpdf
/tools
/ \
158 vendor
/tecnickcom
/tcpdf
/fonts
/ae_fonts_
*/ \
159 vendor
/tecnickcom
/tcpdf
/fonts
/dejavu-fonts-ttf-2.
*/ \
160 vendor
/tecnickcom
/tcpdf
/fonts
/freefont-
*/ \
161 vendor
/tecnickcom
/tcpdf
/include
/sRGB.icc \
162 vendor
/tecnickcom
/tcpdf
/.git \
163 vendor
/tecnickcom
/tcpdf
/.github
/ \
164 vendor
/bacon
/bacon-qr-code
/phpunit.xml.dist \
165 vendor
/bacon
/bacon-qr-code
/test
/ \
166 vendor
/dasprid
/enum
/phpunit.xml.dist \
167 vendor
/dasprid
/enum
/test
/ \
168 vendor
/williamdes
/mariadb-mysql-kbs
/phpunit.xml \
169 vendor
/williamdes
/mariadb-mysql-kbs
/test
/ \
170 vendor
/williamdes
/mariadb-mysql-kbs
/schemas
/ \
171 vendor
/williamdes
/mariadb-mysql-kbs
/dist
/merged-raw.json \
172 vendor
/williamdes
/mariadb-mysql-kbs
/dist
/merged-raw.md \
173 vendor
/williamdes
/mariadb-mysql-kbs
/dist
/merged-slim.json \
174 vendor
/williamdes
/mariadb-mysql-kbs
/dist
/merged-ultraslim.php \
175 vendor
/code-lts
/u2f-php-server
/phpunit.xml \
176 vendor
/code-lts
/u2f-php-server
/test
/ \
177 vendor
/nikic
/fast-route
/.travis.yml \
178 vendor
/nikic
/fast-route
/.hhconfig \
179 vendor
/nikic
/fast-route
/FastRoute.hhi \
180 vendor
/nikic
/fast-route
/phpunit.xml \
181 vendor
/nikic
/fast-route
/psalm.xml \
182 vendor
/nikic
/fast-route
/test
/ \
183 vendor
/twig
/twig
/doc
/ \
184 vendor
/twig
/twig
/test
/ \
185 vendor
/twig
/twig
/.github
/ \
186 vendor
/twig
/twig
/README.rst \
187 vendor
/twig
/twig
/.travis.yml \
188 vendor
/twig
/twig
/.editorconfig \
189 vendor
/twig
/twig
/.php_cs.dist \
190 vendor
/twig
/twig
/drupal_test.sh \
191 vendor
/webmozart
/assert
/.editorconfig \
192 vendor
/webmozart
/assert
/.github
/ \
193 vendor
/webmozart
/assert
/.php_cs \
194 vendor
/webmozart
/assert
/psalm.xml \
195 vendor
/twig
/twig
/src
/Test
/ \
196 vendor
/psr
/log
/Psr
/Log
/Test
/ \
197 vendor
/paragonie
/constant_time_encoding
/tests
/ \
198 vendor
/paragonie
/constant_time_encoding
/psalm.xml \
199 vendor
/paragonie
/constant_time_encoding
/phpunit.xml.dist \
200 vendor
/paragonie
/constant_time_encoding
/.travis.yml \
201 vendor
/paragonie
/random_compat
/build-phar.sh \
202 vendor
/paragonie
/random_compat
/dist
/random_compat.phar.pubkey \
203 vendor
/paragonie
/random_compat
/dist
/random_compat.phar.pubkey.asc \
204 vendor
/paragonie
/random_compat
/psalm.xml \
205 vendor
/pragmarx
/google2fa
/phpstan.neon \
206 vendor
/pragmarx
/google2fa-qrcode
/.scrutinizer.yml \
207 vendor
/pragmarx
/google2fa-qrcode
/.travis.yml \
208 vendor
/pragmarx
/google2fa-qrcode
/phpunit.xml \
209 vendor
/pragmarx
/google2fa-qrcode
/tests \
210 vendor
/google
/recaptcha
/app.yaml \
211 vendor
/google
/recaptcha
/.travis.yml \
212 vendor
/google
/recaptcha
/phpunit.xml.dist \
213 vendor
/google
/recaptcha
/.github
/ \
214 vendor
/google
/recaptcha
/examples
/ \
215 vendor
/google
/recaptcha
/tests
/
217 vendor
/google
/recaptcha
/ARCHITECTURE.md \
218 vendor
/google
/recaptcha
/CONTRIBUTING.md \
219 vendor
/phpmyadmin
/motranslator
/CODE_OF_CONDUCT.md \
220 vendor
/phpmyadmin
/motranslator
/CONTRIBUTING.md \
221 vendor
/phpmyadmin
/motranslator
/PERFORMANCE.md \
222 vendor
/phpmyadmin
/shapefile
/CONTRIBUTING.md \
223 vendor
/phpmyadmin
/shapefile
/CODE_OF_CONDUCT.md \
224 vendor
/phpmyadmin
/sql-parser
/CODE_OF_CONDUCT.md \
225 vendor
/phpmyadmin
/sql-parser
/CONTRIBUTING.md
226 find vendor
/tecnickcom
/tcpdf
/fonts
/ -maxdepth 1 -type f \
227 -not -name 'dejavusans.*' \
228 -not -name 'dejavusansb.*' \
229 -not -name 'helvetica.php' \
230 -print0 |
xargs -0 rm
233 backup_vendor_folder
() {
234 TEMP_FOLDER
="$(mktemp -d /tmp/phpMyAdmin.XXXXXXXXX)"
235 cp -rp .
/vendor
"${TEMP_FOLDER}"
238 restore_vendor_folder
() {
239 if [ ! -d ${TEMP_FOLDER} ]; then
240 echo 'No backup to restore'
244 mv "${TEMP_FOLDER}/vendor" .
/vendor
245 rmdir "${TEMP_FOLDER}"
248 get_composer_package_version
() {
249 awk '/require-dev/ {printline = 1; print; next } printline' composer.json |
grep "$1" |
awk -F [\"] '{print $4}'
252 create_phpunit_sandbox
() {
253 PHPUNIT_VERSION
="$(get_composer_package_version 'phpunit/phpunit')"
254 TEMP_PHPUNIT_FOLDER
="$(mktemp -d /tmp/phpMyAdmin-phpunit.XXXXXXXXX)"
255 cd "${TEMP_PHPUNIT_FOLDER}"
256 composer require
"phpunit/phpunit:${PHPUNIT_VERSION}"
260 delete_phpunit_sandbox
() {
261 if [ ! -d ${TEMP_PHPUNIT_FOLDER} ]; then
262 echo 'No phpunit sandbox to delete'
265 rm -rf "${TEMP_PHPUNIT_FOLDER}"
269 if [ ! -f vendor
/tecnickcom
/tcpdf
/tcpdf.php
]; then
270 echo 'TCPDF should be installed, detection failed !'
273 if [ ! -f vendor
/code-lts
/u2f-php-server
/src
/U2FServer.php
]; then
274 echo 'U2F-server should be installed, detection failed !'
277 if [ ! -f vendor
/pragmarx
/google2fa-qrcode
/src
/Google2FA.php
]; then
278 echo 'Google 2FA should be installed, detection failed !'
283 # Ensure we have tracking branch
284 ensure_local_branch
$branch
286 VERSION_FILE
=libraries
/classes
/Version.php
288 # Keep in sync with update-po script
289 fetchReleaseFromFile
() {
290 php
-r "define('VERSION_SUFFIX', ''); require_once('libraries/classes/Version.php'); echo \PhpMyAdmin\Version::VERSION;"
293 fetchVersionSeriesFromFile
() {
294 php
-r "define('VERSION_SUFFIX', ''); require_once('libraries/classes/Version.php'); echo \PhpMyAdmin\Version::SERIES;"
297 VERSION_SERIES_FROM_FILE
="$(fetchVersionSeriesFromFile)"
299 if [ "${VERSION_SERIES_FROM_FILE}" != "${VERSION_SERIES}" ]; then
300 echo "This script can not handle ${VERSION_SERIES_FROM_FILE} version series."
301 echo "Only ${VERSION_SERIES} version series are allowed, please use your target branch directly or another branch."
302 echo "By changing branches you will have a release script that was designed for your version series."
306 echo "The actual configured release is: $(fetchReleaseFromFile)"
308 if [ $do_ci -eq 0 -a -$do_daily -eq 0 ] ; then
311 Please ensure you have incremented rc count or version in the repository :
312 - run ./scripts/console set-version $version
313 - in $VERSION_FILE Version class:
314 - check that VERSION, MAJOR, MINOR and PATCH are correct.
315 - in doc/conf.py the line
316 " version = '$version' "
317 - in README the "Version" line
318 - in package.json the line
319 " "version": "$version", "
320 - set release date in ChangeLog
326 if [ "$do_release" != 'y' ]; then
331 echo "The actual configured release is now: $(fetchReleaseFromFile)"
333 # Create working copy
336 workdir
=release
/phpMyAdmin-
$version
337 if [ -d $workdir ] ; then
338 echo "Working directory '$workdir' already exists, please move it out of way"
342 # Add worktree with chosen branch
343 git worktree add
--force $workdir $branch
345 if [ $do_pull -eq 1 ] ; then
348 if [ $do_daily -eq 1 ] ; then
349 git_head
=`git log -n 1 --format=%H`
350 git_head_short
=`git log -n 1 --format=%h`
351 today_date
=`date +'%Y%m%d' -u`
354 if [ $do_daily -eq 1 ] ; then
355 echo '* setting the version suffix for the snapshot'
356 sed -i "s/'versionSuffix' => '.*'/'versionSuffix' => '+$today_date.$git_head_short'/" libraries
/vendor_config.php
357 php
-l libraries
/vendor_config.php
360 # Check release version
361 if [ $do_ci -eq 0 -a -$do_daily -eq 0 ] ; then
362 if ! grep -q "VERSION = '$version'" $VERSION_FILE ; then
363 echo "There seems to be wrong version in $VERSION_FILE!"
366 if ! grep -q "version = '$version'" doc
/conf.py
; then
367 echo "There seems to be wrong version in doc/conf.py"
370 if ! grep -q "Version $version\$" README
; then
371 echo "There seems to be wrong version in README"
374 if ! grep -q "\"version\": \"$version\"," package.json
; then
375 echo "There seems to be wrong version in package.json"
380 # Cleanup release dir
381 LC_ALL
=C
date -u > RELEASE-DATE-
${version}
383 # Building documentation
384 echo "* Generating documentation"
385 LC_ALL
=C
make -C doc html
386 find doc
-name '*.pyc' -print0 |
xargs -0 -r rm -f
388 # Check for gettext support
390 echo "* Generating mo files"
391 .
/scripts
/generate-mo
392 if [ -f .
/scripts
/remove-incomplete-mo
] ; then
393 echo "* Removing incomplete translations"
394 .
/scripts
/remove-incomplete-mo
398 if [ -f .
/scripts
/line-counts.sh
] ; then
399 echo "* Generating line counts"
400 .
/scripts
/line-counts.sh
403 echo "* Removing unneeded files"
405 # Remove developer information
406 rm -rf .github CODE_OF_CONDUCT.md DCO
409 rm -f .travis.yml .scrutinizer.yml .jshintrc .weblate codecov.yml
411 # Remove Doctum config file
412 rm -f test
/doctum-config.php
414 # Remove readme for github
417 if [ -f .
/scripts
/console
]; then
418 # Update the vendors to have the dev vendors
419 composer update
--no-interaction
420 # Warm up the routing cache for 5.1+ releases
421 .
/scripts
/console cache
:warmup
--routing
424 PHP_REQ
=$
(sed -n '/"php"/ s/.*"\^\([0-9]\.[0-9]\.[0-9]\).*/\1/p' composer.json
)
426 if [ -z "$PHP_REQ" ] ; then
427 echo "Failed to figure out required PHP version from composer.json"
430 # Okay, there is no way to tell composer to install
431 # suggested package. Let's require it and then revert
432 # composer.json to original state.
433 cp composer.json composer.json.backup
434 COMPOSER_VERSION
="$(composer --version)"
435 echo "* Running composer (version: $COMPOSER_VERSION)"
436 composer config platform.php
"$PHP_REQ"
437 composer update
--no-interaction --no-dev --optimize-autoloader
439 # Parse the required versions from composer.json
441 PACKAGE_LIST
='tecnickcom/tcpdf pragmarx/google2fa-qrcode bacon/bacon-qr-code code-lts/u2f-php-server'
443 for PACKAGES
in $PACKAGE_LIST
445 PKG_VERSION
="$(get_composer_package_version "$PACKAGES")"
446 PACKAGES_VERSIONS
="$PACKAGES_VERSIONS $PACKAGES:$PKG_VERSION"
449 echo "Installing composer packages '$PACKAGES_VERSIONS'"
451 composer require
--no-interaction --optimize-autoloader --update-no-dev $PACKAGES_VERSIONS
455 mv composer.json.backup composer.json
456 cleanup_composer_vendors
459 if [ $do_tag -eq 1 ] ; then
460 echo "* Commiting composer.lock"
461 git add
--force composer.lock
462 git commit
-s -m "Adding composer lock for $version"
465 if [ -f package.json
] ; then
466 echo "* Running Yarn"
467 yarn
install --production
470 # Remove Bootstrap theme
471 rm -rf themes
/bootstrap
473 # Remove git metadata
475 find .
-name .gitignore
-print0 |
xargs -0 -r rm -f
476 find .
-name .gitattributes
-print0 |
xargs -0 -r rm -f
478 if [ $do_test -eq 1 ] ; then
479 # Move the folder out and install dev vendors
480 create_phpunit_sandbox
481 # Backup the files because the new autoloader will change the composer vendor
483 # Generate an autoload for test class files (and include dev namespaces)
484 composer dump-autoload
--dev || php
-r "echo 'Requires: composer >= v2.1.2' . PHP_EOL; exit(1);"
485 "${TEMP_PHPUNIT_FOLDER}/vendor/bin/phpunit" --no-coverage --testsuite unit
487 if [ $do_ci -eq 1 ] ; then
491 if [ "$branch" = "ci" ] ; then
496 if [ $test_ret -ne 0 ] ; then
499 # Remove PHPUnit cache file
500 rm -f .phpunit.result.cache
501 # Generate an normal autoload (this is just a security, because normally the vendor folder will be restored)
502 composer dump-autoload
503 # Remove libs installed for testing
505 delete_phpunit_sandbox
506 restore_vendor_folder
514 for kit
in $KITS ; do
516 name
=phpMyAdmin-
$version-$kit
517 cp -r phpMyAdmin-
$version $name
519 # Cleanup translations
520 cd phpMyAdmin-
$version-$kit
521 .
/scripts
/lang-cleanup.sh
$kit
523 # Remove tests, source code,...
524 if [ $kit != source ] ; then
525 echo "* Removing source files"
528 rm phpunit.xml.
* build.xml
529 rm -f .editorconfig .browserslistrc .eslintignore .jshintrc .eslintrc.json .stylelintrc.json psalm.xml psalm-baseline.xml phpstan.neon.dist phpstan-baseline.neon phpcs.xml.dist jest.config.js infection.json.dist
532 # Documentation source code
537 rm doc
/html
/.buildinfo
doc
/html
/objects.inv
539 # Remove bin files for non source version
540 # https://github.com/phpmyadmin/phpmyadmin/issues/16033
544 # Remove developer scripts
547 # Remove possible tmp folder
552 # Remove tar file possibly left from previous run
555 # Prepare distributions
556 for comp
in $COMPRESSIONS ; do
559 if [ ! -f $name.
tar ] ; then
560 echo "* Creating $name.tar"
561 tar --owner=root
--group=root
--numeric-owner --sort=name
-cf $name.
tar $name
563 if [ $comp = txz
] ; then
564 echo "* Creating $name.tar.xz"
567 if [ $comp = tgz
] ; then
568 echo "* Creating $name.tar.gz"
569 gzip -9c $name.
tar > $name.
tar.gz
573 echo "* Creating $name.zip"
574 7za a
-bd -tzip $name.
zip $name > /dev
/null
577 echo "WARNING: ignoring compression '$comp', not known!"
585 # Remove directory with current dist set
590 rm -rf phpMyAdmin-
${version}
593 # Signing of files with default GPG key
594 echo "* Signing files"
595 for file in phpMyAdmin-
$version-*.gz phpMyAdmin-
$version-*.
zip phpMyAdmin-
$version-*.xz
; do
596 if [ $do_sign -eq 1 ] ; then
597 gpg
--detach-sign --armor $file
599 sha1sum $file > $file.sha1
600 sha256sum
$file > $file.sha256
603 if [ $do_daily -eq 1 ] ; then
604 cat > phpMyAdmin-
${version}.json
<< EOT
606 "date": "`date --iso-8601=seconds`",
607 "commit": "$git_head"
620 ls -la *.gz
*.
zip *.xz
625 if [ $do_tag -eq 1 ] ; then
627 echo "Additional tasks:"
628 tagname
=RELEASE_
`echo $version | tr . _ | tr '[:lower:]' '[:upper:]' | tr -d -`
629 echo "* Tagging release as $tagname"
630 git tag
-s -a -m "Released $version" $tagname $branch
631 echo " Dont forget to push tags using: git push --tags"
632 echo "* Cleanup of $branch"
633 # Remove composer.lock, but we need to create fresh worktree for that
634 git worktree add
--force $workdir $branch
636 git
rm --force composer.lock
637 git commit
-s -m "Removing composer.lock"
643 # Mark as stable release
644 if [ $do_stable -eq 1 ] ; then
645 mark_as_release
$branch STABLE
654 1. Push the new tag upstream, with a command like git push origin --tags
656 2. Push the new STABLE branch upstream
658 3. prepare a release/phpMyAdmin-$version-notes.html explaining in short the goal of
659 this release and paste into it the ChangeLog for this release, followed
660 by the notes of all previous incremental versions (i.e. 4.4.9 through 4.4.0)
662 4. upload the files to our file server, use scripts/upload-release, eg.:
664 ./scripts/upload-release $version release
666 5. add a news item to our website; a good idea is to include a link to the release notes such as https://www.phpmyadmin.net/files/4.4.10/
668 6. send a short mail (with list of major changes) to
669 developers@phpmyadmin.net
672 Don't forget to update the Description section in the announcement,
673 based on documentation.
675 7. increment rc count or version in the repository :
676 - run ./scripts/console set-version $version
677 - in $VERSION_FILE Version class:
678 - check that VERSION, MAJOR, MINOR and PATCH are correct.
679 - in README the "Version" line
680 " Version 2.7.1-dev "
681 - in package.json the line
682 " "version": " 2.7.1-dev", "
683 - in doc/conf.py (if it exists) the line
684 " version = '2.7.1-dev' "
686 8. on https://github.com/phpmyadmin/phpmyadmin/milestones close the milestone corresponding to the released version (if this is a stable release) and open a new one for the next minor release
688 9. for a major release, update demo/php/versions.ini in the scripts repository so that the demo server shows current versions
690 10. in case of a new major release ('y' in x.y.0), update the pmaweb/settings.py in website repository to include the new major releases
692 11. update the Dockerfile in the docker repository to reflect the new version and create a new annotated tag (such as with git tag -s -a 4.7.9-1 -m "Version 4.7.9-1"). Remember to push the tag with git push origin {tagName}