[geany/infrastructure] b64498: Add nightly and CI build scripts to create Windows installers

Enrico Tröger git-noreply at xxxxx
Sun Feb 6 22:48:03 UTC 2022


Branch:      refs/heads/add_ci_builders
Author:      Enrico Tröger <enrico.troeger at uvena.de>
Committer:   Enrico Tröger <enrico.troeger at uvena.de>
Date:        Sun, 06 Feb 2022 22:48:03 UTC
Commit:      b64498b991abd0377688d9881709f8b436fefd52
             https://github.com/geany/infrastructure/commit/b64498b991abd0377688d9881709f8b436fefd52

Log Message:
-----------
Add nightly and CI build scripts to create Windows installers

The scripts, mainly start_build.sh, can be used for nightly builds
and for CI builds.

The Windows scripts use a Docker image containing a full cross
compilation environment for mingw64-x86_64. They create fully working
installer files for Geany and Geany-Plugins, optionally even signed
if a certificate is provided.

The Debian build scripts are yet to be tested and finalized.


Modified Paths:
--------------
    README.md
    builders/.dockerignore
    builders/Dockerfile.debian
    builders/Dockerfile.mingw
    builders/README.md
    builders/certificates/.gitkeep
    builders/mingw/bin/mingw-w64-i686-wine
    builders/mingw/bin/mingw-w64-x86_64-wine
    builders/mingw/etc/pacman.conf
    builders/mingw/etc/pacman.d/mirrorlist.mingw64
    builders/mingw/etc/pacman.d/mirrorlist.msys
    builders/output/.gitkeep
    builders/scripts/build_debian_geany.sh
    builders/scripts/build_debian_geany_plugins.sh
    builders/scripts/build_mingw_geany.sh
    builders/scripts/build_mingw_geany_plugins.sh
    builders/scripts/update_debian_repositories.sh
    builders/start_build.sh

Modified: README.md
11 lines changed, 10 insertions(+), 1 deletions(-)
===================================================================
@@ -57,6 +57,15 @@ If you want to add or remove a repository maintained by these scripts, follow th
     and has files.
 
 
+CI / Nightly-Builders
+=====================
+
+The `builders` directory contains Dockerfiles and scripts to create Debian packages
+as well as a cross-compiled Windows installer for Geany and Geany-Plugins.
+These scripts are used for the nightly builds, for details see
+[builders/README.md](builders/README.md).
+
+
 IRC Bot Plugins
 ===============
 
@@ -68,6 +77,6 @@ features like a bunch of !commands. For details, read the source code.
 
 
 License
-===============
+=======
 Unless stated otherwise all code in this repository is licensed of under the terms
 of the GNU General Public License version 2 (see COPYING in this repository).


Modified: builders/.dockerignore
5 lines changed, 5 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,5 @@
+/.git
+/certificates
+/output
+/scripts
+/start_build.sh


Modified: builders/Dockerfile.debian
25 lines changed, 25 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,25 @@
+#
+# Copyright 2022 The Geany contributors
+# License: GPLv2
+#
+# Docker image for Geany and Geany-Plugins for building Debian packages.
+#
+
+ARG BASE_IMAGE_NAME=debian:bullseye
+FROM $BASE_IMAGE_NAME
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN set -ex && \
+    apt-get update && \
+    apt-get dist-upgrade --assume-yes && \
+    apt-get install --assume-yes --no-install-recommends \
+        ca-certificates wget gnupg build-essential git \
+        devscripts dpkg-dev equivs fakeroot git-buildpackage \
+        intltool libdistro-info-perl reprepro \
+        # pre-install a few basic dependencies we probably need to reduce build time
+        libgtk-3-dev python3 python3-docutils python3-lxml \
+        # pre-install some geany-plugins dependencies
+        cppcheck valac libgpgme-dev libctpl-dev liblua5.1-0-dev libmarkdown2-dev \
+        # tools not necessary for build but useful for debugging
+        nano less


