Skip to content

Commit

Permalink
Add nightly and CI build scripts to create Windows installers
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
eht16 committed Oct 29, 2022
1 parent f9b6e2d commit 3859e2c
Show file tree
Hide file tree
Showing 13 changed files with 576 additions and 1 deletion.
49 changes: 49 additions & 0 deletions .github/workflows/docker.yml
@@ -0,0 +1,49 @@
#
# Copyright: 2022, The Geany contributors
# License: GNU GPL v2 or later

name: Build CI Docker Images

on:
push:
branches:
- master
workflow_dispatch:
schedule:
# Run weekly on Friday
- cron: '34 5 * * FRI'

# cancel already running builds of the same branch or pull request
concurrency:
group: ci-${{ github.head_ref }} || concat(${{ github.ref }}
cancel-in-progress: true

jobs:
mingw64:
name: Build Docker image for mingw664 CI builds
runs-on: ubuntu-22.04
permissions:
packages: write

env:
DOCKER_REGISTRY: "ghcr.io"
DOCKER_IMAGE_NAME: "geany-mingw64-ci"
DOCKER_IMAGE_TAG: "ghcr.io/geany/geany-mingw64-ci:latest"

steps:
- name: Checkout Build Scripts
uses: actions/checkout@v3

- name: Log In To The Container Registry
uses: docker/login-action@v2
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build And Push Docker Image
run: |
cd builders
bash start_build.sh --log-to-stdout --mingw64 --rebuild-images
docker tag ${{ env.DOCKER_IMAGE_NAME }} ${{ env.DOCKER_IMAGE_TAG }}
docker push ${{ env.DOCKER_IMAGE_TAG }}
12 changes: 11 additions & 1 deletion README.md
Expand Up @@ -50,7 +50,17 @@ If you want to add or remove a repository maintained by these scripts, follow th
* Open http://git.geany.org/ in your browser and check whether the new repository is visible
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).


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).
5 changes: 5 additions & 0 deletions builders/.dockerignore
@@ -0,0 +1,5 @@
/.git
/certificates
/output
/scripts
/start_build.sh
119 changes: 119 additions & 0 deletions builders/Dockerfile.mingw64
@@ -0,0 +1,119 @@
#
# 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_mingw64_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~20220623-1-any.pkg.tar.zst"
ENV MSYS2_KEYRING_PKG_SHA256="3508c7fca2f8b9722139666459eb8716f2413fd6daaf997abf0df41d7f285dc9"

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 \
--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 && \
ldconfig

COPY mingw64/etc/ /windows/etc/

# setup pacman-key
RUN set -ex && \
# download MSYS2 keyring
mkdir -p /usr/local/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/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

LABEL org.opencontainers.image.title="Geany-Mingw-w64-CI"
LABEL org.opencontainers.image.description="Build image for Geany CI to support automatic building of Windows installers."
LABEL org.opencontainers.image.url="https://github.com/geany/infrastructure"
LABEL org.opencontainers.image.source="https://github.com/geany/infrastructure"
LABEL org.opencontainers.image.authors="The Geany contributors"
LABEL org.opencontainers.image.licenses="GPL-2.0"

# 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-w64 \
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 /usr/local
COPY mingw64/bin/ /usr/local/bin/
RUN mkdir /build

WORKDIR /build

# 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
ldconfig && \
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
102 changes: 102 additions & 0 deletions builders/README.md
@@ -0,0 +1,102 @@
CI / Nightly-Builders
=====================

## About

Scripts and Dockerfiles for Geany and Geany-Plugins nightly builds.
`start_build.sh` will create (if missing) a Docker image for
Mingw-w64 cross-compilaton to Windows.

## Scripts and files

├── Dockerfile.mingw64 -> Dockerfile for Mingw-64 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)
├── mingw64 -> 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
└── start_build.sh -> Run 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 [-m|--mingw64] [-r|--rebuild-images]
-f, --force-rebuild Force rebuilding of immages even if not necessary
-g, --geany Build Geany
--geany-script Path to the script to be executed to build Geany
--geany-source Path to a Geany source directory (optional, cloned from GIT if missing)
--geany-plugins-script Path to the script to be executed to build Geany-Plugins
--geany-plugins-source Path to a Geany-Plugins source directory (optional, cloned from GIT if missing)
-h Show this help screen
-l, --log-to-stdout Log build output additionally to stdout
-m, --mingw64 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)
-s, --sudo Use "sudo" for Docker commands


Example to build Geany and Geany-Plugins for Windows:

bash start_build.sh --geany --geany-plugins --mingw64

## Windows (Mingw64) 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 `scripts/ci_mingw64_geany.sh` and `build/ci_mingw64_geany_plugins.sh`
in the Geany resp. Geany-Plugins repository.

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.

A Github Action workflow is configured in this repository to build and push the image
to the Github Docker image registry as ghcr.io/geany/geany-mingw64-ci:latest. The workflow
is triggered once a week automatically.

### 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.
Empty file added builders/certificates/.gitkeep
Empty file.
4 changes: 4 additions & 0 deletions builders/mingw64/bin/mingw-w64-i686-wine
@@ -0,0 +1,4 @@
#!/bin/sh -e

WINEPATH="${WINEPATH};/windows/mingw32/bin" wine $@

3 changes: 3 additions & 0 deletions builders/mingw64/bin/mingw-w64-x86_64-wine
@@ -0,0 +1,3 @@
#!/bin/sh -e

WINEPATH="${WINEPATH};/windows/mingw64/bin" wine64 $@
40 changes: 40 additions & 0 deletions builders/mingw64/etc/pacman.conf
@@ -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
6 changes: 6 additions & 0 deletions builders/mingw64/etc/pacman.d/mirrorlist.mingw64
@@ -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
6 changes: 6 additions & 0 deletions builders/mingw64/etc/pacman.d/mirrorlist.msys
@@ -0,0 +1,6 @@
##
## MSYS repository mirrorlist
##

Server = http://repo.msys2.org/msys/$arch/
Server = http://www2.futureware.at/~nickoe/msys2-mirror/msys/$arch/
Empty file added builders/output/.gitkeep
Empty file.

0 comments on commit 3859e2c

Please sign in to comment.