Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nightly and CI build scripts to create Windows installers #7

Merged
merged 1 commit into from Dec 4, 2022

Conversation

eht16
Copy link
Member

@eht16 eht16 commented Feb 6, 2022

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.

Even though the Debian part is not yet ready, the Windows part is working fine and I plan to use it for the nightly builds soon.
The ultimative plan is to use these scripts in the CI builds for Geany and Geany-Plugins and to provide the created installer files as artifacts to download, so developers and users can easily test master or even PR builds.

@kugel-
Copy link
Member

kugel- commented Sep 17, 2022

Wild!

Why is the mingw container not Arch Linux based such that pacman doesnt need to be compiled? I would also expect that other packages take less time to install.

Do I understand correctly that the Docker image is updated manually, and a PR on geany or G-P would download that pre-build image (or even use cached copies) instead of rolling the container every single time (including compiling pacman)?

Remark #1: Generally speaking I'm not a huge fan of docker but since that doesn't run on my machine it's probably OK :-)
Remark #2: I use arch linux on my machine. If you don't feel familiar enough with it I can maybe help you.

@eht16
Copy link
Member Author

eht16 commented Sep 18, 2022

Why is the mingw container not Arch Linux based such that pacman doesnt need to be compiled? I would also expect that other packages take less time to install.

Personal preference and the fact that most other CI resources are also Debian/Ubuntu based.
I don't know if it would make a difference in package installation speed. Why and does it matter if it is a few seconds faster or slower?
Furthermore, I'm not sure if ArchLinux's pre-compiled pacman can be used as is. The self-compiled variant uses a different path layout.

Do I understand correctly that the Docker image is updated manually, and a PR on geany or G-P would download that pre-build image (or even use cached copies) instead of rolling the container every single time (including compiling pacman)?

First, the current image available in the registry is built and uploaded by me manually.
As said in the G-P PR this is an open TODO.

A CI job will try to pull the image from the registry, due to current permissions settings this probably works only for jobs trigger from the repository itself (master builds and PRs created from the repository itself, not forks).

CI jobs which are triggered by a forked repository will not have access to the image in the registry and so fall back to build it on the fly.

In theory, we could push that on the fly built image into the registry. But I consider this too risky to open doors for malicious input.

I didn't make my mind up finally on how to deal with the proper image management:

  • Should we build it reguarly independent from the CI jobs?
  • Which repository handles updating the image, Geany or Geany-PLugins or Infrastructure?
  • Should we open the restrictions and allow access to the image also for forked repositories?

Remark #1: Generally speaking I'm not a huge fan of docker but since that doesn't run on my machine it's probably OK :-)

It took me a few years also to see its advantages and why it might be useful. I think in this it's a quite convenient tool to have a isolated environment to build the code.

Remark #2: I use arch linux on my machine. If you don't feel familiar enough with it I can maybe help you.

I used Arch Linux until a few months ago as well, but IMO this is no reason to use it here :). Again, I guess it won't make a relevant different except that we would have to port the existing scripts. I guess more people out there are already or can get familiar with a Debian/Ubuntu system.
Do you have any other reason for switching to ArchLinux?

# cleanup
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
yes | pacman -Scc && \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--noconfirm. yes doesn't terminate by itself which I is generally problematic IMO.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you did not test what you suggest?
--noconfirm does not clean the caches as the default for the question "Do you want to remove ALL files from cache? [y/N]" is no.

In this context yes seems to work as intended. Did you experience a certain problem?

# For more details, see build_mingw64_geany.sh where this image is used.
#
# Intermediate container for building pacman
FROM debian:bullseye as build-pacman
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is that an "intermediate container"? And what does this mean exactly, i.e. what's the advantage over building pacman in the main docker container?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The advantage is that everything necessary to build Pacman remains in the intermediate container and gets destroyed automatically once it is finished. Nothing from this container will remain in the final container except those items which you copy explicitly.
This is very common and convenient practice when building Docker images.
https://docs.docker.com/build/building/multi-stage/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good to know

