Add ChangeLog for e656f34
[phpmyadmin.git] / scripts / create-release.sh
blob48a3e940d4c334196df3ada45e0115019c7e3ccf
1 #!/bin/sh
3 # vim: expandtab sw=4 ts=4 sts=4:
6 # Do not run as CGI
7 if [ -n "$GATEWAY_INTERFACE" ] ; then
8 echo 'Can not invoke as CGI!'
9 exit 1
12 # More documentation about making a release is available at:
13 # https://wiki.phpmyadmin.net/pma/Releasing
15 # Fail on undefined variables
16 set -u
17 # Fail on failure
18 set -e
20 KITS="all-languages english source"
21 COMPRESSIONS="zip-7z txz tgz"
23 # Process parameters
25 version=""
26 branch=""
27 do_tag=0
28 do_stable=0
29 do_test=0
30 do_ci=0
31 do_sign=1
32 do_pull=0
33 do_daily=0
35 while [ $# -gt 0 ] ; do
36 case "$1" in
37 --tag)
38 do_tag=1
40 --stable)
41 do_stable=1
43 --test)
44 do_test=1
46 --daily)
47 do_sign=0
48 do_pull=1
49 do_daily=1
50 do_test=1
52 --ci)
53 do_test=1
54 do_ci=1
55 if [ -z "$branch" ] ; then
56 git branch ci
57 branch="ci"
59 version="ci"
61 --help)
62 echo "Usages:"
63 echo " create-release.sh <version> <from_branch> [--tag] [--stable] [--test] [--ci]"
64 echo ""
65 echo "If --tag is specified, release tag is automatically created (use this for all releases including pre-releases)"
66 echo "If --stable is specified, the STABLE branch is updated with this release"
67 echo "If --test is specified, the testsuite is executed before creating the release"
68 echo "If --ci is specified, the testsuite is executed and no actual release is created"
69 echo ""
70 echo "Examples:"
71 echo " create-release.sh 2.9.0-rc1 QA_2_9"
72 echo " create-release.sh 2.9.0 MAINT_2_9_0 --tag --stable"
73 exit 65
76 if [ -z "$version" ] ; then
77 version=`echo $1 | tr -d -c '0-9a-z.+-'`
78 if [ "x$version" != "x$1" ] ; then
79 echo "Invalid version: $1"
80 exit 1
82 elif [ -z "$branch" ] ; then
83 branch=`echo $1 | tr -d -c '0-9A-Za-z_-'`
84 if [ "x$branch" != "x$1" ] ; then
85 echo "Invalid branch: $1"
86 exit 1
88 else
89 echo "Unknown parameter: $1!"
90 exit 1
92 esac
93 shift
94 done
96 if [ -z "$version" -o -z "$branch" ] ; then
97 echo "Branch and version have to be specified!"
98 exit 1
101 # Checks whether remote branch has local tracking branch
102 ensure_local_branch() {
103 if ! git branch | grep -q '^..'"$1"'$' ; then
104 git branch --track $1 origin/$1
108 # Marks current head of given branch as head of other branch
109 # Used for STABLE tracking
110 mark_as_release() {
111 branch=$1
112 rel_branch=$2
113 echo "* Marking release as $rel_branch"
114 ensure_local_branch $rel_branch
115 git checkout $rel_branch
116 git merge -s recursive -X theirs $branch
117 git checkout master
120 # Ensure we have tracking branch
121 ensure_local_branch $branch
123 # Check if we're releasing older
124 if git cat-file -e $branch:libraries/classes/Config.php 2> /dev/null ; then
125 CONFIG_LIB=libraries/classes/Config.php
126 elif git cat-file -e $branch:libraries/Config.php 2> /dev/null ; then
127 CONFIG_LIB=libraries/Config.php
128 else
129 CONFIG_LIB=libraries/Config.class.php
132 if [ $do_ci -eq 0 -a -$do_daily -eq 0 ] ; then
133 cat <<END
135 Please ensure you have incremented rc count or version in the repository :
136 - in $CONFIG_LIB Config::__constructor() the line
137 " \$this->set('PMA_VERSION', '$version'); "
138 - in doc/conf.py the line
139 " version = '$version' "
140 - in README
141 - in package.json the line
142 " "version": "$version", "
143 - set release date in ChangeLog
145 Continue (y/n)?
147 read do_release
149 if [ "$do_release" != 'y' ]; then
150 exit 100
154 # Create working copy
155 mkdir -p release
156 git worktree prune
157 workdir=release/phpMyAdmin-$version
158 if [ -d $workdir ] ; then
159 echo "Working directory '$workdir' already exists, please move it out of way"
160 exit 1
163 # Add worktree with chosen branch
164 git worktree add --force $workdir $branch
165 cd $workdir
166 if [ $do_pull -eq 1 ] ; then
167 git pull -q
169 if [ $do_daily -eq 1 ] ; then
170 git_head=`git log -n 1 --format=%H`
173 # Check release version
174 if [ $do_ci -eq 0 -a -$do_daily -eq 0 ] ; then
175 if ! grep -q "'PMA_VERSION', '$version'" $CONFIG_LIB ; then
176 echo "There seems to be wrong version in $CONFIG_LIB!"
177 exit 2
179 if ! grep -q "version = '$version'" doc/conf.py ; then
180 echo "There seems to be wrong version in doc/conf.py"
181 exit 2
183 if ! grep -q "Version $version\$" README ; then
184 echo "There seems to be wrong version in README"
185 exit 2
187 if ! grep -q "\"version\": \"$version\"," package.json ; then
188 echo "There seems to be wrong version in package.json"
189 exit 2
193 # Cleanup release dir
194 LC_ALL=C date -u > RELEASE-DATE-${version}
196 # Building documentation
197 echo "* Generating documentation"
198 LC_ALL=C make -C doc html
199 find doc -name '*.pyc' -print0 | xargs -0 -r rm -f
201 # Check for gettext support
202 if [ -d po ] ; then
203 echo "* Generating mo files"
204 ./scripts/generate-mo
205 if [ -f ./scripts/remove-incomplete-mo ] ; then
206 echo "* Removing incomplete translations"
207 ./scripts/remove-incomplete-mo
211 if [ -f ./scripts/line-counts.sh ] ; then
212 echo "* Generating line counts"
213 ./scripts/line-counts.sh
216 echo "* Removing unneeded files"
218 # Remove developer information
219 rm -rf .github
221 # Remove phpcs coding standard definition
222 rm -rf PMAStandard
224 # Testsuite setup
225 rm -f .travis.yml .coveralls.yml .scrutinizer.yml .jshintrc .weblate codecov.yml
227 # Remove readme for github
228 rm -f README.rst
230 if [ ! -d libraries/tcpdf ] ; then
231 case "$branch" in
232 QA_4*) PHP_REQ=$(sed -n '/"php"/ s/.*">=\([0-9]\.[0-9]\).*/\1/p' composer.json) ;;
233 *) PHP_REQ=$(sed -n '/"php"/ s/.*"\^\([0-9]\.[0-9]\.[0-9]\).*/\1/p' composer.json) ;;
234 esac
236 if [ -z "$PHP_REQ" ] ; then
237 echo "Failed to figure out required PHP version from composer.json"
238 exit 2
240 # Okay, there is no way to tell composer to install
241 # suggested package. Let's require it and then revert
242 # composer.json to original state.
243 cp composer.json composer.json.backup
244 echo "* Running composer"
245 composer config platform.php "$PHP_REQ"
246 composer update --no-dev
248 # Parse the required versions from composer.json
249 PACKAGES_VERSIONS=''
250 case "$branch" in
251 QA_4*) PACKAGE_LIST="tecnickcom/tcpdf pragmarx/google2fa bacon/bacon-qr-code samyoul/u2f-php-server" ;;
252 *) PACKAGE_LIST="tecnickcom/tcpdf pragmarx/google2fa-qrcode samyoul/u2f-php-server" ;;
253 esac
255 for PACKAGES in $PACKAGE_LIST
257 PACKAGES_VERSIONS="$PACKAGES_VERSIONS $PACKAGES:`awk "/require-dev/ {printline = 1; print; next } printline" composer.json | grep "$PACKAGES" | awk -F [\\"] '{print $4}'`"
258 done
259 composer require --update-no-dev $PACKAGES_VERSIONS
261 mv composer.json.backup composer.json
262 echo "* Cleanup of composer packages"
263 rm -rf \
264 vendor/phpmyadmin/sql-parser/tests/ \
265 vendor/phpmyadmin/sql-parser/tools/ \
266 vendor/phpmyadmin/sql-parser/locale/*/LC_MESSAGES/sqlparser.po \
267 vendor/phpmyadmin/motranslator/tests/ \
268 vendor/phpmyadmin/shapefile/tests/ \
269 vendor/phpmyadmin/shapefile/examples/ \
270 vendor/phpmyadmin/shapefile/data/ \
271 vendor/phpseclib/phpseclib/phpseclib/File/ \
272 vendor/phpseclib/phpseclib/phpseclib/Math/ \
273 vendor/phpseclib/phpseclib/phpseclib/Net/ \
274 vendor/phpseclib/phpseclib/phpseclib/System/ \
275 vendor/symfony/cache/Tests/ \
276 vendor/symfony/expression-language/Tests/ \
277 vendor/symfony/expression-language/Resources/ \
278 vendor/tecnickcom/tcpdf/examples/ \
279 vendor/tecnickcom/tcpdf/tools/ \
280 vendor/tecnickcom/tcpdf/fonts/ae_fonts_*/ \
281 vendor/tecnickcom/tcpdf/fonts/dejavu-fonts-ttf-2.33/ \
282 vendor/tecnickcom/tcpdf/fonts/freefont-*/ \
283 vendor/tecnickcom/tcpdf/include/sRGB.icc \
284 vendor/twig/extensions/doc \
285 vendor/twig/extensions/test \
286 vendor/twig/twig/doc \
287 vendor/twig/twig/test \
288 vendor/google/recaptcha/examples/ \
289 vendor/google/recaptcha/tests/
290 find vendor/phpseclib/phpseclib/phpseclib/Crypt/ -maxdepth 1 -type f -not -name AES.php -not -name Base.php -not -name Random.php -not -name Rijndael.php -print0 | xargs -0 rm
291 find vendor/tecnickcom/tcpdf/fonts/ -maxdepth 1 -type f -not -name 'dejavusans.*' -not -name 'dejavusansb.*' -not -name 'helvetica.php' -print0 | xargs -0 rm
292 if [ $do_tag -eq 1 ] ; then
293 echo "* Commiting composer.lock"
294 git add --force composer.lock
295 git commit -s -m "Adding composer lock for $version"
299 if [ -f package.json ] ; then
300 echo "* Running Yarn"
301 yarn install --production
304 # Remove Bootstrap theme
305 rm -rf themes/bootstrap
307 # Remove git metadata
308 rm .git
309 find . -name .gitignore -print0 | xargs -0 -r rm -f
310 find . -name .gitattributes -print0 | xargs -0 -r rm -f
312 if [ $do_test -eq 1 ] ; then
313 composer update
314 ./vendor/bin/phpunit --configuration phpunit.xml.nocoverage --exclude-group selenium
315 test_ret=$?
316 if [ $do_ci -eq 1 ] ; then
317 cd ../..
318 rm -rf $workdir
319 git worktree prune
320 if [ "$branch" = "ci" ] ; then
321 git branch -D ci
323 exit $test_ret
325 if [ $test_ret -ne 0 ] ; then
326 exit $test_ret
328 # Remove PHPUnit cache file
329 rm -f .phpunit.result.cache
330 # Remove libs installed for testing
331 rm -rf build
332 composer update --no-dev
336 cd ..
338 # Prepare all kits
339 for kit in $KITS ; do
340 # Copy all files
341 name=phpMyAdmin-$version-$kit
342 cp -r phpMyAdmin-$version $name
344 # Cleanup translations
345 cd phpMyAdmin-$version-$kit
346 ./scripts/lang-cleanup.sh $kit
348 # Remove tests, source code,...
349 if [ $kit != source ] ; then
350 echo "* Removing source files"
351 # Testsuite
352 rm -rf test/
353 rm phpunit.xml.* build.xml
354 rm -f .editorconfig .eslintignore .eslintrc.json .stylelintrc.json phpstan.neon.dist phpcs.xml.dist
355 # Gettext po files
356 rm -rf po/
357 # Documentation source code
358 mv doc/html htmldoc
359 rm -rf doc
360 mkdir doc
361 mv htmldoc doc/html
362 rm doc/html/.buildinfo doc/html/objects.inv
363 # Javascript sources
364 rm -rf js/vendor/openlayers/src/
365 rm -rf node_modules
368 # Remove developer scripts
369 rm -rf scripts
371 cd ..
373 # Remove tar file possibly left from previous run
374 rm -f $name.tar
376 # Prepare distributions
377 for comp in $COMPRESSIONS ; do
378 case $comp in
379 tbz|tgz|txz)
380 if [ ! -f $name.tar ] ; then
381 echo "* Creating $name.tar"
382 tar --owner=root --group=root --numeric-owner --sort=name -cf $name.tar $name
384 if [ $comp = txz ] ; then
385 echo "* Creating $name.tar.xz"
386 xz -9k $name.tar
388 if [ $comp = tgz ] ; then
389 echo "* Creating $name.tar.gz"
390 gzip -9c $name.tar > $name.tar.gz
393 zip-7z)
394 echo "* Creating $name.zip"
395 7za a -bd -tzip $name.zip $name > /dev/null
398 echo "WARNING: ignoring compression '$comp', not known!"
400 esac
401 done
404 # Cleanup
405 rm -f $name.tar
406 # Remove directory with current dist set
407 rm -rf $name
408 done
410 # Cleanup
411 rm -rf phpMyAdmin-${version}
412 git worktree prune
414 # Signing of files with default GPG key
415 echo "* Signing files"
416 for file in phpMyAdmin-$version-*.gz phpMyAdmin-$version-*.zip phpMyAdmin-$version-*.xz ; do
417 if [ $do_sign -eq 1 ] ; then
418 gpg --detach-sign --armor $file
420 sha1sum $file > $file.sha1
421 sha256sum $file > $file.sha256
422 done
424 if [ $do_daily -eq 1 ] ; then
425 cat > phpMyAdmin-${version}.json << EOT
427 "date": "`date --iso-8601=seconds`",
428 "commit": "$git_head"
431 exit 0
435 echo ""
436 echo ""
437 echo ""
438 echo "Files:"
439 echo "------"
441 ls -la *.gz *.zip *.xz
443 cd ..
445 # Tag as release
446 if [ $do_tag -eq 1 ] ; then
447 echo
448 echo "Additional tasks:"
449 tagname=RELEASE_`echo $version | tr . _ | tr '[:lower:]' '[:upper:]' | tr -d -`
450 echo "* Tagging release as $tagname"
451 git tag -s -a -m "Released $version" $tagname $branch
452 echo " Dont forget to push tags using: git push --tags"
453 echo "* Cleanup of $branch"
454 # Remove composer.lock, but we need to create fresh worktree for that
455 git worktree add --force $workdir $branch
456 cd $workdir
457 git rm --force composer.lock
458 git commit -s -m "Removing composer.lock"
459 cd ../..
460 rm -rf $workdir
461 git worktree prune
464 # Mark as stable release
465 if [ $do_stable -eq 1 ] ; then
466 mark_as_release $branch STABLE
469 cat <<END
472 Todo now:
473 ---------
475 1. Push the new tag upstream, with a command like git push origin --tags
477 2. Push the new STABLE branch upstream
479 3. prepare a release/phpMyAdmin-$version-notes.html explaining in short the goal of
480 this release and paste into it the ChangeLog for this release, followed
481 by the notes of all previous incremental versions (i.e. 4.4.9 through 4.4.0)
483 4. upload the files to our file server, use scripts/upload-release, eg.:
485 ./scripts/upload-release $version release
487 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/
489 6. send a short mail (with list of major changes) to
490 developers@phpmyadmin.net
491 news@phpmyadmin.net
493 Don't forget to update the Description section in the announcement,
494 based on documentation.
496 7. increment rc count or version in the repository :
497 - in $CONFIG_LIB Config::__constructor() the line
498 " \$this->set( 'PMA_VERSION', '2.7.1-dev' ); "
499 - in Documentation.html (if it exists) the 2 lines
500 " <title>phpMyAdmin 2.2.2-rc1 - Documentation</title> "
501 " <h1>phpMyAdmin 2.2.2-rc1 Documentation</h1> "
502 - in doc/conf.py (if it exists) the line
503 " version = '2.7.1-dev' "
505 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
507 9. for a major release, update demo/php/versions.ini in the scripts repository so that the demo server shows current versions
509 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
511 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 --tags