Modified: builders/Dockerfile.mingw
114 lines changed, 114 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,114 @@
+#
+# Copyright 2022 The Geany contributors
+# License: GPLv2
+#
+# Docker image for Geany and Geany-Plugins cross-build to Windows
+# The image contains a self-compiled Pacman to install mingw-w64
+# packages and all other dependencies necessary to build the code
+# and create a ready-use installer.
+# For more details, see build_mingw_geany.sh where this image is used.
+#
+# Intermediate container for building pacman
+FROM debian:bullseye as build-pacman
+
+ENV PACMAN_VERSION=6.0.1
+ENV PACMAN_SHA256="0db61456e56aa49e260e891c0b025be210319e62b15521f29d3e93b00d3bf731"
+ENV MSYS2_KEYRING_PKG="msys2-keyring-1~20210904-1-any.pkg.tar.zst"
+ENV MSYS2_KEYRING_PKG_SHA256="2b2d387edd7c85b27c38f9965854a600c3810714e9aedb35b40d380ff4be24a9"
+ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pacman/lib/x86_64-linux-gnu
+
+RUN set -ex && \
+    apt-get update && \
+    apt-get install --no-install-recommends --assume-yes \
+    build-essential meson wget xz-utils zstd gnupg2 file zstd ca-certificates \
+    pkg-config m4 libarchive-dev libssl-dev libcurl4-gnutls-dev libgpgme-dev \
+    python3-setuptools
+
+# compile Pacman
+RUN set -ex && \
+    wget --no-verbose https://sources.archlinux.org/other/pacman/pacman-${PACMAN_VERSION}.tar.xz && \
+    echo "${PACMAN_SHA256} *pacman-${PACMAN_VERSION}.tar.xz" | sha256sum --check --strict - && \
+    tar xf pacman-${PACMAN_VERSION}.tar.xz && \
+    cd /pacman-${PACMAN_VERSION} && \
+    meson \
+        --prefix /usr/local/pacman \
+        --sysconfdir=/windows/etc \
+        --localstatedir=/windows/var \
+        --buildtype release \
+        --strip \
+        -Dscriptlet-shell='/bin/bash' \
+        -Ddoc='disabled' \
+        -Ddoxygen='disabled' \
+        -Ddoc='disabled' \
+        -Di18n=false \
+        build && \
+    ninja -C build && \
+    ninja -C build install && \
+    ln -s /usr/local/pacman/bin/* /usr/local/bin/
+
+COPY mingw/etc/ /windows/etc/
+
+# setup pacman-key
+RUN set -ex && \
+    # download MSYS2 keyring
+    mkdir -p /usr/local/pacman/share/pacman/keyrings/ && \
+    wget --no-verbose "https://repo.msys2.org/msys/x86_64/${MSYS2_KEYRING_PKG}" && \
+    echo "${MSYS2_KEYRING_PKG_SHA256} *${MSYS2_KEYRING_PKG}" | sha256sum --check --strict - && \
+    tar -x -C /usr/local/pacman/share/pacman/keyrings/ -f "${MSYS2_KEYRING_PKG}" --strip-components 4 usr && \
+    # initialize keyring
+    pacman-key --init && \
+    pacman-key --populate msys2
+
+
+# Main image
+FROM debian:bullseye
+
+# install native tools and libraries
+RUN set -ex && \
+    dpkg --add-architecture i386 && \
+    apt-get update && \
+    apt-get install --no-install-recommends --assume-yes \
+    # libraries \
+    libcurl3-gnutls libgpgme11 libarchive13 libssl1.1 \
+    # common useful utilities \
+    wget curl less nano git gnupg2 file ca-certificates dos2unix \
+    zip unzip xz-utils zstd \
+    # build tools \
+    build-essential automake autoconf autopoint gettext libtool check cppcheck \
+    # genay-plugins autogen.sh requirements
+    intltool libglib2.0-dev \
+    # mingw \
+    gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 mingw-w64-x86-64-dev mingw-w64-tools \
+    # install wine to test installer and created binaries
+    wine wine32 wine64 \
+    # install NSIS and exiftool to inspect binary metadata
+    nsis libimage-exiftool-perl osslsigncode \
+    # Geany build dependencies \
+    python3-lxml python3-docutils
+
+
+# copy pacman and scripts
+COPY --from=build-pacman /windows /windows
+COPY --from=build-pacman /usr/local/pacman /usr/local/pacman
+COPY mingw/bin/ /usr/local/bin/
+RUN ln -s /usr/local/pacman/bin/* /usr/local/bin/ && \
+    mkdir /build
+
+WORKDIR /build
+ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pacman/lib/x86_64-linux-gnu
+
+# start wine to initially create config directory
+RUN /usr/local/bin/mingw-w64-i686-wine hostname.exe && \
+    /usr/local/bin/mingw-w64-x86_64-wine hostname.exe && \
+    # install GTK3 and all its dependencies
+    pacman --noconfirm -Sy mingw-w64-x86_64-gtk3 && \
+    # cleanup
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists/* && \
+    yes | pacman -Scc && \
+    rm -r /usr/share/doc \
+        /usr/share/locale \
+        /usr/share/man \
+        /windows/mingw64/share/icons \
+        /windows/mingw64/share/locale \
+        /windows/mingw64/share/doc


Modified: builders/README.md
130 lines changed, 130 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,130 @@
+CI / Nightly-Builders
+=====================
+
+## About
+
+Scripts and Dockerfiles for Geany and Geany-Plugins nightly builds.
+`start_nightly_build.sh` will create (if missing) Docker images for
+Debian stable and unstable as well as a Docker image for Mingw
+cross-compilaton to Windows.
+For the created Debian packages repositories for the distributions
+(stable and unstable) will be created.
+
+## Scripts and files
+
+    ├── Dockerfile.debian                   -> Dockerfile for Debian build image
+    ├── Dockerfile.mingw                    -> Dockerfile for Debian build image
+    ├── README.md
+    ├── certificates                        -> Certificate for signing Windows binaries and installer
+    │   ├── cert.pem                        -> Certificate public key (the filename is important)
+    │   └── key.pem                         -> Certificate secret key (the filename is important)
+    │
+    ├── mingw                               -> Helpers and configuration for Pacman and Windows builds
+    │   ├── bin                                (these files will be built into the Windows Docker image)
+    │   │   ├── mingw-w64-i686-wine
+    │   │   └── mingw-w64-x86_64-wine
+    │   └── etc
+    │       ├── pacman.conf
+    │       └── pacman.d
+    │           └── mirrorlist.mingw64
+    ├── output                              -> Directory where all build results are stored
+    │
+    ├── scripts                             -> Build scripts to be executed within Docker containers
+    │   ├── build_debian_geany.sh           -> Build Geany Debian packages
+    │   ├── build_debian_geany_plugins.sh   -> Build Geany-Plugins Debian packages
+    │   ├── build_mingw_geany.sh            -> Build Geany Windows installer
+    │   ├── build_mingw_geany_plugins.sh    -> Build Geany-Plugins Windows installer
+    │   └── update_debian_repositories.sh   -> Build repositories for Debian packages
+    │
+    └── start_build.sh                      -> Run Debian and Windows build containers and start builds
+
+## Geany sources
+
+All of the scripts can either use an existing source distribution
+of Geany (and Geany-Plugins) if it is mounted into the build Docker
+container (as `/geany-source` resp. `/geany-plugins-source`).
+If no existing source distribution is found, the scripts will clone
+Geany resp. Geany-Plugins from GIT master.
+
+## start_build.sh
+
+Main entry point to (re-)build the necessary Docker images and trigger
+the builds of Geany and Geany-Plugins for the various targets.
+
+    usage: start_build.sh [-d|--distro DISTRO] [-m|--mingw]
+                          [-r|--rebuild-images]
+     -d, --distro DISTRO     Build for target Debian DISTRO (e.g. "bullseye",
+                             can be specified multiple times
+     -g, --geany             Build Geany
+     -h                      Show this help screen
+     -l, --log-to-stdout     Log build output additionally to stdout
+     -m, --mingw             Build for target Mingw-w64
+     -p, --geany-plugins     Build Geany-Plugins
+     -r, --rebuild-images    Rebuild Docker images before start building
+                             (images are rebuilt automatically every 30 days)
+
+Example to build Geany and Geany-Plugins for Debian Bullseye, Debian Sid and Windows:
+
+    bash start_build.sh --geany --geany-plugins --mingw --distro sid --distro bullseye
+
+## Debian package build
+
+The Debian based builds use as much as possible the official Debian package sources
+from https://salsa.debian.org/geany-team/geany.git (and resp. for Geany-Plugins).
+
+Within the Debian based Docker images, packages are built from a GIT clone of Geany (unless
+a source tree is provided into the container via a volume).
+
+### Docker image
+
+The Debian based Docker image is pretty straight-forward and just extends the official
+"debian:$distro" images. The base image can be passed as build argument on image building and
+so images for different Debian distributions (stable, sid, ...) can be built for later use.
+
+The Dockerfile just installs a couple of development tools and libraries which are required for
+building Geany and Geany-Plugins. This is mainly to prepopulate the image with commonly used
+tools and libraries.
+
+### Repository creation
+
+TBW - WIP
+
+#### GnuPG key
+
+TBW - WIP
+
+## Windows (Mingw) build
+
+Geany and Geany-Plugins are built for Windows by cross-compiling them in a Docker container
+containing all necessary tools.
+
+If the build was started via Github Actions from a pull request, the pull request number
+will be appended to the resulting installer filename. For all other builds, the used GIT
+commit short hash is used.
+
+The created installer for Geany will contain the
+[Geany-Themes](https://github.com/geany/geany-themes) collection as well as the GTK
+runtime with all necessary dependencies.
+
+The created installer for Geany-Plugins will contain all necessary dependencies
+for the plugins to work.
+
+For more details, see the scripts `build_mingw_geany.sh` and `build_mingw_geany_plugins.sh`
+
+In theory, it is also possible to create release installers with this method.
+
+### Docker image
+
+The Docker image for the Windows build is based on a Debian image but has the full toolchain
+for cross-compiling to mingw64 included. Additionally, the image contains a self-compiled
+Pacman package manager to install packages from the MSYS2 repositories.
+
+### Code sign certificate
+
+If the directory `certificates` contains the two files `cert.pem` and `key.pem  `,
+then they will be used to digitally sign all created binary files (all built
+`.exe` and `.dll` files).
+
+If the directory is empty, code signing will be skipped.
+
+The certificate should be in the PEM format and the key should not require a passphrase.


Modified: builders/certificates/.gitkeep
0 lines changed, 0 insertions(+), 0 deletions(-)
===================================================================
No diff available, check online


Modified: builders/mingw/bin/mingw-w64-i686-wine
4 lines changed, 4 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,4 @@
+#!/bin/sh -e
+
+WINEPATH="${WINEPATH};/windows/mingw32/bin" wine $@
+


Modified: builders/mingw/bin/mingw-w64-x86_64-wine
3 lines changed, 3 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,3 @@
+#!/bin/sh -e
+
+WINEPATH="${WINEPATH};/windows/mingw64/bin" wine64 $@


Modified: builders/mingw/etc/pacman.conf
40 lines changed, 40 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,40 @@
+
+[options]
+RootDir     = /windows
+DBPath      = /windows/var/lib/pacman/
+CacheDir    = /windows/var/cache/pacman/pkg/
+LogFile     = /windows/var/log/pacman.log
+GPGDir      = /windows/etc/pacman.d/gnupg/
+HoldPkg      = pacman
+#XferCommand = /usr/bin/curl -C - -f %u > %o
+#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
+#CleanMethod = KeepInstalled
+#UseDelta    = 0.7
+Architecture = x86_64
+
+# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup
+#IgnorePkg   =
+#IgnoreGroup =
+
+#NoUpgrade   =
+#NoExtract   =
+
+# Misc options
+#UseSyslog
+#Color
+#TotalDownload
+CheckSpace
+#VerbosePkgLists
+
+# By default, pacman accepts packages signed by keys that its local keyring
+# trusts (see pacman-key and its man page), as well as unsigned packages.
+#SigLevel = Never
+SigLevel    = Required DatabaseOptional
+LocalFileSigLevel = Optional
+#RemoteFileSigLevel = Required
+
+[mingw64]
+Include = /windows/etc/pacman.d/mirrorlist.mingw64
+
+[msys]
+Include = /windows/etc/pacman.d/mirrorlist.msys


Modified: builders/mingw/etc/pacman.d/mirrorlist.mingw64
6 lines changed, 6 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,6 @@
+##
+## 64-bit Mingw-w64 repository mirrorlist
+##
+
+Server = http://repo.msys2.org/mingw/x86_64
+Server = http://www2.futureware.at/~nickoe/msys2-mirror/mingw/x86_64


Modified: builders/mingw/etc/pacman.d/mirrorlist.msys
6 lines changed, 6 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,6 @@
+##
+## MSYS repository mirrorlist
+##
+
+Server = http://repo.msys2.org/msys/$arch/
+Server = http://www2.futureware.at/~nickoe/msys2-mirror/msys/$arch/


Modified: builders/output/.gitkeep
0 lines changed, 0 insertions(+), 0 deletions(-)
===================================================================
No diff available, check online


Modified: builders/scripts/build_debian_geany.sh
182 lines changed, 182 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,182 @@
+#!/bin/bash
+#
+# Copyright 2022 The Geany contributors
+# License: GPLv2
+#
+# Helper script to build Debian packages for Geany.
+#
+# This script has to be executed within the Docker container.
+# The Docker container should have a bind-mount for ${OUTPUT_DIRECTORY}
+# where the resulting packages is stored.
+#
+# This script is meant to be run in a Docker container.
+#
+
+
+GEANY_VERSION=  # will be set below from configure.ac
+GEANY_GIT_REVISION=  # will be set below from configure.ac
+PACKAGE_VERSION=  # will be set below
+OUTPUT_DIRECTORY="/output"
+GEANY_GIT_REPOSITORY="https://github.com/geany/geany.git"
+GEANY_DEBIAN_REPOSITORY="https://salsa.debian.org/geany-team/geany.git"
+
+# rather static values, unlikely to be changed
+GEANY_SOURCE_DIR="/geany-source"
+GEANY_BUILD_DIR="/tmp/geany-build"
+GEANY_DEBIAN_DIR="/tmp/geany-debian"
+
+# for "dch" (debian changelog)
+export DEBEMAIL="devel at lists.geany.org"
+export DEBFULLNAME="The Geany contributors"
+
+# stop on errors
+set -e
+
+
+log() {
+	echo "=========== $(date '+%Y-%m-%d %H:%M:%S %Z') $* ==========="
+}
+
+
+git_clone_geany_if_necessary() {
+	log "Clone Geany repository (if necessary)"
+	mkdir -p "$(dirname ${GEANY_BUILD_DIR})"
+	if [ -d ${GEANY_SOURCE_DIR} ]; then
+		log "Copying Geany source"
+		cp --archive ${GEANY_SOURCE_DIR}/ ${GEANY_BUILD_DIR}/
+	else
+		log "Cloning Geany repository from ${GEANY_GIT_REPOSITORY}"
+		git clone --depth 1 ${GEANY_GIT_REPOSITORY} ${GEANY_BUILD_DIR}
+	fi
+}
+
+
+parse_geany_version() {
+	log "Parse Geany version"
+	GEANY_VERSION=$(sed -n -E -e 's/^AC_INIT\(\[Geany\], \[(.+)\],/\1/p' ${GEANY_BUILD_DIR}/configure.ac)
+	GEANY_GIT_REVISION=$(cd ${GEANY_BUILD_DIR} && git rev-parse --short --revs-only HEAD 2>/dev/null || true)
+	PACKAGE_VERSION="${GEANY_VERSION}-1~$(date '+%Y%m%d')git${GEANY_GIT_REVISION}"
+}
+
+
+run_autogen_sh() {
+	log "Run ./autogen.sh"
+	cd ${GEANY_BUILD_DIR}
+	# run ./autogen.sh as the Debian package won't run ./autogen.sh for us
+	NOCONFIGURE=1 ./autogen.sh
+}
+
+create_tarball_for_debuild() {
+	log "Create source tarball"
+	cd ${GEANY_BUILD_DIR}
+	# create a source tarball, keep .git included on purpose for Geany GIT build detection
+	tar --transform "s,^,geany-plugins-${GEANY_VERSION}/,S" \
+		--create \
+		--gzip \
+		--file "../geany_${GEANY_VERSION}.orig.tar.gz" \
+		.
+}
+
+
+git_clone_debian_geany() {
+	log "Clone Geany Debian repository"
+	git clone --depth 1 ${GEANY_DEBIAN_REPOSITORY} ${GEANY_DEBIAN_DIR}
+	# move debian package files to Geany GIT checkout
+	mv ${GEANY_DEBIAN_DIR}/debian ${GEANY_BUILD_DIR}
+}
+
+
+install_build_dependencies() {
+	log "Install build dependencies"
+	cd ${GEANY_BUILD_DIR}
+	apt-get --assume-yes update
+	apt-get --assume-yes dist-upgrade
+	mk-build-deps \
+		--install \
+		--remove \
+		--tool "apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --assume-yes"
+	# mk-build-deps leave the following files which then break 'debuild' later on
+	rm -f geany-build-deps_*-?_amd64.buildinfo geany-build-deps_*-?_amd64.changes
+}
+
+
+add_changelog_entry() {
+	log "Add ChangeLog entry for Debian package"
+	cd ${GEANY_BUILD_DIR}
+	dch \
+		--urgency low \
+		--distribution unstable \
+		--newversion "${PACKAGE_VERSION}" \
+		"Autobuilt by CI or nightly build."
+}
+
+
+build_package() {
+	log "Build Debian package"
+	cd ${GEANY_BUILD_DIR}
+
+	debuild -uc -us
+}
+
+
+copy_results() {
+	log "Copy build artefacts"
+
+	BUILD_DIR_DIRNAME=$(dirname ${GEANY_BUILD_DIR})
+
+	rm -rf ${OUTPUT_DIRECTORY}/geany/*
+
+	cp --verbose ${BUILD_DIR_DIRNAME}/geany_* ${OUTPUT_DIRECTORY}/geany
+	cp --verbose ${BUILD_DIR_DIRNAME}/geany-common_* ${OUTPUT_DIRECTORY}/geany
+	cp --verbose ${BUILD_DIR_DIRNAME}/geany-dbgsym_* ${OUTPUT_DIRECTORY}/geany
+}
+
+
+log_and_store_build_environment() {
+	log "Using environment"
+
+	GTK_VERSION=$(pkg-config --modversion gtk+-3.0)
+	GLIB_VERSION=$(pkg-config --modversion glib-2.0)
+	COMPILER_VERSION=$(gcc -dumpfullversion)
+
+	echo "Debian Distribution  : $(grep PRETTY_NAME /etc/os-release | cut -d '=' -f 2)"
+	echo "Geany version        : ${GEANY_VERSION}"
+	echo "Geany GIT revision   : ${GEANY_GIT_REVISION}"
+	echo "GLib version         : ${GLIB_VERSION}"
+	echo "GTK version          : ${GTK_VERSION}"
+	echo "GCC version          : ${COMPILER_VERSION}"
+
+	cat <<EOT > ${OUTPUT_DIRECTORY}/geany/versions.json
+	{
+		"glib_version": "${GLIB_VERSION}",
+		"gtk_version": "${GTK_VERSION}",
+		"gcc_version": "${COMPILER_VERSION}",
+	}
+EOT
+
+	# dump and copy test suite log otherwise it would be lost
+	cat ${GEANY_BUILD_DIR}/tests/ctags/test-suite.log
+	cp ${GEANY_BUILD_DIR}/tests/ctags/test-suite.log ${OUTPUT_DIRECTORY}/geany
+}
+
+
+main() {
+	git_clone_geany_if_necessary
+	parse_geany_version
+	run_autogen_sh
+	create_tarball_for_debuild
+
+	git_clone_debian_geany
+	install_build_dependencies
+	add_changelog_entry
+
+	build_package
+	copy_results
+
+	log_and_store_build_environment
+
+	log "Done."
+}
+
+
+main


Modified: builders/scripts/build_debian_geany_plugins.sh
183 lines changed, 183 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,183 @@
+#!/bin/bash
+#
+# Copyright 2022 The Geany contributors
+# License: GPLv2
+#
+# Helper script to build Debian packages for Geany-Plugins.
+#
+# This script has to be executed within the Docker container.
+# The Docker container should have a bind-mount for ${OUTPUT_DIRECTORY}
+# where the resulting packages is stored.
+#
+# This script is meant to be run in a Docker container.
+#
+
+
+GEANY_PLUGINS_VERSION=  # will be set below from configure.ac
+GEANY_PLUGINS_GIT_REVISION=  # will be set below from configure.ac
+PACKAGE_VERSION=  # will be set below
+OUTPUT_DIRECTORY="/output"
+GEANY_PLUGINS_GIT_REPOSITORY="https://github.com/geany/geany-plugins.git"
+GEANY_PLUGINS_DEBIAN_REPOSITORY="https://salsa.debian.org/geany-team/geany-plugins.git"
+
+# rather static values, unlikely to be changed
+GEANY_PLUGINS_SOURCE_DIR="/geany-plugins-source"
+GEANY_PLUGINS_BUILD_DIR="/tmp/geany-plugins-build"
+GEANY_PLUGINS_DEBIAN_DIR="/tmp/geany-plugins-debian"
+
+# for "dch" (debian changelog)
+export DEBEMAIL="devel at lists.geany.org"
+export DEBFULLNAME="The Geany contributors"
+
+# stop on errors
+set -e
+
+
+log() {
+	echo "=========== $(date '+%Y-%m-%d %H:%M:%S %Z') $* ==========="
+}
+
+
+git_clone_geany_if_necessary() {
+	log "Clone Geany-Plugins repository (if necessary)"
+	mkdir -p "$(dirname ${GEANY_PLUGINS_BUILD_DIR})"
+	if [ -d ${GEANY_PLUGINS_SOURCE_DIR} ]; then
+		log "Copying Geany-Plugins source"
+		cp --archive ${GEANY_PLUGINS_SOURCE_DIR}/ ${GEANY_PLUGINS_BUILD_DIR}/
+	else
+		log "Cloning Geany-Plugins repository from ${GEANY_PLUGINS_GIT_REPOSITORY}"
+		git clone --depth 1 ${GEANY_PLUGINS_GIT_REPOSITORY} ${GEANY_PLUGINS_BUILD_DIR}
+	fi
+}
+
+
+parse_geany_plugins_version() {
+	log "Parse Geany-Plugins version"
+	GEANY_PLUGINS_VERSION=$(sed -n -E -e 's/^AC_INIT\(\[geany-plugins\], \[(.+)\]\)/\1/p' ${GEANY_PLUGINS_BUILD_DIR}/configure.ac)
+	GEANY_PLUGINS_GIT_REVISION=$(cd ${GEANY_PLUGINS_BUILD_DIR} && git rev-parse --short --revs-only HEAD 2>/dev/null || true)
+	PACKAGE_VERSION="${GEANY_PLUGINS_VERSION}-1~$(date '+%Y%m%d')git${GEANY_PLUGINS_GIT_REVISION}"
+}
+
+
+run_autogen_sh() {
+	log "Run ./autogen.sh"
+	cd ${GEANY_PLUGINS_BUILD_DIR}
+	# run ./autogen.sh as the Debian package won't run ./autogen.sh for us
+	NOCONFIGURE=1 ./autogen.sh
+}
+
+
+create_tarball_for_debuild() {
+	log "Create source tarball"
+	cd ${GEANY_PLUGINS_BUILD_DIR}
+	tar --transform "s,^,geany-plugins-${GEANY_PLUGINS_VERSION}/,S" \
+		--create \
+		--gzip \
+		--file "../geany-plugins_${GEANY_PLUGINS_VERSION}.orig.tar.gz" \
+		.
+}
+
+
+git_clone_debian_geany() {
+	log "Clone Geany-Plugins Debian repository"
+	git clone --depth 1 ${GEANY_PLUGINS_DEBIAN_REPOSITORY} ${GEANY_PLUGINS_DEBIAN_DIR}
+	# move debian package files to Geany GIT checkout
+	mv ${GEANY_PLUGINS_DEBIAN_DIR}/debian ${GEANY_PLUGINS_BUILD_DIR}
+}
+
+
+install_build_dependencies() {
+	log "Install build dependencies"
+	cd ${GEANY_PLUGINS_BUILD_DIR}
+	# install Geany from previous build
+	dpkg -i \
+		${OUTPUT_DIRECTORY}/geany/geany-common_*git*_all.deb \
+		${OUTPUT_DIRECTORY}/geany/geany_*git*_amd64.deb
+
+	apt-get --assume-yes update
+	apt-get --assume-yes dist-upgrade
+	mk-build-deps \
+		--install \
+		--remove \
+		--tool "apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --assume-yes"
+	# mk-build-deps leave the following files which then break 'debuild' later on
+	rm -f geany-plugins-build-deps_*-?_amd64.buildinfo geany-plugins-build-deps_*-?_amd64.changes
+}
+
+
+add_changelog_entry() {
+	log "Add ChangeLog entry for Debian package"
+	cd ${GEANY_PLUGINS_BUILD_DIR}
+	dch \
+		--urgency low \
+		--distribution unstable \
+		--newversion "${PACKAGE_VERSION}" \
+		"Autobuilt by CI or nightly build."
+}
+
+
+build_package() {
+	log "Build Debian package"
+	cd ${GEANY_PLUGINS_BUILD_DIR}
+
+	debuild -uc -us
+}
+
+
+copy_results() {
+	log "Copy build artefacts"
+
+	BUILD_DIR_DIRNAME=$(dirname ${GEANY_PLUGINS_BUILD_DIR})
+
+	rm -rf ${OUTPUT_DIRECTORY}/geany-plugins/*
+
+	cp --verbose ${BUILD_DIR_DIRNAME}/geany-plugins_* ${OUTPUT_DIRECTORY}/geany-plugins
+	cp --verbose ${BUILD_DIR_DIRNAME}/geany-plugins-*_* ${OUTPUT_DIRECTORY}/geany-plugins
+	cp --verbose ${BUILD_DIR_DIRNAME}/geany-plugin-*_* ${OUTPUT_DIRECTORY}/geany-plugins
+}
+
+
+log_and_store_build_environment() {
+	log "Using environment"
+
+	GTK_VERSION=$(pkg-config --modversion gtk+-3.0)
+	GLIB_VERSION=$(pkg-config --modversion glib-2.0)
+	COMPILER_VERSION=$(gcc -dumpfullversion)
+
+	echo "Debian Distribution          : $(grep PRETTY_NAME /etc/os-release | cut -d '=' -f 2)"
+	echo "Geany-Plugins version        : ${GEANY_PLUGINS_VERSION}"
+	echo "Geany-Plugins GIT revision   : ${GEANY_PLUGINS_GIT_REVISION}"
+	echo "GLib version                 : ${GLIB_VERSION}"
+	echo "GTK version                  : ${GTK_VERSION}"
+	echo "GCC version                  : ${COMPILER_VERSION}"
+
+	cat <<EOT > ${OUTPUT_DIRECTORY}/geany-plugins/versions.json
+	{
+		"glib_version": "${GLIB_VERSION}",
+		"gtk_version": "${GTK_VERSION}",
+		"gcc_version": "${COMPILER_VERSION}",
+	}
+EOT
+}
+
+
+main() {
+	git_clone_geany_if_necessary
+	parse_geany_plugins_version
+	run_autogen_sh
+	create_tarball_for_debuild
+
+	git_clone_debian_geany
+	install_build_dependencies
+	add_changelog_entry
+
+	build_package
+	copy_results
+
+	log_and_store_build_environment
+
+	log "Done."
+}
+
+
+main


Modified: builders/scripts/build_mingw_geany.sh
326 lines changed, 326 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,326 @@
+#!/bin/bash
+#
+# Copyright 2022 The Geany contributors
+# License: GPLv2
+#
+# Helper script to build Geany for Windows in a Docker container.
+# The following steps are performed:
+# - clone Geany repository if necessary (i.e. if it is not bind-mounted into the container)
+# - cross-compile Geany for Windows 64bit and GTK3
+# - sign all binaries and installer (if /certificates exist and contains cert.pem and key.pem)
+# - download Geany-Themes for bundling
+# - create GTK3 bundle with all dependencies (including grep and sort)
+# - create the NSIS installer in ${OUTPUT_DIRECTORY}
+# - test the created NSIS installer and compiled Geany
+# - test uninstaller and check there is nothing left after uninstalling
+#
+# This script has to be executed within the Docker container.
+# The Docker container should have a bind-mount for ${OUTPUT_DIRECTORY}
+# where the resulting installer binary is stored.
+#
+# To test the installer and Geany binary "wine" is used.
+# Please note that we need to use wine32 and wine64 as the
+# created installer and uninstaller binaries are 32bit whereas the created
+# Geany binary is 64bit.
+#
+
+GEANY_VERSION=  # will be set below from configure.ac
+GEANY_GIT_REVISION=  # will be set below from configure.ac
+OUTPUT_DIRECTORY="/output"
+GEANY_GIT_REPOSITORY="https://github.com/geany/geany.git"
+GEANY_THEMES_REPOSITORY="https://github.com/geany/geany-themes.git"
+
+# rather static values, unlikely to be changed
+GTK_BUNDLE_DIR="/build/gtk-bundle"
+GEANY_SOURCE_DIR="/geany-source"
+GEANY_BUILD_DIR="/build/geany-build"
+GEANY_RELEASE_DIR="/build/geany-release"
+GEANY_INSTALLER_FILENAME=  # will be set below
+GEANY_INSTALLATION_DIR_WIN="C:\\geany_install"
+GEANY_INSTALLATION_DIR=$(winepath --unix ${GEANY_INSTALLATION_DIR_WIN})
+GEANY_THEMES_DIR="/build/geany-themes"
+GEANY_RELEASE_BINARY_PATTERNS=(
+	"${GEANY_RELEASE_DIR}/bin/geany.exe"
+	"${GEANY_RELEASE_DIR}/bin/*.dll"
+	"${GEANY_RELEASE_DIR}/lib/geany/*.dll"
+)
+GEANY_RELEASE_TEXTFILE_PATTERNS=(
+	"${GEANY_RELEASE_DIR}/*.txt"
+	"${GEANY_RELEASE_DIR}/share/doc/geany/*"
+)
+
+# CI CFLAGS
+CFLAGS="\
+	-Wall \
+	-Wextra \
+	-O2 \
+	-Wunused \
+	-Wno-unused-parameter \
+	-Wunreachable-code \
+	-Wformat=2 \
+	-Wundef \
+	-Wpointer-arith \
+	-Wwrite-strings \
+	-Waggregate-return \
+	-Wmissing-prototypes \
+	-Wmissing-declarations \
+	-Wmissing-noreturn \
+	-Wmissing-format-attribute \
+	-Wredundant-decls \
+	-Wnested-externs \
+	-Wno-deprecated-declarations"
+
+# cross-compilation environment
+ARCH="x86_64"
+MINGW_ARCH="mingw64"
+HOST="x86_64-w64-mingw32"
+export CC="/usr/bin/${HOST}-gcc"
+export CPP="/usr/bin/${HOST}-cpp"
+export CXX="/usr/bin/${HOST}-g++"
+export AR="/usr/bin/${HOST}-ar"
+export STRIP="/usr/bin/${HOST}-strip"
+export WINDRES="/usr/bin/${HOST}-windres"
+export CFLAGS="-I/windows/${MINGW_ARCH}/include/ ${CFLAGS}"
+export LDFLAGS="-static-libgcc ${LDFLAGS}"
+export PKG_CONFIG_SYSROOT_DIR="/windows"
+export PKG_CONFIG_PATH="/windows/${MINGW_ARCH}/lib/pkgconfig/"
+export PKG_CONFIG="/usr/bin/pkg-config"
+export NOCONFIGURE=1
+
+# stop on errors
+set -e
+
+
+log() {
+	echo "=========== $(date '+%Y-%m-%d %H:%M:%S %Z') $* ==========="
+}
+
+
+git_clone_geany_if_necessary() {
+	if [ -d ${GEANY_SOURCE_DIR} ]; then
+		log "Copying Geany source"
+		cp --archive ${GEANY_SOURCE_DIR}/ ${GEANY_BUILD_DIR}/
+	else
+		log "Cloning Geany repository from ${GEANY_GIT_REPOSITORY}"
+		git clone --depth 1 ${GEANY_GIT_REPOSITORY} ${GEANY_BUILD_DIR}
+	fi
+}
+
+
+parse_geany_version() {
+	GEANY_VERSION=$(sed -n -E -e 's/^AC_INIT.\[Geany\], \[(.+)\],/\1/p' ${GEANY_BUILD_DIR}/configure.ac)
+	GEANY_GIT_REVISION=$(cd ${GEANY_BUILD_DIR} && git rev-parse --short --revs-only HEAD 2>/dev/null || true)
+	# add pull request number if this is a CI and a PR build
+	if [ "${GITHUB_PULL_REQUEST}" ]; then
+		GEANY_VERSION="${GEANY_VERSION}pr${GITHUB_PULL_REQUEST}"
+	elif [ "${CI}" -a "${GEANY_GIT_REVISION}" ]; then
+		GEANY_VERSION="${GEANY_VERSION}ci${GEANY_GIT_REVISION}"
+	elif [ "${GEANY_GIT_REVISION}" ]; then
+		GEANY_VERSION="${GEANY_VERSION}git${GEANY_GIT_REVISION}"
+	fi
+	GEANY_INSTALLER_FILENAME="geany-${GEANY_VERSION}_setup.exe"
+}
+
+
+log_environment() {
+	log "Using environment"
+	CONFIGURE_OPTIONS="--disable-silent-rules --host=${HOST} --prefix=${GEANY_RELEASE_DIR} --with-libiconv-prefix=/windows/mingw64"
+	echo "Geany version        : ${GEANY_VERSION}"
+	echo "Geany GIT revision   : ${GEANY_GIT_REVISION}"
+	echo "PATH                 : ${PATH}"
+	echo "HOST                 : ${HOST}"
+	echo "CC                   : ${CC}"
+	echo "CFLAGS               : ${CFLAGS}"
+	echo "Configure            : ${CONFIGURE_OPTIONS}"
+}
+
+
+patch_version_information() {
+	log "Patching version information"
+
+	if [ -z "${GEANY_GIT_REVISION}" ] && [ -z "${TRAVIS_PULL_REQUEST}" ]; then
+		return
+	fi
+
+	# parse version string and decrement the patch and/or minor levels to keep nightly build
+	# versions below the next release version
+	regex='^([0-9]*)[.]([0-9]*)([.]([0-9]*))?'
+	if [[ ${GEANY_VERSION} =~ $regex ]]; then
+		MAJOR="${BASH_REMATCH[1]}"
+		MINOR="${BASH_REMATCH[2]}"
+		PATCH="${BASH_REMATCH[4]}"
+		if [ -z "${PATCH}" ] || [ "${PATCH}" = "0" ]; then
+			MINOR="$((MINOR-1))"
+			PATCH="90"
+		else
+			PATCH="$((PATCH-1))"
+		fi
+	else
+		echo "Could not extract or parse version tag" >&2
+		exit 1
+	fi
+	# replace version information in configure.ac and for Windows binaries
+	sed -i -E "s/^AC_INIT.\[Geany\], \[(.+)\],/AC_INIT(\[Geany\], \[${GEANY_VERSION}\],/" ${GEANY_BUILD_DIR}/configure.ac
+	sed -i -E "s/^#define VER_FILEVERSION_STR[[:space:]]+\".*\"+/#define VER_FILEVERSION_STR \"${GEANY_VERSION}\"/" ${GEANY_BUILD_DIR}/geany_private.rc
+	sed -i -E "s/^#define VER_FILEVERSION[[:space:]]+[0-9,]+/#define VER_FILEVERSION ${MAJOR},${MINOR},${PATCH},90/" ${GEANY_BUILD_DIR}/geany_private.rc
+	sed -i -E "s/^[[:space:]]+version=\"[0-9.]+\"/version=\"${MAJOR}.${MINOR}.${PATCH}.90\"/" ${GEANY_BUILD_DIR}/geany.exe.manifest
+	sed -i -E "s/^!define PRODUCT_VERSION \"@VERSION@\"/!define PRODUCT_VERSION \"${GEANY_VERSION}\"/" ${GEANY_BUILD_DIR}/geany.nsi.in
+	sed -i -E "s/^!define PRODUCT_VERSION_ID \"@VERSION at .0.0\"/!define PRODUCT_VERSION_ID \"${MAJOR}.${MINOR}.${PATCH}.90\"/" ${GEANY_BUILD_DIR}/geany.nsi.in
+}
+
+
+build_geany() {
+	cd ${GEANY_BUILD_DIR}
+	log "Running autogen.sh"
+	./autogen.sh
+	log "Running configure"
+	./configure ${CONFIGURE_OPTIONS}
+	log "Running make"
+	make
+	log "Running install-strip"
+	make install-strip
+
+	cd /
+}
+
+
+sign_file() {
+	echo "Sign file $1"
+	if [ -f /certificates/cert.pem ] && [ -f /certificates/key.pem ]; then
+		osslsigncode sign \
+			-certs /certificates/cert.pem \
+			-key /certificates/key.pem \
+			-n "Geany Binary" \
+			-i "https://www.geany.org/" \
+			-ts http://zeitstempel.dfn.de/ \
+			-h sha512 \
+			-in ${1} \
+			-out ${1}-signed
+		mv ${1}-signed ${1}
+	else
+		echo "Skip signing due to missing certificate"
+	fi
+}
+
+
+sign_geany_binaries() {
+	log "Signing Geany binary files"
+	for binary_file_pattern in ${GEANY_RELEASE_BINARY_PATTERNS[@]}; do
+		for binary_file in $(ls ${binary_file_pattern}); do
+			sign_file ${binary_file}
+		done
+	done
+}
+
+
+convert_text_files_to_crlf() {
+	log "Converting line endings to CRLF in text files"
+	for text_file_pattern in ${GEANY_RELEASE_TEXTFILE_PATTERNS[@]}; do
+		for text_file in $(ls ${text_file_pattern}); do
+			mime_type=$(file --brief --mime-type ${text_file})
+			case $mime_type in text/*)
+				unix2dos ${text_file}
+			esac
+		done
+	done
+}
+
+
+create_gtk_bundle() {
+	log "Creating GTK bundle"
+	mkdir ${GTK_BUNDLE_DIR}
+	cd ${GTK_BUNDLE_DIR}
+	bash ${GEANY_BUILD_DIR}/scripts/gtk-bundle-from-msys2.sh -x -3
+	cd /
+}
+
+
+fetch_geany_themes() {
+	log "Cloning Geany-Themes repository from ${GEANY_THEMES_REPOSITORY}"
+	git clone --depth 1 ${GEANY_THEMES_REPOSITORY} ${GEANY_THEMES_DIR}
+}
+
+
+create_installer() {
+	log "Creating NSIS installer"
+	makensis \
+		-V3 \
+		-WX \
+		-DGEANY_INSTALLER_NAME="${GEANY_INSTALLER_FILENAME}" \
+		-DGEANY_RELEASE_DIR=${GEANY_RELEASE_DIR} \
+		-DGEANY_THEMES_DIR=${GEANY_THEMES_DIR} \
+		-DGTK_BUNDLE_DIR=${GTK_BUNDLE_DIR} \
+		${GEANY_BUILD_DIR}/geany.nsi
+}
+
+
+sign_installer() {
+	log "Signing NSIS installer"
+	sign_file ${GEANY_BUILD_DIR}/${GEANY_INSTALLER_FILENAME}
+}
+
+
+test_installer() {
+	log "Test NSIS installer"
+	exiftool -FileName -FileType -FileVersion -FileVersionNumber ${GEANY_BUILD_DIR}/${GEANY_INSTALLER_FILENAME}
+	# install Geany: perform a silent install and check for installed files
+	mingw-w64-i686-wine ${GEANY_BUILD_DIR}/${GEANY_INSTALLER_FILENAME} /S /D=${GEANY_INSTALLATION_DIR_WIN}
+	# check if we have something installed
+	test -f ${GEANY_INSTALLATION_DIR}/uninst.exe || exit 1
+	test -f ${GEANY_INSTALLATION_DIR}/bin/geany.exe || exit 1
+	test -f ${GEANY_INSTALLATION_DIR}/lib/geany/export.dll || exit 1
+	test ! -f ${GEANY_INSTALLATION_DIR}/lib/geany/demoplugin.dll || exit 1
+}
+
+
+log_geany_version() {
+	log "Log installed Geany version"
+	mingw-w64-x86_64-wine ${GEANY_INSTALLATION_DIR}/bin/geany.exe --version 2>/dev/null
+	exiftool -FileName -FileType -FileVersion -FileVersionNumber ${GEANY_INSTALLATION_DIR}/bin/geany.exe
+}
+
+
+test_uninstaller() {
+	log "Test NSIS uninstaller"
+	# uninstall Geany and test if everything is clean
+	mingw-w64-i686-wine ${GEANY_INSTALLATION_DIR}/uninst.exe /S
+	sleep 10  # it seems the uninstaller returns earlier than the files are actually removed, so wait a moment
+	test ! -e ${GEANY_INSTALLATION_DIR}
+}
+
+
+copy_installer_and_bundle() {
+	log "Copying NSIS installer and GTK bundle"
+	cp ${GEANY_BUILD_DIR}/${GEANY_INSTALLER_FILENAME} ${OUTPUT_DIRECTORY}
+	cd ${GTK_BUNDLE_DIR}
+	zip --quiet --recurse-paths ${OUTPUT_DIRECTORY}/gtk_bundle_$(date '+%Y%m%dT%H%M%S').zip *
+	cd /
+}
+
+
+main() {
+	git_clone_geany_if_necessary
+
+	parse_geany_version
+	log_environment
+	patch_version_information
+	build_geany
+	sign_geany_binaries
+	convert_text_files_to_crlf
+
+	create_gtk_bundle
+	fetch_geany_themes
+	create_installer
+	sign_installer
+
+	test_installer
+	log_geany_version
+	test_uninstaller
+
+	copy_installer_and_bundle
+
+	log "Done."
+}
+
+
+main


Modified: builders/scripts/build_mingw_geany_plugins.sh
355 lines changed, 355 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,355 @@
+#!/bin/bash
+#
+# Copyright 2022 The Geany contributors
+# License: GPLv2
+#
+# Helper script to build Geany-Plugins for Windows in a Docker container.
+# The following steps are performed:
+# - clone Geany-Plugins repository if necessary (i.e. if it is not bind-mounted into the container)
+# - cross-compile Geany-Plugins for Windows 64bit and GTK3
+# - sign all binaries and installer (if /certificates exist and contains cert.pem and key.pem)
+# - create bundle with all dependencies
+# - create the NSIS installer in ${OUTPUT_DIRECTORY}
+# - test the created NSIS installer
+# - test uninstaller and check there is nothing unexpected left after uninstalling
+#
+# This script has to be executed within the Docker container.
+# The Docker container should have a bind-mount for ${OUTPUT_DIRECTORY}
+# where the resulting installer binary is stored.
+#
+# To test the installer "wine" is used.
+# Please note that we need to use wine32 as the created installer and uninstaller
+# binaries are 32bit.
+#
+
+GEANY_PLUGINS_VERSION=  # will be set below from configure.ac
+GEANY_PLUGINS_GIT_REVISION=  # will be set below from configure.ac
+OUTPUT_DIRECTORY="/output"
+GEANY_PLUGINS_GIT_REPOSITORY="https://github.com/geany/geany-plugins.git"
+
+# rather static values, unlikely to be changed
+DEPENDENCY_BUNDLE_DIR="/build/dependencies-bundle"
+GEANY_PLUGINS_SOURCE_DIR="/geany-plugins-source"
+GEANY_PLUGINS_BUILD_DIR="/build/geany-plugins-build"
+GEANY_PLUGINS_RELEASE_DIR="/build/geany-plugins-release"
+GEANY_PLUGINS_INSTALLER_FILENAME=  # will be set below
+GEANY_PLUGINS_INSTALLATION_DIR_WIN="C:\\geany_plugins_install"
+GEANY_PLUGINS_INSTALLATION_DIR=$(winepath --unix ${GEANY_PLUGINS_INSTALLATION_DIR_WIN})
+GEANY_PLUGINS_RELEASE_BINARY_PATTERNS=(
+	"${GEANY_PLUGINS_RELEASE_DIR}/lib/geany/*.dll"
+	"${GEANY_PLUGINS_RELEASE_DIR}/lib/geany-plugins/geanylua/libgeanylua.dll"
+	"${GEANY_PLUGINS_RELEASE_DIR}/bin/libgeanypluginutils*.dll"
+)
+
+GEANY_PLUGINS_RELEASE_TEXTFILE_PATTERNS=(
+	"${GEANY_PLUGINS_RELEASE_DIR}/share/doc/geany-plugins/*"
+	"${GEANY_PLUGINS_RELEASE_DIR}/share/doc/geany-plugins/*/*"
+)
+GEANY_INSTALLATION_DIR="/root/.wine/drive_c/geany_install"
+
+GEANY_INSTALL_DIR_WIN=$(winepath --windows ${GEANY_INSTALLATION_DIR})
+GEANY_INSTALLER_EXECUTABLE=$(ls ${OUTPUT_DIRECTORY}/geany-*_setup.exe)
+
+# TODO move to include and use it also in Geany build script
+# CI CFLAGS
+CFLAGS="\
+	-Wall \
+	-Wextra \
+	-O2 \
+	-Wunused \
+	-Wno-unused-parameter \
+	-Wunreachable-code \
+	-Wformat=2 \
+	-Wundef \
+	-Wpointer-arith \
+	-Wwrite-strings \
+	-Waggregate-return \
+	-Wmissing-prototypes \
+	-Wmissing-declarations \
+	-Wmissing-noreturn \
+	-Wmissing-format-attribute \
+	-Wredundant-decls \
+	-Wnested-externs \
+	-Wno-deprecated-declarations"
+
+# cross-compilation environment
+ARCH="x86_64"
+MINGW_ARCH="mingw64"
+HOST="x86_64-w64-mingw32"
+export CC="/usr/bin/${HOST}-gcc"
+export CPP="/usr/bin/${HOST}-cpp"
+export CXX="/usr/bin/${HOST}-g++"
+export AR="/usr/bin/${HOST}-ar"
+export STRIP="/usr/bin/${HOST}-strip"
+export WINDRES="/usr/bin/${HOST}-windres"
+export CFLAGS="-I/windows/${MINGW_ARCH}/include/ ${CFLAGS}"
+export LDFLAGS="-static-libgcc ${LDFLAGS}"
+export PKG_CONFIG_SYSROOT_DIR="/windows"
+export PKG_CONFIG_PATH="/windows/${MINGW_ARCH}/lib/pkgconfig/"
+export PKG_CONFIG="/usr/bin/pkg-config"
+export NOCONFIGURE=1
+
+# stop on errors
+set -e
+
+
+log() {
+	echo "=========== $(date '+%Y-%m-%d %H:%M:%S %Z') $* ==========="
+}
+
+
+git_clone_geany_plugins_if_necessary() {
+	if [ -d ${GEANY_PLUGINS_SOURCE_DIR} ]; then
+		log "Copying Geany-Plugins source"
+		cp --archive ${GEANY_PLUGINS_SOURCE_DIR}/ ${GEANY_PLUGINS_BUILD_DIR}/
+	else
+		log "Cloning Geany-Plugins repository from ${GEANY_PLUGINS_GIT_REPOSITORY}"
+		git clone --depth 1 ${GEANY_PLUGINS_GIT_REPOSITORY} ${GEANY_PLUGINS_BUILD_DIR}
+	fi
+}
+
+
+parse_geany_plugins_version() {
+	GEANY_PLUGINS_VERSION=$(sed -n -E -e 's/^AC_INIT.\[geany-plugins\], \[(.+)\]./\1/p' ${GEANY_PLUGINS_BUILD_DIR}/configure.ac)
+	GEANY_PLUGINS_GIT_REVISION=$(cd ${GEANY_PLUGINS_BUILD_DIR} && git rev-parse --short --revs-only HEAD 2>/dev/null || true)
+	# add pull request number if this is a CI and a PR build
+	if [ "${GITHUB_PULL_REQUEST}" ]; then
+		GEANY_PLUGINS_VERSION="${GEANY_PLUGINS_VERSION}pr${GITHUB_PULL_REQUEST}"
+	elif [ "${CI}" -a "${GEANY_PLUGINS_GIT_REVISION}" ]; then
+		GEANY_PLUGINS_VERSION="${GEANY_PLUGINS_VERSION}ci${GEANY_PLUGINS_GIT_REVISION}"
+	elif [ "${GEANY_PLUGINS_GIT_REVISION}" ]; then
+		GEANY_PLUGINS_VERSION="${GEANY_PLUGINS_VERSION}git${GEANY_PLUGINS_GIT_REVISION}"
+	fi
+	GEANY_PLUGINS_INSTALLER_FILENAME="geany-plugins-${GEANY_PLUGINS_VERSION}_setup.exe"
+}
+
+
+log_environment() {
+	log "Using environment"
+	CONFIGURE_OPTIONS="--disable-silent-rules --host=${HOST} --prefix=${GEANY_PLUGINS_RELEASE_DIR} --with-geany-libdir=${GEANY_PLUGINS_RELEASE_DIR}/lib"
+	echo "Geany-Plugins version        : ${GEANY_PLUGINS_VERSION}"
+	echo "Geany-Plugins GIT revision   : ${GEANY_PLUGINS_GIT_REVISION}"
+	echo "Geany installer              : ${GEANY_INSTALLER_EXECUTABLE}"
+	echo "PATH                         : ${PATH}"
+	echo "HOST                         : ${HOST}"
+	echo "CC                           : ${CC}"
+	echo "CFLAGS                       : ${CFLAGS}"
+	echo "Configure                    : ${CONFIGURE_OPTIONS}"
+}
+
+
+patch_version_information() {
+	log "Patching version information"
+
+	if [ -z "${GEANY_PLUGINS_GIT_REVISION}" ] && [ -z "${TRAVIS_PULL_REQUEST}" ]; then
+		return
+	fi
+
+	# parse version string and decrement the patch and/or minor levels to keep nightly build
+	# versions below the next release version
+	regex='^([0-9]*)[.]([0-9]*)([.]([0-9]*))?'
+	if [[ ${GEANY_PLUGINS_VERSION} =~ $regex ]]; then
+		MAJOR="${BASH_REMATCH[1]}"
+		MINOR="${BASH_REMATCH[2]}"
+		PATCH="${BASH_REMATCH[4]}"
+		if [ -z "${PATCH}" ] || [ "${PATCH}" = "0" ]; then
+			MINOR="$((MINOR-1))"
+			PATCH="90"
+		else
+			PATCH="$((PATCH-1))"
+		fi
+	else
+		echo "Could not extract or parse version tag" >&2
+		exit 1
+	fi
+	# replace version information in configure.ac and for Windows binaries
+	sed -i -E "s/^AC_INIT.\[geany-plugins\], \[(.+)\],/AC_INIT(\[geany-plugins\], \[${GEANY_PLUGINS_VERSION}\],/" ${GEANY_PLUGINS_BUILD_DIR}/configure.ac
+	sed -i -E "s/^!define PRODUCT_VERSION \"(.+)\"/!define PRODUCT_VERSION \"${GEANY_PLUGINS_VERSION}\"/" ${GEANY_PLUGINS_BUILD_DIR}/build/geany-plugins.nsi
+	sed -i -E "s/^!define PRODUCT_VERSION_ID \"(.+)\"/!define PRODUCT_VERSION_ID \"${MAJOR}.${MINOR}.${PATCH}.90\"/" ${GEANY_PLUGINS_BUILD_DIR}/build/geany-plugins.nsi
+	sed -i -E "s/^!define REQUIRED_GEANY_VERSION \"(.+)\"/!define REQUIRED_GEANY_VERSION \"${MAJOR}.${MINOR}\"/" ${GEANY_PLUGINS_BUILD_DIR}/build/geany-plugins.nsi
+}
+
+
+install_dependencies() {
+	log "Installing build dependencies"
+	pacman --noconfirm -Syu
+	pacman --noconfirm -S \
+		mingw-w64-${ARCH}-check \
+		mingw-w64-${ARCH}-cppcheck \
+		mingw-w64-${ARCH}-ctpl-git \
+		mingw-w64-${ARCH}-enchant \
+		mingw-w64-${ARCH}-gpgme \
+		mingw-w64-${ARCH}-gtkspell3 \
+		mingw-w64-${ARCH}-libgit2 \
+		mingw-w64-${ARCH}-libsoup \
+		mingw-w64-${ARCH}-lua51
+}
+
+
+install_geany() {
+	log "Installing Geany (using wine)"
+	if [ -z "${GEANY_INSTALLER_EXECUTABLE}" -o ! -f "${GEANY_INSTALLER_EXECUTABLE}" ]; then
+		echo "No Geany installer found"
+		exit 1
+	fi
+	mingw-w64-i686-wine ${GEANY_INSTALLER_EXECUTABLE} /S /D=${GEANY_INSTALL_DIR_WIN}
+
+	# TODO the following steps are way too hacky: installing Geany from the installer is basically
+	# what we want for CI tests but the installed "geany.pc" file isn't really suitable
+	# for cross-compiling
+
+	# add the Geany installation directory to the PKG_CONFIG_PATH
+	export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${GEANY_INSTALLATION_DIR}/lib/pkgconfig/"
+	# patch Geany pkg-config prefix: pkg-config always prepend "/windows" to the "prefix" variable, so we
+	# need to add ../ to get out of the hardcoded "/windows" path element
+	sed -i "s%^\(prefix=\).*$%\1/..${GEANY_INSTALLATION_DIR}%" ${GEANY_INSTALLATION_DIR}/lib/pkgconfig/geany.pc
+	sed -i "s%^\(exec_prefix=\).*$%\1/..${GEANY_INSTALLATION_DIR}%" ${GEANY_INSTALLATION_DIR}/lib/pkgconfig/geany.pc
+	# we need "${exec_prefix}/bin" additionally for libgeany-0.dll which is installed into bin/ and replace -lgeany by -lgeany-0
+	sed -i "s%^Libs: -L\${libdir} -lgeany$%Libs: -L\${libdir} -L\${exec_prefix}/bin -lgeany-0%" ${GEANY_INSTALLATION_DIR}/lib/pkgconfig/geany.pc
+}
+
+
+build_geany_plugins() {
+	cd ${GEANY_PLUGINS_BUILD_DIR}
+	log "Running autogen.sh"
+	./autogen.sh
+	log "Running configure"
+	./configure ${CONFIGURE_OPTIONS}
+	log "Running make"
+	make
+	log "Running install-strip"
+	make install-strip
+
+	cd /
+}
+
+
+sign_file() {
+	echo "Sign file $1"
+	if [ -f /certificates/cert.pem ] && [ -f /certificates/key.pem ]; then
+		osslsigncode sign \
+			-certs /certificates/cert.pem \
+			-key /certificates/key.pem \
+			-n "Geany-Plugins Binary" \
+			-i "https://www.geany.org/" \
+			-ts http://zeitstempel.dfn.de/ \
+			-h sha512 \
+			-in ${1} \
+			-out ${1}-signed
+		mv ${1}-signed ${1}
+	else
+		echo "Skip signing due to missing certificate"
+	fi
+}
+
+
+sign_geany_plugins_binaries() {
+	log "Signing Geany-Plugins binary files"
+	for binary_file_pattern in ${GEANY_PLUGINS_RELEASE_BINARY_PATTERNS[@]}; do
+		for binary_file in $(ls ${binary_file_pattern}); do
+			sign_file ${binary_file}
+		done
+	done
+}
+
+
+convert_text_files_to_crlf() {
+	log "Converting line endings to CRLF in text files"
+	for text_file_pattern in ${GEANY_PLUGINS_RELEASE_TEXTFILE_PATTERNS[@]}; do
+		for text_file in $(ls ${text_file_pattern}); do
+			mime_type=$(file --brief --mime-type ${text_file})
+			case $mime_type in text/*)
+				unix2dos ${text_file}
+			esac
+		done
+	done
+}
+
+
+create_dependencies_bundle() {
+	log "Creating Geany-Plugins dependencies bundle"
+	mkdir ${DEPENDENCY_BUNDLE_DIR}
+	cd ${DEPENDENCY_BUNDLE_DIR}
+	bash ${GEANY_PLUGINS_BUILD_DIR}/build/gtk-bundle-from-msys2.sh -x -3
+	cd /
+}
+
+
+create_installer() {
+	log "Creating NSIS installer"
+	makensis \
+		-V3 \
+		-WX \
+		-DGEANY_PLUGINS_INSTALLER_NAME="${GEANY_PLUGINS_INSTALLER_FILENAME}" \
+		-DGEANY_PLUGINS_RELEASE_DIR=${GEANY_PLUGINS_RELEASE_DIR} \
+		-DDEPENDENCY_BUNDLE_DIR=${DEPENDENCY_BUNDLE_DIR} \
+		${GEANY_PLUGINS_BUILD_DIR}/build/geany-plugins.nsi
+}
+
+
+sign_installer() {
+	log "Signing NSIS installer"
+	sign_file ${GEANY_PLUGINS_BUILD_DIR}/build/${GEANY_PLUGINS_INSTALLER_FILENAME}
+}
+
+
+test_installer() {
+	log "Test NSIS installer"
+	# perform a silent install and check for installed files
+	exiftool -FileName -FileType -FileVersion -FileVersionNumber ${GEANY_PLUGINS_BUILD_DIR}/build/${GEANY_PLUGINS_INSTALLER_FILENAME}
+	# install Geany-Plugins
+	mingw-w64-i686-wine ${GEANY_PLUGINS_BUILD_DIR}/build/${GEANY_PLUGINS_INSTALLER_FILENAME} /S /D=${GEANY_PLUGINS_INSTALLATION_DIR_WIN}
+	# check if we have something installed
+	ls -l ${GEANY_PLUGINS_INSTALLATION_DIR}/uninst-plugins.exe || exit 1
+	ls -l ${GEANY_PLUGINS_INSTALLATION_DIR}/lib/geany/addons.dll || exit 1
+}
+
+
+test_uninstaller() {
+	log "Test NSIS uninstaller"
+	# uninstall Geany-Plugins and test if everything is clean
+	mingw-w64-i686-wine ${GEANY_PLUGINS_INSTALLATION_DIR}/uninst-plugins.exe /S
+	sleep 15  # it seems the uninstaller returns earlier than the files are actually removed, so wait a moment
+	rest=$(find ${GEANY_PLUGINS_INSTALLATION_DIR} \( -path '*share/locale' -o -path '*share/licenses' \) -prune -false -o -true -printf '%P ')
+	if [ "${rest}" != " share share/locale share/licenses " ]; then
+		# do not treat this as error, it might happen if upstream dependencies have been updated,
+		# the list of files to be removed needs to be updated only before releases
+		echo "WARNING: Uninstaller failed to uninstall the following files files: ${rest}"
+	fi
+}
+
+
+copy_installer_and_bundle() {
+	log "Copying NSIS installer and dependencies bundle"
+	cp ${GEANY_PLUGINS_BUILD_DIR}/build/${GEANY_PLUGINS_INSTALLER_FILENAME} ${OUTPUT_DIRECTORY}
+	cd ${DEPENDENCY_BUNDLE_DIR}
+	zip --quiet --recurse-paths ${OUTPUT_DIRECTORY}/geany_plugins_dependencies_bundle_$(date '+%Y%m%dT%H%M%S').zip *
+	cd /
+}
+
+
+main() {
+	git_clone_geany_plugins_if_necessary
+
+	parse_geany_plugins_version
+	log_environment
+	patch_version_information
+	install_dependencies
+	install_geany
+	build_geany_plugins
+	sign_geany_plugins_binaries
+	convert_text_files_to_crlf
+
+	create_dependencies_bundle
+	create_installer
+	sign_installer
+	copy_installer_and_bundle
+
+	test_installer
+	test_uninstaller
+
+	log "Done."
+}
+
+
+main


Modified: builders/scripts/update_debian_repositories.sh
49 lines changed, 49 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,49 @@
+#!/bin/bash
+#
+# Copyright 2022 The Geany contributors
+# License: GPLv2
+#
+# Create a Debian repository for the Debian distribution
+# requested in the environment variable ${DISTRO}.
+# The repository will be signed with the GnuPG key as found
+# in /gnupg (which must be provided from the caller).
+#
+# This script is meant to be run in a Docker container.
+#
+
+
+# codename -> suite mapping
+declare -A SUITES=([buster]=stable [sid]=unstable)
+
+# stop on errors
+set -e
+
+# cleanup
+rm -rf /repository/conf
+rm -rf /repository/db
+rm -rf /repository/dists
+rm -rf /repository/pool
+
+# create repository config
+mkdir /repository/conf
+cat << CONF > /repository/conf/distributions
+Codename: ${DISTRO}
+Suite: ${SUITES[${DISTRO}]}
+Components: main
+Architectures: amd64 source
+SignWith: ${GNUPG_KEYID}
+CONF
+
+# create repository
+reprepro --silent --gnupghome /gnupg -b /repository createsymlinks
+package_paths=`find /output -name '*.deb'`
+for package in ${package_paths}
+do
+    reprepro --silent --gnupghome /gnupg -b /repository includedeb ${DISTRO} ${package}
+done
+# add source packages
+dsc_paths=`find /output -name '*.dsc'`
+for dsc in ${dsc_paths}
+do
+    reprepro --silent --gnupghome /gnupg -b /repository includedsc ${DISTRO} ${dsc}
+done


Modified: builders/start_build.sh
271 lines changed, 271 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,271 @@
+#!/bin/bash
+#
+# Copyright 2022 The Geany contributors
+# License: GPLv2
+#
+# Run Debian and Windows build containers and start builds within.
+# The Docker image for the containers are rebuilt automatically
+# every 30 days to keep them up to date.
+#
+# This script has to be run outside of the containers.
+#
+# usage: start_build.sh [-d|--distro DISTRO] [-m|--mingw]
+#                       [-r|--rebuild-images]
+#  -d, --distro DISTRO     Build for target Debian DISTRO (e.g. "bullseye",
+#                          can be specified multiple times
+#  -g, --geany             Build Geany
+#  -h                      Show this help screen
+#  -l, --log-to-stdout     Log build output additionally to stdout
+#  -m, --mingw             Build for target Mingw-w64
+#  -p, --geany-plugins     Build Geany-Plugins
+#  -r, --rebuild-images    Rebuild Docker images before start building
+#                          (images are rebuilt automatically every 30 days)
+
+
+DOCKER_IMAGE_MAX_AGE_DAYS=30
+# GNUPG config for the Debian repository, path and key must exist on the local machine
+GNUPG_HOME=${GNUPG_HOME:-~/.gnupg}
+GNUPG_KEYID=${GNUPG_KEYID:-0EE5B5AD}
+
+BASE_OUTPUT_DIRECTORY="${PWD}/output/"
+DOCKER_CMD="docker"
+GEANY_SOURCE=
+GEANY_PLUGINS_SOURCE=
+
+# stop on errors
+set -e
+
+
+log() {
+	log_filename="$1"
+	shift
+	if [ "${log_filename}" = "-" ]; then
+		echo "========== $(date '+%Y-%m-%d %H:%M:%S %Z') $@ =========="
+	else
+		if [ -n "${DO_LOG_TO_STDOUT}" ]; then
+			$@ 2>&1 | tee "${log_filename}"
+		else
+			$@ > "${log_filename}" 2>&1
+		fi
+	fi
+}
+
+
+rebuild_image() {
+	image_name="$1"
+	dockerfile="$2"
+	build_args="$3"
+	# query image created date or use 0 if the image does not exist to trigger a build
+	image_date=$(${DOCKER_CMD} image inspect --format='{{.Created}}' "${image_name}" 2>/dev/null || echo -n 1970-01-01)
+	image_date=$(echo "${image_date}" | xargs) # trim leading and trailing whitespace
+	image_date_seconds=$(date --date="${image_date}" "+%s")
+	expire_date_seconds=$(date --date="${DOCKER_IMAGE_MAX_AGE_DAYS} days ago" "+%s")
+	if [ "${image_date_seconds}" -lt "${expire_date_seconds}" ] || [ -n "${DO_IMAGE_REBUILD}" ]; then
+		log - "Building image ${image_name} (last build: ${image_date})"
+		log "${BASE_OUTPUT_DIRECTORY}/docker_image_build_${image_name}_$(date '+%Y_%m_%d_%H_%M_%S').log" \
+			${DOCKER_CMD} build \
+				--no-cache \
+				--file "${dockerfile}" \
+				--tag "${image_name}" \
+				${build_args} \
+				.
+	fi
+}
+
+
+build_for_debian_distro() {
+	distro=${1}
+	IMAGE_NAME_DEBIAN="geany-debian-${distro}"
+	OUTPUT_DIRECTORY=${BASE_OUTPUT_DIRECTORY}/${distro}
+	LOGFILE_GEANY=${OUTPUT_DIRECTORY}/build_debian_${distro}_geany_$(date '+%Y_%m_%d_%H_%M_%S').log
+	LOGFILE_GEANY_PLUGINS=${OUTPUT_DIRECTORY}/build_debian_${distro}_geany_plugins_$(date '+%Y_%m_%d_%H_%M_%S').log
+
+	mkdir -p "${OUTPUT_DIRECTORY}/geany" "${OUTPUT_DIRECTORY}/geany-plugins"
+
+	# (re)build Docker image
+	rebuild_image "${IMAGE_NAME_DEBIAN}" Dockerfile.debian "--build-arg BASE_IMAGE_NAME=debian:${distro}"
+
+	# build Geany
+	if [ -n "${DO_GEANY}" ]; then
+		log - "Building Geany for ${distro}"
+		log "${LOGFILE_GEANY}" \
+			${DOCKER_CMD} run \
+				--rm \
+				--env=GITHUB_PULL_REQUEST="${GITHUB_PULL_REQUEST}" \
+				--env=CI="${CI}" \
+				--volume "${PWD}/scripts:/scripts/" \
+				--volume "${OUTPUT_DIRECTORY}:/output/" \
+				--tmpfs /tmp:rw,exec,size=1024m \
+				"${IMAGE_NAME_DEBIAN}:latest" \
+				bash /scripts/build_debian_geany.sh
+	fi
+
+	# build Geany-Plugins
+	if [ -n "${DO_GEANY_PLUGINS}" ]; then
+		log - "Building Geany-Plugins for ${distro}"
+		log "${LOGFILE_GEANY_PLUGINS}" \
+			${DOCKER_CMD} run \
+				--rm \
+				--env=GITHUB_PULL_REQUEST="${GITHUB_PULL_REQUEST}" \
+				--env=CI="${CI}" \
+				--volume "${PWD}/scripts:/scripts/" \
+				--volume "${OUTPUT_DIRECTORY}:/output/" \
+				--tmpfs /tmp:rw,exec,size=1024m \
+				"${IMAGE_NAME_DEBIAN}:latest" \
+				bash /scripts/build_debian_geany_plugins.sh
+	fi
+
+	# build/update Debian repository
+	log - "Update Debian repository for ${distro}"
+	log "${OUTPUT_DIRECTORY}/build_debian_repository_$(date '+%Y_%m_%d_%H_%M_%S').log" \
+		${DOCKER_CMD} run \
+			--rm \
+			--env GNUPG_KEYID="${GNUPG_KEYID}" \
+			--env DISTRO="${distro}" \
+			--volume "${PWD}/scripts:/scripts/" \
+			--volume "${GNUPG_HOME}:/gnupg/" \
+			--volume "${OUTPUT_DIRECTORY}:/output/" \
+			--volume "${BASE_OUTPUT_DIRECTORY}/repositories/${distro}:/repository/" \
+			"${IMAGE_NAME_DEBIAN}:latest" \
+			bash /scripts/update_debian_repositories.sh
+}
+
+
+build_mingw() {
+	IMAGE_NAME_WINDOWS="geany-mingw"
+	MINGW_OUTPUT_DIRECTORY=${BASE_OUTPUT_DIRECTORY}/mingw
+	LOGFILE_MINGW_GEANY=${MINGW_OUTPUT_DIRECTORY}/build_mingw_geany_$(date '+%Y_%m_%d_%H_%M_%S').log
+	LOGFILE_MINGW_GEANY_PLUGINS=${MINGW_OUTPUT_DIRECTORY}/build_mingw_geany_plugins_$(date '+%Y_%m_%d_%H_%M_%S').log
+	mkdir -p "${MINGW_OUTPUT_DIRECTORY}"
+
+	# (re)build Docker image
+	rebuild_image ${IMAGE_NAME_WINDOWS} Dockerfile.mingw
+
+	# Build Geany
+	if [ -n "${DO_GEANY}" ]; then
+		log - "Building Geany for Windows"
+		if [ -n "${GEANY_SOURCE}" ]; then
+			source_volume="--volume \"${GEANY_SOURCE}:/geany-source/\":ro"
+		else
+			source_volume=
+		fi
+		log "${LOGFILE_MINGW_GEANY}" \
+			${DOCKER_CMD} run \
+				--rm \
+				--env=GITHUB_PULL_REQUEST="${GITHUB_PULL_REQUEST}" \
+				--env=CI="${CI}" \
+				${source_volume} \
+				--volume "${PWD}/scripts:/scripts/" \
+				--volume "${PWD}/certificates/:/certificates/" \
+				--volume "${MINGW_OUTPUT_DIRECTORY}:/output/" \
+				"${IMAGE_NAME_WINDOWS}:latest" \
+				bash /scripts/build_mingw_geany.sh
+	fi
+
+	# Build Geany-Plugins
+	if [ -n "${DO_GEANY_PLUGINS}" ]; then
+		log - "Building Geany-Plugins for Windows"
+		if [ -n "${GEANY_PLUGINS_SOURCE}" ]; then
+			source_volume="--volume \"${GEANY_PLUGINS_SOURCE}:/geany-plugins-source/\":ro"
+		else
+			source_volume=
+		fi
+		log "${LOGFILE_MINGW_GEANY_PLUGINS}" \
+			${DOCKER_CMD} run \
+				--rm \
+				--env=GITHUB_PULL_REQUEST="${GITHUB_PULL_REQUEST}" \
+				--env=CI="${CI}" \
+				${source_volume} \
+				--volume "${PWD}/scripts:/scripts/" \
+				--volume "${PWD}/certificates/:/certificates/" \
+				--volume "${MINGW_OUTPUT_DIRECTORY}:/output/" \
+				"${IMAGE_NAME_WINDOWS}:latest" \
+				bash /scripts/build_mingw_geany_plugins.sh
+	fi
+}
+
+
+usage() {
+	echo "usage: start_build.sh [-d|--distro DISTRO] [-m|--mingw]"
+	echo "                      [-r|--rebuild-images]"
+	echo " -d, --distro DISTRO     Build for target Debian DISTRO (e.g. \"bullseye\","
+	echo "                         can be specified multiple times"
+	echo " -g, --geany             Build Geany"
+	echo "--geany-source           Path to a Geany source directory (optional)"
+	echo "--geany-plugins-source   Path to a Geany-Plugins source directory (optional)"
+	echo " -h                      Show this help screen"
+	echo " -l, --log-to-stdout     Log build output additionally to stdout"
+	echo " -m, --mingw             Build for target Mingw-w64"
+	echo " -p, --geany-plugins     Build Geany-Plugins"
+	echo " -r, --rebuild-images    Rebuild Docker images before start building"
+	echo "                         (images are rebuilt automatically every ${DOCKER_IMAGE_MAX_AGE_DAYS} days)"
+	echo " -s, --sudo              Use \"sudo\" for Docker commands"
+	exit 1
+}
+
+
+parse_command_line_options() {
+	if [ $# -eq 0 ]; then
+		usage
+	fi
+	for opt in "$@"; do
+		case "$opt" in
+			-d|--distro)
+			DO_DISTRO="${DO_DISTRO} ${2}"
+			shift
+			shift
+			;;
+			-g|--geany)
+			DO_GEANY=1
+			shift
+			;;
+			-l|--log-to-stdout)
+			DO_LOG_TO_STDOUT=1
+			shift
+			;;
+			-m|--mingw)
+			DO_MINGW=1
+			shift
+			;;
+			-p|--geany-plugins)
+			DO_GEANY_PLUGINS=1
+			shift
+			;;
+			-r|--rebuild-images)
+			DO_IMAGE_REBUILD=1
+			shift
+			;;
+			-s|--sudo)
+			DOCKER_CMD="sudo docker"
+			shift
+			;;
+			-h|--help)
+			usage
+			;;
+		esac
+	done
+}
+
+
+DO_DISTRO=
+DO_MINGW=
+DO_IMAGE_REBUILD=
+DO_GEANY=
+DO_GEANY_PLUGINS=
+DO_LOG_TO_STDOUT=
+
+
+main() {
+	if [ -n "${DO_DISTRO}" ]; then
+		for distro in ${DO_DISTRO}; do
+			build_for_debian_distro "${distro}"
+		done
+	fi
+	if [ -n "${DO_MINGW}" ]; then
+		build_mingw
+	fi
+}
+
+
+parse_command_line_options $@
+main



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list