@kugel-
Copy link
Member

kugel- commented Sep 19, 2022

I just thought it's a better match because it comes with pacman, but also because it is generally up-to-date w.r.t. to toolchains and wine. So we could build the Windows binaries using the latest and greatest toolchain.

Debian/Ubuntu is usually several years behind and I worry a bit if that might cause trouble in the future if mingw packages require a newer toolchain (mingw is also rolling like Arch AFAIK). But it's your choice.

I think the current restrictions are OK. Perhaps we could auto-update the image based on CI but I wouldn't trigger that from Geany repos but this repository (this is where the dockerfile is after all). Do we have anything to lose when giving forks access to the image, like losing some GH actions budget to it? Anyway we can discuss that later and leave it to official repos for now.

@kugel-
Copy link
Member

kugel- commented Sep 19, 2022

One more (personal) reason to use Arch: You know I'm working on a flatpak version of Geany. Assuming we ever want to create such a flatpak image for official releases via CI, then I would certainly prefer Arch Linux because that has the latest flatpak tooling.

But that doesn't necessarily mean mingw jobs must use Arch Linux containers as well, so still your choice.

@kugel-
Copy link
Member

kugel- commented Sep 19, 2022

I don't really like that this repository knows how to build Geany and G-P.

A developer might make changes in that area and might become unable to proceed because he can't get CI to work as the job needs to be adapted.

A realistic example: we might want to switch to the meson build by default (or maybe only for specific platforms) and the PR to implement would be unable to fix the CI.

We should probably just provide the Docker image itself and not the scripts to build Geany or packages.

@eht16
Copy link
Member Author

eht16 commented Sep 20, 2022

I just thought it's a better match because it comes with pacman, but also because it is generally up-to-date w.r.t. to toolchains and wine. So we could build the Windows binaries using the latest and greatest toolchain.

Debian/Ubuntu is usually several years behind and I worry a bit if that might cause trouble in the future if mingw packages require a newer toolchain (mingw is also rolling like Arch AFAIK). But it's your choice.

One more (personal) reason to use Arch: You know I'm working on a flatpak version of Geany. Assuming we ever want to create such a flatpak image for official releases via CI, then I would certainly prefer Arch Linux because that has the latest flatpak tooling.

But that doesn't necessarily mean mingw jobs must use Arch Linux containers as well, so still your choice.

I was working on these scripts since 2021 or maybe even 2020 and had no problems with the toolchains provided by Debian, AFAIR.
Of course, I cannot guarantee that it will keep it this way. But as previous long time ArchLinux user I also know sometimes ArchLinux is so bleeding edge that its toolchain or other components might be too new for other software which is not yet compatible.
So I guess this can happen in both directions.

And please stop this too old joke of Debian being "several years" behind. It's usually rather 1-2 years and this is on purpose.

After all, I guess Debian and ArchLinux could work as base and given that the current setup works with Debian, I personally see no need to change it.

I don't really like that this repository knows how to build Geany and G-P.

A developer might make changes in that area and might become unable to proceed because he can't get CI to work as the job needs to be adapted.

A realistic example: we might want to switch to the meson build by default (or maybe only for specific platforms) and the PR to implement would be unable to fix the CI.

We should probably just provide the Docker image itself and not the scripts to build Geany or packages.

Agreed. We could move builders/scripts/build_mingw64_geany_plugins.sh and its companions to the Geany resp. G-P repos.
Will try once I find time for it.

I guess I did it this way because the initial idea of all this started with renewing the nightly build scripts and over the time it turned out to be usable for CI builds as well.

I think the current restrictions are OK. Perhaps we could auto-update the image based on CI but I wouldn't trigger that from Geany repos but this repository (this is where the dockerfile is after all).

Sounds good to me.

Do we have anything to lose when giving forks access to the image, like losing some GH actions budget to it?

Not that I know of. To me it seems that GH actions are not billed at all for us and so there is also no budget or limit.
Giving read access to forks should be OK, even if it would be read access to the world. We should note that images cannot be deleted anymore once they have been made public which is reasonable and probably also acceptable for a automatically built CI image.

@eht16
Copy link
Member Author

eht16 commented Oct 16, 2022

I don't really like that this repository knows how to build Geany and G-P.
A developer might make changes in that area and might become unable to proceed because he can't get CI to work as the job needs to be adapted.
A realistic example: we might want to switch to the meson build by default (or maybe only for specific platforms) and the PR to implement would be unable to fix the CI.
We should probably just provide the Docker image itself and not the scripts to build Geany or packages.

Agreed. We could move builders/scripts/build_mingw64_geany_plugins.sh and its companions to the Geany resp. G-P repos. Will try once I find time for it.

Done.
The scripts to build Geany and Geany-Plugins are now in their respective repositories.
This required to create geany/geany#3315 but it was on my TODO anyway.

@eht16 eht16 marked this pull request as ready for review October 17, 2022 21:28
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" \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

geany-plugins-${GEANY_VERSION} ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks.

# For more details, see build_mingw64_geany.sh where this image is used.
#
# Intermediate container for building pacman
FROM debian:bullseye as build-pacman
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good to know

tar xf pacman-${PACMAN_VERSION}.tar.xz && \
cd /pacman-${PACMAN_VERSION} && \
meson \
--prefix /usr/local/pacman \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not set prefix to /usr/local in the first place? That would avoid having to create symlinks and potential binary-relocation issues in the future.

This is a fresh system container, /usr/local should contain nothing but the pacman installation afterwards.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to install applications into their own prefix if possible. But /usr/local should work as well.
Since the current setup works this way, I'd leave as is.

What do you mean by "potential binary-relocation issues in the future"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand. If you prefer the app-exclusive prefix, then why do you copy it to /usr/local/bin, afterwards?

It appears that pacman is run from /usr/local/bin/pacman, afterwards, yet its prefix is /usr/local/pacman. This can cause trouble if the pacman binary encodes the prefix (remember that Geany isn't relocatable by default either).

Really, I would prefer to define one prefix and then also run the program from there. Anything else is asking for trouble and is just adding confusion (I am confused). Then you don't need ln -s and LD_LIBRARY_PATH workarounds that I find in this file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whateveryou wish.
Pacman is now installed into /usr/local but setting LD_LIBRARY_PATH is still necessary or alternatively running ldconfig to manually update the ldcache.
This is because after installing Pacman with Meson, the ldcache is not updated automatically. So we still need to take care to update the ldcache.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you run ldconfig in the container?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, tried it in the first place. We would need to run it in the build container as well as in the final container (as we copy only the files in /usr/local from the one to the other but no state and cache).
I don't mind whether we set LD_LIBRARY_PATH as it is or run ldconfig.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My feeling: better update the cache properly than messing with LD_LIBRARY_PATH but I don't feel strong either.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, done.


# 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 && \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need to run hostname.exe twice?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once for wine-i686 and once for wine-x86_64. Both commands are only executed to setup the Wind environment initially for both architectures.
We need wine-x86_64 to run Geany itself and wine-i686 to execute the installer which can be built only for i686.

# install NSIS and exiftool to inspect binary metadata
nsis libimage-exiftool-perl osslsigncode \
# Geany build dependencies \
python3-lxml python3-docutils
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still uneasy that Geany dependencies are encoded in the infrastructure script. What happens if a PR in Geany adds new dependencies? How can that PR possibly proceed, without breaking CI?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See https://github.com/geany/geany-plugins/pull/1201/files#diff-306a1de5460f6947d8ee9383b366b8dcc6529fa5c4b18aa9523729d8456e3d0dR175 - this is the canonical place for installing necessary dependencies.

The list here is rather some sort of cache or pre-installation of what is done in each CI run to speed up the build process. If at CI job execution time newer package versions are available than at build time of the Docker image, the newer versions are used at CI job execution.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. I only looked at the geany build script and didn't see how it installs additional dependencies. This was my concern, that the infrastructure script must know about all dependencies. But that's not a problem then, great!

"gtk_version": "${GTK_VERSION}",
"gcc_version": "${COMPILER_VERSION}",
}
EOT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who uses versions.json?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing yet but it might become useful when using the scripts for nightly builds to fill the table on https://www.geany.org/download/nightly-builds/.

But I'm quite undecided yet how to proceed with the nightly builds exactly and the whole Debian package builds scripts are yet to be finalized. For now, I would like to focus on the mingw64 parts to get them integrated into the pipeline.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add such artifacts only when they became needed with a clear use case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are gone with the whole Debian code.

}


main
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of this file is identical to build_debian_geany.sh. Don't you think it would be worthwhile to share code instead of duplication?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was struggling with this as well.
However, consequently we should move the Debian build scripts to the Geany and G-P repositories as we did for the mingw64 scripts but then sharing the code between two repositories gets more complicated again.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above you said you would like to focus on the mingw-parts. Might be a good idea to leave the Debian parts out of this PR for now, then, and deal with that in a separate, follow-up PR. Then we can discuss the proper place.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I removed the Debian parts for now.



# codename -> suite mapping
declare -A SUITES=([buster]=stable [sid]=unstable)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buster -> bullseye

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated, thanks.

@eht16
Copy link
Member Author

eht16 commented Oct 23, 2022

I think the current restrictions are OK. Perhaps we could auto-update the image based on CI but I wouldn't trigger that from Geany repos but this repository (this is where the dockerfile is after all).

Sounds good to me.

I added a CI workflow on this repository to build the Docker image on push events and on a weekly schedule.
For now, the image is configured as private and so it can be used only from within the organization. In particular this means that pull requests for Geany or G-P which are created from a forked clone, cannot access the Docker image. For this, we need to make it public.
This should be ok but I would wait a bit until the new process works as expected. Once an image is made public, it cannot be deleted anymore.

tar xf pacman-${PACMAN_VERSION}.tar.xz && \
cd /pacman-${PACMAN_VERSION} && \
meson \
--prefix /usr/local/pacman \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand. If you prefer the app-exclusive prefix, then why do you copy it to /usr/local/bin, afterwards?

It appears that pacman is run from /usr/local/bin/pacman, afterwards, yet its prefix is /usr/local/pacman. This can cause trouble if the pacman binary encodes the prefix (remember that Geany isn't relocatable by default either).

Really, I would prefer to define one prefix and then also run the program from there. Anything else is asking for trouble and is just adding confusion (I am confused). Then you don't need ln -s and LD_LIBRARY_PATH workarounds that I find in this file.

# install NSIS and exiftool to inspect binary metadata
nsis libimage-exiftool-perl osslsigncode \
# Geany build dependencies \
python3-lxml python3-docutils
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. I only looked at the geany build script and didn't see how it installs additional dependencies. This was my concern, that the infrastructure script must know about all dependencies. But that's not a problem then, great!

"gtk_version": "${GTK_VERSION}",
"gcc_version": "${COMPILER_VERSION}",
}
EOT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add such artifacts only when they became needed with a clear use case.

}


main
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above you said you would like to focus on the mingw-parts. Might be a good idea to leave the Debian parts out of this PR for now, then, and deal with that in a separate, follow-up PR. Then we can discuss the proper place.

Copy link
Member

@kugel- kugel- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome

@eht16
Copy link
Member Author

eht16 commented Oct 27, 2022

@kugel- are you fine when I squash the commits together or do you still need the history?

@kugel-
Copy link
Member

kugel- commented Oct 28, 2022

Squashing is fine

@kugel-
Copy link
Member

kugel- commented Dec 2, 2022

Go for it? Or is anything missing?

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.
@eht16
Copy link
Member Author

eht16 commented Dec 4, 2022

I guess I was waiting for a final "ok" and then forgot about it.

Thanks for the review. I fixed a final typo and now it's going to be merged. Yay.

@eht16 eht16 merged commit 19139f3 into master Dec 4, 2022
@eht16 eht16 deleted the add_ci_builders branch December 4, 2022 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants