public inbox for [email protected]
help / color / mirror / Atom feedHeads Up: cirrus-ci is shutting down June 1st
42+ messages / 18 participants
[nested] [flat]
* Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-09 20:55 Andres Freund <[email protected]>
0 siblings, 7 replies; 42+ messages in thread
From: Andres Freund @ 2026-04-09 20:55 UTC (permalink / raw)
To: pgsql-hackers
Hi,
As the subject says, cirrus-ci, which cfbot uses to run CI and that one can
(for now) enable on one's own repository, is shutting down.
https://cirruslabs.org/ burries the lede a bit, but it has further down:
"Cirrus CI will shut down effective Monday, June 1, 2026."
I can't say I'm terribly surprised, they had been moving a lot slower in the
last few years.
The shutdown window is pretty short, so we'll have to do something soon. Glad
that it didn't happen a few months ago, putting the shutdown before the
feature freeze. This is probably close to the least bad time it could happen
with a short window.
I think having cfbot and CI that one could run on ones own repository, without
sending a mail to the community, has improved the development process a lot.
So clearly we're going to have to do something. I certainly could not have
done stuff like AIO without it.
I'd be interested in feedback about how high folks value different aspects:
1) CI software can be self hosted
E.g. to prevent at least the cfbot case from being unpredictably abandoned
again.
2) CI software is open source
E.g. out of a principled stance, or control concerns.
3) CI runs quickly
This matters e.g. for accepting running in containers and whether it's
crucial to be able to have our images with everything pre-installed.
4) CI tests as many operating systems as possible
A lot of system just support linux, plenty support macos, some support
windows. Barely any support anything beyond that.
5) CI can be enabled on one's own repositories
Cfbot obviously allows everyone to test patches some way, but sending patch
sets to the list just to get a CI run obviously gets noisy quite fast.
There are plenty of open source CI solutions, but clearly it's not viable
for everyone to set that up for themselves. Plenty providers do allow doing
so, but the overlap of this, open source (2), multiple platforms (4) is
small if it exists.
6) There need to be free credits for running at least some CI on one's own
repository
This makes the overlapping constraints mentioned in 5) even smaller.
There are several platforms that do provide a decent amount of CI for a
monthly charge of < 10 USD.
7) Provide CI compute for "well known contributors" for free in their own
repositories
An alternative to 6) - with some CI solutions - can be to add folks to some
team that allows them to use community resources (which so far have been
donated). The problem with that is that it's administratively annoying,
because one does need to be careful, or CI will be used to do
cryptocurrency mining or such within a few days.
For some context about how much CI we have been running, here's the daily
average for cfbot and postgres/postgres CI:
- 1464 core hours (full cores, not SMT), all CI jobs use 4 cores
- 396 core hours of which were windows (visible due to the licensing cost)
- 40 GB of artifacts
- 83 GB of artifacts downloaded externally
- doesn't include macos, which I can't track as easily, due to being self
hosted runners, rather than running on GCP, which provided the above numbers
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-09 23:29 Thomas Munro <[email protected]>
parent: Andres Freund <[email protected]>
6 siblings, 1 reply; 42+ messages in thread
From: Thomas Munro @ 2026-04-09 23:29 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: pgsql-hackers
On Fri, Apr 10, 2026 at 8:55 AM Andres Freund <[email protected]> wrote:
> 4) CI tests as many operating systems as possible
>
> A lot of system just support linux, plenty support macos, some support
> windows. Barely any support anything beyond that.
Nested virtualisation to the rescue?
https://github.com/cross-platform-actions/action
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-10 11:31 Jelte Fennema-Nio <[email protected]>
parent: Andres Freund <[email protected]>
6 siblings, 2 replies; 42+ messages in thread
From: Jelte Fennema-Nio @ 2026-04-10 11:31 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: pgsql-hackers
On Thu, 9 Apr 2026 at 22:55, Andres Freund <[email protected]> wrote:
> I'd be interested in feedback about how high folks value different aspects:
My thoughts below.
> 1) CI software can be self hosted
>
> E.g. to prevent at least the cfbot case from being unpredictably abandoned
> again.
Low, I personally don't want to manage self hosting it. Self-hosted
software can just as easily be abandoned. i.e. I'd expect GitHub
Actions to outlive underfunded open source CI software.
> 2) CI software is open source
>
> E.g. out of a principled stance, or control concerns.
I don't care
> 3) CI runs quickly
>
> This matters e.g. for accepting running in containers and whether it's
> crucial to be able to have our images with everything pre-installed.
Important. We should definitely be able to pre-install stuff for most
OSes. I think running stuff in containers would be fine.
> 4) CI tests as many operating systems as possible
I think we at minimum need linux+macos+windows. Windows is by far the
system that fails most often for me. BSDs would be good, but they
often tend to be fine if osx and linux work. Personally for me I think
on Cirrus The BSDs didn't meet the useful signal to flakiness noise
ratio (i.e. they tended to mostly break randomly for me).
> 5) CI can be enabled on one's own repositories
> ...
> 6) There need to be free credits for running at least some CI on one's own
> repository
> ...
> 7) Provide CI compute for "well known contributors" for free in their own
> repositories
I would say it's a hard requirement that people can run CI without
spamming the list. I don't think that necessarily has to be in
someone's own repository. e.g. having a way for committers to give
e.g. some limited number (e.g. 100) of CI hours to someone submitting
their first patch seems fairly low risk. If they continue contributing
they can receive a recurring number or unlimited access.
On Thu, 9 Apr 2026 at 22:55, Andres Freund <[email protected]> wrote:
>
> Hi,
>
> As the subject says, cirrus-ci, which cfbot uses to run CI and that one can
> (for now) enable on one's own repository, is shutting down.
>
> https://cirruslabs.org/ burries the lede a bit, but it has further down:
> "Cirrus CI will shut down effective Monday, June 1, 2026."
>
> I can't say I'm terribly surprised, they had been moving a lot slower in the
> last few years.
>
> The shutdown window is pretty short, so we'll have to do something soon. Glad
> that it didn't happen a few months ago, putting the shutdown before the
> feature freeze. This is probably close to the least bad time it could happen
> with a short window.
>
>
> I think having cfbot and CI that one could run on ones own repository, without
> sending a mail to the community, has improved the development process a lot.
> So clearly we're going to have to do something. I certainly could not have
> done stuff like AIO without it.
>
>
> I'd be interested in feedback about how high folks value different aspects:
>
> 1) CI software can be self hosted
>
> E.g. to prevent at least the cfbot case from being unpredictably abandoned
> again.
>
>
> 2) CI software is open source
>
> E.g. out of a principled stance, or control concerns.
>
>
> 3) CI runs quickly
>
> This matters e.g. for accepting running in containers and whether it's
> crucial to be able to have our images with everything pre-installed.
>
>
> 4) CI tests as many operating systems as possible
>
> A lot of system just support linux, plenty support macos, some support
> windows. Barely any support anything beyond that.
>
>
> 5) CI can be enabled on one's own repositories
>
> Cfbot obviously allows everyone to test patches some way, but sending patch
> sets to the list just to get a CI run obviously gets noisy quite fast.
>
> There are plenty of open source CI solutions, but clearly it's not viable
> for everyone to set that up for themselves. Plenty providers do allow doing
> so, but the overlap of this, open source (2), multiple platforms (4) is
> small if it exists.
>
>
> 6) There need to be free credits for running at least some CI on one's own
> repository
>
> This makes the overlapping constraints mentioned in 5) even smaller.
>
> There are several platforms that do provide a decent amount of CI for a
> monthly charge of < 10 USD.
>
>
> 7) Provide CI compute for "well known contributors" for free in their own
> repositories
>
> An alternative to 6) - with some CI solutions - can be to add folks to some
> team that allows them to use community resources (which so far have been
> donated). The problem with that is that it's administratively annoying,
> because one does need to be careful, or CI will be used to do
> cryptocurrency mining or such within a few days.
>
>
> For some context about how much CI we have been running, here's the daily
> average for cfbot and postgres/postgres CI:
>
> - 1464 core hours (full cores, not SMT), all CI jobs use 4 cores
>
> - 396 core hours of which were windows (visible due to the licensing cost)
>
> - 40 GB of artifacts
>
> - 83 GB of artifacts downloaded externally
>
> - doesn't include macos, which I can't track as easily, due to being self
> hosted runners, rather than running on GCP, which provided the above numbers
>
>
> Greetings,
>
> Andres Freund
>
>
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-10 11:51 Nazir Bilal Yavuz <[email protected]>
parent: Jelte Fennema-Nio <[email protected]>
1 sibling, 0 replies; 42+ messages in thread
From: Nazir Bilal Yavuz @ 2026-04-10 11:51 UTC (permalink / raw)
To: Jelte Fennema-Nio <[email protected]>; +Cc: Andres Freund <[email protected]>; pgsql-hackers
Hi,
On Fri, 10 Apr 2026 at 14:31, Jelte Fennema-Nio <[email protected]> wrote:
>
> On Thu, 9 Apr 2026 at 22:55, Andres Freund <[email protected]> wrote:
> > I'd be interested in feedback about how high folks value different aspects:
>
> My thoughts below.
I agree with all of Jelte's points except:
> > 4) CI tests as many operating systems as possible
>
> I think we at minimum need linux+macos+windows. Windows is by far the
> system that fails most often for me. BSDs would be good, but they
> often tend to be fine if osx and linux work. Personally for me I think
> on Cirrus The BSDs didn't meet the useful signal to flakiness noise
> ratio (i.e. they tended to mostly break randomly for me).
I think BSDs are quite capable of catching issues that others can't
catch. That has at least been my experience with OpenBSD.
However, I agree that OpenBSD and NetBSD tasks are flaky; I think that
is mostly because we generate these VM images from scratch (i.e. other
operating systems' VM images were already available on GCP). I don't
think FreeBSD is flaky.
--
Regards,
Nazir Bilal Yavuz
Microsoft
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-10 12:23 Alexander Korotkov <[email protected]>
parent: Andres Freund <[email protected]>
6 siblings, 1 reply; 42+ messages in thread
From: Alexander Korotkov @ 2026-04-10 12:23 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: pgsql-hackers
Hi!
On Thu, Apr 9, 2026 at 11:55 PM Andres Freund <[email protected]> wrote:
>
> As the subject says, cirrus-ci, which cfbot uses to run CI and that one can
> (for now) enable on one's own repository, is shutting down.
>
> https://cirruslabs.org/ burries the lede a bit, but it has further down:
> "Cirrus CI will shut down effective Monday, June 1, 2026."
>
> I can't say I'm terribly surprised, they had been moving a lot slower in the
> last few years.
>
> The shutdown window is pretty short, so we'll have to do something soon. Glad
> that it didn't happen a few months ago, putting the shutdown before the
> feature freeze. This is probably close to the least bad time it could happen
> with a short window.
+1
>
> I think having cfbot and CI that one could run on ones own repository, without
> sending a mail to the community, has improved the development process a lot.
> So clearly we're going to have to do something. I certainly could not have
> done stuff like AIO without it.
>
>
> I'd be interested in feedback about how high folks value different aspects:
>
> 1) CI software can be self hosted
>
> E.g. to prevent at least the cfbot case from being unpredictably abandoned
> again.
>
>
> 2) CI software is open source
>
> E.g. out of a principled stance, or control concerns.
>
>
> 3) CI runs quickly
>
> This matters e.g. for accepting running in containers and whether it's
> crucial to be able to have our images with everything pre-installed.
>
>
> 4) CI tests as many operating systems as possible
>
> A lot of system just support linux, plenty support macos, some support
> windows. Barely any support anything beyond that.
>
>
> 5) CI can be enabled on one's own repositories
>
> Cfbot obviously allows everyone to test patches some way, but sending patch
> sets to the list just to get a CI run obviously gets noisy quite fast.
>
> There are plenty of open source CI solutions, but clearly it's not viable
> for everyone to set that up for themselves. Plenty providers do allow doing
> so, but the overlap of this, open source (2), multiple platforms (4) is
> small if it exists.
>
>
> 6) There need to be free credits for running at least some CI on one's own
> repository
>
> This makes the overlapping constraints mentioned in 5) even smaller.
>
> There are several platforms that do provide a decent amount of CI for a
> monthly charge of < 10 USD.
>
>
> 7) Provide CI compute for "well known contributors" for free in their own
> repositories
>
> An alternative to 6) - with some CI solutions - can be to add folks to some
> team that allows them to use community resources (which so far have been
> donated). The problem with that is that it's administratively annoying,
> because one does need to be careful, or CI will be used to do
> cryptocurrency mining or such within a few days.
It's hard for me to judge priorities, but I have a proposal on how we
can try to handle this.
Migrate to Open Source CI software, and run it on (cheap) cloud + get
sponsorship to cover the migration cost. This should protect us from
disasters like this. In worst case we would need to loop for
different cloud or different sponsor.
Provide CI workflow for GIthub Actions on our repository. This
wouldn't provide the plurality of platforms that we have now, but at
least everybody can get some basic CI coverage for free.
What do you think?
------
Regards,
Alexander Korotkov
Supabase
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-10 12:24 Alexander Korotkov <[email protected]>
parent: Alexander Korotkov <[email protected]>
0 siblings, 0 replies; 42+ messages in thread
From: Alexander Korotkov @ 2026-04-10 12:24 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: pgsql-hackers
On Fri, Apr 10, 2026 at 3:23 PM Alexander Korotkov <[email protected]> wrote:
> On Thu, Apr 9, 2026 at 11:55 PM Andres Freund <[email protected]> wrote:
> >
> > As the subject says, cirrus-ci, which cfbot uses to run CI and that one can
> > (for now) enable on one's own repository, is shutting down.
> >
> > https://cirruslabs.org/ burries the lede a bit, but it has further down:
> > "Cirrus CI will shut down effective Monday, June 1, 2026."
> >
> > I can't say I'm terribly surprised, they had been moving a lot slower in the
> > last few years.
> >
> > The shutdown window is pretty short, so we'll have to do something soon. Glad
> > that it didn't happen a few months ago, putting the shutdown before the
> > feature freeze. This is probably close to the least bad time it could happen
> > with a short window.
>
>
> +1
>
> >
> > I think having cfbot and CI that one could run on ones own repository, without
> > sending a mail to the community, has improved the development process a lot.
> > So clearly we're going to have to do something. I certainly could not have
> > done stuff like AIO without it.
> >
> >
> > I'd be interested in feedback about how high folks value different aspects:
> >
> > 1) CI software can be self hosted
> >
> > E.g. to prevent at least the cfbot case from being unpredictably abandoned
> > again.
> >
> >
> > 2) CI software is open source
> >
> > E.g. out of a principled stance, or control concerns.
> >
> >
> > 3) CI runs quickly
> >
> > This matters e.g. for accepting running in containers and whether it's
> > crucial to be able to have our images with everything pre-installed.
> >
> >
> > 4) CI tests as many operating systems as possible
> >
> > A lot of system just support linux, plenty support macos, some support
> > windows. Barely any support anything beyond that.
> >
> >
> > 5) CI can be enabled on one's own repositories
> >
> > Cfbot obviously allows everyone to test patches some way, but sending patch
> > sets to the list just to get a CI run obviously gets noisy quite fast.
> >
> > There are plenty of open source CI solutions, but clearly it's not viable
> > for everyone to set that up for themselves. Plenty providers do allow doing
> > so, but the overlap of this, open source (2), multiple platforms (4) is
> > small if it exists.
> >
> >
> > 6) There need to be free credits for running at least some CI on one's own
> > repository
> >
> > This makes the overlapping constraints mentioned in 5) even smaller.
> >
> > There are several platforms that do provide a decent amount of CI for a
> > monthly charge of < 10 USD.
> >
> >
> > 7) Provide CI compute for "well known contributors" for free in their own
> > repositories
> >
> > An alternative to 6) - with some CI solutions - can be to add folks to some
> > team that allows them to use community resources (which so far have been
> > donated). The problem with that is that it's administratively annoying,
> > because one does need to be careful, or CI will be used to do
> > cryptocurrency mining or such within a few days.
>
> It's hard for me to judge priorities, but I have a proposal on how we
> can try to handle this.
>
> Migrate to Open Source CI software, and run it on (cheap) cloud + get
> sponsorship to cover the migration cost.
Sorry, I meant sponsorship to cover the cloud cost.
------
Regards,
Alexander Korotkov
Supabase
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-10 13:05 Peter Eisentraut <[email protected]>
parent: Andres Freund <[email protected]>
6 siblings, 0 replies; 42+ messages in thread
From: Peter Eisentraut @ 2026-04-10 13:05 UTC (permalink / raw)
To: Andres Freund <[email protected]>; pgsql-hackers
On 09.04.26 22:55, Andres Freund wrote:
> I'd be interested in feedback about how high folks value different aspects:
>
> 1) CI software can be self hosted
>
> E.g. to prevent at least the cfbot case from being unpredictably abandoned
> again.
>
>
> 2) CI software is open source
>
> E.g. out of a principled stance, or control concerns.
I think we should work toward that in the long run. Open-source
software should also have an open-source (and distributed, and
privacy-respecting, and reusable, etc.) development process.
In the short run, meaning something that is plausible to get ready
between now and June/July, using some stopgap from an existing
established provider (such as GH actions) would probably be better.
> 3) CI runs quickly
>
> This matters e.g. for accepting running in containers and whether it's
> crucial to be able to have our images with everything pre-installed.
>
>
> 4) CI tests as many operating systems as possible
>
> A lot of system just support linux, plenty support macos, some support
> windows. Barely any support anything beyond that.
>
>
> 5) CI can be enabled on one's own repositories
>
> Cfbot obviously allows everyone to test patches some way, but sending patch
> sets to the list just to get a CI run obviously gets noisy quite fast.
>
> There are plenty of open source CI solutions, but clearly it's not viable
> for everyone to set that up for themselves. Plenty providers do allow doing
> so, but the overlap of this, open source (2), multiple platforms (4) is
> small if it exists.
This is the most important one, for me.
I think it would be even more useful if one could run the whole thing,
or most of the thing, locally. I mean, I can run all kinds of VMs
locally, all the pieces of this already exist. But it needs some
integration to build the images locally, and then run the build and test
processes in this images. This wouldn't cover everything (e.g., can't
virtualize macOS unless on macOS, IIRC), but I shouldn't really need to
push my code half-way around the world just to do a build run on NetBSD.
This could be someone's $season of code project.
> 7) Provide CI compute for "well known contributors" for free in their own
> repositories
>
> An alternative to 6) - with some CI solutions - can be to add folks to some
> team that allows them to use community resources (which so far have been
> donated). The problem with that is that it's administratively annoying,
> because one does need to be careful, or CI will be used to do
> cryptocurrency mining or such within a few days.
In a way, well known contributors can fend for themselves. We want to
get as many new or occasional contributors to run this so that the
patches build and test successfully before anyone else has to look at them.
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-10 13:27 Bruce Momjian <[email protected]>
parent: Jelte Fennema-Nio <[email protected]>
1 sibling, 0 replies; 42+ messages in thread
From: Bruce Momjian @ 2026-04-10 13:27 UTC (permalink / raw)
To: Jelte Fennema-Nio <[email protected]>; +Cc: Andres Freund <[email protected]>; pgsql-hackers
On Fri, Apr 10, 2026 at 01:31:38PM +0200, Jelte Fennema-Nio wrote:
> On Thu, 9 Apr 2026 at 22:55, Andres Freund <[email protected]> wrote:
> > I'd be interested in feedback about how high folks value different aspects:
>
> My thoughts below.
>
> > 1) CI software can be self hosted
> >
> > E.g. to prevent at least the cfbot case from being unpredictably abandoned
> > again.
>
> Low, I personally don't want to manage self hosting it. Self-hosted
> software can just as easily be abandoned. i.e. I'd expect GitHub
> Actions to outlive underfunded open source CI software.
Uh, I actually think the opposite. while proprietary software doesn't
disappear, it seems to become obsolete (underfunded development) or
prohibitively expensive sooner than open source. The dataase industry
has certainly shown that in the past 30 years. Also, four months ago
Github wanted to charge for self-hosted actions, which supports
"prohibitively expensive":
https://www.reddit.com/r/devops/comments/1po8hj5/github_actions_introducing_a_perminute_fee_for/
--
Bruce Momjian <[email protected]> https://momjian.us
EDB https://enterprisedb.com
Do not let urgent matters crowd out time for investment in the future.
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-13 08:34 Heikki Linnakangas <[email protected]>
parent: Andres Freund <[email protected]>
6 siblings, 1 reply; 42+ messages in thread
From: Heikki Linnakangas @ 2026-04-13 08:34 UTC (permalink / raw)
To: Andres Freund <[email protected]>; pgsql-hackers
On 09/04/2026 23:55, Andres Freund wrote:
> As the subject says, cirrus-ci, which cfbot uses to run CI and that one can
> (for now) enable on one's own repository, is shutting down.
>
> https://cirruslabs.org/ burries the lede a bit, but it has further down:
> "Cirrus CI will shut down effective Monday, June 1, 2026."
>
> I can't say I'm terribly surprised, they had been moving a lot slower in the
> last few years.
Darn, I liked Cirrus CI. One reason being precisely that it has been
stable, i.e. moved slowly, for years :-).
> I think having cfbot and CI that one could run on ones own repository, without
> sending a mail to the community, has improved the development process a lot.
> So clearly we're going to have to do something. I certainly could not have
> done stuff like AIO without it.
+1. I rely heavily on cirrus CI nowadays to validate before I push.
> I'd be interested in feedback about how high folks value different aspects:
>
> 1) CI software can be self hosted
>
> E.g. to prevent at least the cfbot case from being unpredictably abandoned
> again.
>
>
> 2) CI software is open source
>
> E.g. out of a principled stance, or control concerns.
These probably go together.
I think it's important that you can self-host. Even with cirrus-ci I
actually wished there was an easy way to run the jobs locally. I don't
know how often I'd really do it, but especially developing and testing
the ci yaml files is painful when you can't run it locally.
> 3) CI runs quickly
>
> This matters e.g. for accepting running in containers and whether it's
> crucial to be able to have our images with everything pre-installed.
Pretty important. "quickly" is pretty subjective though, I'm not sure
what number to put to it. Cirrus-CI has felt fast enough.
> 4) CI tests as many operating systems as possible
>
> A lot of system just support linux, plenty support macos, some support
> windows. Barely any support anything beyond that.
Windows support is pretty important as it's different enough from
others. Macos is definitely good to have too. For others, we have the
buildfarm.
> 5) CI can be enabled on one's own repositories
>
> Cfbot obviously allows everyone to test patches some way, but sending patch
> sets to the list just to get a CI run obviously gets noisy quite fast.
>
> There are plenty of open source CI solutions, but clearly it's not viable
> for everyone to set that up for themselves. Plenty providers do allow doing
> so, but the overlap of this, open source (2), multiple platforms (4) is
> small if it exists.
This is important. I run the CI as part of development on my own
branches all the time.
If it's easy to self-host, that might cover it.
> 6) There need to be free credits for running at least some CI on one's own
> repository
>
> This makes the overlapping constraints mentioned in 5) even smaller.
>
> There are several platforms that do provide a decent amount of CI for a
> monthly charge of < 10 USD.
Not important. For running on one's own repository, it's totally
reasonable that you pay for it yourself. Especially if you can self-host
for free.
> 7) Provide CI compute for "well known contributors" for free in their own
> repositories
>
> An alternative to 6) - with some CI solutions - can be to add folks to some
> team that allows them to use community resources (which so far have been
> donated). The problem with that is that it's administratively annoying,
> because one does need to be careful, or CI will be used to do
> cryptocurrency mining or such within a few days.
Not important. Active contributors can easily pay for what they use, or
self-host.
- Heikki
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-13 11:53 David Steele <[email protected]>
parent: Thomas Munro <[email protected]>
0 siblings, 1 reply; 42+ messages in thread
From: David Steele @ 2026-04-13 11:53 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; Andres Freund <[email protected]>; +Cc: pgsql-hackers
On 4/10/26 06:29, Thomas Munro wrote:
> On Fri, Apr 10, 2026 at 8:55 AM Andres Freund <[email protected]> wrote:
>> 4) CI tests as many operating systems as possible
>>
>> A lot of system just support linux, plenty support macos, some support
>> windows. Barely any support anything beyond that.
>
> Nested virtualisation to the rescue?
>
> https://github.com/cross-platform-actions/action
I used this to migrate our FreeBSD tests [1] and it worked out OK. The
only downside is it doesn't look like you can split out steps so all the
commands end up logged together.
Regards,
-David
[1]
https://github.com/pgbackrest/pgbackrest/blob/main/.github/workflows/test.yml#L148
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-13 14:34 David E. Wheeler <[email protected]>
parent: Heikki Linnakangas <[email protected]>
0 siblings, 0 replies; 42+ messages in thread
From: David E. Wheeler @ 2026-04-13 14:34 UTC (permalink / raw)
To: Heikki Linnakangas <[email protected]>; +Cc: Andres Freund <[email protected]>; pgsql-hackers
Hi,
I’ve started thinking about moving away from GitHub actions myself, and was wondering what else was out there that fulfills a bunch of these needs. Feedback I got and some brief research turned up Woodpecker CI[0]
[0]: https://woodpecker-ci.org/
On Apr 13, 2026, at 04:34, Heikki Linnakangas <[email protected]> wrote:
> These probably go together.
>
> I think it's important that you can self-host. Even with cirrus-ci I actually wished there was an easy way to run the jobs locally. I don't know how often I'd really do it, but especially developing and testing the ci yaml files is painful when you can't run it locally.
While Woodpecker promotes its Docker images, esp. for integration with Codeberg and other Forgejo services, it’s a Go app so compiles for quite a lot of platforms, and has a “local mode” in which, from what I understand, you can run it on whatever trusted hardware you’d like.
So if we have, say, a Mac Mini plus an arm and amd system capable of virtualizing Linux, BSD, etc., perhaps we’d be able to get the coverage we need and host the results in a self-hosted Woodpecker service?
As I say, I’ve just started to kind of cast about for alternatives, so don’t know a lot about it myself, but on the surface it looks promising.
Best,
David
Attachments:
[application/pgp-signature] signature.asc (833B, 2-signature.asc)
download
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-14 00:57 Thomas Munro <[email protected]>
parent: David Steele <[email protected]>
0 siblings, 0 replies; 42+ messages in thread
From: Thomas Munro @ 2026-04-14 00:57 UTC (permalink / raw)
To: David Steele <[email protected]>; +Cc: Andres Freund <[email protected]>; pgsql-hackers
On Mon, Apr 13, 2026 at 11:53 PM David Steele <[email protected]> wrote:
> On 4/10/26 06:29, Thomas Munro wrote:
> > Nested virtualisation to the rescue?
> >
> > https://github.com/cross-platform-actions/action
>
> I used this to migrate our FreeBSD tests [1] and it worked out OK. The
> only downside is it doesn't look like you can split out steps so all the
> commands end up logged together.
- name: Run Test
uses: cross-platform-actions/[email protected]
with:
operating_system: freebsd
version: ${{matrix.os.version}}
run: |
uname -a
sudo pkg update && sudo pkg upgrade -y libiconv && sudo
pkg install -y bash git postgresql-libpqxx pkgconf libxml2 gmake perl5
libyaml p5-YAML-LibYAML rsync meson
cd .. && perl ${GITHUB_WORKSPACE?}/test/test.pl --vm-max=2
--no-coverage --no-valgrind --module=command --test=backup
--test=info --test=archive-push
Nice!
I guess the problems with this are:
1. It has to install the packages every time because it's not yet
using a pre-prepared image.
2. It has no ccache memory.
3. It has lost all that user-friendly stuff like artefact
archival/browsing, core file debugging etc.
4. IIRC the log URLs are not "public", you have to have to be logged
into an account to view them.
(That 4th point was one of Cirrus's unique advantages at the time we
selected it. We wanted to be able to share URLs for discussion on the
mailing list without requiring everyone to be a GitHub user.)
Perhaps for point 1, we could publish fast-start qemu images for
Debian, FreeBSD, NetBSD, OpenBSD*. The pg-vm-images repo that Andres
and Bilal maintain currently uploads images to Google Cloud's image
repository where Cirrus VMs can boot from them, but it could instead
publish qemu images to our own public URLs. I'm picturing a bunch of
images available as
https://ci.postgresql.org/images/qemu/arm64/{freebsd-15,debian-13,...}-with-postgresql-dependencies.img.
The point of per-arch variants would be to match common hosts for fast
kernel hypervisor support, eg on a Mac you want arm64, though you
could still run amd64 slowly if you need to. Could even do ppc and
riscv with emulation.
Qemu images should hopefully be usable in many different environments:
1. We could run them locally with some one-button command, and also
have images you can log into and hack on if you want.
2. We could run all of them or just the license-encumbered ones on
public clouds (not through a CI service) with some one-button command,
if you have an account.
3. We could use them in people's private GitHub/GitLab/... accounts
as you showed, just add
image_url=https://ci.postgresql.org/images/qemu/....
4. Cfbot could do any of those things, not sure what would be best.
For the license-encumbered OSes, we could at least make disk images or
archives containing a MacPorts installation or
bunch-of-installed-libraries-for-Windows, but not including the OS.
Just mount/unpack as /opt or C:\pg-packages or whatever, I guess, if
you can figure out how to get a VM running ... somewhere. Perhaps
there is some way to make project-owned resources (MacMinis, Windows
VMs) available to our community too, but IDK how that would work.
Some random half-baked thoughts about the ccache, browsing, etc problems:
1. Local qemu: we could use overlay images so that your downloaded
copy of X-with-postgres-dependencies.img remains read-only. Create a
new empty overlay image for each clean run, and if you need to inspect
logs, core files, you can just log in before the next run wipes it.
2. Local qemu: we could mount a separate disk image as /cache that
survives between runs and can be wiped any time.
3. Public CI system like GitHub actions: I suppose we could run our
own ccache, artefact, log hosting service that it could push to...
that was something I already wondered about under Cirrus due to
various disk space and retention problems... but I'm quite hesitant to
get tangled up in running "public" services and unsure how you'd
control access.
I would at least like to think about trying to make cfbot
capitalism-proof. I may be underestimating the difficulty, but I keep
wondering if cfbot should at least be able to do everything itself,
with some combination of local qemu, qemu-on-project-Mac-fleet, and
public cloud VMs controlled directly. It doesn't really *need* to
depend on ephemeral venture capital-powered CI companies, it was just
nice to make it use the exact same CI setup as you could use for
yourself in your GitHub account. I'm imagining that it would still
push branches to GitHub, since that's a nice interface to browse code
on, and I suppose it might even be possible to publish our own
minimalist GitHub plugin that allows cfbot to push its green/red
result indicators to it since that's clearly something that external
providers can do (as well as pushing them to the commitfest UI as
now). But if you clicked them, you'd be taken to a really primitive
cfbot web interface where you could browse logs and artefacts retained
for N days. In other words, an extremely cut down and limited
"let's-make-our-own-CI" project, which doesn't have to tackle the much
harder "let's-make-our-own-semi-public-CI-platform" project. I like
the idea of at least having such a mode as an insurance policy anyway,
but I'm not sure what nitty gritty details might make it hard to pull
off... In this thought experiment, people could continue to work
separately on making personal CI work in various ways, GitHub, GitLab,
whatever else, and local, and all ways of doing it would be using the
same scripts and VM images.
* ... and AFAIK we could add illumos to the set if we wanted, in the
past a couple of us tried to get that going but ran into ... I think
it was driver problems? ... when using GCP VMs, but it definitely
works in qemu VMs as that cross-platform-actions project shows. Every
OS project makes sure it can boot in qemu. Even AIX can boot in qemu,
if you have a license.
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-17 18:50 Robert Haas <[email protected]>
parent: Andres Freund <[email protected]>
6 siblings, 1 reply; 42+ messages in thread
From: Robert Haas @ 2026-04-17 18:50 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: pgsql-hackers
On Thu, Apr 9, 2026 at 4:55 PM Andres Freund <[email protected]> wrote:
> I'd be interested in feedback about how high folks value different aspects:
>
> 1) CI software can be self hosted
> 2) CI software is open source
> 3) CI runs quickly
> 4) CI tests as many operating systems as possible
> 5) CI can be enabled on one's own repositories
> 6) There need to be free credits for running at least some CI on one's own
> repository
> 7) Provide CI compute for "well known contributors" for free in their own
> repositories
I think we need most of these things. CI has become an indispensable
development tool for most of us at this point. If (1) and (2) then (6)
and (7) are less necessary, and conversely. (5) seems pretty critical;
as long as I took to get CI set up on my own repo, I now use it
extensively. (4) is less critical: we could probably live with just
Linux and Windows in a pinch; adding MacOS and/or *BSD would be nicer.
> For some context about how much CI we have been running, here's the daily
> average for cfbot and postgres/postgres CI:
>
> - 1464 core hours (full cores, not SMT), all CI jobs use 4 cores
> - 396 core hours of which were windows (visible due to the licensing cost)
> - 40 GB of artifacts
> - 83 GB of artifacts downloaded externally
> - doesn't include macos, which I can't track as easily, due to being self
> hosted runners, rather than running on GCP, which provided the above numbers
I wonder if we should be looking to add more heuristics to the system
to try to reduce these numbers. For example, just browsing through the
cfbot queue, I found this:
heapam_tuple_complete_speculative : remove unnecessary tuple fetch
https://cirrus-ci.com/github/postgresql-cfbot/postgresql/cf%2F6613
This patch removes six lines of code and adds none. There are four
messages on the thread. We've done 14 complete CI runs. That might be
an extreme example, but I just don't know if repeatedly running CI on
small patches that aren't being actively updated is really what we
want to be doing.
--
Robert Haas
EDB: http://www.enterprisedb.com
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-17 21:41 Michael Paquier <[email protected]>
parent: Robert Haas <[email protected]>
0 siblings, 1 reply; 42+ messages in thread
From: Michael Paquier @ 2026-04-17 21:41 UTC (permalink / raw)
To: Robert Haas <[email protected]>; +Cc: Andres Freund <[email protected]>; pgsql-hackers
On Fri, Apr 17, 2026 at 02:50:53PM -0400, Robert Haas wrote:
> This patch removes six lines of code and adds none. There are four
> messages on the thread. We've done 14 complete CI runs. That might be
> an extreme example, but I just don't know if repeatedly running CI on
> small patches that aren't being actively updated is really what we
> want to be doing.
Yes, starting with a low threshold should have little impact. I
suspect that we could take it slow, say by testing much less patches
that have a max of N lines touched (20~50?), and shave in resource
usage. This would not change much how useful the information provided
is.
--
Michael
Attachments:
[application/pgp-signature] signature.asc (833B, 2-signature.asc)
download
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-17 21:48 Tom Lane <[email protected]>
parent: Michael Paquier <[email protected]>
0 siblings, 1 reply; 42+ messages in thread
From: Tom Lane @ 2026-04-17 21:48 UTC (permalink / raw)
To: Michael Paquier <[email protected]>; +Cc: Robert Haas <[email protected]>; Andres Freund <[email protected]>; pgsql-hackers
Michael Paquier <[email protected]> writes:
> On Fri, Apr 17, 2026 at 02:50:53PM -0400, Robert Haas wrote:
>> This patch removes six lines of code and adds none. There are four
>> messages on the thread. We've done 14 complete CI runs. That might be
>> an extreme example, but I just don't know if repeatedly running CI on
>> small patches that aren't being actively updated is really what we
>> want to be doing.
> Yes, starting with a low threshold should have little impact. I
> suspect that we could take it slow, say by testing much less patches
> that have a max of N lines touched (20~50?), and shave in resource
> usage. This would not change much how useful the information provided
> is.
I think running a test promptly after a new patch submission is
useful, even for small patches. I agree that the periodic re-tests
for bit-rot could be scaled back a lot.
regards, tom lane
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-04-18 02:19 Euler Taveira <[email protected]>
parent: Tom Lane <[email protected]>
0 siblings, 0 replies; 42+ messages in thread
From: Euler Taveira @ 2026-04-18 02:19 UTC (permalink / raw)
To: Tom Lane <[email protected]>; Michael Paquier <[email protected]>; +Cc: Robert Haas <[email protected]>; Andres Freund <[email protected]>; pgsql-hackers
On Fri, Apr 17, 2026, at 6:48 PM, Tom Lane wrote:
>
> I think running a test promptly after a new patch submission is
> useful, even for small patches. I agree that the periodic re-tests
> for bit-rot could be scaled back a lot.
>
That's my opinion too. This is particularly important for first-time
contributors that may not know about the Postgres development process. For
regular contributors, I expect that they have a CI setup and submit a new
version only after the patch passes CI in its own repository.
I'm not sure about restricting the CI runs to small patches. Although it is a
minority, there are small patches that has a big potential to break things.
Maybe an alternative to small and/or high-frequency patches is to not run them
automatically but have a mechanism to trigger them manually once detected. The
author or even one of the reviewers can trigger it.
--
Euler Taveira
EDB https://www.enterprisedb.com/
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-18 21:22 Jelte Fennema-Nio <[email protected]>
parent: Andres Freund <[email protected]>
6 siblings, 2 replies; 42+ messages in thread
From: Jelte Fennema-Nio @ 2026-05-18 21:22 UTC (permalink / raw)
To: Andres Freund <[email protected]>; Nazir Bilal Yavuz <[email protected]>; Thomas Munro <[email protected]>; +Cc: pgsql-hackers
On Thu, 9 Apr 2026 at 22:55, Andres Freund <[email protected]> wrote:
> https://cirruslabs.org/ burries the lede a bit, but it has further down:
> "Cirrus CI will shut down effective Monday, June 1, 2026."
June 1st is getting really close. *In less than two weeks we won't have
a working CI anymore*. Effectively that's probably one week of calendar
dev time that's left, because almost everyone is at PGConf.dev right
now.
So today I decided to take a stab at an initial GitHub Actions yaml
file, as that seemed like the only viable option within that timeline.
Note: Claude Code wrote this file entirely, following extensive
back-and-forth with me after repeatadly getting red builds due to some
differences between Cirrus and Github Actions.
But finally, I managed to get a green build for all systems that we
support on Cirrus CI!
IMPORTANT CONTEXT: I only did a cursory review of the workflow file that
Claude created. So there's probably still a bunch of cleanup to do, but
I at least wanted to share this initial base. I don't know if I'll have
any more time to work on this before June 1st. I have a newborn that's
taking up a lot of my spare time. So, I'd be very happy if someone else
wants to take this patch over and get it to a committable state.
A few things (apart from more extensive review) that I think should be
improved soon (but maybe not before the first commit):
1. io_uring support is disabled. I couldn't get it to work on the GitHub
Actions runners, I think it's disabled in the host kernel. @Andres
2. It's not using pre-built images at the moment, except for the Linux
docker images I think. So it re-downloads a bunch of dependencies for
every build for most OSes. @Bilal or @Andres
3. There's currently no integration with the CFBot or commitfest yet. @Thomas
P.S. This is not an attempt to decide on the proprietary vs self-hosted
opensource discussion. Self hosting might still be the best long-term
solution. I just don't realistically see that happening within two
weeks.
Attachments:
[text/x-patch] v1-0001-Add-GitHub-Actions-yaml-file.patch (54.5K, 2-v1-0001-Add-GitHub-Actions-yaml-file.patch)
download | inline diff:
From fbc590ffb520607f780a62f31d870a25d98896bd Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <[email protected]>
Date: Mon, 18 May 2026 10:56:20 +0200
Subject: [PATCH v1] Add GitHub Actions yaml file
Cirrus CI is shutting down. This is an initial attempt to get a GitHub
Actions CI working.
IMPORTANT NOTE: The workflow file has only received a very rough review
by me. A more detailed review should still be done.
---
.github/workflows/ci.yml | 1485 +++++++++++++++++++++
src/test/modules/test_aio/t/TestAio.pm | 10 +
src/test/perl/PostgreSQL/Test/Kerberos.pm | 8 +
3 files changed, 1503 insertions(+)
create mode 100644 .github/workflows/ci.yml
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000000..c86df1b66a7
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,1485 @@
+# GitHub Actions CI configuration for PostgreSQL.
+#
+# Ported from the Cirrus CI configuration (.cirrus.tasks.yml /
+# .cirrus.star). The SanityCheck job runs first and gates the more
+# expensive jobs; per-OS gating via the "ci-os-only:" commit-message tag
+# is implemented in the setup job below.
+#
+# NB: Different jobs intentionally test with different, non-default,
+# configurations, to increase the chance of catching problems. Each job
+# documents non-obvious choices in a "SPECIAL:" comment near the top.
+
+name: CI
+
+on:
+ push:
+
+# NB: intentionally NO workflow-level `concurrency:` block. The native
+# concurrency mechanism makes a new run wait for the previous one to fully
+# cancel before it starts — which on the BSD jobs can take a while. Instead
+# the `cancel-previous` job below fires a cancel API call asynchronously,
+# so the new run gets going immediately. On master and REL_*_STABLE the
+# cancel job is skipped, so every push runs to completion.
+
+env:
+ # The lower depth accelerates git clone. Use a bit of depth so that
+ # concurrent jobs and retrying older runs have a chance of working.
+ CLONE_DEPTH: 500
+
+ CCACHE_MAXSIZE: "250M"
+
+ # check target for the autoconf builds
+ CHECK: check-world
+ CHECKFLAGS: -Otarget
+ PROVE_FLAGS: --timer
+
+ # Build test dependencies as part of the build step, to see compiler
+ # errors/warnings in one place.
+ MBUILD_TARGET: all testprep
+ MTEST_ARGS: --print-errorlogs --no-rebuild -C build
+ PGCTLTIMEOUT: 120 # avoids spurious failures during parallel tests
+ PG_TEST_EXTRA: kerberos ldap ssl libpq_encryption load_balance oauth
+
+ # Shared meson config args (except for the SanityCheck job)
+ MESON_COMMON_PG_CONFIG_ARGS: -Dcassert=true -Dinjection_points=true
+
+ # Meson feature flags shared by all meson jobs except:
+ # SanityCheck: uses almost no dependencies
+ # Windows - VS: has fewer dependencies than listed here
+ # Linux: uses 'auto' feature option to test meson feature autodetection
+ MESON_COMMON_FEATURES: >-
+ -Dauto_features=disabled
+ -Dldap=enabled
+ -Dssl=openssl
+ -Dtap_tests=enabled
+ -Dplperl=enabled
+ -Dplpython=enabled
+ -Ddocs=enabled
+ -Dicu=enabled
+ -Dlibxml=enabled
+ -Dlibxslt=enabled
+ -Dlz4=enabled
+ -Dpltcl=enabled
+ -Dreadline=enabled
+ -Dzlib=enabled
+ -Dzstd=enabled
+
+ # Shared between the Linux meson/autoconf jobs and the CompilerWarnings job
+ LINUX_CONFIGURE_FEATURES: >-
+ --with-gssapi
+ --with-icu
+ --with-ldap
+ --with-libcurl
+ --with-libxml
+ --with-libxslt
+ --with-llvm
+ --with-lz4
+ --with-pam
+ --with-perl
+ --with-python
+ --with-selinux
+ --with-ssl=openssl
+ --with-systemd
+ --with-tcl --with-tclconfig=/usr/lib/tcl8.6/
+ --with-uuid=ossp
+ --with-zstd
+
+ # The docker image equivalent of the pg-ci-trixie GCE image used by the
+ # Cirrus config. Built by pg-vm-images (docker/linux_debian_ci).
+ LINUX_CI_IMAGE: us-docker.pkg.dev/pg-ci-images/ci/linux_debian_trixie_ci:latest
+
+
+jobs:
+ # Cancel any older in-progress runs of this workflow on the same branch.
+ # Skipped on master and the REL_*_STABLE release branches so every push
+ # there runs to completion.
+ cancel-previous:
+ name: Cancel previous runs
+ if: github.ref != 'refs/heads/master' && !startsWith(github.ref, 'refs/heads/REL_')
+ runs-on: ubuntu-latest
+ permissions:
+ actions: write
+ steps:
+ - name: Cancel
+ env:
+ GH_TOKEN: ${{ github.token }}
+ REPO: ${{ github.repository }}
+ run: |
+ gh run list \
+ -R "$REPO" \
+ --workflow="${{ github.workflow }}" \
+ --branch="${{ github.ref_name }}" \
+ --status=in_progress \
+ --json databaseId \
+ --jq '.[].databaseId' \
+ --limit 50 \
+ | while read -r id; do
+ if [ "$id" != "${{ github.run_id }}" ]; then
+ echo "Cancelling run $id"
+ gh run cancel "$id" -R "$REPO" || true
+ fi
+ done
+
+ # Parse "ci-os-only: ..." from the commit message and expose flags
+ # consumed by the per-OS job `if:` conditions. Equivalent to
+ # .cirrus.star::compute_environment_vars().
+ setup:
+ name: Determine enabled OSes
+ runs-on: ubuntu-latest
+ outputs:
+ linux: ${{ steps.os.outputs.linux }}
+ freebsd: ${{ steps.os.outputs.freebsd }}
+ netbsd: ${{ steps.os.outputs.netbsd }}
+ openbsd: ${{ steps.os.outputs.openbsd }}
+ macos: ${{ steps.os.outputs.macos }}
+ windows: ${{ steps.os.outputs.windows }}
+ mingw: ${{ steps.os.outputs.mingw }}
+ compilerwarnings: ${{ steps.os.outputs.compilerwarnings }}
+ sanitycheck: ${{ steps.os.outputs.sanitycheck }}
+ steps:
+ - id: os
+ env:
+ MSG: ${{ github.event.head_commit.message }}
+ shell: bash
+ run: |
+ set -e
+ all_os="linux freebsd netbsd openbsd macos windows mingw compilerwarnings sanitycheck"
+ if printf '%s\n' "$MSG" | grep -qE '^ci-os-only: '; then
+ sel=$(printf '%s\n' "$MSG" | grep -E '^ci-os-only: ' | head -1 | sed 's/^ci-os-only: //')
+ echo "ci-os-only selection: $sel"
+ else
+ sel="$all_os"
+ fi
+ for o in $all_os; do
+ if echo " $sel " | grep -qE "[ ,]$o[ ,]"; then
+ echo "$o=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "$o=false" >> "$GITHUB_OUTPUT"
+ fi
+ done
+ cat "$GITHUB_OUTPUT"
+
+ # SPECIAL:
+ # - Builds with --auto-features=disabled and thus almost no enabled
+ # dependencies
+ #
+ # To avoid unnecessarily spinning up a lot of VMs / containers for entirely
+ # broken commits, all other jobs depend on this one.
+ sanity-check:
+ name: SanityCheck
+ needs: setup
+ if: needs.setup.outputs.sanitycheck == 'true'
+ runs-on: ubuntu-latest
+ container:
+ image: us-docker.pkg.dev/pg-ci-images/ci/linux_debian_trixie_ci:latest
+ env:
+ BUILD_JOBS: 8
+ TEST_JOBS: 8
+ CCACHE_DIR: ${{ github.workspace }}/ccache_dir
+ # no options enabled, should be small
+ CCACHE_MAXSIZE: "150M"
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-sanitycheck-${{ github.run_id }}
+ restore-keys: ccache-sanitycheck-
+
+ - name: Prepare workspace
+ run: |
+ useradd -m postgres
+ chown -R postgres:postgres .
+ mkdir -p "$CCACHE_DIR"
+ chown -R postgres:postgres "$CCACHE_DIR"
+ echo '* - memlock 134217728' > /etc/security/limits.d/postgres.conf
+ # Can't change the container's kernel.core_pattern; the postgres
+ # user can't write to / normally. Make / writable.
+ chown root:postgres /
+ chmod g+rwx /
+
+ - name: Configure
+ run: |
+ su postgres <<-'EOF'
+ set -e
+ meson setup \
+ --buildtype=debug \
+ --auto-features=disabled \
+ -Ddefault_library=shared \
+ -Dtap_tests=enabled \
+ build
+ EOF
+
+ - name: Build
+ run: |
+ su postgres <<EOF
+ set -e
+ ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+ EOF
+
+ # Minimal set of tests: the main regression tests take too long for
+ # this purpose. A pg_regress style test and a tap test exercising
+ # both a frontend binary and the backend.
+ - name: Test
+ run: |
+ su postgres <<EOF
+ set -e
+ ulimit -c unlimited
+ meson test ${MTEST_ARGS} --suite setup
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS} \
+ cube/regress pg_ctl/001_start_stop
+ EOF
+
+ - name: Core backtraces
+ if: failure()
+ run: |
+ mkdir -m 770 /tmp/cores || true
+ find / -maxdepth 1 -type f -name 'core*' -exec mv '{}' /tmp/cores/ \; || true
+ src/tools/ci/cores_backtrace.sh linux /tmp/cores || true
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: sanitycheck-logs
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ if-no-files-found: ignore
+
+ # SPECIAL:
+ # - Uses address sanitizer (sanitizer failures are typically printed in
+ # the server log)
+ # - Configures postgres with a small segment size
+ linux-autoconf:
+ name: Linux - Debian Trixie - Autoconf
+ needs: [setup, sanity-check]
+ if: needs.setup.outputs.linux == 'true'
+ runs-on: ubuntu-latest
+ container:
+ image: us-docker.pkg.dev/pg-ci-images/ci/linux_debian_trixie_ci:latest
+ # Share the host PID + IPC namespaces. 017_shm.pl rapidly creates,
+ # kill9's, and restarts postgres; with the container's small PID
+ # space a new postgres can recycle the dead postmaster's PID before
+ # pg_ctl's postmaster.pid check notices, producing spurious "node X
+ # is already running" failures. SysV shm in the test also relies on
+ # host-like IPC behavior.
+ options: --pid=host --ipc=host
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ CCACHE_DIR: /tmp/ccache_dir
+ DEBUGINFOD_URLS: "https://debuginfod.debian.net"
+ SANITIZER_FLAGS: -fsanitize=address
+ # See Cirrus config for sanitizer option explanations.
+ UBSAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:verbosity=2
+ ASAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:detect_leaks=0:detect_stack_use_after_return=0
+ CFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=address
+ CXXFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=address
+ LDFLAGS: -fsanitize=address
+ CC: ccache gcc
+ CXX: ccache g++
+ PG_TEST_PG_COMBINEBACKUP_MODE: --copy-file-range
+ # See linux-meson for the rationale; same kernel/seccomp limitation
+ # applies in this job's container.
+ PG_TEST_SKIP_IO_URING: 1
+ TEMP_CONFIG: ${{ github.workspace }}/src/tools/ci/pg_ci_base.conf
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-linux-autoconf-${{ github.run_id }}
+ restore-keys: ccache-linux-autoconf-
+
+ - name: Prepare workspace
+ run: |
+ useradd -m postgres
+ chown -R postgres:postgres .
+ mkdir -p "$CCACHE_DIR"
+ chown -R postgres:postgres "$CCACHE_DIR"
+ echo '* - memlock 134217728' > /etc/security/limits.d/postgres.conf
+ mkdir -m 770 /tmp/cores
+ chown root:postgres /tmp/cores
+ sysctl kernel.core_pattern='/tmp/cores/%e-%s-%p.core' || true
+
+ # Hosts for the load balance test
+ cat >> /etc/hosts <<-EOF
+ 127.0.0.1 pg-loadbalancetest
+ 127.0.0.2 pg-loadbalancetest
+ 127.0.0.3 pg-loadbalancetest
+ EOF
+
+ # Use a very small, non-power-of-two segment size to exercise relation
+ # segment code that is otherwise nearly uncovered.
+ - name: Configure
+ run: |
+ su postgres <<EOF
+ set -e
+ ./configure \
+ --enable-cassert --enable-injection-points --enable-debug \
+ --enable-tap-tests --enable-nls \
+ --with-segsize-blocks=6 \
+ --with-libnuma \
+ --with-liburing \
+ \
+ ${LINUX_CONFIGURE_FEATURES} \
+ \
+ CLANG="ccache clang"
+ EOF
+
+ - name: Build
+ run: su postgres -c "make -s -j${BUILD_JOBS} world-bin"
+
+ - name: Test world
+ run: |
+ su postgres <<EOF
+ set -e
+ ulimit -c unlimited
+ make -s ${CHECK} ${CHECKFLAGS} PROVE_FLAGS="${PROVE_FLAGS}" -j${TEST_JOBS}
+ EOF
+
+ - name: Core backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh linux /tmp/cores || true
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: linux-autoconf-logs
+ path: |
+ **/*.log
+ **/*.diffs
+ **/regress_log_*
+ if-no-files-found: ignore
+
+ # SPECIAL:
+ # - Uses undefined behaviour and alignment sanitizers
+ # - Builds both 64-bit and 32-bit
+ # - Uses io_method=io_uring
+ # - Uses meson feature autodetection
+ linux-meson:
+ name: Linux - Debian Trixie - Meson
+ needs: [setup, sanity-check]
+ if: needs.setup.outputs.linux == 'true'
+ runs-on: ubuntu-latest
+ container:
+ image: us-docker.pkg.dev/pg-ci-images/ci/linux_debian_trixie_ci:latest
+ # See linux-autoconf for the rationale.
+ options: --pid=host --ipc=host
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ CCACHE_DIR: /tmp/ccache_dir
+ CCACHE_MAXSIZE: "400M" # two builds (32 + 64 bit)
+ DEBUGINFOD_URLS: "https://debuginfod.debian.net"
+ SANITIZER_FLAGS: -fsanitize=alignment,undefined
+ UBSAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:verbosity=2
+ ASAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:detect_leaks=0:detect_stack_use_after_return=0
+ CFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=alignment,undefined
+ CXXFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=alignment,undefined
+ LDFLAGS: -fsanitize=alignment,undefined
+ CC: ccache gcc
+ CXX: ccache g++
+ # GitHub-hosted runners block io_uring_setup at the syscall layer
+ # (EPERM) even when the kernel.io_uring_disabled sysctl reads as 0
+ # inside the container. Force AIO tests to skip the io_uring matrix
+ # entry. io_uring is still built (-Dauto_features picks up liburing),
+ # just not exercised at runtime.
+ PG_TEST_SKIP_IO_URING: 1
+ TEMP_CONFIG: ${{ github.workspace }}/src/tools/ci/pg_ci_base.conf
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-linux-meson-${{ github.run_id }}
+ restore-keys: ccache-linux-meson-
+
+ - name: Prepare workspace
+ run: |
+ useradd -m postgres
+ chown -R postgres:postgres .
+ mkdir -p "$CCACHE_DIR"
+ chown -R postgres:postgres "$CCACHE_DIR"
+ echo '* - memlock 134217728' > /etc/security/limits.d/postgres.conf
+ mkdir -m 770 /tmp/cores
+ chown root:postgres /tmp/cores
+ sysctl kernel.core_pattern='/tmp/cores/%e-%s-%p.core' || true
+
+ cat >> /etc/hosts <<-EOF
+ 127.0.0.1 pg-loadbalancetest
+ 127.0.0.2 pg-loadbalancetest
+ 127.0.0.3 pg-loadbalancetest
+ EOF
+
+ - name: Configure (64-bit)
+ run: |
+ su postgres <<EOF
+ set -e
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ --buildtype=debug \
+ -Duuid=e2fs -Dllvm=enabled \
+ build
+ EOF
+
+ # It's gotten rare to test 32-bit locally; do it in CI.
+ - name: Configure (32-bit)
+ run: |
+ su postgres <<EOF
+ set -e
+ export CC='ccache gcc -m32'
+ export CXX='ccache g++ -m32'
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ --buildtype=debug \
+ --pkg-config-path /usr/lib/i386-linux-gnu/pkgconfig/ \
+ -DPERL=perl5.40-i386-linux-gnu \
+ -Duuid=e2fs -Dlibnuma=disabled \
+ build-32
+ EOF
+
+ - name: Build (64-bit)
+ run: |
+ su postgres <<EOF
+ set -e
+ ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+ ninja -C build -t missingdeps
+ EOF
+
+ - name: Build (32-bit)
+ run: |
+ su postgres <<EOF
+ set -e
+ ninja -C build-32 -j${BUILD_JOBS} ${MBUILD_TARGET}
+ ninja -C build-32 -t missingdeps
+ EOF
+
+ - name: Test world (64-bit)
+ run: |
+ su postgres <<EOF
+ set -e
+ ulimit -c unlimited
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+ EOF
+ # so that we don't upload 64-bit logs if 32-bit fails
+ rm -rf build/
+
+ # Provide some coverage of icu with LANG=C. Newer python insists on
+ # changing LC_CTYPE away from C; PYTHONCOERCECLOCALE=0 prevents that.
+ - name: Test world (32-bit)
+ run: |
+ su postgres <<EOF
+ set -e
+ ulimit -c unlimited
+ PYTHONCOERCECLOCALE=0 LANG=C meson test ${MTEST_ARGS} -C build-32 --num-processes ${TEST_JOBS}
+ EOF
+
+ - name: Core backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh linux /tmp/cores || true
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: linux-meson-logs
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ if-no-files-found: ignore
+
+ # SPECIAL:
+ # - Uses postgres-specific CPPFLAGS that increase test coverage
+ # - Configuration options that test reading/writing/copying of node trees
+ # - debug_parallel_query=regress to catch related issues during CI
+ # - Also runs tests against a running postgres (test_running step)
+ freebsd:
+ name: FreeBSD - Meson
+ needs: [setup, sanity-check]
+ if: needs.setup.outputs.freebsd == 'true'
+ runs-on: ubuntu-latest
+ timeout-minutes: 90
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ # Sits under $GITHUB_WORKSPACE so cross-platform-actions's rsync syncs
+ # it into the VM at the same absolute path, and back out at the end.
+ CCACHE_DIR: ${{ github.workspace }}/.ccache
+ CPPFLAGS: -DRELCACHE_FORCE_RELEASE -DENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
+ CFLAGS: -Og -ggdb
+ PG_TEST_INITDB_EXTRA_OPTS: >-
+ -c debug_copy_parse_plan_trees=on
+ -c debug_write_read_parse_plan_trees=on
+ -c debug_raw_expression_coverage_test=on
+ -c debug_parallel_query=regress
+ PG_TEST_PG_UPGRADE_MODE: --link
+ defaults:
+ run:
+ # After cross-platform-actions sets up the VM, subsequent `run:`
+ # steps execute inside the FreeBSD VM via cpa.sh.
+ shell: cpa.sh {0}
+ steps:
+ - name: Checkout (on runner)
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ # Restore ccache *before* booting the VM, so the runner-to-vm sync
+ # pulls the previous cache contents into the VM.
+ - name: Restore ccache
+ uses: actions/cache/restore@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-freebsd-${{ github.run_id }}
+ restore-keys: ccache-freebsd-
+
+ - name: Boot FreeBSD VM
+ uses: cross-platform-actions/[email protected]
+ with:
+ operating_system: freebsd
+ version: '14.3'
+ cpu_count: 4
+ memory: 8G
+ # Initial sync only. We push updated ccache contents back at the
+ # end of the job via a manual `cpa.sh --sync-files vm-to-runner`.
+ sync_files: runner-to-vm
+ shell: bash
+ # cross-platform-actions only forwards CI / GITHUB_* by default;
+ # list every job-level env var the VM scripts read.
+ environment_variables: >-
+ BUILD_JOBS TEST_JOBS CCACHE_DIR CCACHE_MAXSIZE
+ MBUILD_TARGET MTEST_ARGS PGCTLTIMEOUT PG_TEST_EXTRA
+ MESON_COMMON_PG_CONFIG_ARGS MESON_COMMON_FEATURES
+ CPPFLAGS CFLAGS CXXFLAGS LDFLAGS
+ PG_TEST_INITDB_EXTRA_OPTS PG_TEST_PG_UPGRADE_MODE
+
+ - name: Sysinfo
+ run: |
+ id
+ uname -a
+ ulimit -a -H && ulimit -a -S
+ env
+
+ # NB: intentionally no llvm. FreeBSD image size is large and even
+ # without llvm, FreeBSD is slower than other platforms except Windows.
+ - name: Install dependencies
+ run: |
+ sudo pkg update
+ sudo pkg install -y -g \
+ bash \
+ git-tiny \
+ gmake \
+ meson \
+ ninja \
+ perl5 \
+ pkgconf \
+ bison \
+ ccache4 \
+ flex \
+ gettext \
+ gnupg \
+ 'p5-IPC-Run' \
+ 'p5-Module-Signature' \
+ curl \
+ docbook-xml \
+ liblz4 \
+ libbacktrace \
+ libxml2 \
+ libxslt \
+ python3 \
+ 'py311-cryptography' \
+ 'py311-packaging' \
+ 'py311-pip' \
+ 'py311-pytest' \
+ readline \
+ tcl86 \
+ zstd \
+ krb5 \
+ openldap25-client \
+ openldap25-server
+
+ - name: Setup core files
+ run: |
+ sudo mkdir -m 770 /tmp/cores
+ sudo chown root:wheel /tmp/cores
+ sudo sysctl kern.corefile='/tmp/cores/%N.%P.core'
+
+ - name: Configure
+ run: |
+ set -e
+ export MESON_COMMON_FEATURES="${MESON_COMMON_FEATURES}"
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ --buildtype=debug \
+ -Dextra_lib_dirs=/usr/local/lib -Dextra_include_dirs=/usr/local/include/ \
+ ${MESON_COMMON_FEATURES} \
+ -Ddtrace=enabled \
+ -Dgssapi=enabled \
+ -Dlibcurl=enabled \
+ -Dnls=enabled \
+ -Dpam=enabled \
+ -Dtcl_version=tcl86 \
+ -Duuid=bsd \
+ build
+
+ - name: Build
+ run: ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+
+ - name: Test world
+ run: |
+ set -e
+ ulimit -c unlimited
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+
+ # Run tests against a running postgres. FreeBSD was chosen because it
+ # is currently fast enough.
+ - name: Test running
+ run: |
+ set -e
+ ulimit -c unlimited
+ meson test ${MTEST_ARGS} --quiet --suite setup
+ export LD_LIBRARY_PATH="$(pwd)/build/tmp_install/usr/local/pgsql/lib/:$LD_LIBRARY_PATH"
+ mkdir -p build/testrun
+ build/tmp_install/usr/local/pgsql/bin/initdb -N build/runningcheck --no-instructions -A trust
+ echo "include '$(pwd)/src/tools/ci/pg_ci_base.conf'" >> build/runningcheck/postgresql.conf
+ build/tmp_install/usr/local/pgsql/bin/pg_ctl -c -o '-c fsync=off' -D build/runningcheck -l build/testrun/runningcheck.log start
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS} --setup running
+ build/tmp_install/usr/local/pgsql/bin/pg_ctl -D build/runningcheck stop
+
+ - name: Stop running postgres on failure
+ if: failure()
+ run: |
+ build/tmp_install/usr/local/pgsql/bin/pg_ctl -D build/runningcheck stop || true
+
+ - name: Core backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh freebsd /tmp/cores || true
+
+ # Always sync VM -> runner so the updated ccache makes it back even
+ # when tests fail. The same sync also brings test logs back, so we
+ # no longer need a separate failure-only sync step.
+ - name: Sync VM back to runner
+ if: always()
+ run: cpa.sh --sync-files vm-to-runner
+ shell: bash
+
+ - name: Save ccache
+ if: always()
+ uses: actions/cache/save@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-freebsd-${{ github.run_id }}
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: freebsd-logs
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ if-no-files-found: ignore
+
+ netbsd:
+ name: NetBSD - Meson
+ needs: [setup, sanity-check]
+ if: needs.setup.outputs.netbsd == 'true'
+ runs-on: ubuntu-latest
+ timeout-minutes: 120
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ # See freebsd for the path choice.
+ CCACHE_DIR: ${{ github.workspace }}/.ccache
+ # initdb fails with: 'invalid locale settings' error on NetBSD.
+ # Force LANG / LC_* variables to C.
+ # See https://postgr.es/m/2490325.1734471752%40sss.pgh.pa.us
+ LANG: "C"
+ LC_ALL: "C"
+ PKGCONFIG_PATH: "/usr/lib/pkgconfig:/usr/pkg/lib/pkgconfig"
+ defaults:
+ run:
+ shell: cpa.sh {0}
+ steps:
+ - name: Checkout (on runner)
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Restore ccache
+ uses: actions/cache/restore@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-netbsd-${{ github.run_id }}
+ restore-keys: ccache-netbsd-
+
+ - name: Boot NetBSD VM
+ uses: cross-platform-actions/[email protected]
+ with:
+ operating_system: netbsd
+ version: '10.1'
+ cpu_count: 4
+ memory: 8G
+ sync_files: runner-to-vm
+ shell: bash
+ environment_variables: >-
+ BUILD_JOBS TEST_JOBS CCACHE_DIR CCACHE_MAXSIZE
+ MBUILD_TARGET MTEST_ARGS PGCTLTIMEOUT PG_TEST_EXTRA
+ MESON_COMMON_PG_CONFIG_ARGS MESON_COMMON_FEATURES
+ LANG LC_ALL PKGCONFIG_PATH
+
+ - name: Sysinfo
+ run: |
+ locale
+ id
+ uname -a
+ ulimit -a -H && ulimit -a -S
+ env
+
+ # NetBSD ships with very low SysV-semaphore limits. initdb hits
+ # SEMMNI right away ("could not create semaphores: No space left on
+ # device"). The pg-vm-images NetBSD packer image bumped these at
+ # boot via /etc/rc.local; replicate that here.
+ - name: Raise kernel limits
+ run: |
+ sudo sysctl -w kern.ipc.semmni=2048
+ sudo sysctl -w kern.ipc.semmns=32768
+
+ - name: Install dependencies
+ run: |
+ # NetBSD's default 'pkgin' might point at an outdated repo on the
+ # cross-platform-actions image. Set it to the live release branch.
+ set -e
+ rel=$(uname -r | cut -d. -f1,2)
+ arch=$(uname -m)
+ repo="https://cdn.netbsd.org/pub/pkgsrc/packages/NetBSD/$arch/${rel}/All"
+ echo "$repo" | sudo tee /usr/pkg/etc/pkgin/repositories.conf
+ sudo pkgin -y update
+ sudo pkgin -y install \
+ git gmake gettext meson bison ccache docbook-xml gnupg \
+ 'p5-IPC-Run' 'p5-Module-Signature' flex pkgconf \
+ python312 'py312-cryptography' 'py312-packaging' 'py312-pip' \
+ 'py312-test' icu lz4 libxslt mit-krb5 tcl zstd
+
+ # -Duuid=bsd is not set since 'bsd' uuid is broken on NetBSD/OpenBSD.
+ # See https://www.postgresql.org/message-id/[email protected]
+ - name: Configure
+ run: |
+ set -e
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ --buildtype=debugoptimized \
+ --pkg-config-path ${PKGCONFIG_PATH} \
+ ${MESON_COMMON_FEATURES} \
+ -Dgssapi=enabled \
+ -Dlibcurl=enabled \
+ -Dnls=enabled \
+ -Dpam=enabled \
+ build
+
+ - name: Build
+ run: ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+
+ - name: Test world
+ run: |
+ set -e
+ ulimit -c unlimited
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+
+ - name: Core backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh netbsd /var/crash || true
+
+ - name: Sync VM back to runner
+ if: always()
+ run: cpa.sh --sync-files vm-to-runner
+ shell: bash
+
+ - name: Save ccache
+ if: always()
+ uses: actions/cache/save@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-netbsd-${{ github.run_id }}
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: netbsd-logs
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ if-no-files-found: ignore
+
+ openbsd:
+ name: OpenBSD - Meson
+ needs: [setup, sanity-check]
+ if: needs.setup.outputs.openbsd == 'true'
+ runs-on: ubuntu-latest
+ timeout-minutes: 120
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ # See freebsd for the path choice.
+ CCACHE_DIR: ${{ github.workspace }}/.ccache
+ PKGCONFIG_PATH: "/usr/lib/pkgconfig:/usr/local/lib/pkgconfig"
+ defaults:
+ run:
+ shell: cpa.sh {0}
+ steps:
+ - name: Checkout (on runner)
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Restore ccache
+ uses: actions/cache/restore@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-openbsd-${{ github.run_id }}
+ restore-keys: ccache-openbsd-
+
+ - name: Boot OpenBSD VM
+ uses: cross-platform-actions/[email protected]
+ with:
+ operating_system: openbsd
+ version: '7.7'
+ cpu_count: 4
+ memory: 8G
+ sync_files: runner-to-vm
+ shell: bash
+ environment_variables: >-
+ BUILD_JOBS TEST_JOBS CCACHE_DIR CCACHE_MAXSIZE
+ MBUILD_TARGET MTEST_ARGS PGCTLTIMEOUT PG_TEST_EXTRA
+ MESON_COMMON_PG_CONFIG_ARGS MESON_COMMON_FEATURES
+ PKGCONFIG_PATH
+
+ - name: Sysinfo
+ run: |
+ locale
+ id
+ uname -a
+ ulimit -a -H && ulimit -a -S
+ env
+
+ # OpenBSD also ships with low SysV-semaphore limits / per-user
+ # process limits. Mirror what pg-vm-images set in /etc/rc.local.
+ - name: Raise kernel limits
+ run: |
+ sudo sysctl kern.seminfo.semmni=2048
+ sudo sysctl kern.seminfo.semmns=32768
+ sudo sysctl kern.maxfiles=10000
+
+ - name: Install dependencies
+ run: |
+ sudo pkg_add -I \
+ git \
+ bash \
+ gmake \
+ meson \
+ pkgconf \
+ bison \
+ ccache \
+ gettext-tools \
+ gnupg \
+ 'p5-IPC-Run' \
+ 'p5-Module-Signature' \
+ docbook \
+ icu4c \
+ libxml \
+ libxslt \
+ lz4 \
+ openpam \
+ 'py3-cryptography' \
+ 'py3-packaging' \
+ 'py3-test' \
+ 'python%3' \
+ readline \
+ 'tcl%8.6' \
+ zstd \
+ login_krb5 \
+ 'openldap-client--gssapi' \
+ 'openldap-server--gssapi'
+
+ - name: Setup core files
+ run: |
+ # On OpenBSD core dumps land next to the binary by default. Switch
+ # to a fixed dir so we can find them after the build.
+ sudo mkdir -p /var/crash
+ sudo chmod 770 /var/crash
+ # Always core dump to /var/crash for setuid programs too.
+ sudo sysctl -w kern.nosuidcoredump=2
+
+ - name: Configure
+ run: |
+ set -e
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ --buildtype=debugoptimized \
+ --pkg-config-path ${PKGCONFIG_PATH} \
+ ${MESON_COMMON_FEATURES} \
+ -Dbsd_auth=enabled \
+ -Dlibcurl=enabled \
+ -Dtcl_version=tcl86 \
+ -Duuid=e2fs \
+ build
+
+ - name: Build
+ run: ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+
+ - name: Test world
+ run: |
+ set -e
+ ulimit -c unlimited
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+
+ - name: Core backtraces
+ if: failure()
+ run: |
+ find build/ -type f -name '*.core' -exec mv '{}' /var/crash \; || true
+ src/tools/ci/cores_backtrace.sh openbsd /var/crash "$PWD/build/tmp_install/usr/local/pgsql/bin" || true
+
+ - name: Sync VM back to runner
+ if: always()
+ run: cpa.sh --sync-files vm-to-runner
+ shell: bash
+
+ - name: Save ccache
+ if: always()
+ uses: actions/cache/save@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-openbsd-${{ github.run_id }}
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: openbsd-logs
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ if-no-files-found: ignore
+
+ # NB: macOS is by far the most expensive OS to run CI for; do not add
+ # additional expensive checks here.
+ #
+ # SPECIAL:
+ # - Enables --clone for pg_upgrade and pg_combinebackup
+ macos:
+ name: macOS - Meson
+ needs: [setup, sanity-check]
+ if: needs.setup.outputs.macos == 'true'
+ runs-on: macos-15
+ timeout-minutes: 90
+ env:
+ BUILD_JOBS: 4
+ # Test performance regresses noticeably when using all cores. 8 works OK.
+ # https://postgr.es/m/20220927040208.l3shfcidovpzqxfh%40awork3.anarazel.de
+ TEST_JOBS: 8
+ CCACHE_DIR: ${{ github.workspace }}/ccache_dir
+ MACOS_PACKAGE_LIST: >-
+ ccache
+ icu
+ kerberos5
+ lz4
+ meson
+ openldap
+ openssl
+ p5.34-io-tty
+ p5.34-ipc-run
+ python312
+ tcl
+ zstd
+ CC: ccache cc
+ CXX: ccache c++
+ CFLAGS: -Og -ggdb
+ CXXFLAGS: -Og -ggdb
+ PG_TEST_PG_UPGRADE_MODE: --clone
+ PG_TEST_PG_COMBINEBACKUP_MODE: --clone
+ TEMP_CONFIG: ${{ github.workspace }}/src/tools/ci/pg_ci_base.conf
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Sysinfo
+ run: |
+ id
+ uname -a
+ ulimit -a -H && ulimit -a -S
+ env
+
+ - name: Setup core files
+ run: |
+ mkdir -p $HOME/cores
+ sudo sysctl kern.corefile="$HOME/cores/core.%P"
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-macos-${{ github.run_id }}
+ restore-keys: ccache-macos-
+
+ # Install dependencies via Homebrew rather than Macports — on stock
+ # GH runners macports requires a heavy bootstrap, and the relevant
+ # Postgres deps are all available in brew.
+ - name: Install dependencies
+ run: |
+ brew update
+ brew install \
+ ccache icu4c krb5 lz4 meson openldap openssl@3 [email protected] tcl-tk zstd
+ # IPC::Run via cpanm (system perl)
+ sudo cpan -T -i IPC::Run IO::Tty || true
+
+ - name: Configure
+ run: |
+ # All these formulae are keg-only, so their pkgconfig dirs are not
+ # on the default PKG_CONFIG_PATH — list them explicitly.
+ BREW=$(brew --prefix)
+ OPENLDAP_PREFIX=$(brew --prefix openldap)
+ KRB5_PREFIX=$(brew --prefix krb5)
+ OPENSSL_PREFIX=$(brew --prefix openssl@3)
+ ICU_PREFIX=$(brew --prefix icu4c)
+ export PKG_CONFIG_PATH="${OPENSSL_PREFIX}/lib/pkgconfig:${ICU_PREFIX}/lib/pkgconfig:${KRB5_PREFIX}/lib/pkgconfig:${OPENLDAP_PREFIX}/lib/pkgconfig:$(brew --prefix lz4)/lib/pkgconfig:$(brew --prefix zstd)/lib/pkgconfig"
+ # -Dextra_include_dirs / -Dextra_lib_dirs are meson array options:
+ # comma-separated, not colon-separated.
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ --buildtype=debug \
+ -Dextra_include_dirs="${BREW}/include,${OPENLDAP_PREFIX}/include,${KRB5_PREFIX}/include,${OPENSSL_PREFIX}/include,${ICU_PREFIX}/include" \
+ -Dextra_lib_dirs="${BREW}/lib,${OPENLDAP_PREFIX}/lib,${KRB5_PREFIX}/lib,${OPENSSL_PREFIX}/lib,${ICU_PREFIX}/lib" \
+ ${MESON_COMMON_FEATURES} \
+ -Dbonjour=enabled \
+ -Ddtrace=enabled \
+ -Dgssapi=enabled \
+ -Dlibcurl=enabled \
+ -Dnls=enabled \
+ -Duuid=e2fs \
+ build
+
+ - name: Build
+ run: ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+
+ - name: Test world
+ run: |
+ ulimit -c unlimited
+ ulimit -n 1024
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+
+ - name: Core backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh macos "$HOME/cores" || true
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: macos-logs
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ if-no-files-found: ignore
+
+ windows-vs:
+ name: Windows - VS 2022 - Meson & ninja
+ needs: [setup, sanity-check]
+ if: needs.setup.outputs.windows == 'true'
+ runs-on: windows-2022
+ timeout-minutes: 120
+ env:
+ TEST_JOBS: 8
+ # Avoid port conflicts between concurrent tap tests
+ PG_TEST_USE_UNIX_SOCKETS: 1
+ PG_REGRESS_SOCK_DIR: "c:/pgsock/"
+ TAR: "c:/windows/system32/tar.exe"
+ # 0x8001 = SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX — needed
+ # so that crash reporting works on this runner. See Cirrus config
+ # comment for the full reasoning.
+ CIRRUS_WINDOWS_ERROR_MODE: 0x8001
+ defaults:
+ run:
+ shell: cmd
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Sysinfo
+ run: |
+ chcp
+ systeminfo
+ set
+
+ # The TAP tests build an initdb template under build/tmp_install and
+ # then `robocopy` it into per-test data directories. Robocopy with the
+ # default /COPY:DAT flag doesn't copy ACLs — destinations inherit from
+ # their parent dir. On GitHub-hosted Windows runners the workspace's
+ # inherited ACL grants Administrators:(F) and Users:(RX) but does NOT
+ # grant the runner user (runneradmin) directly. That matters because
+ # pg_ctl on Windows uses CreateRestrictedProcess to drop admin
+ # privileges from postmaster, so the postmaster process has the user
+ # SID in its token but no longer the Administrators group — leaving it
+ # with only "Users:(RX)" on pg_control and friends, which causes
+ # "PANIC: could not open file global/pg_control: Permission denied".
+ #
+ # Fix it once on the workspace dir with (OI)(CI) inheritance flags so
+ # every file/dir created underneath gets an explicit grant for the
+ # current user.
+ - name: Grant workspace ACL to runner user
+ shell: pwsh
+ run: |
+ icacls "${{ github.workspace }}" /grant "${env:USERNAME}:(OI)(CI)F" /Q | Out-Null
+ Write-Host "Granted Full Control to $env:USERNAME on ${{ github.workspace }}"
+
+ # postgres' plpython3u loads python3.dll (the stable-ABI forwarder)
+ # which in turn loads whichever python3NN.dll the Windows loader finds
+ # first on PATH. On windows-2022 `C:\Program Files\Mercurial\` ships
+ # its own python3.dll + python39.dll and appears on PATH *before* the
+ # hostedtoolcache Python 3.12 — so without intervention the backend
+ # ends up running Python 3.9 while postgres' stdlib search uses 3.12,
+ # producing `ImportError: cannot import name 'text_encoding' from
+ # 'io'` (the 3.12 `io.py` calling into 3.9's `_io`).
+ #
+ # Pin PYTHONHOME to the Python 3.12 prefix, and prepend that prefix
+ # to PATH so its python3.dll wins the DLL search.
+ - name: Pin Python prefix on PATH and PYTHONHOME
+ shell: pwsh
+ run: |
+ $prefix = (python -c "import sys; print(sys.prefix)").Trim()
+ Add-Content $env:GITHUB_ENV "PYTHONHOME=$prefix"
+ Add-Content $env:GITHUB_PATH $prefix
+ Write-Host "PYTHONHOME=$prefix"
+ Write-Host "Prepended $prefix to PATH"
+
+ - name: Install dependencies
+ shell: pwsh
+ run: |
+ choco install -y --no-progress --limitoutput diffutils winflexbison
+ # meson + ninja aren't preinstalled on windows-2022. Install via pip
+ # (python is preinstalled). Pin to known-good versions if needed.
+ python -m pip install --upgrade meson ninja
+ # OpenSSL 1.1 (matches Cirrus). slproweb installer.
+ curl.exe -fsSL -o openssl-setup.exe https://slproweb.com/download/Win64OpenSSL-1_1_1w.exe
+ Start-Process -Wait -FilePath ./openssl-setup.exe `
+ -ArgumentList '/DIR=c:\openssl\1.1\ /VERYSILENT /SP- /SUPPRESSMSGBOXES'
+ # The slproweb installer puts libcrypto-1_1-x64.dll / libssl-1_1-x64.dll
+ # in c:\openssl\1.1\bin\ and updates the system PATH. GH Actions
+ # snapshots PATH at job start though, so the running job won't
+ # see those DLLs and initdb.exe would crash silently at runtime.
+ # Push the bin dir onto GITHUB_PATH so it persists for later steps.
+ Add-Content $env:GITHUB_PATH "c:\openssl\1.1\bin"
+ # Install IPC::Run.
+ # - recommends_policy=0 keeps cpan from pulling in IO::Tty / IO::Pty,
+ # which don't build on Windows ("This module requires a POSIX
+ # compliant system to work").
+ # - Pin to NJM/IPC-Run-20250809.0 because TODDR/IPC-Run-20260322.0
+ # broke postgres tap tests on Windows (changed pipe stdio
+ # handling). See upstream pg-vm-images commit ff5238afa3 and
+ # the thread at
+ # https://postgr.es/m/CAN55FZ06xanSbJdHe-CurjX_qNuBWZDEvS1kAk36L38YCtZXnw%40mail.gmail.com
+ "o conf recommends_policy 0`no conf commit`nnotest install NJM/IPC-Run-20250809.0.tar.gz" | cpan
+ perl -mIPC::Run -e 1
+
+ - name: Setup hosts file
+ shell: pwsh
+ run: |
+ Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.1 pg-loadbalancetest"
+ Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.2 pg-loadbalancetest"
+ Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.3 pg-loadbalancetest"
+
+ - name: Setup sock dir
+ run: mkdir c:\pgsock
+
+ - name: Configure
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ meson setup --backend ninja %MESON_COMMON_PG_CONFIG_ARGS% --buildtype debug -Db_pch=true -Dcpp_args=/std:c++20 -Dextra_lib_dirs=c:\openssl\1.1\lib -Dextra_include_dirs=c:\openssl\1.1\include -DTAR=%TAR% -Dauto_features=disabled -Dldap=enabled -Dssl=openssl -Dtap_tests=enabled -Dplperl=enabled -Dplpython=enabled build
+
+ - name: Build
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ ninja -C build %MBUILD_TARGET%
+ ninja -C build -t missingdeps
+
+ - name: Test world
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ meson test %MTEST_ARGS% --num-processes %TEST_JOBS%
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: windows-vs-logs
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ crashlog-*.txt
+ if-no-files-found: ignore
+
+ windows-mingw:
+ name: Windows - MinGW64 - Meson
+ needs: [setup, sanity-check]
+ if: needs.setup.outputs.mingw == 'true'
+ runs-on: windows-2022
+ timeout-minutes: 180
+ env:
+ TEST_JOBS: 4 # higher concurrency causes occasional failures
+ PG_TEST_USE_UNIX_SOCKETS: 1
+ PG_REGRESS_SOCK_DIR: "c:/pgsock/"
+ TAR: "c:/windows/system32/tar.exe"
+ # for mingw plpython to find its installation
+ PYTHONHOME: D:/a/_temp/msys64/ucrt64
+ MSYS: winjitdebug
+ CHERE_INVOKING: 1
+ CCACHE_DIR: D:/a/ccache
+ CCACHE_MAXSIZE: "500M"
+ CCACHE_SLOPPINESS: pch_defines,time_macros
+ CCACHE_DEPEND: 1
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ # postgres tap tests use PG_REGRESS_SOCK_DIR for short Unix-socket
+ # paths (Windows still enforces the ~108-byte sockaddr_un.sun_path
+ # limit). The dir must exist before the tests run.
+ - name: Setup sock dir
+ shell: cmd
+ run: mkdir c:\pgsock
+
+ - name: Setup MSYS2
+ uses: msys2/setup-msys2@v2
+ with:
+ msystem: UCRT64
+ update: true
+ install: >-
+ git bison flex make diffutils
+ mingw-w64-ucrt-x86_64-ccache
+ mingw-w64-ucrt-x86_64-docbook-xml
+ mingw-w64-ucrt-x86_64-gcc
+ mingw-w64-ucrt-x86_64-icu
+ mingw-w64-ucrt-x86_64-libbacktrace
+ mingw-w64-ucrt-x86_64-libxml2
+ mingw-w64-ucrt-x86_64-libxslt
+ mingw-w64-ucrt-x86_64-lz4
+ mingw-w64-ucrt-x86_64-make
+ mingw-w64-ucrt-x86_64-meson
+ mingw-w64-ucrt-x86_64-perl
+ mingw-w64-ucrt-x86_64-pkg-config
+ mingw-w64-ucrt-x86_64-python-cryptography
+ mingw-w64-ucrt-x86_64-python-pip
+ mingw-w64-ucrt-x86_64-python-pytest
+ mingw-w64-ucrt-x86_64-readline
+ mingw-w64-ucrt-x86_64-zlib
+
+ - name: Install IPC::Run for tap tests
+ shell: msys2 {0}
+ run: |
+ # Pin IPC::Run to NJM/IPC-Run-20250809.0; TODDR/IPC-Run-20260322.0
+ # broke postgres tap tests on Windows (pipe stdio handling).
+ # See pg-vm-images commit ff5238afa3.
+ (echo; echo o conf recommends_policy 0; echo notest install NJM/IPC-Run-20250809.0.tar.gz) | cpan
+ perl -mIPC::Run -e 1
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-mingw-${{ github.run_id }}
+ restore-keys: ccache-mingw-
+
+ - name: Configure
+ shell: msys2 {0}
+ run: |
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ -Ddebug=true -Doptimization=g -Db_pch=true \
+ ${MESON_COMMON_FEATURES} \
+ -Dnls=disabled \
+ -DTAR=${TAR} \
+ build
+
+ - name: Build
+ shell: msys2 {0}
+ run: ninja -C build ${MBUILD_TARGET}
+
+ - name: Test world
+ shell: msys2 {0}
+ run: meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: windows-mingw-logs
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ crashlog-*.txt
+ if-no-files-found: ignore
+
+ # Test that code can be built with both gcc and clang without warnings,
+ # with various combinations of cassert/dtrace flags. Trace probes have
+ # a history of getting accidentally broken; the matrix is there to
+ # catch that.
+ #
+ # The autoconf cache files (gcc.cache / clang.cache) are intentionally
+ # reused across the matrix entries that share a compiler, so we don't
+ # pay for full feature detection on every entry.
+ compiler-warnings:
+ name: CompilerWarnings
+ needs: [setup, sanity-check]
+ if: needs.setup.outputs.compilerwarnings == 'true'
+ runs-on: ubuntu-latest
+ container:
+ image: us-docker.pkg.dev/pg-ci-images/ci/linux_debian_trixie_ci:latest
+ env:
+ BUILD_JOBS: 4
+ CCACHE_DIR: /tmp/ccache_dir
+ # Use larger ccache cache as this job compiles with multiple
+ # compilers / flag combinations.
+ CCACHE_MAXSIZE: "1G"
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-compiler-warnings-${{ github.run_id }}
+ restore-keys: ccache-compiler-warnings-
+
+ - name: Sysinfo
+ run: |
+ id
+ uname -a
+ cat /proc/cmdline
+ ulimit -a -H && ulimit -a -S
+ gcc -v
+ clang -v
+ env
+
+ - name: Setup workspace
+ run: |
+ echo "COPT=-Werror" > src/Makefile.custom
+ mkdir -p "$CCACHE_DIR"
+
+ # gcc, cassert off, dtrace on
+ - name: gcc warning
+ if: always()
+ run: |
+ ./configure \
+ --cache gcc.cache \
+ --enable-dtrace \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ # gcc, cassert on, dtrace off
+ - name: gcc warning - cassert
+ if: always()
+ run: |
+ ./configure \
+ --cache gcc.cache \
+ --enable-cassert \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ # clang, cassert off, dtrace off
+ - name: clang warning
+ if: always()
+ run: |
+ ./configure \
+ --cache clang.cache \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache clang" CXX="ccache clang++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ # clang, cassert on, dtrace on
+ - name: clang warning - cassert + dtrace
+ if: always()
+ run: |
+ ./configure \
+ --cache clang.cache \
+ --enable-cassert \
+ --enable-dtrace \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache clang" CXX="ccache clang++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ - name: mingw cross compile
+ if: always()
+ run: |
+ ./configure \
+ --host=x86_64-w64-mingw32ucrt \
+ --enable-cassert \
+ --without-icu \
+ CC="ccache x86_64-w64-mingw32ucrt-gcc" \
+ CXX="ccache x86_64-w64-mingw32ucrt-g++"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ - name: Docs build
+ if: always()
+ run: |
+ ./configure \
+ --cache gcc.cache \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} -C doc
+
+ # headerscheck / cpluspluscheck. Run both in the same script for
+ # parallelism; -k to get the result of both. -fmax-errors because
+ # cpluspluscheck can be very verbose.
+ - name: headerscheck + cpluspluscheck
+ if: always()
+ run: |
+ ./configure \
+ ${LINUX_CONFIGURE_FEATURES} \
+ --cache gcc.cache \
+ --quiet \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} -k ${CHECKFLAGS} headerscheck cpluspluscheck EXTRAFLAGS='-fmax-errors=10'
diff --git a/src/test/modules/test_aio/t/TestAio.pm b/src/test/modules/test_aio/t/TestAio.pm
index 84e784db75f..15fe5d6a91d 100644
--- a/src/test/modules/test_aio/t/TestAio.pm
+++ b/src/test/modules/test_aio/t/TestAio.pm
@@ -76,6 +76,16 @@ Return if io_uring is supported
sub have_io_uring
{
+ # Some environments (cloud VMs, GitHub Actions hosted runners, etc.)
+ # disable io_uring at the kernel level or block io_uring_setup at the
+ # seccomp/LSM layer. Build-time support is necessary but not sufficient.
+ # Allow CI to force-skip io_uring via an env var.
+ if ($ENV{PG_TEST_SKIP_IO_URING})
+ {
+ note "io_uring skipped via PG_TEST_SKIP_IO_URING";
+ return 0;
+ }
+
# To detect if io_uring is supported, we look at the error message for
# assigning an invalid value to an enum GUC, which lists all the valid
# options. We need to use -C to deal with running as administrator on
diff --git a/src/test/perl/PostgreSQL/Test/Kerberos.pm b/src/test/perl/PostgreSQL/Test/Kerberos.pm
index e861d93533e..de820281935 100644
--- a/src/test/perl/PostgreSQL/Test/Kerberos.pm
+++ b/src/test/perl/PostgreSQL/Test/Kerberos.pm
@@ -37,6 +37,14 @@ INIT
$krb5_bin_dir = '/usr/local/bin';
$krb5_sbin_dir = '/usr/local/sbin';
}
+ elsif ($^O eq 'netbsd')
+ {
+ # pkgsrc's mit-krb5 installs under /usr/pkg; the base system's
+ # /usr/bin/krb5-config is Heimdal, which the tap tests don't
+ # support, so pin to the pkgsrc layout explicitly.
+ $krb5_bin_dir = '/usr/pkg/bin';
+ $krb5_sbin_dir = '/usr/pkg/sbin';
+ }
elsif ($^O eq 'linux')
{
$krb5_sbin_dir = '/usr/sbin';
base-commit: a28fa2947d2a507089605c47bbfa9016d457208c
--
2.54.0
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-18 22:27 Nazir Bilal Yavuz <[email protected]>
parent: Jelte Fennema-Nio <[email protected]>
1 sibling, 1 reply; 42+ messages in thread
From: Nazir Bilal Yavuz @ 2026-05-18 22:27 UTC (permalink / raw)
To: Jelte Fennema-Nio <[email protected]>; +Cc: Andres Freund <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers
Hi,
On Tue, 19 May 2026 at 00:22, Jelte Fennema-Nio <[email protected]> wrote:
>
> On Thu, 9 Apr 2026 at 22:55, Andres Freund <[email protected]> wrote:
> > https://cirruslabs.org/ burries the lede a bit, but it has further down:
> > "Cirrus CI will shut down effective Monday, June 1, 2026."
>
> June 1st is getting really close. *In less than two weeks we won't have
> a working CI anymore*. Effectively that's probably one week of calendar
> dev time that's left, because almost everyone is at PGConf.dev right
> now.
>
> So today I decided to take a stab at an initial GitHub Actions yaml
> file, as that seemed like the only viable option within that timeline.
> Note: Claude Code wrote this file entirely, following extensive
> back-and-forth with me after repeatadly getting red builds due to some
> differences between Cirrus and Github Actions.
Thank you for working on this!
> But finally, I managed to get a green build for all systems that we
> support on Cirrus CI!
>
> IMPORTANT CONTEXT: I only did a cursory review of the workflow file that
> Claude created. So there's probably still a bunch of cleanup to do, but
> I at least wanted to share this initial base. I don't know if I'll have
> any more time to work on this before June 1st. I have a newborn that's
> taking up a lot of my spare time. So, I'd be very happy if someone else
> wants to take this patch over and get it to a committable state.
I am actually working on the same thing and I was about to create a
new thread, I am glad that I checked my emails before doing that. I
can take this patch and move forward.
I am attaching my WIP version for visibility. My version doesn't have
BSD operating systems and uses Ubuntu instead of Debian. I didn't know
that containers can be used like you did. Another difference between
our versions is that mine has helper scripts to call things like
installing dependencies, configure, build and test. I did it that way
as we can use these helper scripts for other CI providers in the
future.
I think we can merge these two patches and move forward that way. I am
planning to review your patch and see what I can come up with to get
it to a committable state.
> A few things (apart from more extensive review) that I think should be
> improved soon (but maybe not before the first commit):
> 1. io_uring support is disabled. I couldn't get it to work on the GitHub
> Actions runners, I think it's disabled in the host kernel. @Andres
I managed to get it to work. I think it was due to memlock and I
solved it by running this command: 'sudo prlimit --pid $$
--memlock=unlimited:unlimited' before running the tests.
> 2. It's not using pre-built images at the moment, except for the Linux
> docker images I think. So it re-downloads a bunch of dependencies for
> every build for most OSes. @Bilal or @Andres
Yes, that is a problem and needs to be handled separately.
One other problem is the logs. Github Actions' logs are not public,
you need to sign in to see them. I think we can solve them by
uploading logs to the public when the task fails but perhaps that can
be handled afterwards.
--
Regards,
Nazir Bilal Yavuz
Microsoft
Attachments:
[application/octet-stream] v1-0001-nbyavuz-Add-Github-Actions-as-CI-provider.patch (45.6K, 2-v1-0001-nbyavuz-Add-Github-Actions-as-CI-provider.patch)
download | inline diff:
From fb877cdd7ed13cb41376049fadcf19f84a27094f Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <[email protected]>
Date: Mon, 18 May 2026 23:05:36 +0300
Subject: [PATCH v1] Add Github Actions as CI provider
---
.github/workflows/main.yml | 747 +++++++++++++++++++
src/tools/ci/ci_provider_helpers.sh | 443 +++++++++++
src/tools/ci/ci_provider_windows_helpers.ps1 | 93 +++
3 files changed, 1283 insertions(+)
create mode 100644 .github/workflows/main.yml
create mode 100755 src/tools/ci/ci_provider_helpers.sh
create mode 100644 src/tools/ci/ci_provider_windows_helpers.ps1
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 00000000000..6366ac3d8e3
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,747 @@
+# GitHub Actions CI workflow
+
+name: Postgres Github Actions CI
+
+on:
+ push:
+ branches: [ "*" ]
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ # Never cancel in-progress runs on master to ensure all commits are tested.
+ cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
+
+env:
+ PGCTLTIMEOUT: 120
+ PG_TEST_EXTRA: kerberos ldap ssl libpq_encryption load_balance oauth
+ CCACHE_MAXSIZE: 250M
+ CI_OS_ONLY_JOBS: sanitycheck linux macos windows mingw compilerwarnings
+
+ MBUILD_TARGET: all testprep
+ MTEST_ARGS: --print-errorlogs --no-rebuild -C build
+ CHECK: check-world PROVE_FLAGS=--timer
+ CHECKFLAGS: -Otarget
+
+ MESON_COMMON_PG_CONFIG_ARGS: -Dcassert=true -Dinjection_points=true
+ MESON_COMMON_FEATURES: >-
+ -Dauto_features=disabled
+ -Dldap=enabled
+ -Dssl=openssl
+ -Dtap_tests=enabled
+ -Dplperl=enabled
+ -Dplpython=enabled
+ -Ddocs=enabled
+ -Dicu=enabled
+ -Dlibxml=enabled
+ -Dlibxslt=enabled
+ -Dlz4=enabled
+ -Dpltcl=enabled
+ -Dreadline=enabled
+ -Dzlib=enabled
+ -Dzstd=enabled
+
+ LINUX_CONFIGURE_FEATURES: >-
+ --with-gssapi
+ --with-icu
+ --with-ldap
+ --with-libcurl
+ --with-libxml
+ --with-libxslt
+ --with-llvm
+ --with-lz4
+ --with-pam
+ --with-perl
+ --with-python
+ --with-selinux
+ --with-ssl=openssl
+ --with-systemd
+ --with-tcl --with-tclconfig=/usr/lib/tcl8.6/
+ --with-uuid=ossp
+ --with-zstd
+
+ ARTIFACT_RETENTION_DAYS: 30
+ MESON_LOG_PATHS: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+
+
+jobs:
+ # Add 'ci-os-only: <job1> <job2> ...' to the commit description to run
+ # only specific jobs. Valid names:
+ # sanitycheck, linux, macos, windows, mingw, compilerwarnings
+ # Jobs can be space or comma-separated.
+ # Example: 'ci-os-only: macos, linux' runs only macOS and Linux jobs.
+ # If omitted, all jobs run.
+ ci-config:
+ name: CI Configuration
+ runs-on: ubuntu-24.04
+ timeout-minutes: 1
+ outputs:
+ run-sanitycheck: ${{ steps.parse.outputs.run-sanitycheck }}
+ run-linux: ${{ steps.parse.outputs.run-linux }}
+ run-macos: ${{ steps.parse.outputs.run-macos }}
+ run-windows: ${{ steps.parse.outputs.run-windows }}
+ run-mingw: ${{ steps.parse.outputs.run-mingw }}
+ run-compilerwarnings: ${{ steps.parse.outputs.run-compilerwarnings }}
+ steps:
+ - name: Parse ci-os-only from commit message
+ id: parse
+ env:
+ # NOTE: github.event.head_commit.message is null on pull_request
+ # events. This workflow only triggers on push, so this is fine.
+ # If a pull_request trigger is added later, the filter will be
+ # silently disabled unless this is reworked.
+ COMMIT_MSG: ${{ github.event.head_commit.message }}
+ run: |
+ set -e
+ CI_ONLY=$(echo "${COMMIT_MSG}" | grep -i '^ci-os-only:' | head -1 | sed 's/^[^:]*://' | tr ',' ' ' | xargs)
+ if [ -z "${CI_ONLY}" ]; then
+ echo "No ci-os-only filter found, all jobs enabled"
+ for name in ${CI_OS_ONLY_JOBS}; do
+ echo "run-${name}=true" >> "${GITHUB_OUTPUT}"
+ done
+ else
+ echo "ci-os-only filter: ${CI_ONLY}"
+ for name in ${CI_OS_ONLY_JOBS}; do
+ if echo " ${CI_ONLY} " | grep -qi " ${name} "; then
+ echo "run-${name}=true" >> "${GITHUB_OUTPUT}"
+ else
+ echo "run-${name}=false" >> "${GITHUB_OUTPUT}"
+ fi
+ done
+ fi
+
+
+ sanity-check:
+ name: SanityCheck
+ needs: ci-config
+ if: needs.ci-config.outputs.run-sanitycheck == 'true'
+ runs-on: ubuntu-24.04
+ timeout-minutes: 15
+
+ env:
+ BUILD_JOBS: 8
+ TEST_JOBS: 8
+ CCACHE_DIR: ${{ github.workspace }}/ccache_dir
+ CCACHE_MAXSIZE: 150M
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+
+ - name: System info
+ run: src/tools/ci/ci_provider_helpers.sh github_actions sysinfo
+
+ - name: Install dependencies
+ run: sudo src/tools/ci/ci_provider_helpers.sh github_actions install_packages linux minimal
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-${{ github.job }}-${{ github.ref }}-${{ github.sha }}
+ restore-keys: |
+ ccache-${{ github.job }}-${{ github.ref }}-
+ ccache-${{ github.job }}-
+
+ - name: Setup cores
+ run: sudo src/tools/ci/ci_provider_helpers.sh github_actions setup_cores linux /tmp/cores $(whoami)
+
+ - name: Configure
+ run: |
+ set -e
+ src/tools/ci/ci_provider_helpers.sh github_actions configure_meson build \
+ --buildtype=debug \
+ --auto-features=disabled \
+ -Ddefault_library=shared \
+ -Dtap_tests=enabled
+
+ - name: Build
+ run: src/tools/ci/ci_provider_helpers.sh github_actions build_meson build ${BUILD_JOBS} ${MBUILD_TARGET}
+
+ - name: Test (minimal)
+ run: |
+ set -e
+ # Allow locked memory for AIO and core dumps for debugging failures.
+ sudo prlimit --pid $$ --memlock=unlimited:unlimited --core=unlimited:unlimited
+ src/tools/ci/ci_provider_helpers.sh github_actions sanity_test ${TEST_JOBS} ${MTEST_ARGS}
+
+ - name: Upload logs on failure
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: ${{ github.job }}-logs-${{ github.run_id }}
+ path: ${{ env.MESON_LOG_PATHS }}
+ retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }}
+
+
+ linux-meson:
+ name: Linux - Ubuntu 24.04 - Meson
+ needs: [ci-config, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.ci-config.outputs.run-linux == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: ubuntu-24.04
+ timeout-minutes: 45
+
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ CCACHE_DIR: /tmp/ccache_dir
+ CCACHE_MAXSIZE: 400M
+ # NOTE: GitHub Actions does not allow referencing one env var from
+ # another in the same env block (neither workflow- nor job-level env
+ # is exposed via the ${{ env.* }} context here). The SANITIZER_FLAGS
+ # value is therefore duplicated in CFLAGS/CXXFLAGS/LDFLAGS below; keep
+ # them in sync.
+ SANITIZER_FLAGS: -fsanitize=alignment,undefined
+ CFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=alignment,undefined
+ CXXFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=alignment,undefined
+ LDFLAGS: -fsanitize=alignment,undefined
+ CC: ccache gcc
+ CXX: ccache g++
+ UBSAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:verbosity=2
+ ASAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:detect_leaks=0:detect_stack_use_after_return=0
+ DEBUGINFOD_URLS: "https://debuginfod.debian.net"
+ LINUX_MESON_FEATURES: -Duuid=e2fs
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+
+ - name: System info
+ run: src/tools/ci/ci_provider_helpers.sh github_actions sysinfo
+
+ - name: Install dependencies
+ run: sudo src/tools/ci/ci_provider_helpers.sh github_actions install_packages linux full_32bit
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-${{ github.job }}-${{ github.ref }}-${{ github.sha }}
+ restore-keys: |
+ ccache-${{ github.job }}-${{ github.ref }}-
+ ccache-${{ github.job }}-
+
+ - name: Setup cores
+ run: sudo src/tools/ci/ci_provider_helpers.sh github_actions setup_cores linux /tmp/cores $(whoami)
+
+ - name: Configure (64-bit)
+ run: |
+ set -e
+ src/tools/ci/ci_provider_helpers.sh github_actions configure_meson build \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ --buildtype=debug \
+ ${LINUX_MESON_FEATURES} -Dllvm=enabled
+
+ - name: Build (64-bit)
+ run: |
+ set -e
+ src/tools/ci/ci_provider_helpers.sh github_actions build_meson build ${BUILD_JOBS} ${MBUILD_TARGET}
+ ninja -C build -t missingdeps
+
+ - name: Test (64-bit)
+ env:
+ PG_TEST_INITDB_EXTRA_OPTS: -c io_method=io_uring
+ run: |
+ set -e
+ # Allow locked memory for AIO and core dumps for debugging failures.
+ sudo prlimit --pid $$ --memlock=unlimited:unlimited --core=unlimited:unlimited
+ src/tools/ci/ci_provider_helpers.sh github_actions test_meson ${TEST_JOBS} ${MTEST_ARGS}
+ # so that we don't upload 64bit logs if 32bit fails
+ rm -rf build/
+
+ - name: Install conflicting 32-bit packages
+ run: sudo src/tools/ci/ci_provider_helpers.sh github_actions install_packages linux full_32bit_extra
+
+ - name: Configure (32-bit)
+ env:
+ CC: ccache gcc -m32
+ CXX: ccache g++ -m32
+ run: |
+ set -e
+ src/tools/ci/ci_provider_helpers.sh github_actions configure_meson build-32 \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ --buildtype=debug \
+ --pkg-config-path /usr/lib/i386-linux-gnu/pkgconfig/ \
+ -DPERL=perl5.38-i386-linux-gnu \
+ ${LINUX_MESON_FEATURES} -Dlibnuma=disabled -Dliburing=disabled
+
+ - name: Build (32-bit)
+ run: |
+ set -e
+ src/tools/ci/ci_provider_helpers.sh github_actions build_meson build-32 ${BUILD_JOBS} ${MBUILD_TARGET}
+ ninja -C build-32 -t missingdeps
+
+ - name: Test (32-bit)
+ env:
+ # Override MTEST_ARGS to point at the 32-bit build directory.
+ MTEST_ARGS: --print-errorlogs --no-rebuild -C build-32
+ run: |
+ set -e
+ # Allow locked memory for AIO and core dumps for debugging failures.
+ sudo prlimit --pid $$ --memlock=unlimited:unlimited --core=unlimited:unlimited
+ PYTHONCOERCECLOCALE=0 LANG=C \
+ src/tools/ci/ci_provider_helpers.sh github_actions test_meson ${TEST_JOBS} ${MTEST_ARGS}
+
+ - name: Core dump backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh linux /tmp/cores
+
+ - name: Upload logs on failure
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: ${{ github.job }}-logs-${{ github.run_id }}
+ path: ${{ env.MESON_LOG_PATHS }}
+ retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }}
+
+
+ linux-autoconf:
+ name: Linux - Ubuntu 24.04 - Autoconf
+ needs: [ci-config, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.ci-config.outputs.run-linux == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: ubuntu-24.04
+ timeout-minutes: 30
+
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ CCACHE_DIR: /tmp/ccache_dir
+ # NOTE: GitHub Actions does not allow referencing one env var from
+ # another in the same env block (neither workflow- nor job-level env
+ # is exposed via the ${{ env.* }} context here). The SANITIZER_FLAGS
+ # value is therefore duplicated in CFLAGS/CXXFLAGS/LDFLAGS below; keep
+ # them in sync.
+ SANITIZER_FLAGS: -fsanitize=address
+ CFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=address
+ CXXFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=address
+ LDFLAGS: -fsanitize=address
+ CC: ccache gcc
+ CXX: ccache g++
+ UBSAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:verbosity=2
+ ASAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:detect_leaks=0:detect_stack_use_after_return=0
+ PG_TEST_PG_COMBINEBACKUP_MODE: --copy-file-range
+ DEBUGINFOD_URLS: "https://debuginfod.debian.net"
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+
+ - name: System info
+ run: src/tools/ci/ci_provider_helpers.sh github_actions sysinfo
+
+ - name: Install dependencies
+ run: sudo src/tools/ci/ci_provider_helpers.sh github_actions install_packages linux full
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-${{ github.job }}-${{ github.ref }}-${{ github.sha }}
+ restore-keys: |
+ ccache-${{ github.job }}-${{ github.ref }}-
+ ccache-${{ github.job }}-
+
+ - name: Setup cores
+ run: sudo src/tools/ci/ci_provider_helpers.sh github_actions setup_cores linux /tmp/cores $(whoami)
+
+ - name: Setup hosts
+ run: sudo src/tools/ci/ci_provider_helpers.sh github_actions setup_hosts
+
+ - name: Configure
+ run: |
+ set -e
+ src/tools/ci/ci_provider_helpers.sh github_actions configure_autoconf \
+ "${LINUX_CONFIGURE_FEATURES}" \
+ --enable-cassert --enable-injection-points --enable-debug \
+ --enable-tap-tests --enable-nls \
+ --with-segsize-blocks=6 \
+ --with-libnuma \
+ --with-liburing \
+ CLANG="ccache clang"
+
+ - name: Build
+ run: src/tools/ci/ci_provider_helpers.sh github_actions build_autoconf ${BUILD_JOBS} world-bin
+
+ - name: Test
+ run: |
+ set -e
+ # Allow locked memory for AIO and core dumps for debugging failures.
+ sudo prlimit --pid $$ --memlock=unlimited:unlimited --core=unlimited:unlimited
+ src/tools/ci/ci_provider_helpers.sh github_actions test_autoconf ${TEST_JOBS} ${CHECK} ${CHECKFLAGS}
+
+ - name: Core dump backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh linux /tmp/cores
+
+ - name: Upload logs on failure
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: ${{ github.job }}-logs-${{ github.run_id }}
+ path: |
+ **/*.log
+ **/*.diffs
+ **/regress_log_*
+ retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }}
+
+
+ macos-meson:
+ name: macOS - Sequoia - Meson
+ needs: [ci-config, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.ci-config.outputs.run-macos == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: macos-15
+ timeout-minutes: 30
+
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ CCACHE_DIR: ${{ github.workspace }}/ccache
+ CFLAGS: -Og -ggdb
+ CXXFLAGS: -Og -ggdb
+ CC: ccache cc
+ CXX: ccache c++
+ PG_TEST_PG_UPGRADE_MODE: --clone
+ PG_TEST_PG_COMBINEBACKUP_MODE: --clone
+ MESON_FEATURES: >-
+ -Dbonjour=enabled
+ -Ddtrace=enabled
+ -Dgssapi=enabled
+ -Dlibcurl=enabled
+ -Dnls=enabled
+ -Duuid=e2fs
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+
+ - name: System info
+ run: src/tools/ci/ci_provider_helpers.sh github_actions sysinfo
+
+ - name: Install dependencies
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ set -e
+ sudo -E src/tools/ci/ci_provider_helpers.sh github_actions install_packages macos
+ echo "/opt/local/sbin:/opt/local/bin" >> ${GITHUB_PATH}
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-${{ github.job }}-${{ github.ref }}-${{ github.sha }}
+ restore-keys: |
+ ccache-${{ github.job }}-${{ github.ref }}-
+ ccache-${{ github.job }}-
+
+ - name: Setup cores
+ run: sudo src/tools/ci/ci_provider_helpers.sh github_actions setup_cores macos "${HOME}/cores"
+
+ - name: Configure
+ env:
+ PKG_CONFIG_PATH: /opt/local/lib/pkgconfig
+ run: |
+ set -e
+ src/tools/ci/ci_provider_helpers.sh github_actions configure_meson build \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ --buildtype=debug \
+ ${MESON_COMMON_FEATURES} ${MESON_FEATURES} \
+ -Dextra_include_dirs=/opt/local/include \
+ -Dextra_lib_dirs=/opt/local/lib
+
+ - name: Build
+ run: src/tools/ci/ci_provider_helpers.sh github_actions build_meson build ${BUILD_JOBS} ${MBUILD_TARGET}
+
+ - name: Test
+ run: |
+ set -e
+ ulimit -c unlimited
+ ulimit -n 1024
+ src/tools/ci/ci_provider_helpers.sh github_actions test_meson ${TEST_JOBS} ${MTEST_ARGS}
+
+ - name: Core dump backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh macos "${HOME}/cores"
+
+ - name: Upload logs on failure
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: ${{ github.job }}-logs-${{ github.run_id }}
+ path: ${{ env.MESON_LOG_PATHS }}
+ retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }}
+
+
+ windows-msvc:
+ name: Windows - Server 2022, VS 2022 - Meson & ninja
+ needs: [ci-config, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.ci-config.outputs.run-windows == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: windows-2022
+ timeout-minutes: 60
+
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ PG_TEST_USE_UNIX_SOCKETS: 1
+ PG_REGRESS_SOCK_DIR: ${{ github.workspace }}
+ MESON_FEATURES: >-
+ -Dcpp_args=/std:c++20
+ -Dauto_features=disabled
+ -Dtap_tests=enabled
+ -Dldap=enabled
+ -Dssl=openssl
+ -Dplperl=enabled
+ -Dplpython=enabled
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+
+ - name: System info
+ run: src/tools/ci/ci_provider_windows_helpers.ps1 github_actions sysinfo
+
+ - name: Disable Windows Defender
+ shell: powershell
+ run: src/tools/ci/ci_provider_windows_helpers.ps1 github_actions disable_defender
+
+ - name: Install dependencies
+ shell: powershell
+ run: src/tools/ci/ci_provider_windows_helpers.ps1 github_actions install_packages
+
+ - name: Setup hosts file
+ shell: powershell
+ run: src/tools/ci/ci_provider_windows_helpers.ps1 github_actions setup_hosts
+
+ - name: Setup MSVC environment and configure
+ shell: cmd
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ meson setup %MESON_COMMON_PG_CONFIG_ARGS% --backend ninja --buildtype debug -Db_pch=true -DTAR=c:\windows\system32\tar.exe %MESON_FEATURES% build
+
+ - name: Build
+ shell: cmd
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ ninja -C build -j%BUILD_JOBS% %MBUILD_TARGET%
+ ninja -C build -t missingdeps
+
+ - name: Test
+ shell: cmd
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ REM Grant Everyone full control on the build directory so that
+ REM postgres.exe can access data files after it drops admin
+ REM privileges via CreateRestrictedToken().
+ icacls build /grant Everyone:(OI)(CI)(F) /T /Q
+ meson test %MTEST_ARGS% --num-processes %TEST_JOBS%
+
+ - name: Upload logs on failure
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: ${{ github.job }}-logs-${{ github.run_id }}
+ path: |
+ ${{ env.MESON_LOG_PATHS }}
+ crashlog-*.txt
+ retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }}
+
+
+ windows-mingw:
+ name: Windows - Server 2022, MinGW64 - Meson
+ needs: [ci-config, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.ci-config.outputs.run-mingw == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: windows-2022
+ timeout-minutes: 60
+
+ defaults:
+ run:
+ shell: msys2 {0}
+
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 4
+ CCACHE_MAXSIZE: 500M
+ CCACHE_SLOPPINESS: pch_defines,time_macros
+ CCACHE_DEPEND: 1
+ PG_TEST_USE_UNIX_SOCKETS: 1
+ PG_REGRESS_SOCK_DIR: ${{ github.workspace }}
+
+ steps:
+ - name: Disable Windows Defender
+ shell: powershell
+ # Disable Windows Defender before installing packages to speed up the
+ # process. We cannot use the helper script here because it requires the
+ # repository to be checked out first, and checkout in turn requires
+ # MSYS2 to already be set up with all packages installed. To break this
+ # circular dependency, the Defender disabling logic is inlined below.
+ run: |
+ Set-MpPreference -DisableRealtimeMonitoring $true -SubmitSamplesConsent NeverSend -MAPSReporting Disable
+ # Verify Defender status
+ $status = Get-MpComputerStatus -ErrorAction SilentlyContinue
+ if ($status) {
+ Write-Host "RealTimeProtectionEnabled: $($status.RealTimeProtectionEnabled)"
+ Write-Host "AntivirusEnabled: $($status.AntivirusEnabled)"
+ }
+
+ - name: Setup MSYS2
+ uses: msys2/setup-msys2@v2
+ with:
+ msystem: UCRT64
+ update: true
+ install: >-
+ git bison flex make diffutils
+ mingw-w64-ucrt-x86_64-ccache
+ mingw-w64-ucrt-x86_64-docbook-xml
+ mingw-w64-ucrt-x86_64-gcc
+ mingw-w64-ucrt-x86_64-icu
+ mingw-w64-ucrt-x86_64-libbacktrace
+ mingw-w64-ucrt-x86_64-libxml2
+ mingw-w64-ucrt-x86_64-libxslt
+ mingw-w64-ucrt-x86_64-lz4
+ mingw-w64-ucrt-x86_64-make
+ mingw-w64-ucrt-x86_64-meson
+ mingw-w64-ucrt-x86_64-perl
+ mingw-w64-ucrt-x86_64-pkg-config
+ mingw-w64-ucrt-x86_64-python-cryptography
+ mingw-w64-ucrt-x86_64-python-pip
+ mingw-w64-ucrt-x86_64-python-pytest
+ mingw-w64-ucrt-x86_64-readline
+ mingw-w64-ucrt-x86_64-zlib
+
+ - name: Checkout
+ uses: actions/checkout@v5
+
+ - name: System info
+ run: src/tools/ci/ci_provider_helpers.sh github_actions sysinfo
+
+ - name: Install IPC::Run
+ run: src/tools/ci/ci_provider_helpers.sh github_actions install_ipc_run
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: C:/msys64/ccache
+ key: ccache-${{ github.job }}-${{ github.ref }}-${{ github.sha }}
+ restore-keys: |
+ ccache-${{ github.job }}-${{ github.ref }}-
+ ccache-${{ github.job }}-
+
+ - name: Configure
+ env:
+ CCACHE_DIR: C:/msys64/ccache
+ # Keep -Dnls explicitly disabled (creates too many files, causes slowdown)
+ MESON_FEATURES: -Dnls=disabled
+ run: |
+ set -e
+ src/tools/ci/ci_provider_helpers.sh github_actions configure_meson build \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ -Ddebug=true -Doptimization=g -Db_pch=true \
+ ${MESON_COMMON_FEATURES} ${MESON_FEATURES} \
+ -DTAR=c:/windows/system32/tar.exe
+
+ - name: Build
+ run: src/tools/ci/ci_provider_helpers.sh github_actions build_meson build ${BUILD_JOBS} ${MBUILD_TARGET}
+
+ - name: Test
+ run: src/tools/ci/ci_provider_helpers.sh github_actions test_meson ${TEST_JOBS} ${MTEST_ARGS}
+
+ - name: Upload logs on failure
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: ${{ github.job }}-logs-${{ github.run_id }}
+ path: |
+ ${{ env.MESON_LOG_PATHS }}
+ crashlog-*.txt
+ retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }}
+
+
+ compiler-warnings:
+ name: CompilerWarnings
+ needs: [ci-config, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.ci-config.outputs.run-compilerwarnings == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: ubuntu-24.04
+ timeout-minutes: 60
+
+ env:
+ BUILD_JOBS: 4
+ CCACHE_DIR: /tmp/ccache_dir
+ CCACHE_MAXSIZE: 1G
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+
+ - name: System info
+ run: |
+ set -e
+ src/tools/ci/ci_provider_helpers.sh github_actions sysinfo
+ gcc -v
+ clang -v
+
+ - name: Install dependencies
+ run: sudo src/tools/ci/ci_provider_helpers.sh github_actions install_packages linux compiler_warnings
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-${{ github.job }}-${{ github.ref }}-${{ github.sha }}
+ restore-keys: |
+ ccache-${{ github.job }}-${{ github.ref }}-
+ ccache-${{ github.job }}-
+
+ - name: Setup Werror
+ run: src/tools/ci/ci_provider_helpers.sh github_actions compiler_warnings_setup
+
+ - name: "Warnings: gcc (cassert off, dtrace on)"
+ run: src/tools/ci/ci_provider_helpers.sh github_actions compiler_warnings_gcc_no_cassert ${BUILD_JOBS} "${LINUX_CONFIGURE_FEATURES}"
+
+ - name: "Warnings: gcc (cassert on, dtrace off)"
+ run: src/tools/ci/ci_provider_helpers.sh github_actions compiler_warnings_gcc_cassert ${BUILD_JOBS} "${LINUX_CONFIGURE_FEATURES}"
+
+ - name: "Warnings: clang (cassert off, dtrace off)"
+ run: src/tools/ci/ci_provider_helpers.sh github_actions compiler_warnings_clang_no_cassert ${BUILD_JOBS} "${LINUX_CONFIGURE_FEATURES}"
+
+ - name: "Warnings: clang (cassert on, dtrace on)"
+ run: src/tools/ci/ci_provider_helpers.sh github_actions compiler_warnings_clang_cassert ${BUILD_JOBS} "${LINUX_CONFIGURE_FEATURES}"
+
+ - name: "Warnings: mingw cross-compile"
+ run: src/tools/ci/ci_provider_helpers.sh github_actions compiler_warnings_mingw_cross ${BUILD_JOBS}
+
+ - name: "Warnings: docs build"
+ run: src/tools/ci/ci_provider_helpers.sh github_actions compiler_warnings_docs ${BUILD_JOBS}
+
+ - name: "Warnings: headerscheck & cpluspluscheck"
+ run: src/tools/ci/ci_provider_helpers.sh github_actions compiler_warnings_headerscheck ${BUILD_JOBS} "${LINUX_CONFIGURE_FEATURES}"
+
+ - name: Upload logs on failure
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: ${{ github.job }}-logs-${{ github.run_id }}
+ path: |
+ **/*.log
+ **/*.diffs
+ retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }}
diff --git a/src/tools/ci/ci_provider_helpers.sh b/src/tools/ci/ci_provider_helpers.sh
new file mode 100755
index 00000000000..5d72cc1d84e
--- /dev/null
+++ b/src/tools/ci/ci_provider_helpers.sh
@@ -0,0 +1,443 @@
+#!/bin/sh
+# src/tools/ci/provider_helpers/main.sh - Unified CI entry point for PostgreSQL
+#
+# Usage: main.sh <provider> <task> [args...]
+#
+# Providers:
+# github_actions - GitHub Actions
+#
+
+set -e
+
+PROVIDER="${1}"
+TASK="${2}"
+shift 2
+
+##############################################################################
+# Setup tasks
+##############################################################################
+
+task_sysinfo() {
+ echo "=== System Information ==="
+ echo "Provider: ${PROVIDER}"
+ echo "User: $(whoami)"
+ echo "Hostname: $(hostname)"
+ echo "Kernel: $(uname -a)"
+ echo ""
+ echo "=== Resource Limits (Hard) ==="
+ ulimit -a -H
+ echo ""
+ echo "=== Resource Limits (Soft) ==="
+ ulimit -a -S
+ echo ""
+ echo "=== Environment ==="
+ export
+}
+
+# install_packages <os> [profile]
+# os: linux | macos
+# profile: minimal | full | full_32bit | compiler_warnings (linux only)
+task_install_packages() {
+ local os="${1}"
+ local profile="${2:-full}"
+
+ case "${os}" in
+ linux) _install_linux_packages "${profile}" ;;
+ macos) _install_macos_packages ;;
+ *)
+ echo "Error: unsupported OS '${os}' for install_packages"
+ exit 1
+ ;;
+ esac
+}
+
+_install_linux_packages() {
+ local profile="${1}"
+
+ # Packages shared by every Linux build
+ local common="build-essential gdb git make meson ccache perl libperl-dev libipc-run-perl"
+
+ # Full dependency set for autoconf / meson builds
+ local full="
+ libreadline-dev libssl-dev zlib1g-dev libicu-dev
+ libxml2-dev libxslt1-dev gettext
+ liblz4-dev libzstd-dev
+ libldap-dev libkrb5-dev krb5-admin-server krb5-kdc krb5-user
+ libpam0g-dev uuid-dev libossp-uuid-dev
+ python3-dev libtcl8.6 tcl-dev
+ libcurl4-openssl-dev
+ llvm-dev clang
+ libselinux1-dev libsystemd-dev
+ systemtap-sdt-dev
+ libnuma-dev liburing-dev"
+
+ apt-get update -qq
+
+ case "${profile}" in
+ minimal)
+ DEBIAN_FRONTEND=noninteractive \
+ apt-get install -y -qq --no-install-recommends ${common}
+ ;;
+ full)
+ DEBIAN_FRONTEND=noninteractive \
+ apt-get install -y -qq --no-install-recommends ${common} ${full}
+ ;;
+ full_32bit)
+ dpkg --add-architecture i386
+ apt-get update -qq
+ DEBIAN_FRONTEND=noninteractive \
+ apt-get install -y -qq --no-install-recommends --no-remove \
+ ${common} ${full} \
+ gcc-multilib \
+ libicu-dev:i386 \
+ libldap2-dev:i386 \
+ liblz4-dev:i386 \
+ libpam-dev:i386 \
+ libperl-dev:i386 \
+ libpython3-dev:i386 \
+ libreadline-dev:i386 \
+ libselinux-dev:i386 \
+ libssl-dev:i386 \
+ libsystemd-dev:i386 \
+ libxml2-dev:i386 \
+ libxslt1-dev:i386 \
+ libzstd-dev:i386 \
+ tcl-dev:i386 \
+ uuid-dev:i386
+ ;;
+ full_32bit_extra)
+ # Packages that conflict with their amd64 counterparts (they
+ # install arch-independent files like curl-config). Install these
+ # with --force-overwrite after the 64-bit build and tests are done,
+ # so the 64-bit toolchain is not affected.
+ DEBIAN_FRONTEND=noninteractive \
+ apt-get install -y -qq --no-install-recommends \
+ -o Dpkg::Options::="--force-overwrite" \
+ libcurl4-openssl-dev:i386
+ ;;
+ compiler_warnings)
+ DEBIAN_FRONTEND=noninteractive \
+ apt-get install -y -qq --no-install-recommends \
+ ${common} ${full} \
+ gcc g++ clang \
+ gcc-mingw-w64-x86-64-posix g++-mingw-w64-x86-64-posix \
+ docbook-xml docbook-xsl xsltproc libxml2-utils
+ ;;
+ *)
+ echo "Error: unknown Linux package profile '${profile}'"
+ exit 1
+ ;;
+ esac
+}
+
+_install_macos_packages() {
+ local macports_version="2.10.1"
+ local macos_major_version
+ macos_major_version=$(sw_vers -productVersion | sed 's/\..*//')
+
+ if [ ! -x /opt/local/bin/port ]; then
+ echo "=== Installing MacPorts ==="
+ # Fetch the .pkg URL from the GitHub releases API for this macOS version.
+ local macports_url
+ local api_response
+ # Need to use GITHUB_TOKEN, otherwise might get API rate limit
+ # exceeded for ${ip_adress}. Only send the Authorization header when
+ # GITHUB_TOKEN is non-empty: an empty token results in a malformed
+ # "Authorization: token " header that some GitHub endpoints reject.
+ if [ -n "${GITHUB_TOKEN:-}" ]; then
+ api_response=$(curl -sH "Authorization: token ${GITHUB_TOKEN}" \
+ "https://api.github.com/repos/macports/macports-base/releases")
+ else
+ api_response=$(curl -s \
+ "https://api.github.com/repos/macports/macports-base/releases")
+ fi
+ macports_url=$(echo "${api_response}" | python3 -c "
+import json, sys, re
+releases = json.loads(sys.stdin.read(), strict=False)
+for rel in releases:
+ if not rel['tag_name'].startswith('v${macports_version}'):
+ continue
+ for asset in rel.get('assets', []):
+ if re.match(r'MacPorts-.*-${macos_major_version}-.*\.pkg\$', asset['name']):
+ print(asset['browser_download_url'])
+ sys.exit(0)
+")
+ if [ -z "${macports_url}" ]; then
+ echo "Error: could not find MacPorts package for macOS ${macos_major_version}"
+ exit 1
+ fi
+ echo "Downloading: ${macports_url}"
+ curl -fsSL -o /tmp/macports.pkg "${macports_url}"
+ installer -pkg /tmp/macports.pkg -target /
+ rm -f /tmp/macports.pkg
+ fi
+
+ export PATH=/opt/local/sbin/:/opt/local/bin/:${PATH}
+
+ echo "=== Installing packages via MacPorts ==="
+ port install -N \
+ ccache icu kerberos5 lz4 meson openldap openssl \
+ p5.34-io-tty p5.34-ipc-run python312 tcl zstd
+ /opt/local/bin/port select python3 python312
+}
+
+
+
+# setup_cores <os> [core_dir]
+task_setup_cores() {
+ local os="${1}"
+ local core_dir="${2:-/tmp/cores}"
+ local username="${3}"
+
+ mkdir -p "${core_dir}"
+ chmod 770 "${core_dir}"
+
+ case "${os}" in
+ linux)
+ local conf_file="/etc/security/limits.d/${username}.conf"
+
+ sysctl kernel.core_pattern="${core_dir}/%e-%s-%p.core"
+
+ touch "${conf_file}" && chown "${username}:${username}" "${conf_file}"
+ # Allow all users to create unlimited core dumps
+ echo '* - core unlimited' > "${conf_file}"
+ ;;
+ macos)
+ sysctl kern.corefile="${core_dir}/core.%P"
+ ;;
+ *)
+ echo "Error: unsupported OS '${os}' for setup_cores"
+ exit 1
+ ;;
+ esac
+}
+
+task_setup_hosts() {
+ echo "127.0.0.1 pg-loadbalancetest" >> /etc/hosts
+ echo "127.0.0.2 pg-loadbalancetest" >> /etc/hosts
+ echo "127.0.0.3 pg-loadbalancetest" >> /etc/hosts
+ echo "Updated /etc/hosts with load-balance test entries"
+}
+
+# install_ipc_run
+# Installs IPC::Run for Perl (used by MinGW CI).
+task_install_ipc_run() {
+ echo "=== Installing IPC::Run ==="
+ echo "Check if IPC::Run is already installed, it shouldn't be at this point"
+ if perl -mIPC::Run -e 1 2>/dev/null; then echo "ERROR: IPC::Run already installed"; exit 1; fi
+ # MinGW CI tasks started failing after the package was updated from
+ # NJM/IPC-Run-20250809.0 to TODDR/IPC-Run-20260322.0. There is no way to
+ # install IPC::Run from an author without specifying the exact version number
+ # so install the latest working one. (NJM/IPC-Run-20250809.0.tar.gz). See:
+ # - https://postgr.es/m/CAN55FZ06xanSbJdHe-CurjX_qNuBWZDEvS1kAk36L38YCtZXnw%40mail.gmail.com
+ (echo; echo o conf recommends_policy 0; echo notest install NJM/IPC-Run-20250809.0.tar.gz) | cpan
+ # Check if IPC::Run is installed correctly
+ perl -mIPC::Run -e 1
+}
+
+##############################################################################
+# Configure tasks
+##############################################################################
+
+# configure_meson <build_dir> [meson_args...]
+task_configure_meson() {
+ local build_dir="${1}"
+ shift
+
+ meson setup "$(pwd)" "${build_dir}" "$@"
+}
+
+# configure_autoconf <configure_features> [configure_args...]
+task_configure_autoconf() {
+ local features="${1}"
+ shift
+
+ # shellcheck disable=SC2086
+ ./configure ${features} "$@"
+}
+
+##############################################################################
+# Build tasks
+##############################################################################
+
+# build_meson <build_dir> <jobs> <targets...>
+task_build_meson() {
+ local build_dir="${1}"
+ local jobs="${2}"
+ shift 2
+
+ ninja -C "${build_dir}" -j"${jobs}" "$@"
+}
+
+# build_autoconf <jobs> <targets...>
+task_build_autoconf() {
+ local jobs="${1}"
+ shift
+
+ make -s -j"${jobs}" "$@"
+}
+
+##############################################################################
+# Test tasks
+##############################################################################
+
+# test_meson <jobs> <mtest_args...>
+task_test_meson() {
+ local jobs="${1}"
+ shift
+
+ ulimit -c unlimited
+ meson test "$@" --num-processes "${jobs}"
+}
+
+# test_autoconf <jobs> <make_args...>
+task_test_autoconf() {
+ local jobs="${1}"
+ shift
+
+ ulimit -c unlimited
+ make -s -j"${jobs}" "$@"
+}
+
+# sanity_test <jobs> <mtest_args...>
+task_sanity_test() {
+ local jobs="${1}"
+ shift
+
+ ulimit -c unlimited
+ meson test "$@" --suite setup
+ meson test "$@" --num-processes "${jobs}" \
+ cube/regress pg_ctl/001_start_stop
+}
+
+task_compiler_warnings_setup() {
+ echo "COPT=-Werror" > src/Makefile.custom
+}
+
+# compiler_warnings_gcc_no_cassert <jobs> <configure_features>
+task_compiler_warnings_gcc_no_cassert() {
+ local jobs="${1}"
+ local features="${2}"
+
+ echo "====== gcc, cassert off, dtrace on ======"
+ # shellcheck disable=SC2086
+ ./configure --cache gcc-no-cassert.cache --enable-dtrace \
+ ${features} CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j"${jobs}" clean
+ make -s -j"${jobs}" world-bin
+}
+
+# compiler_warnings_gcc_cassert <jobs> <configure_features>
+task_compiler_warnings_gcc_cassert() {
+ local jobs="${1}"
+ local features="${2}"
+
+ echo "====== gcc, cassert on, dtrace off ======"
+ # shellcheck disable=SC2086
+ ./configure --cache gcc-cassert.cache --enable-cassert \
+ ${features} CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j"${jobs}" clean
+ make -s -j"${jobs}" world-bin
+}
+
+# compiler_warnings_clang_no_cassert <jobs> <configure_features>
+task_compiler_warnings_clang_no_cassert() {
+ local jobs="${1}"
+ local features="${2}"
+
+ echo "====== clang, cassert off, dtrace off ======"
+ # shellcheck disable=SC2086
+ ./configure --cache clang-no-cassert.cache \
+ ${features} CC="ccache clang" CXX="ccache clang++" CLANG="ccache clang"
+ make -s -j"${jobs}" clean
+ make -s -j"${jobs}" world-bin
+}
+
+# compiler_warnings_clang_cassert <jobs> <configure_features>
+task_compiler_warnings_clang_cassert() {
+ local jobs="${1}"
+ local features="${2}"
+
+ echo "====== clang, cassert on, dtrace on ======"
+ # shellcheck disable=SC2086
+ ./configure --cache clang-cassert.cache --enable-cassert --enable-dtrace \
+ ${features} CC="ccache clang" CXX="ccache clang++" CLANG="ccache clang"
+ make -s -j"${jobs}" clean
+ make -s -j"${jobs}" world-bin
+}
+
+# compiler_warnings_mingw_cross <jobs>
+task_compiler_warnings_mingw_cross() {
+ local jobs="${1}"
+
+ ./configure --host=x86_64-w64-mingw32 --enable-cassert \
+ --without-icu --without-zlib \
+ CC="ccache x86_64-w64-mingw32-gcc" \
+ CXX="ccache x86_64-w64-mingw32-g++"
+ make -s -j"${jobs}" clean
+ make -s -j"${jobs}" world-bin
+}
+
+# compiler_warnings_docs <jobs>
+task_compiler_warnings_docs() {
+ local jobs="${1}"
+
+ ./configure --cache docs.cache \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j"${jobs}" clean
+ make -s -j"${jobs}" -C doc
+}
+
+# compiler_warnings_headerscheck <jobs> <configure_features>
+task_compiler_warnings_headerscheck() {
+ local jobs="${1}"
+ local features="${2}"
+
+ # shellcheck disable=SC2086
+ ./configure ${features} --cache headerscheck.cache --quiet \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j"${jobs}" clean
+ make -s -j"${jobs}" -k -Otarget headerscheck cpluspluscheck \
+ EXTRAFLAGS='-fmax-errors=10'
+}
+
+##############################################################################
+# Dispatch
+##############################################################################
+
+case "${TASK}" in
+ sysinfo) task_sysinfo "$@" ;;
+ install_packages) task_install_packages "$@" ;;
+ install_ipc_run) task_install_ipc_run "$@" ;;
+ setup_cores) task_setup_cores "$@" ;;
+ setup_hosts) task_setup_hosts "$@" ;;
+ configure_meson) task_configure_meson "$@" ;;
+ configure_autoconf) task_configure_autoconf "$@" ;;
+ build_meson) task_build_meson "$@" ;;
+ build_autoconf) task_build_autoconf "$@" ;;
+ test_meson) task_test_meson "$@" ;;
+ test_autoconf) task_test_autoconf "$@" ;;
+ sanity_test) task_sanity_test "$@" ;;
+ compiler_warnings_setup) task_compiler_warnings_setup "$@" ;;
+ compiler_warnings_gcc_no_cassert) task_compiler_warnings_gcc_no_cassert "$@" ;;
+ compiler_warnings_gcc_cassert) task_compiler_warnings_gcc_cassert "$@" ;;
+ compiler_warnings_clang_no_cassert) task_compiler_warnings_clang_no_cassert "$@" ;;
+ compiler_warnings_clang_cassert) task_compiler_warnings_clang_cassert "$@" ;;
+ compiler_warnings_mingw_cross) task_compiler_warnings_mingw_cross "$@" ;;
+ compiler_warnings_docs) task_compiler_warnings_docs "$@" ;;
+ compiler_warnings_headerscheck) task_compiler_warnings_headerscheck "$@" ;;
+ *)
+ echo "Error: unknown task '${TASK}'"
+ echo ""
+ echo "Available tasks:"
+ echo " sysinfo install_packages install_ipc_run setup_cores setup_hosts"
+ echo " configure_meson configure_autoconf"
+ echo " build_meson build_autoconf"
+ echo " test_meson test_autoconf sanity_test"
+ echo " compiler_warnings_setup compiler_warnings_gcc_no_cassert"
+ echo " compiler_warnings_gcc_cassert compiler_warnings_clang_no_cassert"
+ echo " compiler_warnings_clang_cassert compiler_warnings_mingw_cross"
+ echo " compiler_warnings_docs compiler_warnings_headerscheck"
+ exit 1
+ ;;
+esac
diff --git a/src/tools/ci/ci_provider_windows_helpers.ps1 b/src/tools/ci/ci_provider_windows_helpers.ps1
new file mode 100644
index 00000000000..af9cdbc4431
--- /dev/null
+++ b/src/tools/ci/ci_provider_windows_helpers.ps1
@@ -0,0 +1,93 @@
+# src/tools/ci/provider_helpers/main.ps1
+#
+# Usage: main.ps1 <provider> <task> [args...]
+#
+# Providers:
+# github_actions - GitHub Actions
+#
+
+param(
+ [Parameter(Mandatory = $true, Position = 0)]
+ [string]$Provider,
+
+ [Parameter(Mandatory = $true, Position = 1)]
+ [string]$Task,
+
+ [Parameter(ValueFromRemainingArguments = $true)]
+ [string[]]$ExtraArgs
+)
+
+$ErrorActionPreference = "Stop"
+
+function Invoke-Sysinfo {
+ Write-Host "=== System Information ==="
+ Write-Host "Provider: $Provider"
+ chcp
+ systeminfo
+ Get-PSDrive -PSProvider FileSystem
+ Get-ChildItem Env: | Sort-Object Name
+}
+
+function Invoke-SetupHosts {
+ $hostsFile = "C:\Windows\System32\Drivers\etc\hosts"
+ Add-Content -Path $hostsFile -Value "127.0.0.1 pg-loadbalancetest"
+ Add-Content -Path $hostsFile -Value "127.0.0.2 pg-loadbalancetest"
+ Add-Content -Path $hostsFile -Value "127.0.0.3 pg-loadbalancetest"
+ Write-Host "Updated hosts file:"
+ Get-Content $hostsFile
+}
+
+function Invoke-DisableDefender {
+ Set-MpPreference -DisableRealtimeMonitoring $true -SubmitSamplesConsent NeverSend -MAPSReporting Disable
+ # Verify Defender status
+ $status = Get-MpComputerStatus -ErrorAction SilentlyContinue
+ if ($status) {
+ Write-Host "RealTimeProtectionEnabled: $($status.RealTimeProtectionEnabled)"
+ Write-Host "AntivirusEnabled: $($status.AntivirusEnabled)"
+ }
+}
+
+function Invoke-InstallPackages {
+ $before = $env:Path -split ';'
+
+ # First install only strawberryperl with the --version option,
+ # otherwise --version tag applies to all packages.
+ choco install -y --no-progress --force `
+ strawberryperl --version=5.42.0.1
+
+ choco install -y --no-progress `
+ meson `
+ ninja `
+ winflexbison3 `
+ diffutils `
+ pkgconfiglite `
+ openssl `
+ xsltproc `
+ zstandard `
+ python3
+
+ # Refresh PATH using Chocolatey's helper to pick up Machine PATH changes
+ Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1
+ refreshenv
+ # Persist new PATH entries for subsequent steps.
+ # Deduplicate to avoid appending the same path multiple times when
+ # multiple installed packages contribute the same directory.
+ $after = $env:Path -split ';'
+ $new = $after | Where-Object { $_ -and $before -notcontains $_ } | Select-Object -Unique
+ Write-Host "=== New PATH entries ==="
+ $new | ForEach-Object { Write-Host " $_" }
+ $new | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+}
+
+switch ($Task) {
+ "sysinfo" { Invoke-Sysinfo }
+ "setup_hosts" { Invoke-SetupHosts }
+ "disable_defender" { Invoke-DisableDefender }
+ "install_packages" { Invoke-InstallPackages }
+ default {
+ Write-Error "Unknown task: $Task"
+ Write-Host ""
+ Write-Host "Available tasks: sysinfo setup_hosts disable_defender install_packages"
+ exit 1
+ }
+}
--
2.43.0
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-25 12:14 Nazir Bilal Yavuz <[email protected]>
parent: Nazir Bilal Yavuz <[email protected]>
0 siblings, 4 replies; 42+ messages in thread
From: Nazir Bilal Yavuz @ 2026-05-25 12:14 UTC (permalink / raw)
To: Jelte Fennema-Nio <[email protected]>; +Cc: Andres Freund <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers
Hi,
We had an unconference session at the PGConf.dev 2026. Here are the
notes [1] (Thank you Lukas for taking and publishing the notes!). Some
important points are:
- We can use Github Actions for now, and revisit alternatives later.
- We won't have BSDs for the first version.
- Backpatch until PG15, where CI introduced.
- No need to test VS 2019, we can continue with VS 2022.
- Deal with making logs public later.
On Tue, 19 May 2026 at 01:27, Nazir Bilal Yavuz <[email protected]> wrote:
>
> I think we can merge these two patches and move forward that way. I am
> planning to review your patch and see what I can come up with to get
> it to a committable state.
Here is the v2, I took Jelte's patch and reviewed & merged it with my
patch. Updates and questions are:
1- I continued to use Jelte's container method (Linux tasks only for
now, BSD tasks will be included in the future) because I think that is
the future-proof way since we might want to generate our container
images in the future. Also, up-to-date Debian images can be tested
with this way; otherwise we would need to use Ubuntu 24.04.
2- io_uring tests work on the Linux Meson task.
3- I didn't put commands to helper scripts for now. I think it is a
good thing to have a helper script but it would be better to have this
helper script after the first version is committed since it can extend
the timeline. Also, I found that having all commands in one file makes
debugging easier.
4- FreeBSD task has these options:
PG_TEST_INITDB_EXTRA_OPTS: >-
-c debug_copy_parse_plan_trees=on
-c debug_write_read_parse_plan_trees=on
-c debug_raw_expression_coverage_test=on
-c debug_parallel_query=regress
Since we won't have FreeBSD for the first version. I put these options
to the MacOS task but I couldn't decide where to put
'PG_TEST_PG_UPGRADE_MODE: --link'.
Also, I am planning to work on back patches when we agree on the
upstream one. Does that sound good?
CI run link of attached patch:
https://github.com/nbyavuz/postgres/actions/runs/26398508250
[1] https://wiki.postgresql.org/wiki/PGConf.dev_2026_Developer_Unconference
--
Regards,
Nazir Bilal Yavuz
Microsoft
Attachments:
[text/x-patch] v2-0001-Add-GitHub-Actions-yaml-file.patch (40.1K, 2-v2-0001-Add-GitHub-Actions-yaml-file.patch)
download | inline diff:
From 4f66a8a93e6090fd2d127be0972615297ec48c0f Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <[email protected]>
Date: Mon, 25 May 2026 14:28:42 +0300
Subject: [PATCH v2] Add GitHub Actions yaml file
Cirrus CI is shutting down. This is an initial attempt to get a GitHub
Actions CI working.
---
.github/workflows/ci.yml | 1125 ++++++++++++++++++++++++++++++++++++++
1 file changed, 1125 insertions(+)
create mode 100644 .github/workflows/ci.yml
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000000..6d20068727c
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,1125 @@
+# GitHub Actions CI configuration for PostgreSQL
+
+name: Github Actions CI
+
+on:
+ push:
+ branches: [ "*" ]
+
+# Default to the minimum privilege the jobs need (just reading the repo
+# contents during checkout). Individual jobs override this when they need
+# more, e.g. `cancel-previous` needs `actions: write` to cancel runs.
+permissions:
+ contents: read
+
+# NB: intentionally NO workflow-level `concurrency:` block. The native
+# concurrency mechanism makes a new run wait for the previous one to fully
+# cancel before it starts — which can take a while. Instead the
+# `cancel-previous` job below fires a cancel API call asynchronously,
+# so the new run gets going immediately. On master the cancel job is skipped,
+# so every push runs to completion.
+
+env:
+ # The lower depth accelerates git clone. Use a bit of depth so that
+ # concurrent jobs and retrying older runs have a chance of working.
+ CLONE_DEPTH: 500
+
+ CCACHE_MAXSIZE: "250M"
+
+ # check target for the autoconf builds
+ CHECK: check-world PROVE_FLAGS=--timer
+ CHECKFLAGS: -Otarget
+
+ # Build test dependencies as part of the build step, to see compiler
+ # errors/warnings in one place.
+ MBUILD_TARGET: all testprep
+ MTEST_ARGS: --print-errorlogs --no-rebuild -C build
+ PGCTLTIMEOUT: 120 # avoids spurious failures during parallel tests
+ TEMP_CONFIG: ${{ github.workspace }}/src/tools/ci/pg_ci_base.conf
+ PG_TEST_EXTRA: kerberos ldap ssl libpq_encryption load_balance oauth
+
+ # Postgres config args for the meson builds, shared between all meson tasks
+ # except the 'SanityCheck' task
+ MESON_COMMON_PG_CONFIG_ARGS: -Dcassert=true -Dinjection_points=true
+
+ # Meson feature flags shared by all meson tasks, except:
+ # SanityCheck: uses almost no dependencies.
+ # Windows - VS: has fewer dependencies than listed here, so defines its own.
+ # Linux: uses the 'auto' feature option to test meson feature autodetection.
+ MESON_COMMON_FEATURES: >-
+ -Dauto_features=disabled
+ -Dldap=enabled
+ -Dssl=openssl
+ -Dtap_tests=enabled
+ -Dplperl=enabled
+ -Dplpython=enabled
+ -Ddocs=enabled
+ -Dicu=enabled
+ -Dlibxml=enabled
+ -Dlibxslt=enabled
+ -Dlz4=enabled
+ -Dpltcl=enabled
+ -Dreadline=enabled
+ -Dzlib=enabled
+ -Dzstd=enabled
+
+ # Shared between the Linux autoconf job and the CompilerWarnings jobs
+ LINUX_CONFIGURE_FEATURES: >-
+ --with-gssapi
+ --with-icu
+ --with-ldap
+ --with-libcurl
+ --with-libxml
+ --with-libxslt
+ --with-llvm
+ --with-lz4
+ --with-pam
+ --with-perl
+ --with-python
+ --with-selinux
+ --with-ssl=openssl
+ --with-systemd
+ --with-tcl --with-tclconfig=/usr/lib/tcl8.6/
+ --with-uuid=ossp
+ --with-zstd
+
+ # Debian Trixie container image used by all Linux jobs. Built by
+ # 'https://github.com/anarazel/pg-vm-images/'.
+ LINUX_CI_IMAGE: us-docker.pkg.dev/pg-ci-images/ci/linux_debian_trixie_ci:latest
+
+ # The full set of OS / job selectors recognized by the `ci-os-only:`
+ # commit-message directive parsed in the `setup` job below.
+ CI_OS_ONLY_JOBS: "linux macos windows mingw compilerwarnings sanitycheck"
+
+
+jobs:
+ # Cancel any older in-progress runs of this workflow on the same branch.
+ # Skipped on master so every push there runs to completion.
+ cancel-previous:
+ name: Cancel previous runs
+ if: github.ref != 'refs/heads/master'
+ runs-on: ubuntu-latest
+ timeout-minutes: 1
+ permissions:
+ actions: write
+ steps:
+ - name: Cancel
+ env:
+ GH_TOKEN: ${{ github.token }}
+ REPO: ${{ github.repository }}
+ run: |
+ # Look up this run's workflow id to cancel them.
+ workflow_id=$(gh run view "${{ github.run_id }}" -R "$REPO" \
+ --json workflowDatabaseId --jq .workflowDatabaseId)
+ gh run list \
+ -R "$REPO" \
+ --workflow="$workflow_id" \
+ --branch="${{ github.ref_name }}" \
+ --status=in_progress \
+ --json databaseId \
+ --jq '.[].databaseId' \
+ --limit 50 \
+ | while read -r id; do
+ if [ "$id" != "${{ github.run_id }}" ]; then
+ echo "Cancelling run $id"
+ gh run cancel "$id" -R "$REPO"
+ fi
+ done
+
+ # Parse "ci-os-only: ..." from the commit message and expose flags
+ # consumed by the per-OS job `if:` conditions.
+ setup:
+ name: Determine enabled OSes
+ runs-on: ubuntu-latest
+ timeout-minutes: 1
+ outputs:
+ linux: ${{ steps.os.outputs.linux }}
+ macos: ${{ steps.os.outputs.macos }}
+ windows: ${{ steps.os.outputs.windows }}
+ mingw: ${{ steps.os.outputs.mingw }}
+ compilerwarnings: ${{ steps.os.outputs.compilerwarnings }}
+ sanitycheck: ${{ steps.os.outputs.sanitycheck }}
+ # Re-export workflow-level env vars that other jobs need to reference
+ # from contexts (e.g. `jobs.<id>.container.image`) where the `env`
+ # context is not available.
+ linux_ci_image: ${{ env.LINUX_CI_IMAGE }}
+ steps:
+ - id: os
+ env:
+ MSG: ${{ github.event.head_commit.message }}
+ shell: bash
+ run: |
+ set -e
+ all_os="${CI_OS_ONLY_JOBS}"
+ if printf '%s\n' "$MSG" | grep -qE '^ci-os-only: '; then
+ sel=$(printf '%s\n' "$MSG" | grep -E '^ci-os-only: ' | head -1 | sed 's/^ci-os-only: //')
+ echo "ci-os-only selection: $sel"
+ else
+ sel="$all_os"
+ fi
+ for o in $all_os; do
+ if echo " $sel " | grep -qE "[ ,]$o[ ,]"; then
+ echo "$o=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "$o=false" >> "$GITHUB_OUTPUT"
+ fi
+ done
+ cat "$GITHUB_OUTPUT"
+
+
+ # To avoid unnecessarily spinning up a lot of VMs / containers for entirely
+ # broken commits, have a minimal task that all others depend on.
+ #
+ # SPECIAL:
+ # - Builds with --auto-features=disabled and thus almost no enabled
+ # dependencies
+ sanity-check:
+ name: SanityCheck
+ needs: setup
+ if: needs.setup.outputs.sanitycheck == 'true'
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ container:
+ image: ${{ needs.setup.outputs.linux_ci_image }}
+ env:
+ BUILD_JOBS: 8
+ TEST_JOBS: 8
+ CCACHE_DIR: ${{ github.workspace }}/ccache_dir
+ # no options enabled, should be small
+ CCACHE_MAXSIZE: "150M"
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-sanitycheck-${{ github.run_id }}
+ restore-keys: ccache-sanitycheck-
+
+ - name: Prepare workspace
+ run: |
+ whoami
+ useradd -m postgres
+ chown -R postgres:postgres .
+ mkdir -p "$CCACHE_DIR"
+ chown -R postgres:postgres "$CCACHE_DIR"
+ # Can't change the container's kernel.core_pattern; the postgres
+ # user can't write to / normally. Make / writable.
+ chown root:postgres /
+ chmod g+rwx /
+
+ - name: Configure
+ run: |
+ su postgres <<-'EOF'
+ set -e
+ meson setup \
+ --buildtype=debug \
+ --auto-features=disabled \
+ -Ddefault_library=shared \
+ -Dtap_tests=enabled \
+ build
+ EOF
+
+ - name: Build
+ run: |
+ su postgres <<EOF
+ set -e
+ ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+ EOF
+
+ # Run a minimal set of tests. The main regression tests take too long
+ # for this purpose. For now this is a random quick pg_regress style
+ # test, and a tap test that exercises both a frontend binary and the
+ # backend.
+ - name: Test
+ run: |
+ su postgres <<EOF
+ set -e
+ ulimit -c unlimited
+ meson test ${MTEST_ARGS} --suite setup
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS} \
+ cube/regress pg_ctl/001_start_stop
+ EOF
+
+ - name: Core backtraces
+ if: failure()
+ run: |
+ mkdir -m 770 /tmp/cores
+ find / -maxdepth 1 -type f -name 'core*' -exec mv '{}' /tmp/cores/ \;
+ src/tools/ci/cores_backtrace.sh linux /tmp/cores
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: sanitycheck-logs-${{ github.run_id }}
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ if-no-files-found: ignore
+
+
+ # SPECIAL:
+ # - Uses address sanitizer (sanitizer failures are typically printed in
+ # the server log)
+ # - Configures postgres with a small segment size
+ #
+ # Enable a reasonable set of sanitizers. Use the linux task for that, as
+ # it's one of the fastest tasks (without sanitizers). Also several of the
+ # sanitizers work best on linux.
+ #
+ # The overhead of alignment sanitizer is low, undefined behaviour has
+ # moderate overhead. Test alignment sanitizer in the meson task, as it
+ # does both 32 and 64 bit builds and is thus more likely to expose
+ # alignment bugs.
+ #
+ # Address sanitizer in contrast is somewhat expensive. Enable it in the
+ # autoconf task, as the meson task tests both 32 and 64bit.
+ #
+ # disable_coredump=0, abort_on_error=1: for useful backtraces in case of crashes
+ # print_stacktraces=1,verbosity=2, duh
+ # detect_leaks=0: too many uninteresting leak errors in short-lived binaries
+ linux-autoconf:
+ name: Linux - Debian Trixie - Autoconf
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.linux == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ container:
+ image: ${{ needs.setup.outputs.linux_ci_image }}
+ # Share the host PID + IPC namespaces. 017_shm.pl rapidly creates,
+ # kill9's, and restarts postgres; with the container's small PID
+ # space a new postgres can recycle the dead postmaster's PID before
+ # pg_ctl's postmaster.pid check notices, producing spurious "node X
+ # is already running" failures. SysV shm in the test also relies on
+ # host-like IPC behavior.
+ #
+ # --ulimit raises memlock and core dump size. Memlock is needed for
+ # running the AIO tests.
+ #
+ # --privileged is needed so the prepare step can write to sysctls
+ # under /proc/sys (it's mounted read-only without it). We use it to
+ # set kernel.core_pattern.
+ options: --pid=host --ipc=host --ulimit memlock=-1:-1 --privileged
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ CCACHE_DIR: /tmp/ccache_dir
+ DEBUGINFOD_URLS: "https://debuginfod.debian.net"
+
+ SANITIZER_FLAGS: -fsanitize=address
+ UBSAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:verbosity=2
+ ASAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:detect_leaks=0:detect_stack_use_after_return=0
+ CFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=address
+ CXXFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=address
+ LDFLAGS: -fsanitize=address
+ CC: ccache gcc
+ CXX: ccache g++
+
+ PG_TEST_PG_COMBINEBACKUP_MODE: --copy-file-range
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-linux-autoconf-${{ github.run_id }}
+ restore-keys: ccache-linux-autoconf-
+
+ - name: Prepare workspace
+ run: |
+ useradd -m postgres
+ chown -R postgres:postgres .
+ mkdir -p "$CCACHE_DIR"
+ chown -R postgres:postgres "$CCACHE_DIR"
+ mkdir -m 770 /tmp/cores
+ chown root:postgres /tmp/cores
+ sysctl kernel.core_pattern='/tmp/cores/%e-%s-%p.core'
+
+ # Hosts for the load balance test
+ cat >> /etc/hosts <<-EOF
+ 127.0.0.1 pg-loadbalancetest
+ 127.0.0.2 pg-loadbalancetest
+ 127.0.0.3 pg-loadbalancetest
+ EOF
+
+ # Normally, the "relation segment" code basically has no coverage in our
+ # tests, because we (quite reasonably) don't generate tables large
+ # enough in tests. We've had plenty bugs that we didn't notice due the
+ # code not being exercised much. Thus specify a very small segment size
+ # here. Use a non-power-of-two segment size, given we currently allow
+ # that.
+ - name: Configure
+ run: |
+ su postgres <<EOF
+ set -e
+ ./configure \
+ --enable-cassert --enable-injection-points --enable-debug \
+ --enable-tap-tests --enable-nls \
+ --with-segsize-blocks=6 \
+ --with-libnuma \
+ --with-liburing \
+ \
+ ${LINUX_CONFIGURE_FEATURES} \
+ \
+ CLANG="ccache clang"
+ EOF
+
+ - name: Build
+ run: su postgres -c "make -s -j${BUILD_JOBS} world-bin"
+
+ - name: Test world
+ run: |
+ su postgres <<EOF
+ set -e
+ ulimit -c unlimited
+ make -s ${CHECK} ${CHECKFLAGS} -j${TEST_JOBS}
+ EOF
+
+ - name: Core backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh linux /tmp/cores
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: linux-autoconf-logs-${{ github.run_id }}
+ path: |
+ **/*.log
+ **/*.diffs
+ **/regress_log_*
+ if-no-files-found: ignore
+
+
+ # SPECIAL:
+ # - Uses undefined behaviour and alignment sanitizers, sanitizer failures
+ # are typically printed in the server log
+ # - Test both 64bit and 32 bit builds
+ # - Uses io_method=io_uring
+ # - Uses meson feature autodetection
+ linux-meson:
+ name: Linux - Debian Trixie - Meson
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.linux == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ container:
+ image: ${{ needs.setup.outputs.linux_ci_image }}
+ # See linux-autoconf for the details.
+ #
+ # --privileged is needed so the prepare step can write to sysctls
+ # under /proc/sys (it's mounted read-only without it). We use it to
+ # flip kernel.io_uring_disabled (default 2 on recent GH runner
+ # kernels, which makes io_uring_setup() return EPERM for everyone)
+ # and to set kernel.core_pattern.
+ options: --pid=host --ipc=host --ulimit memlock=-1:-1 --privileged
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ CCACHE_DIR: /tmp/ccache_dir
+ CCACHE_MAXSIZE: "400M" # tests two different builds
+ DEBUGINFOD_URLS: "https://debuginfod.debian.net"
+
+ SANITIZER_FLAGS: -fsanitize=alignment,undefined
+ UBSAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:verbosity=2
+ ASAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:detect_leaks=0:detect_stack_use_after_return=0
+ CFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=alignment,undefined
+ CXXFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=alignment,undefined
+ LDFLAGS: -fsanitize=alignment,undefined
+ CC: ccache gcc
+ CXX: ccache g++
+
+ MESON_FEATURES: >-
+ -Duuid=e2fs
+
+ PG_TEST_INITDB_EXTRA_OPTS: >-
+ -c io_method=io_uring
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-linux-meson-${{ github.run_id }}
+ restore-keys: ccache-linux-meson-
+
+ - name: Prepare workspace
+ run: |
+ useradd -m postgres
+ chown -R postgres:postgres .
+ mkdir -p "$CCACHE_DIR"
+ chown -R postgres:postgres "$CCACHE_DIR"
+ mkdir -m 770 /tmp/cores
+ chown root:postgres /tmp/cores
+ sysctl kernel.core_pattern='/tmp/cores/%e-%s-%p.core'
+
+ # Enable io_uring; GH runner kernels default to 2 (disabled).
+ sysctl -w kernel.io_uring_disabled=0
+
+ cat >> /etc/hosts <<-EOF
+ 127.0.0.1 pg-loadbalancetest
+ 127.0.0.2 pg-loadbalancetest
+ 127.0.0.3 pg-loadbalancetest
+ EOF
+
+ - name: Configure (64-bit)
+ run: |
+ su postgres <<EOF
+ set -e
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ ${MESON_FEATURES} \
+ --buildtype=debug \
+ -Dllvm=enabled \
+ build
+ EOF
+
+ # Also build & test in a 32bit build - it's gotten rare to test that
+ # locally.
+ - name: Configure (32-bit)
+ run: |
+ su postgres <<EOF
+ set -e
+ export CC='ccache gcc -m32'
+ export CXX='ccache g++ -m32'
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ ${MESON_FEATURES} \
+ --buildtype=debug \
+ --pkg-config-path /usr/lib/i386-linux-gnu/pkgconfig/ \
+ -DPERL=perl5.40-i386-linux-gnu \
+ -Dlibnuma=disabled \
+ build-32
+ EOF
+
+ - name: Build (64-bit)
+ run: |
+ su postgres <<EOF
+ set -e
+ ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+ ninja -C build -t missingdeps
+ EOF
+
+ - name: Build (32-bit)
+ run: |
+ su postgres <<EOF
+ set -e
+ ninja -C build-32 -j${BUILD_JOBS} ${MBUILD_TARGET}
+ ninja -C build-32 -t missingdeps
+ EOF
+
+ - name: Test world (64-bit)
+ run: |
+ su postgres <<EOF
+ set -e
+ ulimit -c unlimited
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+ EOF
+ # so that we don't upload 64-bit logs if 32-bit fails
+ rm -rf build/
+
+ # There's currently no coverage of icu with LANG=C in the buildfarm. We
+ # can easily provide some here by running one of the sets of tests that
+ # way. Newer versions of python insist on changing the LC_CTYPE away
+ # from C, prevent that with PYTHONCOERCECLOCALE.
+ - name: Test world (32-bit)
+ run: |
+ su postgres <<EOF
+ set -e
+ ulimit -c unlimited
+ PYTHONCOERCECLOCALE=0 LANG=C meson test ${MTEST_ARGS} -C build-32 --num-processes ${TEST_JOBS}
+ EOF
+
+ - name: Core backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh linux /tmp/cores
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: linux-meson-logs-${{ github.run_id }}
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ if-no-files-found: ignore
+
+
+ # SPECIAL:
+ # - Enables --clone for pg_upgrade and pg_combinebackup
+ # - Specifies configuration options that test reading/writing/copying of node trees
+ # - Specifies debug_parallel_query=regress, to catch related issues during CI
+ macos:
+ name: macOS - Sequoia - Meson
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.macos == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: macos-15
+ timeout-minutes: 60
+ env:
+ BUILD_JOBS: 4
+ # Test performance regresses noticeably when using all cores. 8 works OK.
+ # https://postgr.es/m/20220927040208.l3shfcidovpzqxfh%40awork3.anarazel.de
+ # Fix: Needs to be re-tested for Github Actions.
+ TEST_JOBS: 8
+
+ CCACHE_DIR: ${{ github.workspace }}/ccache_dir
+
+ MESON_FEATURES: >-
+ -Dbonjour=enabled
+ -Ddtrace=enabled
+ -Dgssapi=enabled
+ -Dlibcurl=enabled
+ -Dnls=enabled
+ -Duuid=e2fs
+
+ CC: ccache cc
+ CXX: ccache c++
+ CFLAGS: -Og -ggdb
+ CXXFLAGS: -Og -ggdb
+ PG_TEST_PG_UPGRADE_MODE: --clone
+ PG_TEST_PG_COMBINEBACKUP_MODE: --clone
+
+ # Several buildfarm animals enable these options. Without testing them
+ # during CI, it would be easy to cause breakage on the buildfarm with CI
+ # passing.
+ PG_TEST_INITDB_EXTRA_OPTS: >-
+ -c debug_copy_parse_plan_trees=on
+ -c debug_write_read_parse_plan_trees=on
+ -c debug_raw_expression_coverage_test=on
+ -c debug_parallel_query=regress
+
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Sysinfo
+ run: |
+ id
+ uname -a
+ ulimit -a -H && ulimit -a -S
+ env
+
+ - name: Setup core files
+ run: |
+ mkdir -p $HOME/cores
+ sudo sysctl kern.corefile="$HOME/cores/core.%P"
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-macos-${{ github.run_id }}
+ restore-keys: ccache-macos-
+
+ # Install dependencies via Homebrew rather than Macports. On stock
+ # GH runners macports requires a heavy bootstrap, and the relevant
+ # Postgres deps are all available in brew.
+ - name: Install dependencies
+ run: |
+ brew update
+ brew install \
+ ccache meson openldap [email protected] tcl-tk
+ # IPC::Run via cpanm (system perl)
+ sudo cpan -T -i IPC::Run IO::Tty
+
+ - name: Configure
+ run: |
+ # These formulae are keg-only (not symlinked into $(brew --prefix)),
+ # so pkg-config wouldn't find them via the default search path.
+ # lz4, zstd and other non-keg-only deps are picked up automatically.
+ for f in openssl@3 icu4c krb5 openldap; do
+ PKG_CONFIG_PATH="$(brew --prefix $f)/lib/pkgconfig:${PKG_CONFIG_PATH}"
+ done
+ export PKG_CONFIG_PATH
+ extra_inc=
+ extra_lib=
+ for f in gettext krb5; do
+ prefix=$(brew --prefix $f)
+ extra_inc="${extra_inc:+$extra_inc,}${prefix}/include"
+ extra_lib="${extra_lib:+$extra_lib,}${prefix}/lib"
+ done
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ --buildtype=debug \
+ -Dextra_include_dirs="${extra_inc}" \
+ -Dextra_lib_dirs="${extra_lib}" \
+ ${MESON_COMMON_FEATURES} \
+ ${MESON_FEATURES} \
+ build
+
+ - name: Build
+ run: ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+
+ - name: Test world
+ run: |
+ ulimit -c unlimited
+ ulimit -n 1024
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+
+ - name: Core backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh macos "$HOME/cores"
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: macos-logs-${{ github.run_id }}
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ if-no-files-found: ignore
+
+
+ windows-vs:
+ name: Windows - Server 2022, VS 2022 - Meson & ninja
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.windows == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: windows-2022
+ timeout-minutes: 60
+ env:
+ TEST_JOBS: 8
+ # Avoid port conflicts between concurrent tap tests
+ PG_TEST_USE_UNIX_SOCKETS: 1
+ PG_REGRESS_SOCK_DIR: 'c:\pgsock\'
+
+ MESON_FEATURES: >-
+ -Dcpp_args=/std:c++20
+ -Dauto_features=disabled
+ -Dtap_tests=enabled
+ -Dldap=enabled
+ -Dssl=openssl
+ -Dplperl=enabled
+ -Dplpython=enabled
+ TAR: "c:/windows/system32/tar.exe"
+
+ defaults:
+ run:
+ shell: cmd
+ steps:
+ - name: Disable Windows Defender
+ shell: powershell
+ run: |
+ Set-MpPreference -DisableRealtimeMonitoring $true -SubmitSamplesConsent NeverSend -MAPSReporting Disable
+ # Verify Defender status
+ $status = Get-MpComputerStatus -ErrorAction SilentlyContinue
+ if ($status) {
+ Write-Host "RealTimeProtectionEnabled: $($status.RealTimeProtectionEnabled)"
+ Write-Host "AntivirusEnabled: $($status.AntivirusEnabled)"
+ }
+
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Sysinfo
+ run: |
+ chcp
+ systeminfo
+ set
+
+ # The TAP tests build an initdb template under build/tmp_install and
+ # then `robocopy` it into per-test data directories. Robocopy with the
+ # default /COPY:DAT flag doesn't copy ACLs — destinations inherit from
+ # their parent dir. On GitHub-hosted Windows runners the workspace's
+ # inherited ACL grants Administrators:(F) and Users:(RX) but does NOT
+ # grant the runner user (runneradmin) directly. That matters because
+ # pg_ctl on Windows uses CreateRestrictedProcess to drop admin
+ # privileges from postmaster, so the postmaster process has the user
+ # SID in its token but no longer the Administrators group — leaving it
+ # with only "Users:(RX)" on pg_control and friends, which causes
+ # "PANIC: could not open file global/pg_control: Permission denied".
+ #
+ # Fix it once on the workspace dir with (OI)(CI) inheritance flags so
+ # every file/dir created underneath gets an explicit grant for the
+ # current user.
+ - name: Grant workspace ACL to runner user
+ shell: pwsh
+ run: |
+ icacls "${{ github.workspace }}" /grant "${env:USERNAME}:(OI)(CI)F" /Q | Out-Null
+ Write-Host "Granted Full Control to $env:USERNAME on ${{ github.workspace }}"
+
+ # postgres' plpython3u loads python3.dll (the stable-ABI forwarder)
+ # which in turn loads whichever python3NN.dll the Windows loader finds
+ # first on PATH. On windows-2022 `C:\Program Files\Mercurial\` ships
+ # its own python3.dll + python39.dll and appears on PATH *before* the
+ # hostedtoolcache Python 3.12 — so without intervention the backend
+ # ends up running Python 3.9 while postgres' stdlib search uses 3.12,
+ # producing `ImportError: cannot import name 'text_encoding' from
+ # 'io'` (the 3.12 `io.py` calling into 3.9's `_io`).
+ #
+ # Pin PYTHONHOME to the Python 3.12 prefix, and prepend that prefix
+ # to PATH so its python3.dll wins the DLL search.
+ - name: Pin Python prefix on PATH and PYTHONHOME
+ shell: pwsh
+ run: |
+ $prefix = (python -c "import sys; print(sys.prefix)").Trim()
+ Add-Content $env:GITHUB_ENV "PYTHONHOME=$prefix"
+ Add-Content $env:GITHUB_PATH $prefix
+ Write-Host "PYTHONHOME=$prefix"
+ Write-Host "Prepended $prefix to PATH"
+
+ - name: Install dependencies
+ shell: pwsh
+ run: |
+ choco install -y --no-progress --limitoutput diffutils winflexbison
+ # meson + ninja aren't preinstalled on windows-2022. Install via pip
+ python -m pip install --upgrade meson ninja
+
+ # OpenSSL 1.1 via the slproweb installer (pinned to match the
+ # version used elsewhere in postgres CI).
+ curl.exe -fsSL -o openssl-setup.exe https://slproweb.com/download/Win64OpenSSL-1_1_1w.exe
+ Start-Process -Wait -FilePath ./openssl-setup.exe `
+ -ArgumentList '/DIR=c:\openssl\1.1\ /VERYSILENT /SP- /SUPPRESSMSGBOXES'
+ # The slproweb installer puts libcrypto-1_1-x64.dll / libssl-1_1-x64.dll
+ # in c:\openssl\1.1\bin\ and updates the system PATH. GH Actions
+ # snapshots PATH at job start though, so the running job won't
+ # see those DLLs and initdb.exe would crash silently at runtime.
+ # Push the bin dir onto GITHUB_PATH so it persists for later steps.
+ Add-Content $env:GITHUB_PATH "c:\openssl\1.1\bin"
+
+ # Install IPC::Run.
+ # - recommends_policy=0 keeps cpan from pulling in IO::Tty / IO::Pty,
+ # which don't build on Windows ("This module requires a POSIX
+ # compliant system to work").
+ # - Pin to NJM/IPC-Run-20250809.0 because TODDR/IPC-Run-20260322.0
+ # broke postgres tap tests on Windows (changed pipe stdio
+ # handling). See upstream pg-vm-images commit ff5238afa3 and
+ # the thread at
+ # https://postgr.es/m/CAN55FZ06xanSbJdHe-CurjX_qNuBWZDEvS1kAk36L38YCtZXnw%40mail.gmail.com
+ "o conf recommends_policy 0`no conf commit`nnotest install NJM/IPC-Run-20250809.0.tar.gz" | cpan
+ perl -mIPC::Run -e 1
+
+ - name: Setup hosts file
+ shell: pwsh
+ run: |
+ Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.1 pg-loadbalancetest"
+ Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.2 pg-loadbalancetest"
+ Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.3 pg-loadbalancetest"
+
+ - name: Setup sock dir
+ shell: cmd
+ run: mkdir %PG_REGRESS_SOCK_DIR%
+
+ - name: Configure
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ meson setup --backend ninja %MESON_COMMON_PG_CONFIG_ARGS% %MESON_FEATURES% --buildtype debug -Db_pch=true -Dextra_lib_dirs=c:\openssl\1.1\lib -Dextra_include_dirs=c:\openssl\1.1\include -DTAR=%TAR% build
+
+ - name: Build
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ ninja -C build %MBUILD_TARGET%
+ ninja -C build -t missingdeps
+
+ - name: Test world
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ meson test %MTEST_ARGS% --num-processes %TEST_JOBS%
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: windows-vs-logs-${{ github.run_id }}
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ crashlog-*.txt
+ if-no-files-found: ignore
+
+
+ windows-mingw:
+ name: Windows - Server 2022, MinGW64 - Meson
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.mingw == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: windows-2022
+ timeout-minutes: 60
+ env:
+ TEST_JOBS: 4 # higher concurrency causes occasional failures
+ PG_TEST_USE_UNIX_SOCKETS: 1
+ PG_REGRESS_SOCK_DIR: 'c:\pgsock\'
+ TAR: "c:/windows/system32/tar.exe"
+ # for mingw plpython to find its installation
+ PYTHONHOME: D:/a/_temp/msys64/ucrt64
+
+ MSYS: winjitdebug
+ CHERE_INVOKING: 1
+
+ MESON_FEATURES: >-
+ -Dnls=disabled
+
+ CCACHE_DIR: D:/a/ccache
+ CCACHE_MAXSIZE: "500M"
+ CCACHE_SLOPPINESS: pch_defines,time_macros
+ CCACHE_DEPEND: 1
+
+ steps:
+ - name: Disable Windows Defender
+ shell: powershell
+ run: |
+ Set-MpPreference -DisableRealtimeMonitoring $true -SubmitSamplesConsent NeverSend -MAPSReporting Disable
+ # Verify Defender status
+ $status = Get-MpComputerStatus -ErrorAction SilentlyContinue
+ if ($status) {
+ Write-Host "RealTimeProtectionEnabled: $($status.RealTimeProtectionEnabled)"
+ Write-Host "AntivirusEnabled: $($status.AntivirusEnabled)"
+ }
+
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Setup MSYS2
+ uses: msys2/setup-msys2@v2
+ with:
+ msystem: UCRT64
+ update: true
+ install: >-
+ git bison flex make diffutils
+ mingw-w64-ucrt-x86_64-ccache
+ mingw-w64-ucrt-x86_64-docbook-xml
+ mingw-w64-ucrt-x86_64-gcc
+ mingw-w64-ucrt-x86_64-icu
+ mingw-w64-ucrt-x86_64-libbacktrace
+ mingw-w64-ucrt-x86_64-libxml2
+ mingw-w64-ucrt-x86_64-libxslt
+ mingw-w64-ucrt-x86_64-lz4
+ mingw-w64-ucrt-x86_64-make
+ mingw-w64-ucrt-x86_64-meson
+ mingw-w64-ucrt-x86_64-perl
+ mingw-w64-ucrt-x86_64-pkg-config
+ mingw-w64-ucrt-x86_64-python-cryptography
+ mingw-w64-ucrt-x86_64-python-pip
+ mingw-w64-ucrt-x86_64-python-pytest
+ mingw-w64-ucrt-x86_64-readline
+ mingw-w64-ucrt-x86_64-zlib
+
+ - name: Install IPC::Run for tap tests
+ shell: msys2 {0}
+ run: |
+ # Pin IPC::Run to NJM/IPC-Run-20250809.0; TODDR/IPC-Run-20260322.0
+ # broke postgres tap tests on Windows (pipe stdio handling).
+ # See pg-vm-images commit ff5238afa3.
+ (echo; echo o conf recommends_policy 0; echo notest install NJM/IPC-Run-20250809.0.tar.gz) | cpan
+ perl -mIPC::Run -e 1
+
+ - name: Setup sock dir
+ shell: cmd
+ run: mkdir %PG_REGRESS_SOCK_DIR%
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-mingw-${{ github.run_id }}
+ restore-keys: ccache-mingw-
+
+ - name: Configure
+ shell: msys2 {0}
+ run: |
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ -Ddebug=true -Doptimization=g -Db_pch=true \
+ ${MESON_COMMON_FEATURES} \
+ ${MESON_FEATURES} \
+ -DTAR=${TAR} \
+ build
+
+ - name: Build
+ shell: msys2 {0}
+ run: ninja -C build ${MBUILD_TARGET}
+
+ - name: Test world
+ shell: msys2 {0}
+ run: meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: windows-mingw-logs-${{ github.run_id }}
+ path: |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+ crashlog-*.txt
+ if-no-files-found: ignore
+
+ # Test that code can be built with both gcc and clang without warnings,
+ # with various combinations of cassert/dtrace flags. Trace probes have
+ # a history of getting accidentally broken; the matrix is there to
+ # catch that.
+ #
+ # The autoconf cache files (gcc.cache / clang.cache) are intentionally
+ # reused across the matrix entries that share a compiler, so we don't
+ # pay for full feature detection on every entry.
+ compiler-warnings:
+ name: CompilerWarnings
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.compilerwarnings == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ container:
+ image: ${{ needs.setup.outputs.linux_ci_image }}
+ env:
+ BUILD_JOBS: 4
+ CCACHE_DIR: /tmp/ccache_dir
+ # Use larger ccache cache as this job compiles with multiple
+ # compilers / flag combinations.
+ CCACHE_MAXSIZE: "1G"
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-compiler-warnings-${{ github.run_id }}
+ restore-keys: ccache-compiler-warnings-
+
+ - name: Sysinfo
+ run: |
+ id
+ uname -a
+ cat /proc/cmdline
+ ulimit -a -H && ulimit -a -S
+ gcc -v
+ clang -v
+ env
+
+ - name: Setup workspace
+ run: |
+ echo "COPT=-Werror" > src/Makefile.custom
+ mkdir -p "$CCACHE_DIR"
+
+ # gcc, cassert off, dtrace on
+ - name: gcc warning + (dtrace)
+ if: always()
+ run: |
+ ./configure \
+ --cache gcc.cache \
+ --enable-dtrace \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ # gcc, cassert on, dtrace off
+ - name: gcc warning + (cassert)
+ if: always()
+ run: |
+ ./configure \
+ --cache gcc.cache \
+ --enable-cassert \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ # clang, cassert off, dtrace off
+ - name: clang warning
+ if: always()
+ run: |
+ ./configure \
+ --cache clang.cache \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache clang" CXX="ccache clang++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ # clang, cassert on, dtrace on
+ - name: clang warning + (cassert + dtrace)
+ if: always()
+ run: |
+ ./configure \
+ --cache clang.cache \
+ --enable-cassert \
+ --enable-dtrace \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache clang" CXX="ccache clang++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ - name: mingw cross compile
+ if: always()
+ run: |
+ ./configure \
+ --host=x86_64-w64-mingw32ucrt \
+ --enable-cassert \
+ --without-icu \
+ CC="ccache x86_64-w64-mingw32ucrt-gcc" \
+ CXX="ccache x86_64-w64-mingw32ucrt-g++"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ ###
+ # Verify docs can be built
+ ###
+ # XXX: Only do this if there have been changes in doc/ since last build
+ - name: Docs build
+ if: always()
+ run: |
+ ./configure \
+ --cache gcc.cache \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} -C doc
+
+ ###
+ # Verify headerscheck / cpluspluscheck succeed
+ #
+ # - Run both in same script to increase parallelism, use -k to get
+ # result of both
+ # - Use -fmax-errors, as particularly cpluspluscheck can be very verbose
+ ###
+ - name: headerscheck + cpluspluscheck
+ if: always()
+ run: |
+ ./configure \
+ ${LINUX_CONFIGURE_FEATURES} \
+ --cache gcc.cache \
+ --quiet \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} -k ${CHECKFLAGS} headerscheck cpluspluscheck EXTRAFLAGS='-fmax-errors=10'
--
2.47.3
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-27 03:54 Thomas Munro <[email protected]>
parent: Jelte Fennema-Nio <[email protected]>
1 sibling, 0 replies; 42+ messages in thread
From: Thomas Munro @ 2026-05-27 03:54 UTC (permalink / raw)
To: Jelte Fennema-Nio <[email protected]>; +Cc: Andres Freund <[email protected]>; Nazir Bilal Yavuz <[email protected]>; pgsql-hackers
On Tue, May 19, 2026 at 9:22 AM Jelte Fennema-Nio <[email protected]> wrote:
> 3. There's currently no integration with the CFBot or commitfest yet. @Thomas
Looking into this part urgently...
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-27 18:10 Andres Freund <[email protected]>
parent: Nazir Bilal Yavuz <[email protected]>
3 siblings, 3 replies; 42+ messages in thread
From: Andres Freund @ 2026-05-27 18:10 UTC (permalink / raw)
To: Nazir Bilal Yavuz <[email protected]>; +Cc: Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers
Hi,
> Here is the v2, I took Jelte's patch and reviewed & merged it with my
> patch. Updates and questions are:
>
> 1- I continued to use Jelte's container method (Linux tasks only for
> now, BSD tasks will be included in the future) because I think that is
> the future-proof way since we might want to generate our container
> images in the future. Also, up-to-date Debian images can be tested
> with this way; otherwise we would need to use Ubuntu 24.04.
Good.
> 2- io_uring tests work on the Linux Meson task.
Is there a reason to not just do that for all the tasks?
> 3- I didn't put commands to helper scripts for now. I think it is a
> good thing to have a helper script but it would be better to have this
> helper script after the first version is committed since it can extend
> the timeline. Also, I found that having all commands in one file makes
> debugging easier.
Hm. I'm a bit worried about this getting pretty unmaintainable, due to the
repetition. I think at least we need to use yaml anchors to deduplicate some
steps.
> 4- FreeBSD task has these options:
>
> PG_TEST_INITDB_EXTRA_OPTS: >-
> -c debug_copy_parse_plan_trees=on
> -c debug_write_read_parse_plan_trees=on
> -c debug_raw_expression_coverage_test=on
> -c debug_parallel_query=regress
>
> Since we won't have FreeBSD for the first version. I put these options
> to the MacOS task but I couldn't decide where to put
> 'PG_TEST_PG_UPGRADE_MODE: --link'.
Makes sense.
> Also, I am planning to work on back patches when we agree on the
> upstream one. Does that sound good?
Yep.
> diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
> new file mode 100644
> index 00000000000..6d20068727c
> --- /dev/null
> +++ b/.github/workflows/ci.yml
> @@ -0,0 +1,1125 @@
> +# GitHub Actions CI configuration for PostgreSQL
> +
> +name: Github Actions CI
> +
> +on:
> + push:
> + branches: [ "*" ]
> +
> +# Default to the minimum privilege the jobs need (just reading the repo
> +# contents during checkout). Individual jobs override this when they need
> +# more, e.g. `cancel-previous` needs `actions: write` to cancel runs.
> +permissions:
> + contents: read
I'm not sure I like that we ever need more than that. I'd expect that
postgresql-cfbot will explicitly disable write permissions for runs.
> +# NB: intentionally NO workflow-level `concurrency:` block. The native
> +# concurrency mechanism makes a new run wait for the previous one to fully
> +# cancel before it starts — which can take a while. Instead the
> +# `cancel-previous` job below fires a cancel API call asynchronously,
> +# so the new run gets going immediately. On master the cancel job is skipped,
> +# so every push runs to completion.
Is this really worth having our own code? Seems like it'd not be that frequent
to push if there are already running runs? What kind of delays are we talking
about?
> + # To avoid unnecessarily spinning up a lot of VMs / containers for entirely
> + # broken commits, have a minimal task that all others depend on.
> + #
> + # SPECIAL:
> + # - Builds with --auto-features=disabled and thus almost no enabled
> + # dependencies
> + sanity-check:
> + name: SanityCheck
> + needs: setup
> + if: needs.setup.outputs.sanitycheck == 'true'
> + runs-on: ubuntu-latest
> + timeout-minutes: 15
> + container:
> + image: ${{ needs.setup.outputs.linux_ci_image }}
> + env:
> + BUILD_JOBS: 8
> + TEST_JOBS: 8
> + CCACHE_DIR: ${{ github.workspace }}/ccache_dir
> + # no options enabled, should be small
> + CCACHE_MAXSIZE: "150M"
> + steps:
> + - uses: actions/checkout@v6
> + with:
> + fetch-depth: ${{ env.CLONE_DEPTH }}
> +
> + - name: Restore ccache
> + uses: actions/cache@v5
Seems like this is used by every task. Can we move this into a yaml anchor or
such, by using a variable representing the job name?
> + with:
> + path: ${{ env.CCACHE_DIR }}
> + key: ccache-sanitycheck-${{ github.run_id }}
> + restore-keys: ccache-sanitycheck-
Why is the key here the run id? Doesn't that mean that we will never have a
precise cache match and that we will keep multiple versions of the cache
around? That seems like a waste of cache space?
For efficiency, particularly on cfbot, it seems like it could be useful to
populate the cache of branches with the cache of the master branch. For that
we'd need the branch name in the key. Which I think would also good for
postgres/postgres, as we currently have a lot of interference between runs on
the main and the REL_XY_STABLE branches.
> + - name: Prepare workspace
> + run: |
> + whoami
> + useradd -m postgres
> + chown -R postgres:postgres .
> + mkdir -p "$CCACHE_DIR"
> + chown -R postgres:postgres "$CCACHE_DIR"
> + # Can't change the container's kernel.core_pattern; the postgres
> + # user can't write to / normally. Make / writable.
> + chown root:postgres /
> + chmod g+rwx /
Why not just always use a privileged container?
> + - name: Configure
> + run: |
> + su postgres <<-'EOF'
> + set -e
> + meson setup \
> + --buildtype=debug \
> + --auto-features=disabled \
> + -Ddefault_library=shared \
> + -Dtap_tests=enabled \
> + build
> + EOF
> +
> + - name: Build
> + run: |
> + su postgres <<EOF
> + set -e
> + ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
> + EOF
Should we have an explicit cache upload step here? Or are upload steps run
unconditionally?
> + # Run a minimal set of tests. The main regression tests take too long
> + # for this purpose. For now this is a random quick pg_regress style
> + # test, and a tap test that exercises both a frontend binary and the
> + # backend.
> + - name: Test
> + run: |
> + su postgres <<EOF
> + set -e
> + ulimit -c unlimited
> + meson test ${MTEST_ARGS} --suite setup
> + meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS} \
> + cube/regress pg_ctl/001_start_stop
> + EOF
> +
> + - name: Core backtraces
> + if: failure()
> + run: |
> + mkdir -m 770 /tmp/cores
> + find / -maxdepth 1 -type f -name 'core*' -exec mv '{}' /tmp/cores/ \;
> + src/tools/ci/cores_backtrace.sh linux /tmp/cores
> +
> + - name: Upload logs
> + if: failure()
> + uses: actions/upload-artifact@v7
> + with:
> + name: sanitycheck-logs-${{ github.run_id }}
> + path: |
> + build*/testrun/**/*.log
> + build*/testrun/**/*.diffs
> + build*/testrun/**/regress_log_*
> + build*/meson-logs/*.txt
> + if-no-files-found: ignore
I think this really should be in a yaml anchor, we have a few somewhat
different versions of this now.
It's pretty annoying that the output of the failures isn't visible in the UI.
Maybe we ought to print a few of the failures out or something?
> +
> + # SPECIAL:
> + # - Uses address sanitizer (sanitizer failures are typically printed in
> + # the server log)
> + # - Configures postgres with a small segment size
> + #
> + # Enable a reasonable set of sanitizers. Use the linux task for that, as
> + # it's one of the fastest tasks (without sanitizers). Also several of the
> + # sanitizers work best on linux.
> + #
> + # The overhead of alignment sanitizer is low, undefined behaviour has
> + # moderate overhead. Test alignment sanitizer in the meson task, as it
> + # does both 32 and 64 bit builds and is thus more likely to expose
> + # alignment bugs.
> + #
> + # Address sanitizer in contrast is somewhat expensive. Enable it in the
> + # autoconf task, as the meson task tests both 32 and 64bit.
I wonder if we should split the meson task into two, one for 32bit and one for
64bit. The concurrency limits for public repos are high enough for that to
seem like a reasonable tradeoff? There's no work, other than the repo
checkout, shared between them.
> + # disable_coredump=0, abort_on_error=1: for useful backtraces in case of crashes
> + # print_stacktraces=1,verbosity=2, duh
> + # detect_leaks=0: too many uninteresting leak errors in short-lived binaries
> + linux-autoconf:
> + name: Linux - Debian Trixie - Autoconf
> + needs: [setup, sanity-check]
> + if: |
> + !cancelled() &&
> + needs.setup.outputs.linux == 'true' &&
> + needs.sanity-check.result != 'failure'
> + runs-on: ubuntu-latest
> + timeout-minutes: 60
> + container:
> + image: ${{ needs.setup.outputs.linux_ci_image }}
> + # Share the host PID + IPC namespaces. 017_shm.pl rapidly creates,
> + # kill9's, and restarts postgres; with the container's small PID
> + # space a new postgres can recycle the dead postmaster's PID before
> + # pg_ctl's postmaster.pid check notices, producing spurious "node X
> + # is already running" failures. SysV shm in the test also relies on
> + # host-like IPC behavior.
> + #
> + # --ulimit raises memlock and core dump size. Memlock is needed for
> + # running the AIO tests.
> + #
> + # --privileged is needed so the prepare step can write to sysctls
> + # under /proc/sys (it's mounted read-only without it). We use it to
> + # set kernel.core_pattern.
> + options: --pid=host --ipc=host --ulimit memlock=-1:-1 --privileged
> + env:
> + BUILD_JOBS: 4
> + TEST_JOBS: 8
> + CCACHE_DIR: /tmp/ccache_dir
> + DEBUGINFOD_URLS: "https://debuginfod.debian.net";
> +
> + SANITIZER_FLAGS: -fsanitize=address
> + UBSAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:verbosity=2
> + ASAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:detect_leaks=0:detect_stack_use_after_return=0
> + CFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=address
> + CXXFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=address
> + LDFLAGS: -fsanitize=address
> + CC: ccache gcc
> + CXX: ccache g++
There's a fair bit of stuff shared between the meson/autoconf linux
tasks. Previously they used a matrix to reduce that a *bit*. But now it's
entirely duplicated, including stuff that doesn't apply to the current job
(e.g. UBSAN_OPTIONS/ASAN_OPTIONS). And blocks like the following:
> + - name: Prepare workspace
> + run: |
> + useradd -m postgres
> + chown -R postgres:postgres .
> + mkdir -p "$CCACHE_DIR"
> + chown -R postgres:postgres "$CCACHE_DIR"
> + mkdir -m 770 /tmp/cores
> + chown root:postgres /tmp/cores
> + sysctl kernel.core_pattern='/tmp/cores/%e-%s-%p.core'
> +
> + # Hosts for the load balance test
> + cat >> /etc/hosts <<-EOF
> + 127.0.0.1 pg-loadbalancetest
> + 127.0.0.2 pg-loadbalancetest
> + 127.0.0.3 pg-loadbalancetest
> + EOF
> + # Install dependencies via Homebrew rather than Macports. On stock
> + # GH runners macports requires a heavy bootstrap, and the relevant
> + # Postgres deps are all available in brew.
What does "heavy bootstrap" mean?
> + - name: Install dependencies
> + run: |
> + brew update
> + brew install \
> + ccache meson openldap [email protected] tcl-tk
> + # IPC::Run via cpanm (system perl)
> + sudo cpan -T -i IPC::Run IO::Tty
We do spend ~95s on this every run, that's not nothing. And it puts a bunch of
load onto the brew's mirrors to do that every run.
> + - name: Test world
> + run: |
> + ulimit -c unlimited
> + ulimit -n 1024
> + meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
I'd re-add the comments that were in .cirrus.yml about this.
> + windows-vs:
> + name: Windows - Server 2022, VS 2022 - Meson & ninja
> + needs: [setup, sanity-check]
> + if: |
> + !cancelled() &&
> + needs.setup.outputs.windows == 'true' &&
> + needs.sanity-check.result != 'failure'
> + runs-on: windows-2022
> + timeout-minutes: 60
> + env:
> + TEST_JOBS: 8
> + # Avoid port conflicts between concurrent tap tests
> + PG_TEST_USE_UNIX_SOCKETS: 1
> + PG_REGRESS_SOCK_DIR: 'c:\pgsock\'
At least my editor gets confused by the \', thinking it's escaping the '. As
everything just works without the trailing \, I'd go that way.
> + # The TAP tests build an initdb template under build/tmp_install and
> + # then `robocopy` it into per-test data directories. Robocopy with the
> + # default /COPY:DAT flag doesn't copy ACLs — destinations inherit from
> + # their parent dir. On GitHub-hosted Windows runners the workspace's
> + # inherited ACL grants Administrators:(F) and Users:(RX) but does NOT
> + # grant the runner user (runneradmin) directly. That matters because
> + # pg_ctl on Windows uses CreateRestrictedProcess to drop admin
> + # privileges from postmaster, so the postmaster process has the user
> + # SID in its token but no longer the Administrators group — leaving it
> + # with only "Users:(RX)" on pg_control and friends, which causes
> + # "PANIC: could not open file global/pg_control: Permission denied".
> + #
> + # Fix it once on the workspace dir with (OI)(CI) inheritance flags so
> + # every file/dir created underneath gets an explicit grant for the
> + # current user.
> + - name: Grant workspace ACL to runner user
> + shell: pwsh
> + run: |
> + icacls "${{ github.workspace }}" /grant "${env:USERNAME}:(OI)(CI)F" /Q | Out-Null
> + Write-Host "Granted Full Control to $env:USERNAME on ${{ github.workspace }}"
Perhaps this would be better to fix by changing the robocopy flags?
> + # postgres' plpython3u loads python3.dll (the stable-ABI forwarder)
> + # which in turn loads whichever python3NN.dll the Windows loader finds
> + # first on PATH. On windows-2022 `C:\Program Files\Mercurial\` ships
> + # its own python3.dll + python39.dll and appears on PATH *before* the
> + # hostedtoolcache Python 3.12 — so without intervention the backend
> + # ends up running Python 3.9 while postgres' stdlib search uses 3.12,
> + # producing `ImportError: cannot import name 'text_encoding' from
> + # 'io'` (the 3.12 `io.py` calling into 3.9's `_io`).
> + #
> + # Pin PYTHONHOME to the Python 3.12 prefix, and prepend that prefix
> + # to PATH so its python3.dll wins the DLL search.
> + - name: Pin Python prefix on PATH and PYTHONHOME
> + shell: pwsh
> + run: |
> + $prefix = (python -c "import sys; print(sys.prefix)").Trim()
> + Add-Content $env:GITHUB_ENV "PYTHONHOME=$prefix"
> + Add-Content $env:GITHUB_PATH $prefix
> + Write-Host "PYTHONHOME=$prefix"
> + Write-Host "Prepended $prefix to PATH"
GRJGJKLJKJDFJKDF.
> + - name: Install dependencies
> + shell: pwsh
> + run: |
> + choco install -y --no-progress --limitoutput diffutils winflexbison
> + # meson + ninja aren't preinstalled on windows-2022. Install via pip
> + python -m pip install --upgrade meson ninja
> +
> + # OpenSSL 1.1 via the slproweb installer (pinned to match the
> + # version used elsewhere in postgres CI).
> + curl.exe -fsSL -o openssl-setup.exe https://slproweb.com/download/Win64OpenSSL-1_1_1w.exe
> + Start-Process -Wait -FilePath ./openssl-setup.exe `
> + -ArgumentList '/DIR=c:\openssl\1.1\ /VERYSILENT /SP- /SUPPRESSMSGBOXES'
> + # The slproweb installer puts libcrypto-1_1-x64.dll / libssl-1_1-x64.dll
> + # in c:\openssl\1.1\bin\ and updates the system PATH. GH Actions
> + # snapshots PATH at job start though, so the running job won't
> + # see those DLLs and initdb.exe would crash silently at runtime.
> + # Push the bin dir onto GITHUB_PATH so it persists for later steps.
> + Add-Content $env:GITHUB_PATH "c:\openssl\1.1\bin"
I don't like that much, but I'm not sure we have a better alternative
short-term.
> + windows-mingw:
> + name: Windows - Server 2022, MinGW64 - Meson
> + needs: [setup, sanity-check]
> + if: |
> + !cancelled() &&
> + needs.setup.outputs.mingw == 'true' &&
> + needs.sanity-check.result != 'failure'
> + runs-on: windows-2022
> + timeout-minutes: 60
> + env:
> + TEST_JOBS: 4 # higher concurrency causes occasional failures
> + PG_TEST_USE_UNIX_SOCKETS: 1
> + PG_REGRESS_SOCK_DIR: 'c:\pgsock\'
> + TAR: "c:/windows/system32/tar.exe"
> + # for mingw plpython to find its installation
> + PYTHONHOME: D:/a/_temp/msys64/ucrt64
> +
> + MSYS: winjitdebug
> + CHERE_INVOKING: 1
> + MESON_FEATURES: >-
> + -Dnls=disabled
Missing comments from .cirrus.tasks.yml
Thanks for working on this!
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-27 20:33 Jelte Fennema-Nio <[email protected]>
parent: Andres Freund <[email protected]>
2 siblings, 0 replies; 42+ messages in thread
From: Jelte Fennema-Nio @ 2026-05-27 20:33 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Nazir Bilal Yavuz <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers
I didn't look at the patch, and I won't be able too before June 1st.
But I wanted to give some quick context on the things andres called
out, that I'm pretty sure originate from the patch I submitted.
On Wed, 27 May 2026 at 20:10, Andres Freund <[email protected]> wrote:
> > +# NB: intentionally NO workflow-level `concurrency:` block. The native
> > +# concurrency mechanism makes a new run wait for the previous one to fully
> > +# cancel before it starts — which can take a while. Instead the
> > +# `cancel-previous` job below fires a cancel API call asynchronously,
> > +# so the new run gets going immediately. On master the cancel job is skipped,
> > +# so every push runs to completion.
>
> Is this really worth having our own code? Seems like it'd not be that frequent
> to push if there are already running runs? What kind of delays are we talking
> about?
I agree this doesn't pull its weight and can be removed. It was part
of me trying to iterate quickly. I think it could take a few minutes
to cancel some of the jobs BSD nested virtualized jobs (might have
been other jobs though).
> I wonder if we should split the meson task into two, one for 32bit and one for
> 64bit.
+1
> > + # Install dependencies via Homebrew rather than Macports. On stock
> > + # GH runners macports requires a heavy bootstrap, and the relevant
> > + # Postgres deps are all available in brew.
>
> What does "heavy bootstrap" mean?
Not sure. This was Claude's doing. MacOS was green pretty quickly, so
I didn't bother questioning details while all the other builds were
still red.
> We do spend ~95s on this every run, that's not nothing. And it puts a bunch of
> load onto the brew's mirrors to do that every run.
I think we can only avoid that if we have our own runners.
> > + # The TAP tests build an initdb template under build/tmp_install and
> > + # then `robocopy` it into per-test data directories. Robocopy with the
> > + # default /COPY:DAT flag doesn't copy ACLs — destinations inherit from
> > + # their parent dir. On GitHub-hosted Windows runners the workspace's
> > + # inherited ACL grants Administrators:(F) and Users:(RX) but does NOT
> > + # grant the runner user (runneradmin) directly. That matters because
> > + # pg_ctl on Windows uses CreateRestrictedProcess to drop admin
> > + # privileges from postmaster, so the postmaster process has the user
> > + # SID in its token but no longer the Administrators group — leaving it
> > + # with only "Users:(RX)" on pg_control and friends, which causes
> > + # "PANIC: could not open file global/pg_control: Permission denied".
> > + #
> > + # Fix it once on the workspace dir with (OI)(CI) inheritance flags so
> > + # every file/dir created underneath gets an explicit grant for the
> > + # current user.
> > + - name: Grant workspace ACL to runner user
> > + shell: pwsh
> > + run: |
> > + icacls "${{ github.workspace }}" /grant "${env:USERNAME}:(OI)(CI)F" /Q | Out-Null
> > + Write-Host "Granted Full Control to $env:USERNAME on ${{ github.workspace }}"
>
> Perhaps this would be better to fix by changing the robocopy flags?
Getting the Windows build working took a lot of work. To be clear that
involved me copy-pasting log output into Claude or pointing it to
download log tarballs. All of these huge comments I *did not* write.
While iterating the comments seemed believable (but LLMs are good at
that). My intent was to review them for correctness and for cleaner
solutions. But I did not have time nor energy for that anymore. So
yeah other fixes might very well be better (similarly for the
python3 or openssl stuff).
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-27 22:15 Jacob Champion <[email protected]>
parent: Andres Freund <[email protected]>
2 siblings, 1 reply; 42+ messages in thread
From: Jacob Champion @ 2026-05-27 22:15 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Nazir Bilal Yavuz <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers
On Wed, May 27, 2026 at 11:10 AM Andres Freund <[email protected]> wrote:
> > +# Default to the minimum privilege the jobs need (just reading the repo
> > +# contents during checkout). Individual jobs override this when they need
> > +# more, e.g. `cancel-previous` needs `actions: write` to cancel runs.
> > +permissions:
> > + contents: read
>
> I'm not sure I like that we ever need more than that. I'd expect that
> postgresql-cfbot will explicitly disable write permissions for runs.
+1, and +1 for getting rid of the custom cancel, for that reason.
- Do we need to defend our downstream forks from this workflow? (We
have 5,700 of them, apparently.)
- Do the pginfra folks who own the repo need to lock down all the
Actions settings before we ship this? (On my fork, at least, the
default settings were horrifically permissive.)
--Jacob
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-27 23:10 Zsolt Parragi <[email protected]>
parent: Nazir Bilal Yavuz <[email protected]>
3 siblings, 1 reply; 42+ messages in thread
From: Zsolt Parragi @ 2026-05-27 23:10 UTC (permalink / raw)
To: [email protected]
Hello!
I didn't try the workflow on github yet, I only have a few comments
based on the yaml file:
+on:
+ push:
+ branches: [ "*" ]
+
Should this be "**", otherwise we ignore branches with a "/" in it?
+ SANITIZER_FLAGS: -fsanitize=address
is this used anywhere? Seems like it's directly included into CFLAGS/LDFLAGS.
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 11:49 Peter Eisentraut <[email protected]>
parent: Nazir Bilal Yavuz <[email protected]>
3 siblings, 1 reply; 42+ messages in thread
From: Peter Eisentraut @ 2026-05-28 11:49 UTC (permalink / raw)
To: Nazir Bilal Yavuz <[email protected]>; Jelte Fennema-Nio <[email protected]>; +Cc: Andres Freund <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers
On 25.05.26 14:14, Nazir Bilal Yavuz wrote:
> On Tue, 19 May 2026 at 01:27, Nazir Bilal Yavuz<[email protected]> wrote:
>> I think we can merge these two patches and move forward that way. I am
>> planning to review your patch and see what I can come up with to get
>> it to a committable state.
> Here is the v2, I took Jelte's patch and reviewed & merged it with my
> patch.
I have tested this patch and inspected the output mostly to make sure
that there are no regressions about what features and dependency
versions are being tested (diffed the various logs). I'm proposing a
few minor fixups in the attached patch, but other than that (and what
others have mentioned), this pretty much works well, and I would be
content to proceed with this or whatever state it's on in a few days.
Some comments in detail:
- Others have already mentioned about the potential for this to conflict
with downstream uses of GH Actions. I suggest renaming the file from
ci.yml to something like postgresql-ci.yml, so that there is no file
naming conflict or confusion.
- As was already mentioned, the Linux/Meson job is very long (slow) and
should be split into separate 32/64-bit jobs.
- The job names are too long and get truncated in the UI. This is
especially annoying when the important differentiator like "Autoconf" or
"Meson" gets cut off. I'm proposing some changes to the job names that
make them display better. (Also consider this if you make separate jobs
for 32/64-bit. The usable space is about 20 characters.)
- On macOS, there were some dependency differences:
- readline was not used.
- tcl-tk (version 9) was used instead of tcl-tk@8.
- [email protected] was installed but not actually used in the build.
- zlib version differed.
Maybe the zlib difference is not important and could be ignored.
Also, maybe we don't need to use a versioned python dependency. (We
didn't have one before we switched Cirrus from Homebrew to MacPorts.)
- On macOS, the meson setup output reported a significantly different
sysroot, which was confusing. I think the sysroot is only used if you
build against a system perl/python/tcl, which we don't, so I added an
option to disable the sysroot use. That way, if we do end up making use
of the sysroot, someone is forced to investigate this issue. I don't
know if this makes sense.
- For macOS, I threw in some HOMEBREW_* environment variables to disable
some unnecessary additional output or cleanup steps.
- On Windows/VS, we should install winflexbison3 not winflexbison, to
get an up-to-date version.
- FUTURE: On Windows/VS, we use openssl 1.1, which matches the Cirrus
setup, so it's ok, but the equivalent buildfarm members all use openssl
3.*, so we should consider upgrading that sometime to make that more
consistent.
- On Windows/minGW, I dropped a few packages from the set to be
installed, which didn't seem necessary.
From c1bab3b0809899a0b8fb61cdb398947c8f169a28 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 28 May 2026 13:20:50 +0200
Subject: [PATCH v2.1.pe] Fixups
- Shorten job names to avoid truncation in UI
- Tweak CompilerWarnings step names
- macOS:
- Add some HOMEBREW_* environment variables to disable unnecessary
steps and output
- Typo cpanm -> cpan
- Install readline tcl-tk@8 zlib for consistency with previous setup
- Disable sysroot
- Use the intended Python version
- Windows VS:
- Install winflexbison3, not winflexbison (old)
- Windows minGW:
- Reduce set of installed packages
---
.github/workflows/ci.yml | 49 +++++++++++++++++++++-------------------
1 file changed, 26 insertions(+), 23 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6d20068727c..21c4106e603 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -285,7 +285,7 @@ jobs:
# print_stacktraces=1,verbosity=2, duh
# detect_leaks=0: too many uninteresting leak errors in short-lived binaries
linux-autoconf:
- name: Linux - Debian Trixie - Autoconf
+ name: Linux - Debian - Autoconf
needs: [setup, sanity-check]
if: |
!cancelled() &&
@@ -410,7 +410,7 @@ jobs:
# - Uses io_method=io_uring
# - Uses meson feature autodetection
linux-meson:
- name: Linux - Debian Trixie - Meson
+ name: Linux - Debian - Meson
needs: [setup, sanity-check]
if: |
!cancelled() &&
@@ -570,7 +570,7 @@ jobs:
# - Specifies configuration options that test reading/writing/copying of node trees
# - Specifies debug_parallel_query=regress, to catch related issues during CI
macos:
- name: macOS - Sequoia - Meson
+ name: macOS - Meson
needs: [setup, sanity-check]
if: |
!cancelled() &&
@@ -585,6 +585,12 @@ jobs:
# Fix: Needs to be re-tested for Github Actions.
TEST_JOBS: 8
+ HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_DISPLAY_INSTALL_TIMES: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
+ HOMEBREW_NO_INSTALL_UPGRADE: 1
+ HOMEBREW_NO_UPDATE_REPORT_NEW: 1
+
CCACHE_DIR: ${{ github.workspace }}/ccache_dir
MESON_FEATURES: >-
@@ -642,16 +648,15 @@ jobs:
run: |
brew update
brew install \
- ccache meson openldap [email protected] tcl-tk
- # IPC::Run via cpanm (system perl)
+ ccache meson openldap [email protected] readline tcl-tk@8 zlib
+ # IPC::Run via cpan (system perl)
sudo cpan -T -i IPC::Run IO::Tty
- name: Configure
run: |
# These formulae are keg-only (not symlinked into $(brew --prefix)),
# so pkg-config wouldn't find them via the default search path.
- # lz4, zstd and other non-keg-only deps are picked up automatically.
- for f in openssl@3 icu4c krb5 openldap; do
+ for f in openssl@3 icu4c krb5 openldap readline tcl-tk@8 zlib; do
PKG_CONFIG_PATH="$(brew --prefix $f)/lib/pkgconfig:${PKG_CONFIG_PATH}"
done
export PKG_CONFIG_PATH
@@ -667,6 +672,8 @@ jobs:
--buildtype=debug \
-Dextra_include_dirs="${extra_inc}" \
-Dextra_lib_dirs="${extra_lib}" \
+ -Ddarwin_sysroot=none \
+ -DPYTHON=python3.12 \
${MESON_COMMON_FEATURES} \
${MESON_FEATURES} \
build
@@ -698,7 +705,7 @@ jobs:
windows-vs:
- name: Windows - Server 2022, VS 2022 - Meson & ninja
+ name: Windows - VS - Meson & ninja
needs: [setup, sanity-check]
if: |
!cancelled() &&
@@ -791,7 +798,7 @@ jobs:
- name: Install dependencies
shell: pwsh
run: |
- choco install -y --no-progress --limitoutput diffutils winflexbison
+ choco install -y --no-progress --limitoutput diffutils winflexbison3
# meson + ninja aren't preinstalled on windows-2022. Install via pip
python -m pip install --upgrade meson ninja
@@ -826,7 +833,7 @@ jobs:
Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.2 pg-loadbalancetest"
Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.3 pg-loadbalancetest"
- - name: Setup sock dir
+ - name: Setup socket directory
shell: cmd
run: mkdir %PG_REGRESS_SOCK_DIR%
@@ -861,7 +868,7 @@ jobs:
windows-mingw:
- name: Windows - Server 2022, MinGW64 - Meson
+ name: Windows - MinGW - Meson
needs: [setup, sanity-check]
if: |
!cancelled() &&
@@ -912,7 +919,6 @@ jobs:
install: >-
git bison flex make diffutils
mingw-w64-ucrt-x86_64-ccache
- mingw-w64-ucrt-x86_64-docbook-xml
mingw-w64-ucrt-x86_64-gcc
mingw-w64-ucrt-x86_64-icu
mingw-w64-ucrt-x86_64-libbacktrace
@@ -923,13 +929,10 @@ jobs:
mingw-w64-ucrt-x86_64-meson
mingw-w64-ucrt-x86_64-perl
mingw-w64-ucrt-x86_64-pkg-config
- mingw-w64-ucrt-x86_64-python-cryptography
- mingw-w64-ucrt-x86_64-python-pip
- mingw-w64-ucrt-x86_64-python-pytest
mingw-w64-ucrt-x86_64-readline
mingw-w64-ucrt-x86_64-zlib
- - name: Install IPC::Run for tap tests
+ - name: Install additional dependencies
shell: msys2 {0}
run: |
# Pin IPC::Run to NJM/IPC-Run-20250809.0; TODDR/IPC-Run-20260322.0
@@ -938,7 +941,7 @@ jobs:
(echo; echo o conf recommends_policy 0; echo notest install NJM/IPC-Run-20250809.0.tar.gz) | cpan
perl -mIPC::Run -e 1
- - name: Setup sock dir
+ - name: Setup socket directory
shell: cmd
run: mkdir %PG_REGRESS_SOCK_DIR%
@@ -1034,7 +1037,7 @@ jobs:
mkdir -p "$CCACHE_DIR"
# gcc, cassert off, dtrace on
- - name: gcc warning + (dtrace)
+ - name: gcc warnings + (dtrace)
if: always()
run: |
./configure \
@@ -1046,7 +1049,7 @@ jobs:
make -s -j${BUILD_JOBS} world-bin
# gcc, cassert on, dtrace off
- - name: gcc warning + (cassert)
+ - name: gcc warnings + (cassert)
if: always()
run: |
./configure \
@@ -1058,7 +1061,7 @@ jobs:
make -s -j${BUILD_JOBS} world-bin
# clang, cassert off, dtrace off
- - name: clang warning
+ - name: clang warnings
if: always()
run: |
./configure \
@@ -1069,7 +1072,7 @@ jobs:
make -s -j${BUILD_JOBS} world-bin
# clang, cassert on, dtrace on
- - name: clang warning + (cassert + dtrace)
+ - name: clang warnings + (cassert + dtrace)
if: always()
run: |
./configure \
@@ -1081,7 +1084,7 @@ jobs:
make -s -j${BUILD_JOBS} clean
make -s -j${BUILD_JOBS} world-bin
- - name: mingw cross compile
+ - name: mingw warnings (cross compilation)
if: always()
run: |
./configure \
@@ -1097,7 +1100,7 @@ jobs:
# Verify docs can be built
###
# XXX: Only do this if there have been changes in doc/ since last build
- - name: Docs build
+ - name: Build documentation
if: always()
run: |
./configure \
--
2.54.0
Attachments:
[text/plain] v2.1.pe-0001-Fixups.patch (7.2K, 2-v2.1.pe-0001-Fixups.patch)
download | inline diff:
From c1bab3b0809899a0b8fb61cdb398947c8f169a28 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 28 May 2026 13:20:50 +0200
Subject: [PATCH v2.1.pe] Fixups
- Shorten job names to avoid truncation in UI
- Tweak CompilerWarnings step names
- macOS:
- Add some HOMEBREW_* environment variables to disable unnecessary
steps and output
- Typo cpanm -> cpan
- Install readline tcl-tk@8 zlib for consistency with previous setup
- Disable sysroot
- Use the intended Python version
- Windows VS:
- Install winflexbison3, not winflexbison (old)
- Windows minGW:
- Reduce set of installed packages
---
.github/workflows/ci.yml | 49 +++++++++++++++++++++-------------------
1 file changed, 26 insertions(+), 23 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6d20068727c..21c4106e603 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -285,7 +285,7 @@ jobs:
# print_stacktraces=1,verbosity=2, duh
# detect_leaks=0: too many uninteresting leak errors in short-lived binaries
linux-autoconf:
- name: Linux - Debian Trixie - Autoconf
+ name: Linux - Debian - Autoconf
needs: [setup, sanity-check]
if: |
!cancelled() &&
@@ -410,7 +410,7 @@ jobs:
# - Uses io_method=io_uring
# - Uses meson feature autodetection
linux-meson:
- name: Linux - Debian Trixie - Meson
+ name: Linux - Debian - Meson
needs: [setup, sanity-check]
if: |
!cancelled() &&
@@ -570,7 +570,7 @@ jobs:
# - Specifies configuration options that test reading/writing/copying of node trees
# - Specifies debug_parallel_query=regress, to catch related issues during CI
macos:
- name: macOS - Sequoia - Meson
+ name: macOS - Meson
needs: [setup, sanity-check]
if: |
!cancelled() &&
@@ -585,6 +585,12 @@ jobs:
# Fix: Needs to be re-tested for Github Actions.
TEST_JOBS: 8
+ HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_DISPLAY_INSTALL_TIMES: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
+ HOMEBREW_NO_INSTALL_UPGRADE: 1
+ HOMEBREW_NO_UPDATE_REPORT_NEW: 1
+
CCACHE_DIR: ${{ github.workspace }}/ccache_dir
MESON_FEATURES: >-
@@ -642,16 +648,15 @@ jobs:
run: |
brew update
brew install \
- ccache meson openldap [email protected] tcl-tk
- # IPC::Run via cpanm (system perl)
+ ccache meson openldap [email protected] readline tcl-tk@8 zlib
+ # IPC::Run via cpan (system perl)
sudo cpan -T -i IPC::Run IO::Tty
- name: Configure
run: |
# These formulae are keg-only (not symlinked into $(brew --prefix)),
# so pkg-config wouldn't find them via the default search path.
- # lz4, zstd and other non-keg-only deps are picked up automatically.
- for f in openssl@3 icu4c krb5 openldap; do
+ for f in openssl@3 icu4c krb5 openldap readline tcl-tk@8 zlib; do
PKG_CONFIG_PATH="$(brew --prefix $f)/lib/pkgconfig:${PKG_CONFIG_PATH}"
done
export PKG_CONFIG_PATH
@@ -667,6 +672,8 @@ jobs:
--buildtype=debug \
-Dextra_include_dirs="${extra_inc}" \
-Dextra_lib_dirs="${extra_lib}" \
+ -Ddarwin_sysroot=none \
+ -DPYTHON=python3.12 \
${MESON_COMMON_FEATURES} \
${MESON_FEATURES} \
build
@@ -698,7 +705,7 @@ jobs:
windows-vs:
- name: Windows - Server 2022, VS 2022 - Meson & ninja
+ name: Windows - VS - Meson & ninja
needs: [setup, sanity-check]
if: |
!cancelled() &&
@@ -791,7 +798,7 @@ jobs:
- name: Install dependencies
shell: pwsh
run: |
- choco install -y --no-progress --limitoutput diffutils winflexbison
+ choco install -y --no-progress --limitoutput diffutils winflexbison3
# meson + ninja aren't preinstalled on windows-2022. Install via pip
python -m pip install --upgrade meson ninja
@@ -826,7 +833,7 @@ jobs:
Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.2 pg-loadbalancetest"
Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.3 pg-loadbalancetest"
- - name: Setup sock dir
+ - name: Setup socket directory
shell: cmd
run: mkdir %PG_REGRESS_SOCK_DIR%
@@ -861,7 +868,7 @@ jobs:
windows-mingw:
- name: Windows - Server 2022, MinGW64 - Meson
+ name: Windows - MinGW - Meson
needs: [setup, sanity-check]
if: |
!cancelled() &&
@@ -912,7 +919,6 @@ jobs:
install: >-
git bison flex make diffutils
mingw-w64-ucrt-x86_64-ccache
- mingw-w64-ucrt-x86_64-docbook-xml
mingw-w64-ucrt-x86_64-gcc
mingw-w64-ucrt-x86_64-icu
mingw-w64-ucrt-x86_64-libbacktrace
@@ -923,13 +929,10 @@ jobs:
mingw-w64-ucrt-x86_64-meson
mingw-w64-ucrt-x86_64-perl
mingw-w64-ucrt-x86_64-pkg-config
- mingw-w64-ucrt-x86_64-python-cryptography
- mingw-w64-ucrt-x86_64-python-pip
- mingw-w64-ucrt-x86_64-python-pytest
mingw-w64-ucrt-x86_64-readline
mingw-w64-ucrt-x86_64-zlib
- - name: Install IPC::Run for tap tests
+ - name: Install additional dependencies
shell: msys2 {0}
run: |
# Pin IPC::Run to NJM/IPC-Run-20250809.0; TODDR/IPC-Run-20260322.0
@@ -938,7 +941,7 @@ jobs:
(echo; echo o conf recommends_policy 0; echo notest install NJM/IPC-Run-20250809.0.tar.gz) | cpan
perl -mIPC::Run -e 1
- - name: Setup sock dir
+ - name: Setup socket directory
shell: cmd
run: mkdir %PG_REGRESS_SOCK_DIR%
@@ -1034,7 +1037,7 @@ jobs:
mkdir -p "$CCACHE_DIR"
# gcc, cassert off, dtrace on
- - name: gcc warning + (dtrace)
+ - name: gcc warnings + (dtrace)
if: always()
run: |
./configure \
@@ -1046,7 +1049,7 @@ jobs:
make -s -j${BUILD_JOBS} world-bin
# gcc, cassert on, dtrace off
- - name: gcc warning + (cassert)
+ - name: gcc warnings + (cassert)
if: always()
run: |
./configure \
@@ -1058,7 +1061,7 @@ jobs:
make -s -j${BUILD_JOBS} world-bin
# clang, cassert off, dtrace off
- - name: clang warning
+ - name: clang warnings
if: always()
run: |
./configure \
@@ -1069,7 +1072,7 @@ jobs:
make -s -j${BUILD_JOBS} world-bin
# clang, cassert on, dtrace on
- - name: clang warning + (cassert + dtrace)
+ - name: clang warnings + (cassert + dtrace)
if: always()
run: |
./configure \
@@ -1081,7 +1084,7 @@ jobs:
make -s -j${BUILD_JOBS} clean
make -s -j${BUILD_JOBS} world-bin
- - name: mingw cross compile
+ - name: mingw warnings (cross compilation)
if: always()
run: |
./configure \
@@ -1097,7 +1100,7 @@ jobs:
# Verify docs can be built
###
# XXX: Only do this if there have been changes in doc/ since last build
- - name: Docs build
+ - name: Build documentation
if: always()
run: |
./configure \
--
2.54.0
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 15:07 Andres Freund <[email protected]>
parent: Jacob Champion <[email protected]>
0 siblings, 1 reply; 42+ messages in thread
From: Andres Freund @ 2026-05-28 15:07 UTC (permalink / raw)
To: Jacob Champion <[email protected]>; +Cc: Nazir Bilal Yavuz <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers
Hi,
On 2026-05-27 15:15:46 -0700, Jacob Champion wrote:
> On Wed, May 27, 2026 at 11:10 AM Andres Freund <[email protected]> wrote:
> > > +# Default to the minimum privilege the jobs need (just reading the repo
> > > +# contents during checkout). Individual jobs override this when they need
> > > +# more, e.g. `cancel-previous` needs `actions: write` to cancel runs.
> > > +permissions:
> > > + contents: read
> >
> > I'm not sure I like that we ever need more than that. I'd expect that
> > postgresql-cfbot will explicitly disable write permissions for runs.
>
> +1, and +1 for getting rid of the custom cancel, for that reason.
>
> - Do we need to defend our downstream forks from this workflow? (We
> have 5,700 of them, apparently.)
I don't see why. I think it's good if they run CI. Having forks not run CI by
default would imo take one of the main advantages of using github actions
away.
> - Do the pginfra folks who own the repo need to lock down all the
> Actions settings before we ship this? (On my fork, at least, the
> default settings were horrifically permissive.)
Yes, they are too permissive by default, including on postgres/postgres. I
think postgres/postgres isn't *that* threatened, but we should make things are
shored up anyway. Where it's really crucial is the postgresql-cfbot repo.
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 15:51 Jacob Champion <[email protected]>
parent: Andres Freund <[email protected]>
0 siblings, 1 reply; 42+ messages in thread
From: Jacob Champion @ 2026-05-28 15:51 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Nazir Bilal Yavuz <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers
On Thu, May 28, 2026 at 8:07 AM Andres Freund <[email protected]> wrote:
> On 2026-05-27 15:15:46 -0700, Jacob Champion wrote:
> > - Do we need to defend our downstream forks from this workflow? (We
> > have 5,700 of them, apparently.)
>
> I don't see why. I think it's good if they run CI. Having forks not run CI by
> default would imo take one of the main advantages of using github actions
> away.
I was imagining a quick opt-in, like the Cirrus flow did, that fork
owners can do once they have checked their settings.
(I thought we planned to research medium-term alternatives to Actions
anyway; is it important that the entire graph starts running hundreds
or thousands of CI copies right away?)
> Yes, they are too permissive by default, including on postgres/postgres. I
> think postgres/postgres isn't *that* threatened, but we should make things are
> shored up anyway. Where it's really crucial is the postgresql-cfbot repo.
Combining with the above: I'm worried that if all of our 5.7k forks
have permissive settings, and we accidentally ship a workflow
vulnerability that doesn't affect us but does affect them, that would
not be a fun cleanup.
--Jacob
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 16:13 Andres Freund <[email protected]>
parent: Jacob Champion <[email protected]>
0 siblings, 1 reply; 42+ messages in thread
From: Andres Freund @ 2026-05-28 16:13 UTC (permalink / raw)
To: Jacob Champion <[email protected]>; +Cc: Nazir Bilal Yavuz <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers
Hi,
On 2026-05-28 08:51:09 -0700, Jacob Champion wrote:
> On Thu, May 28, 2026 at 8:07 AM Andres Freund <[email protected]> wrote:
> > On 2026-05-27 15:15:46 -0700, Jacob Champion wrote:
> > > - Do we need to defend our downstream forks from this workflow? (We
> > > have 5,700 of them, apparently.)
> >
> > I don't see why. I think it's good if they run CI. Having forks not run CI by
> > default would imo take one of the main advantages of using github actions
> > away.
>
> I was imagining a quick opt-in, like the Cirrus flow did, that fork
> owners can do once they have checked their settings.
I'm not aware of a good way to do that. I'm sure we could hack up a way,
e.g. by requiring an environment variable to be configured on the repo level
to opt-in, but it seems pretty crufty.
I think making it easier for forks to run CI is a far bigger gain than the
risk of GHA doing something stupid in a fork. There were a lot of folks that
didn't realize that they could run CI individually or had a hard time enabling
it.
> (I thought we planned to research medium-term alternatives to Actions
> anyway; is it important that the entire graph starts running hundreds
> or thousands of CI copies right away?)
I suspect where we will end up coming out is that we use an alternative for
actions for cfbot and regular contributors, but that everyone else will use
GHA.
> > Yes, they are too permissive by default, including on postgres/postgres.
> > I think postgres/postgres isn't *that* threatened, but we should make
> > things are shored up anyway. Where it's really crucial is the
> > postgresql-cfbot repo.
>
> Combining with the above: I'm worried that if all of our 5.7k forks have
> permissive settings, and we accidentally ship a workflow vulnerability that
> doesn't affect us but does affect them, that would not be a fun cleanup.
I'm not sure what path for that would exist that don't already? ISTM that'd
require downstream repos to have added their own actions workflows that
somehow interact with ours, or that they blindly run PRs from unknown folks
that add new workflows - in either case it seems they have a problem
independent of us shipping a runs-by-default actions workflow?
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 16:19 Andres Freund <[email protected]>
parent: Nazir Bilal Yavuz <[email protected]>
3 siblings, 0 replies; 42+ messages in thread
From: Andres Freund @ 2026-05-28 16:19 UTC (permalink / raw)
To: Nazir Bilal Yavuz <[email protected]>; +Cc: Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers
Hi,
On 2026-05-25 15:14:41 +0300, Nazir Bilal Yavuz wrote:
> Also, I am planning to work on back patches when we agree on the
> upstream one. Does that sound good?
On this aspect: I suspect that a sane process here might be to merge GHA CI
into master only, run cfbot for a few days, and only then backpatch the
support to the older branches. It seems rather likely that there will be some
stability improvements we'll have to do initially, and that we only will find
those issues with sufficient runs. If we have to backpatch all of those it'll
be a lot more work (and noise).
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 17:04 Jacob Champion <[email protected]>
parent: Andres Freund <[email protected]>
0 siblings, 0 replies; 42+ messages in thread
From: Jacob Champion @ 2026-05-28 17:04 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Nazir Bilal Yavuz <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers
On Thu, May 28, 2026 at 9:13 AM Andres Freund <[email protected]> wrote:
> On 2026-05-28 08:51:09 -0700, Jacob Champion wrote:
> > I was imagining a quick opt-in, like the Cirrus flow did, that fork
> > owners can do once they have checked their settings.
>
> I'm not aware of a good way to do that. I'm sure we could hack up a way,
> e.g. by requiring an environment variable to be configured on the repo level
> to opt-in,
That was more or less my thought.
> but it seems pretty crufty.
>
> I think making it easier for forks to run CI is a far bigger gain than the
> risk of GHA doing something stupid in a fork. There were a lot of folks that
> didn't realize that they could run CI individually or had a hard time enabling
> it.
Right, but Cirrus only ever had the ability to run a CI, not write to
the code base it was running. If we unleash a bunch of newcomer GitHub
CIs without first explaining "hey, you really need to lock some stuff
down first", I think we may be doing them all a disservice.
Especially since GitHub claims to protect downstream forks from this
[1] -- which is undocumented? -- but that protection appears to not
actually work [2] if we push a workflow at the root of the graph. (I
haven't verified any of that myself yet, but in the absence of
documentation, I'm not really optimistic.)
> > Combining with the above: I'm worried that if all of our 5.7k forks have
> > permissive settings, and we accidentally ship a workflow vulnerability that
> > doesn't affect us but does affect them, that would not be a fun cleanup.
>
> I'm not sure what path for that would exist that don't already?
Using the current v2 patch, for instance, a `actions: write` token
that gets leaked by accident can then be used to approve pending
workflow runs. (Consensus seems to be forming that we shouldn't have
those privileges in the workflow spec, but we have to all remember why
that rule exists when we're reviewing workflow patches.)
--Jacob
[1] https://github.com/github/docs/issues/15761
[2] https://github.com/orgs/community/discussions/53510
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 17:06 Nazir Bilal Yavuz <[email protected]>
parent: Andres Freund <[email protected]>
2 siblings, 3 replies; 42+ messages in thread
From: Nazir Bilal Yavuz @ 2026-05-28 17:06 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers; Zsolt Parragi <[email protected]>; Peter Eisentraut <[email protected]>
Hi,
Thank you for looking into this!
On Wed, 27 May 2026 at 21:10, Andres Freund <[email protected]> wrote:
>
> > Here is the v2, I took Jelte's patch and reviewed & merged it with my
> > patch. Updates and questions are:
> >
> > 1- I continued to use Jelte's container method (Linux tasks only for
> > now, BSD tasks will be included in the future) because I think that is
> > the future-proof way since we might want to generate our container
> > images in the future. Also, up-to-date Debian images can be tested
> > with this way; otherwise we would need to use Ubuntu 24.04.
>
> Good.
>
>
> > 2- io_uring tests work on the Linux Meson task.
>
> Is there a reason to not just do that for all the tasks?
I might word it incorrectly. I meant that Linux meson tests use:
PG_TEST_INITDB_EXTRA_OPTS: >-
-c io_method=io_uring
and that wasn't working before, now it works. I guess we have this
only on Linux because we wanted to test io_method=worker in the other
tasks.
> > 3- I didn't put commands to helper scripts for now. I think it is a
> > good thing to have a helper script but it would be better to have this
> > helper script after the first version is committed since it can extend
> > the timeline. Also, I found that having all commands in one file makes
> > debugging easier.
>
> Hm. I'm a bit worried about this getting pretty unmaintainable, due to the
> repetition. I think at least we need to use yaml anchors to deduplicate some
> steps.
Github Actions added support of yaml anchors last year but
unfortunately they don't support merge keys. Related information: [1].
> > 4- FreeBSD task has these options:
> >
> > PG_TEST_INITDB_EXTRA_OPTS: >-
> > -c debug_copy_parse_plan_trees=on
> > -c debug_write_read_parse_plan_trees=on
> > -c debug_raw_expression_coverage_test=on
> > -c debug_parallel_query=regress
> >
> > Since we won't have FreeBSD for the first version. I put these options
> > to the MacOS task but I couldn't decide where to put
> > 'PG_TEST_PG_UPGRADE_MODE: --link'.
>
> Makes sense.
>
>
> > Also, I am planning to work on back patches when we agree on the
> > upstream one. Does that sound good?
>
> Yep.
>
>
>
> > diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
> > new file mode 100644
> > index 00000000000..6d20068727c
> > --- /dev/null
> > +++ b/.github/workflows/ci.yml
> > @@ -0,0 +1,1125 @@
> > +# GitHub Actions CI configuration for PostgreSQL
> > +
> > +name: Github Actions CI
> > +
> > +on:
> > + push:
> > + branches: [ "*" ]
> > +
> > +# Default to the minimum privilege the jobs need (just reading the repo
> > +# contents during checkout). Individual jobs override this when they need
> > +# more, e.g. `cancel-previous` needs `actions: write` to cancel runs.
> > +permissions:
> > + contents: read
>
> I'm not sure I like that we ever need more than that. I'd expect that
> postgresql-cfbot will explicitly disable write permissions for runs.
Done. Updated the comment and removed the 'Cancel previous runs' step.
> > +# NB: intentionally NO workflow-level `concurrency:` block. The native
> > +# concurrency mechanism makes a new run wait for the previous one to fully
> > +# cancel before it starts — which can take a while. Instead the
> > +# `cancel-previous` job below fires a cancel API call asynchronously,
> > +# so the new run gets going immediately. On master the cancel job is skipped,
> > +# so every push runs to completion.
>
> Is this really worth having our own code? Seems like it'd not be that frequent
> to push if there are already running runs? What kind of delays are we talking
> about?
Jelte already answered this in [2]. 'Cancel previous runs' step is
removed and concurrency is used instead.
> > + # To avoid unnecessarily spinning up a lot of VMs / containers for entirely
> > + # broken commits, have a minimal task that all others depend on.
> > + #
> > + # SPECIAL:
> > + # - Builds with --auto-features=disabled and thus almost no enabled
> > + # dependencies
> > + sanity-check:
> > + name: SanityCheck
> > + needs: setup
> > + if: needs.setup.outputs.sanitycheck == 'true'
> > + runs-on: ubuntu-latest
> > + timeout-minutes: 15
> > + container:
> > + image: ${{ needs.setup.outputs.linux_ci_image }}
> > + env:
> > + BUILD_JOBS: 8
> > + TEST_JOBS: 8
> > + CCACHE_DIR: ${{ github.workspace }}/ccache_dir
> > + # no options enabled, should be small
> > + CCACHE_MAXSIZE: "150M"
> > + steps:
> > + - uses: actions/checkout@v6
> > + with:
> > + fetch-depth: ${{ env.CLONE_DEPTH }}
> > +
> > + - name: Restore ccache
> > + uses: actions/cache@v5
>
> Seems like this is used by every task. Can we move this into a yaml anchor or
> such, by using a variable representing the job name?
Github Actions doesn't support merge keys. So we can't really
duplicate them. I used yaml anchors for the checkout step since it is
exactly for all jobs.
> > + with:
> > + path: ${{ env.CCACHE_DIR }}
> > + key: ccache-sanitycheck-${{ github.run_id }}
> > + restore-keys: ccache-sanitycheck-
>
> Why is the key here the run id? Doesn't that mean that we will never have a
> precise cache match and that we will keep multiple versions of the cache
> around? That seems like a waste of cache space?
>
> For efficiency, particularly on cfbot, it seems like it could be useful to
> populate the cache of branches with the cache of the master branch. For that
> we'd need the branch name in the key. Which I think would also good for
> postgres/postgres, as we currently have a lot of interference between runs on
> the main and the REL_XY_STABLE branches.
I think that is the default way. If the cache has the exact hit, it
doesn't refresh the cache. So, having ${{ github.run_id }} makes sure
we won't have exact hits and the cache will always be refreshed. This
sounds bad but that is what I understood :(
I can implement something like this:
- name: Restore ccache
uses: actions/cache/restore@v5
with:
path: ${{ env.CCACHE_DIR }}
key: ccache-sanitycheck-master
restore-keys: |
ccache-sanitycheck-${{ github.ref_name }}
ccache-sanitycheck-
- name: Save ccache
if: always()
uses: actions/cache/save@v5
with:
path: ${{ env.CCACHE_DIR }}
key: ccache-sanitycheck-${{ github.ref_name }}-${{ github.run_id }}
So, it will first look for master's cache, then current branch's cache
and lastly whatever cache is available. Do you prefer that?
> > + - name: Prepare workspace
> > + run: |
> > + whoami
> > + useradd -m postgres
> > + chown -R postgres:postgres .
> > + mkdir -p "$CCACHE_DIR"
> > + chown -R postgres:postgres "$CCACHE_DIR"
> > + # Can't change the container's kernel.core_pattern; the postgres
> > + # user can't write to / normally. Make / writable.
> > + chown root:postgres /
> > + chmod g+rwx /
>
> Why not just always use a privileged container?
Done.
> > + - name: Configure
> > + run: |
> > + su postgres <<-'EOF'
> > + set -e
> > + meson setup \
> > + --buildtype=debug \
> > + --auto-features=disabled \
> > + -Ddefault_library=shared \
> > + -Dtap_tests=enabled \
> > + build
> > + EOF
> > +
> > + - name: Build
> > + run: |
> > + su postgres <<EOF
> > + set -e
> > + ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
> > + EOF
>
> Should we have an explicit cache upload step here? Or are upload steps run
> unconditionally?
Like I explained above, that is done by having ${{ github.run_id }} in
the cache key.
> > + # Run a minimal set of tests. The main regression tests take too long
> > + # for this purpose. For now this is a random quick pg_regress style
> > + # test, and a tap test that exercises both a frontend binary and the
> > + # backend.
> > + - name: Test
> > + run: |
> > + su postgres <<EOF
> > + set -e
> > + ulimit -c unlimited
> > + meson test ${MTEST_ARGS} --suite setup
> > + meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS} \
> > + cube/regress pg_ctl/001_start_stop
> > + EOF
> > +
> > + - name: Core backtraces
> > + if: failure()
> > + run: |
> > + mkdir -m 770 /tmp/cores
> > + find / -maxdepth 1 -type f -name 'core*' -exec mv '{}' /tmp/cores/ \;
> > + src/tools/ci/cores_backtrace.sh linux /tmp/cores
> > +
> > + - name: Upload logs
> > + if: failure()
> > + uses: actions/upload-artifact@v7
> > + with:
> > + name: sanitycheck-logs-${{ github.run_id }}
> > + path: |
> > + build*/testrun/**/*.log
> > + build*/testrun/**/*.diffs
> > + build*/testrun/**/regress_log_*
> > + build*/meson-logs/*.txt
> > + if-no-files-found: ignore
>
> I think this really should be in a yaml anchor, we have a few somewhat
> different versions of this now.
Same thing, we can't have yaml anchors because merge keys are not
supported. I created this variable:
_LOG_PATHS: &log_paths |
build*/testrun/**/*.log
build*/testrun/**/*.diffs
build*/testrun/**/regress_log_*
build*/meson-logs/*.txt
and used it in the Upload logs' path.
> It's pretty annoying that the output of the failures isn't visible in the UI.
> Maybe we ought to print a few of the failures out or something?
We already have '--print-errorlogs', do you mean something different?
> > +
> > + # SPECIAL:
> > + # - Uses address sanitizer (sanitizer failures are typically printed in
> > + # the server log)
> > + # - Configures postgres with a small segment size
> > + #
> > + # Enable a reasonable set of sanitizers. Use the linux task for that, as
> > + # it's one of the fastest tasks (without sanitizers). Also several of the
> > + # sanitizers work best on linux.
> > + #
> > + # The overhead of alignment sanitizer is low, undefined behaviour has
> > + # moderate overhead. Test alignment sanitizer in the meson task, as it
> > + # does both 32 and 64 bit builds and is thus more likely to expose
> > + # alignment bugs.
> > + #
> > + # Address sanitizer in contrast is somewhat expensive. Enable it in the
> > + # autoconf task, as the meson task tests both 32 and 64bit.
>
> I wonder if we should split the meson task into two, one for 32bit and one for
> 64bit. The concurrency limits for public repos are high enough for that to
> seem like a reasonable tradeoff? There's no work, other than the repo
> checkout, shared between them.
Done.
> > + # disable_coredump=0, abort_on_error=1: for useful backtraces in case of crashes
> > + # print_stacktraces=1,verbosity=2, duh
> > + # detect_leaks=0: too many uninteresting leak errors in short-lived binaries
> > + linux-autoconf:
> > + name: Linux - Debian Trixie - Autoconf
> > + needs: [setup, sanity-check]
> > + if: |
> > + !cancelled() &&
> > + needs.setup.outputs.linux == 'true' &&
> > + needs.sanity-check.result != 'failure'
> > + runs-on: ubuntu-latest
> > + timeout-minutes: 60
> > + container:
> > + image: ${{ needs.setup.outputs.linux_ci_image }}
> > + # Share the host PID + IPC namespaces. 017_shm.pl rapidly creates,
> > + # kill9's, and restarts postgres; with the container's small PID
> > + # space a new postgres can recycle the dead postmaster's PID before
> > + # pg_ctl's postmaster.pid check notices, producing spurious "node X
> > + # is already running" failures. SysV shm in the test also relies on
> > + # host-like IPC behavior.
> > + #
> > + # --ulimit raises memlock and core dump size. Memlock is needed for
> > + # running the AIO tests.
> > + #
> > + # --privileged is needed so the prepare step can write to sysctls
> > + # under /proc/sys (it's mounted read-only without it). We use it to
> > + # set kernel.core_pattern.
> > + options: --pid=host --ipc=host --ulimit memlock=-1:-1 --privileged
> > + env:
> > + BUILD_JOBS: 4
> > + TEST_JOBS: 8
> > + CCACHE_DIR: /tmp/ccache_dir
> > + DEBUGINFOD_URLS: "https://debuginfod.debian.net";
> > +
> > + SANITIZER_FLAGS: -fsanitize=address
> > + UBSAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:verbosity=2
> > + ASAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:detect_leaks=0:detect_stack_use_after_return=0
> > + CFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=address
> > + CXXFLAGS: -Og -ggdb -fno-sanitize-recover=all -fsanitize=address
> > + LDFLAGS: -fsanitize=address
> > + CC: ccache gcc
> > + CXX: ccache g++
>
> There's a fair bit of stuff shared between the meson/autoconf linux
> tasks. Previously they used a matrix to reduce that a *bit*. But now it's
> entirely duplicated, including stuff that doesn't apply to the current job
> (e.g. UBSAN_OPTIONS/ASAN_OPTIONS). And blocks like the following:
>
>
> > + - name: Prepare workspace
> > + run: |
> > + useradd -m postgres
> > + chown -R postgres:postgres .
> > + mkdir -p "$CCACHE_DIR"
> > + chown -R postgres:postgres "$CCACHE_DIR"
> > + mkdir -m 770 /tmp/cores
> > + chown root:postgres /tmp/cores
> > + sysctl kernel.core_pattern='/tmp/cores/%e-%s-%p.core'
> > +
> > + # Hosts for the load balance test
> > + cat >> /etc/hosts <<-EOF
> > + 127.0.0.1 pg-loadbalancetest
> > + 127.0.0.2 pg-loadbalancetest
> > + 127.0.0.3 pg-loadbalancetest
> > + EOF
I found we can use matrices and merged all linux tasks. I am not sure
that is better since it is a bit harder to read now.
> > + # Install dependencies via Homebrew rather than Macports. On stock
> > + # GH runners macports requires a heavy bootstrap, and the relevant
> > + # Postgres deps are all available in brew.
>
> What does "heavy bootstrap" mean?
I used MacPorts on my first version. It took ~10 minutes to download
MacPorts. I think that if we could use caching like we did in the
Cirrus, it makes sense to use MacPorts. I will spend some time on
that.
And after spending some time, I am able to make it work. Now the first
run's dependencies install takes ~10 minutes since there is no
MacPorts cache but subsequent runs' install only take ~5 seconds.
> > + - name: Install dependencies
> > + run: |
> > + brew update
> > + brew install \
> > + ccache meson openldap [email protected] tcl-tk
> > + # IPC::Run via cpanm (system perl)
> > + sudo cpan -T -i IPC::Run IO::Tty
>
> We do spend ~95s on this every run, that's not nothing. And it puts a bunch of
> load onto the brew's mirrors to do that every run.
You are right. MacPorts is used now.
> > + - name: Test world
> > + run: |
> > + ulimit -c unlimited
> > + ulimit -n 1024
> > + meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
>
> I'd re-add the comments that were in .cirrus.yml about this.
Done.
> > + windows-vs:
> > + name: Windows - Server 2022, VS 2022 - Meson & ninja
> > + needs: [setup, sanity-check]
> > + if: |
> > + !cancelled() &&
> > + needs.setup.outputs.windows == 'true' &&
> > + needs.sanity-check.result != 'failure'
> > + runs-on: windows-2022
> > + timeout-minutes: 60
> > + env:
> > + TEST_JOBS: 8
> > + # Avoid port conflicts between concurrent tap tests
> > + PG_TEST_USE_UNIX_SOCKETS: 1
> > + PG_REGRESS_SOCK_DIR: 'c:\pgsock\'
>
> At least my editor gets confused by the \', thinking it's escaping the '. As
> everything just works without the trailing \, I'd go that way.
Done.
> > + # The TAP tests build an initdb template under build/tmp_install and
> > + # then `robocopy` it into per-test data directories. Robocopy with the
> > + # default /COPY:DAT flag doesn't copy ACLs — destinations inherit from
> > + # their parent dir. On GitHub-hosted Windows runners the workspace's
> > + # inherited ACL grants Administrators:(F) and Users:(RX) but does NOT
> > + # grant the runner user (runneradmin) directly. That matters because
> > + # pg_ctl on Windows uses CreateRestrictedProcess to drop admin
> > + # privileges from postmaster, so the postmaster process has the user
> > + # SID in its token but no longer the Administrators group — leaving it
> > + # with only "Users:(RX)" on pg_control and friends, which causes
> > + # "PANIC: could not open file global/pg_control: Permission denied".
> > + #
> > + # Fix it once on the workspace dir with (OI)(CI) inheritance flags so
> > + # every file/dir created underneath gets an explicit grant for the
> > + # current user.
> > + - name: Grant workspace ACL to runner user
> > + shell: pwsh
> > + run: |
> > + icacls "${{ github.workspace }}" /grant "${env:USERNAME}:(OI)(CI)F" /Q | Out-Null
> > + Write-Host "Granted Full Control to $env:USERNAME on ${{ github.workspace }}"
>
> Perhaps this would be better to fix by changing the robocopy flags?
I couldn't fix this by using robocopy flags. I used /COPYALL and
/SECFIX together but they didn't work.
> > + # postgres' plpython3u loads python3.dll (the stable-ABI forwarder)
> > + # which in turn loads whichever python3NN.dll the Windows loader finds
> > + # first on PATH. On windows-2022 `C:\Program Files\Mercurial\` ships
> > + # its own python3.dll + python39.dll and appears on PATH *before* the
> > + # hostedtoolcache Python 3.12 — so without intervention the backend
> > + # ends up running Python 3.9 while postgres' stdlib search uses 3.12,
> > + # producing `ImportError: cannot import name 'text_encoding' from
> > + # 'io'` (the 3.12 `io.py` calling into 3.9's `_io`).
> > + #
> > + # Pin PYTHONHOME to the Python 3.12 prefix, and prepend that prefix
> > + # to PATH so its python3.dll wins the DLL search.
> > + - name: Pin Python prefix on PATH and PYTHONHOME
> > + shell: pwsh
> > + run: |
> > + $prefix = (python -c "import sys; print(sys.prefix)").Trim()
> > + Add-Content $env:GITHUB_ENV "PYTHONHOME=$prefix"
> > + Add-Content $env:GITHUB_PATH $prefix
> > + Write-Host "PYTHONHOME=$prefix"
> > + Write-Host "Prepended $prefix to PATH"
>
> GRJGJKLJKJDFJKDF.
I re-checked this since Jelte wasn't completely sure about this [2]
but this is unfortunately correct :(
> > + - name: Install dependencies
> > + shell: pwsh
> > + run: |
> > + choco install -y --no-progress --limitoutput diffutils winflexbison
> > + # meson + ninja aren't preinstalled on windows-2022. Install via pip
> > + python -m pip install --upgrade meson ninja
> > +
> > + # OpenSSL 1.1 via the slproweb installer (pinned to match the
> > + # version used elsewhere in postgres CI).
> > + curl.exe -fsSL -o openssl-setup.exe https://slproweb.com/download/Win64OpenSSL-1_1_1w.exe
> > + Start-Process -Wait -FilePath ./openssl-setup.exe `
> > + -ArgumentList '/DIR=c:\openssl\1.1\ /VERYSILENT /SP- /SUPPRESSMSGBOXES'
> > + # The slproweb installer puts libcrypto-1_1-x64.dll / libssl-1_1-x64.dll
> > + # in c:\openssl\1.1\bin\ and updates the system PATH. GH Actions
> > + # snapshots PATH at job start though, so the running job won't
> > + # see those DLLs and initdb.exe would crash silently at runtime.
> > + # Push the bin dir onto GITHUB_PATH so it persists for later steps.
> > + Add-Content $env:GITHUB_PATH "c:\openssl\1.1\bin"
>
> I don't like that much, but I'm not sure we have a better alternative
> short-term.
Making chocolatey would be a nice alternative. You already said
sometimes chocolatey takes too much time. I am planning to spend time
on it unless we are planning to use our own Windows containers.
> > + windows-mingw:
> > + name: Windows - Server 2022, MinGW64 - Meson
> > + needs: [setup, sanity-check]
> > + if: |
> > + !cancelled() &&
> > + needs.setup.outputs.mingw == 'true' &&
> > + needs.sanity-check.result != 'failure'
> > + runs-on: windows-2022
> > + timeout-minutes: 60
> > + env:
> > + TEST_JOBS: 4 # higher concurrency causes occasional failures
> > + PG_TEST_USE_UNIX_SOCKETS: 1
> > + PG_REGRESS_SOCK_DIR: 'c:\pgsock\'
> > + TAR: "c:/windows/system32/tar.exe"
> > + # for mingw plpython to find its installation
> > + PYTHONHOME: D:/a/_temp/msys64/ucrt64
> > +
> > + MSYS: winjitdebug
> > + CHERE_INVOKING: 1
> > + MESON_FEATURES: >-
> > + -Dnls=disabled
>
> Missing comments from .cirrus.tasks.yml
Done.
v3 is attached. Just a quick note, v3 includes Zsolt [3] And Peter's
[4] reviews & feedback too. I will reply to them after sending this.
GA run after v3 is applied:
https://github.com/nbyavuz/postgres/actions/runs/26587973538
[1]
https://github.com/actions/runner/issues/1182
https://github.com/orgs/community/discussions/185877
[2] https://postgr.es/m/CAGECzQQBCF%3DHSk4eCc1fEYTpCt59rgpcwWp47%2B6M-CDMYEaM2A%40mail.gmail.com
[3] https://postgr.es/m/CAN4CZFO4usEzFQoYzEywvOgoagW%3DU4yhpB4Oq-a7bUCR53djHA%40mail.gmail.com
[4] https://postgr.es/m/3daa29a4-6a08-41c1-8a6a-53ba8cd3c7fb%40eisentraut.org
--
Regards,
Nazir Bilal Yavuz
Microsoft
Attachments:
[text/x-patch] v3-0001-Add-GitHub-Actions-yaml-file.patch (38.6K, 2-v3-0001-Add-GitHub-Actions-yaml-file.patch)
download | inline diff:
From b6b0c0b6b0b3846c81cf5fa599d32167f1beb4b7 Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <[email protected]>
Date: Thu, 28 May 2026 19:31:34 +0300
Subject: [PATCH v3] Add GitHub Actions yaml file
Cirrus CI is shutting down. This is an initial attempt to get a GitHub
Actions CI working.
---
.github/workflows/postgresql-ci.yml | 1013 ++++++++++++++++++++++++++
src/tools/ci/ci_macports_packages.sh | 19 +-
2 files changed, 1029 insertions(+), 3 deletions(-)
create mode 100644 .github/workflows/postgresql-ci.yml
diff --git a/.github/workflows/postgresql-ci.yml b/.github/workflows/postgresql-ci.yml
new file mode 100644
index 00000000000..b0130e868ac
--- /dev/null
+++ b/.github/workflows/postgresql-ci.yml
@@ -0,0 +1,1013 @@
+# GitHub Actions CI configuration for PostgreSQL
+
+name: Github Actions CI
+
+on:
+ push:
+
+# Restrict GITHUB_TOKEN to the minimum the jobs need: reading repo
+# contents during checkout.
+permissions:
+ contents: read
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ # Never cancel in-progress runs on master to ensure all commits are tested.
+ cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
+
+env:
+ # The lower depth accelerates git clone. Use a bit of depth so that
+ # concurrent jobs and retrying older runs have a chance of working.
+ CLONE_DEPTH: 500
+
+ CCACHE_MAXSIZE: "250M"
+
+ # check target for the autoconf builds
+ CHECK: check-world PROVE_FLAGS=--timer
+ CHECKFLAGS: -Otarget
+
+ # Build test dependencies as part of the build step, to see compiler
+ # errors/warnings in one place.
+ MBUILD_TARGET: all testprep
+ MTEST_ARGS: --print-errorlogs --no-rebuild -C build
+ PGCTLTIMEOUT: 120 # avoids spurious failures during parallel tests
+ TEMP_CONFIG: ${{ github.workspace }}/src/tools/ci/pg_ci_base.conf
+ PG_TEST_EXTRA: kerberos ldap ssl libpq_encryption load_balance oauth
+
+ # Postgres config args for the meson builds, shared between all meson tasks
+ # except the 'SanityCheck' task
+ MESON_COMMON_PG_CONFIG_ARGS: -Dcassert=true -Dinjection_points=true
+
+ # Meson feature flags shared by all meson tasks, except:
+ # SanityCheck: uses almost no dependencies.
+ # Windows - VS: has fewer dependencies than listed here, so defines its own.
+ # Linux: uses the 'auto' feature option to test meson feature autodetection.
+ MESON_COMMON_FEATURES: >-
+ -Dauto_features=disabled
+ -Dldap=enabled
+ -Dssl=openssl
+ -Dtap_tests=enabled
+ -Dplperl=enabled
+ -Dplpython=enabled
+ -Ddocs=enabled
+ -Dicu=enabled
+ -Dlibxml=enabled
+ -Dlibxslt=enabled
+ -Dlz4=enabled
+ -Dpltcl=enabled
+ -Dreadline=enabled
+ -Dzlib=enabled
+ -Dzstd=enabled
+
+ # Shared between the Linux autoconf job and the CompilerWarnings jobs
+ LINUX_CONFIGURE_FEATURES: >-
+ --with-gssapi
+ --with-icu
+ --with-ldap
+ --with-libcurl
+ --with-libxml
+ --with-libxslt
+ --with-llvm
+ --with-lz4
+ --with-pam
+ --with-perl
+ --with-python
+ --with-selinux
+ --with-ssl=openssl
+ --with-systemd
+ --with-tcl --with-tclconfig=/usr/lib/tcl8.6/
+ --with-uuid=ossp
+ --with-zstd
+
+ # Debian Trixie container image used by all Linux jobs. Built by
+ # 'https://github.com/anarazel/pg-vm-images/'.
+ LINUX_CI_IMAGE: us-docker.pkg.dev/pg-ci-images/ci/linux_debian_trixie_ci:latest
+
+ # The full set of OS / job selectors recognized by the `ci-os-only:`
+ # commit-message directive parsed in the `setup` job below.
+ CI_OS_ONLY_JOBS: "linux macos windows mingw compilerwarnings sanitycheck"
+
+ _LOG_PATHS: &log_paths |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+
+
+jobs:
+ # Parse "ci-os-only: ..." from the commit message and expose flags
+ # consumed by the jobs' `if:` conditions.
+ setup:
+ name: Determine enabled jobs
+ runs-on: ubuntu-latest
+ timeout-minutes: 1
+ outputs:
+ linux: ${{ steps.os.outputs.linux }}
+ macos: ${{ steps.os.outputs.macos }}
+ windows: ${{ steps.os.outputs.windows }}
+ mingw: ${{ steps.os.outputs.mingw }}
+ compilerwarnings: ${{ steps.os.outputs.compilerwarnings }}
+ sanitycheck: ${{ steps.os.outputs.sanitycheck }}
+ # Re-export workflow-level env vars that other jobs need to reference
+ # from contexts (e.g. `jobs.<id>.container.image`) where the `env`
+ # context is not available.
+ linux_ci_image: ${{ env.LINUX_CI_IMAGE }}
+ steps:
+ - id: os
+ env:
+ MSG: ${{ github.event.head_commit.message }}
+ shell: bash
+ run: |
+ set -e
+ all_os="${CI_OS_ONLY_JOBS}"
+ if printf '%s\n' "$MSG" | grep -qE '^ci-os-only: '; then
+ sel=$(printf '%s\n' "$MSG" | grep -E '^ci-os-only: ' | head -1 | sed 's/^ci-os-only: //')
+ echo "ci-os-only selection: $sel"
+ else
+ sel="$all_os"
+ fi
+ for o in $all_os; do
+ if echo " $sel " | grep -qE "[ ,]$o[ ,]"; then
+ echo "$o=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "$o=false" >> "$GITHUB_OUTPUT"
+ fi
+ done
+ cat "$GITHUB_OUTPUT"
+
+
+ # To avoid unnecessarily spinning up a lot of VMs / containers for entirely
+ # broken commits, have a minimal task that all others depend on.
+ #
+ # SPECIAL:
+ # - Builds with --auto-features=disabled and thus almost no enabled
+ # dependencies
+ sanity-check:
+ name: SanityCheck
+ needs: setup
+ if: needs.setup.outputs.sanitycheck == 'true'
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ container:
+ image: ${{ needs.setup.outputs.linux_ci_image }}
+ # --privileged is needed so the prepare step can write to sysctls
+ # under /proc/sys (it's mounted read-only without it). We use it to
+ # set kernel.core_pattern.
+ options: --privileged
+ env:
+ BUILD_JOBS: 8
+ TEST_JOBS: 8
+ CCACHE_DIR: ${{ github.workspace }}/ccache_dir
+ # no options enabled, should be small
+ CCACHE_MAXSIZE: "150M"
+ steps:
+ # Anchor reused by other jobs further down. GitHub Actions supports
+ # YAML anchors/aliases but not merge keys, so the alias copies the
+ # whole step verbatim. The anchor is resolved at YAML parse time, so the
+ # alias keeps working even if this job is skipped at runtime.
+ - &checkout_step
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-sanitycheck-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ccache-sanitycheck-${{ github.ref_name }}-
+ ccache-sanitycheck-
+
+ - name: Prepare workspace
+ run: |
+ whoami
+ useradd -m postgres
+ chown -R postgres:postgres .
+ mkdir -p "$CCACHE_DIR"
+ chown -R postgres:postgres "$CCACHE_DIR"
+
+ - name: Configure
+ run: |
+ su postgres <<-'EOF'
+ set -e
+ meson setup \
+ --buildtype=debug \
+ --auto-features=disabled \
+ -Ddefault_library=shared \
+ -Dtap_tests=enabled \
+ build
+ EOF
+
+ - name: Build
+ run: |
+ su postgres <<EOF
+ set -e
+ ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+ EOF
+
+ # Run a minimal set of tests. The main regression tests take too long
+ # for this purpose. For now this is a random quick pg_regress style
+ # test, and a tap test that exercises both a frontend binary and the
+ # backend.
+ - name: Test
+ run: |
+ su postgres <<EOF
+ set -e
+ ulimit -c unlimited
+ meson test ${MTEST_ARGS} --suite setup
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS} \
+ cube/regress pg_ctl/001_start_stop
+ EOF
+
+ - name: Core backtraces
+ if: failure()
+ run: |
+ mkdir -m 770 /tmp/cores
+ find / -maxdepth 1 -type f -name 'core*' -exec mv '{}' /tmp/cores/ \;
+ src/tools/ci/cores_backtrace.sh linux /tmp/cores
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: sanitycheck-logs-${{ github.run_id }}
+ path: *log_paths
+ if-no-files-found: ignore
+
+
+ # Build & test postgres on Linux in three configurations.
+ #
+ # Autoconf:
+ # - Uses address sanitizer (sanitizer failures are typically printed in
+ # the server log)
+ # - Configures postgres with a small segment size
+ # - Uses PG_TEST_PG_COMBINEBACKUP_MODE=--copy-file-range
+ #
+ # Meson:
+ # - Test both 64 and 32 bit builds
+ # - Uses undefined behaviour and alignment sanitizers, (sanitizer failures
+ # are typically printed in the server log)
+ # - Uses io_method=io_uring
+ # - Uses meson feature autodetection
+ # - 32 bit build tests with LANG=C to give ICU some buildfarm-uncovered
+ # coverage. Also, newer Python insists on changing LC_CTYPE away from C,
+ # prevent that with PYTHONCOERCECLOCALE.
+ #
+ # disable_coredump=0, abort_on_error=1: for useful backtraces in case of crashes
+ # print_stacktraces=1,verbosity=2, duh
+ # detect_leaks=0: too many uninteresting leak errors in short-lived binaries
+ linux:
+ name: Linux - ${{ matrix.name }}
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.linux == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: Autoconf
+ slug: autoconf
+ cc: ccache gcc
+ cxx: ccache g++
+ sanitizer_flags: -fsanitize=address
+ pg_test_pg_combinebackup_mode: '--copy-file-range'
+ configure: |
+ ./configure \
+ --enable-cassert --enable-injection-points --enable-debug \
+ --enable-tap-tests --enable-nls \
+ --with-segsize-blocks=6 \
+ --with-libnuma \
+ --with-liburing \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CLANG="ccache clang"
+ build: |
+ make -s -j${BUILD_JOBS} world-bin
+ test: |
+ make -s ${CHECK} ${CHECKFLAGS} -j${TEST_JOBS}
+ logs_paths: |
+ **/*.log
+ **/*.diffs
+ **/regress_log_*
+
+ - name: Meson (64bit)
+ slug: meson-64
+ cc: ccache gcc
+ cxx: ccache g++
+ sanitizer_flags: -fsanitize=alignment,undefined
+ pg_test_initdb_extra_opts: '-c io_method=io_uring'
+ configure: |
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ -Duuid=e2fs \
+ --buildtype=debug \
+ -Dllvm=enabled \
+ build
+ build: |
+ ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+ ninja -C build -t missingdeps
+ test: |
+ meson test ${MTEST_ARGS} -C build --num-processes ${TEST_JOBS}
+ logs_paths: *log_paths
+
+ - name: Meson (32bit)
+ slug: meson-32
+ cc: ccache gcc -m32
+ cxx: ccache g++ -m32
+ sanitizer_flags: -fsanitize=alignment,undefined
+ pg_test_initdb_extra_opts: '-c io_method=io_uring'
+ configure: |
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ -Duuid=e2fs \
+ --buildtype=debug \
+ --pkg-config-path /usr/lib/i386-linux-gnu/pkgconfig/ \
+ -DPERL=perl5.40-i386-linux-gnu \
+ -Dlibnuma=disabled \
+ build
+ build: |
+ ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+ ninja -C build -t missingdeps
+ test: |
+ PYTHONCOERCECLOCALE=0 LANG=C \
+ meson test ${MTEST_ARGS} -C build --num-processes ${TEST_JOBS}
+ logs_paths: *log_paths
+ container:
+ image: ${{ needs.setup.outputs.linux_ci_image }}
+ # Share the host PID + IPC namespaces. 017_shm.pl rapidly creates,
+ # kill9's, and restarts postgres; with the container's small PID
+ # space a new postgres can recycle the dead postmaster's PID before
+ # pg_ctl's postmaster.pid check notices, producing spurious "node X
+ # is already running" failures. SysV shm in the test also relies on
+ # host-like IPC behavior.
+ #
+ # --ulimit raises memlock and core dump size. Memlock is needed for
+ # running the AIO tests.
+ #
+ # --privileged is needed so the prepare step can write to sysctls
+ # under /proc/sys (it's mounted read-only without it). We use it to
+ # set kernel.core_pattern and (for the meson entries) to flip
+ # kernel.io_uring_disabled (default 2 on recent GH runner kernels).
+ options: --pid=host --ipc=host --ulimit memlock=-1:-1 --privileged
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ CCACHE_DIR: /tmp/ccache_dir
+ DEBUGINFOD_URLS: "https://debuginfod.debian.net"
+
+ UBSAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:verbosity=2
+ ASAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:detect_leaks=0:detect_stack_use_after_return=0
+ CFLAGS: -Og -ggdb -fno-sanitize-recover=all ${{ matrix.sanitizer_flags }}
+ CXXFLAGS: -Og -ggdb -fno-sanitize-recover=all ${{ matrix.sanitizer_flags }}
+ LDFLAGS: ${{ matrix.sanitizer_flags }}
+ CC: ${{ matrix.cc }}
+ CXX: ${{ matrix.cxx }}
+
+ PG_TEST_INITDB_EXTRA_OPTS: ${{ matrix.pg_test_initdb_extra_opts }}
+ PG_TEST_PG_COMBINEBACKUP_MODE: ${{ matrix.pg_test_pg_combinebackup_mode }}
+ steps:
+ - *checkout_step
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-linux-${{ matrix.slug }}-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ccache-linux-${{ matrix.slug }}-${{ github.ref_name }}-
+ ccache-linux-${{ matrix.slug }}-
+
+ - name: Prepare workspace
+ run: |
+ useradd -m postgres
+ chown -R postgres:postgres .
+ mkdir -p "$CCACHE_DIR"
+ chown -R postgres:postgres "$CCACHE_DIR"
+ mkdir -m 770 /tmp/cores
+ chown root:postgres /tmp/cores
+ sysctl kernel.core_pattern='/tmp/cores/%e-%s-%p.core'
+ # This is only needed on Linux Meson but it doesn't harm to have
+ # this enabled.
+ sysctl -w kernel.io_uring_disabled=0
+
+ cat >> /etc/hosts <<-EOF
+ 127.0.0.1 pg-loadbalancetest
+ 127.0.0.2 pg-loadbalancetest
+ 127.0.0.3 pg-loadbalancetest
+ EOF
+
+ - name: Configure
+ run: |
+ su postgres <<EOF
+ set -e
+ ${{ matrix.configure }}
+ EOF
+
+ - name: Build
+ run: |
+ su postgres <<EOF
+ set -e
+ ${{ matrix.build }}
+ EOF
+
+ - name: Test world
+ run: |
+ su postgres <<EOF
+ set -e
+ ulimit -c unlimited
+ ${{ matrix.test }}
+ EOF
+
+ - name: Core backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh linux /tmp/cores
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: linux-${{ matrix.slug }}-logs-${{ github.run_id }}
+ path: ${{ matrix.logs_paths }}
+ if-no-files-found: ignore
+
+
+ # SPECIAL:
+ # - Enables --clone for pg_upgrade and pg_combinebackup
+ # - Specifies configuration options that test reading/writing/copying of node trees
+ # - Specifies debug_parallel_query=regress, to catch related issues during CI
+ macos:
+ name: macOS - Meson
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.macos == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: macos-15
+ timeout-minutes: 60
+ env:
+ BUILD_JOBS: 4
+ # Test performance regresses noticeably when using all cores. 8 works OK.
+ # https://postgr.es/m/20220927040208.l3shfcidovpzqxfh%40awork3.anarazel.de
+ # Fix: Needs to be re-tested for Github Actions.
+ TEST_JOBS: 8
+
+ CCACHE_DIR: ${{ github.workspace }}/ccache_dir
+ MACPORTS_CACHE: ${{ github.workspace }}/macports-cache
+
+ MESON_FEATURES: >-
+ -Dbonjour=enabled
+ -Ddtrace=enabled
+ -Dgssapi=enabled
+ -Dlibcurl=enabled
+ -Dnls=enabled
+ -Duuid=e2fs
+
+ MACOS_PACKAGE_LIST: >-
+ ccache
+ icu
+ kerberos5
+ lz4
+ meson
+ openldap
+ openssl
+ p5.34-io-tty
+ p5.34-ipc-run
+ python312
+ tcl
+ zstd
+
+ CC: ccache cc
+ CXX: ccache c++
+ CFLAGS: -Og -ggdb
+ CXXFLAGS: -Og -ggdb
+ PG_TEST_PG_UPGRADE_MODE: --clone
+ PG_TEST_PG_COMBINEBACKUP_MODE: --clone
+
+ # Several buildfarm animals enable these options. Without testing them
+ # during CI, it would be easy to cause breakage on the buildfarm with CI
+ # passing.
+ PG_TEST_INITDB_EXTRA_OPTS: >-
+ -c debug_copy_parse_plan_trees=on
+ -c debug_write_read_parse_plan_trees=on
+ -c debug_raw_expression_coverage_test=on
+ -c debug_parallel_query=regress
+
+ steps:
+ - *checkout_step
+
+ - name: Sysinfo
+ run: |
+ id
+ uname -a
+ ulimit -a -H && ulimit -a -S
+ env
+
+ - name: Setup core files
+ run: |
+ mkdir -p $HOME/cores
+ sudo sysctl kern.corefile="$HOME/cores/core.%P"
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-macos-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ccache-macos-${{ github.ref_name }}-
+ ccache-macos-
+
+ - name: Compute MacPorts cache key
+ id: mpkey
+ run: |
+ macos_major=$(sw_vers -productVersion | sed 's/\..*//')
+ pkglist_hash=$(printf '%s' "$MACOS_PACKAGE_LIST" | md5 -q)
+ script_hash=$(md5 -q src/tools/ci/ci_macports_packages.sh)
+ echo "key=macports-${macos_major}-${pkglist_hash}-${script_hash}-${GITHUB_RUN_ID}" >> "$GITHUB_OUTPUT"
+ echo "restore-key=macports-${macos_major}-${pkglist_hash}-${script_hash}-" >> "$GITHUB_OUTPUT"
+
+ - name: Restore MacPorts cache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.MACPORTS_CACHE }}
+ key: ${{ steps.mpkey.outputs.key }}
+ restore-keys: ${{ steps.mpkey.outputs.restore-key }}
+
+ # Use macports, even though homebrew is installed. The installation
+ # of the additional packages we need would take quite a while with
+ # homebrew, even if we cache the downloads. We can't cache all of
+ # homebrew, because it's already large. So we use macports. To cache
+ # the installation we create a .dmg file that we mount if it already
+ # exists.
+ # XXX: The reason for the direct p5.34* references is that we'd need
+ # the large macport tree around to figure out that p5-io-tty is
+ # actually p5.34-io-tty. Using the unversioned name works, but
+ # updates macports every time.
+ - name: Install dependencies (MacPorts)
+ env:
+ # Pass token so the script's GitHub API call to list MacPorts
+ # releases isn't subject to the 60/hr/IP unauthenticated rate
+ # limit (shared across all jobs on the runner's IP).
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ sh src/tools/ci/ci_macports_packages.sh $MACOS_PACKAGE_LIST
+ # system python doesn't provide headers
+ sudo /opt/local/bin/port select python3 python312
+ # Make macports install visible to subsequent steps
+ echo /opt/local/sbin >> "$GITHUB_PATH"
+ echo /opt/local/bin >> "$GITHUB_PATH"
+
+ - name: Configure
+ run: |
+ export PKG_CONFIG_PATH="/opt/local/lib/pkgconfig/"
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ --buildtype=debug \
+ -Dextra_include_dirs=/opt/local/include \
+ -Dextra_lib_dirs=/opt/local/lib \
+ -Ddarwin_sysroot=none \
+ ${MESON_COMMON_FEATURES} \
+ ${MESON_FEATURES} \
+ build
+
+ - name: Build
+ run: ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+
+ - name: Test world
+ run: |
+ ulimit -c unlimited # default is 0
+ ulimit -n 1024 # default is 256, pretty low
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+
+ - name: Core backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh macos "$HOME/cores"
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: macos-logs-${{ github.run_id }}
+ path: *log_paths
+ if-no-files-found: ignore
+
+
+ windows-vs:
+ name: Windows - VS - Meson & ninja
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.windows == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: windows-2022
+ timeout-minutes: 60
+ env:
+ TEST_JOBS: 8
+ # Avoid port conflicts between concurrent tap tests
+ PG_TEST_USE_UNIX_SOCKETS: 1
+ PG_REGRESS_SOCK_DIR: 'c:\pgsock'
+
+ MESON_FEATURES: >-
+ -Dcpp_args=/std:c++20
+ -Dauto_features=disabled
+ -Dtap_tests=enabled
+ -Dldap=enabled
+ -Dssl=openssl
+ -Dplperl=enabled
+ -Dplpython=enabled
+ TAR: "c:/windows/system32/tar.exe"
+
+ defaults:
+ run:
+ shell: cmd
+ steps:
+ - name: Disable Windows Defender
+ shell: powershell
+ run: |
+ Set-MpPreference -DisableRealtimeMonitoring $true -SubmitSamplesConsent NeverSend -MAPSReporting Disable
+ # Verify Defender status
+ $status = Get-MpComputerStatus -ErrorAction SilentlyContinue
+ if ($status) {
+ Write-Host "RealTimeProtectionEnabled: $($status.RealTimeProtectionEnabled)"
+ Write-Host "AntivirusEnabled: $($status.AntivirusEnabled)"
+ }
+
+ - *checkout_step
+
+ - name: Sysinfo
+ run: |
+ chcp
+ systeminfo
+ set
+
+ # The TAP tests build an initdb template under build/tmp_install and
+ # then `robocopy` it into per-test data directories. Robocopy with the
+ # default /COPY:DAT flag doesn't copy ACLs — destinations inherit from
+ # their parent dir. On GitHub-hosted Windows runners the workspace's
+ # inherited ACL grants Administrators:(F) and Users:(RX) but does NOT
+ # grant the runner user (runneradmin) directly. That matters because
+ # pg_ctl on Windows uses CreateRestrictedProcess to drop admin
+ # privileges from postmaster, so the postmaster process has the user
+ # SID in its token but no longer the Administrators group — leaving it
+ # with only "Users:(RX)" on pg_control and friends, which causes
+ # "PANIC: could not open file global/pg_control: Permission denied".
+ #
+ # Fix it once on the workspace dir with (OI)(CI) inheritance flags so
+ # every file/dir created underneath gets an explicit grant for the
+ # current user.
+ - name: Grant workspace ACL to runner user
+ shell: pwsh
+ run: |
+ icacls "${{ github.workspace }}" /grant "${env:USERNAME}:(OI)(CI)F" /Q | Out-Null
+ Write-Host "Granted Full Control to $env:USERNAME on ${{ github.workspace }}"
+
+ # postgres' plpython3u loads python3.dll (the stable-ABI forwarder)
+ # which in turn loads whichever python3NN.dll the Windows loader finds
+ # first on PATH. On windows-2022 `C:\Program Files\Mercurial\` ships
+ # its own python3.dll + python39.dll and appears on PATH *before* the
+ # hostedtoolcache Python 3.12 — so without intervention the backend
+ # ends up running Python 3.9 while postgres' stdlib search uses 3.12,
+ # producing `ImportError: cannot import name 'text_encoding' from
+ # 'io'` (the 3.12 `io.py` calling into 3.9's `_io`).
+ #
+ # Pin PYTHONHOME to the Python 3.12 prefix, and prepend that prefix
+ # to PATH so its python3.dll wins the DLL search.
+ - name: Pin Python prefix on PATH and PYTHONHOME
+ shell: pwsh
+ run: |
+ $prefix = (python -c "import sys; print(sys.prefix)").Trim()
+ Add-Content $env:GITHUB_ENV "PYTHONHOME=$prefix"
+ Add-Content $env:GITHUB_PATH $prefix
+ Write-Host "PYTHONHOME=$prefix"
+ Write-Host "Prepended $prefix to PATH"
+
+ - name: Install dependencies
+ shell: pwsh
+ run: |
+ choco install -y --no-progress --limitoutput diffutils winflexbison3
+ # meson + ninja aren't preinstalled on windows-2022. Install via pip
+ python -m pip install --upgrade meson ninja
+
+ # OpenSSL 1.1 via the slproweb installer (pinned to match the
+ # version used elsewhere in postgres CI).
+ curl.exe -fsSL -o openssl-setup.exe https://slproweb.com/download/Win64OpenSSL-1_1_1w.exe
+ Start-Process -Wait -FilePath ./openssl-setup.exe `
+ -ArgumentList '/DIR=c:\openssl\1.1\ /VERYSILENT /SP- /SUPPRESSMSGBOXES'
+ # The slproweb installer puts libcrypto-1_1-x64.dll / libssl-1_1-x64.dll
+ # in c:\openssl\1.1\bin\ and updates the system PATH. GH Actions
+ # snapshots PATH at job start though, so the running job won't
+ # see those DLLs and initdb.exe would crash silently at runtime.
+ # Push the bin dir onto GITHUB_PATH so it persists for later steps.
+ Add-Content $env:GITHUB_PATH "c:\openssl\1.1\bin"
+
+ # Install IPC::Run.
+ # - recommends_policy=0 keeps cpan from pulling in IO::Tty / IO::Pty,
+ # which don't build on Windows ("This module requires a POSIX
+ # compliant system to work").
+ # - Pin to NJM/IPC-Run-20250809.0 because TODDR/IPC-Run-20260322.0
+ # broke postgres tap tests on Windows (changed pipe stdio
+ # handling). See upstream pg-vm-images commit ff5238afa3 and
+ # the thread at
+ # https://postgr.es/m/CAN55FZ06xanSbJdHe-CurjX_qNuBWZDEvS1kAk36L38YCtZXnw%40mail.gmail.com
+ "o conf recommends_policy 0`no conf commit`nnotest install NJM/IPC-Run-20250809.0.tar.gz" | cpan
+ perl -mIPC::Run -e 1
+
+ - name: Setup hosts file
+ shell: pwsh
+ run: |
+ Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.1 pg-loadbalancetest"
+ Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.2 pg-loadbalancetest"
+ Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.3 pg-loadbalancetest"
+
+ - name: Setup socket directory
+ shell: cmd
+ run: mkdir %PG_REGRESS_SOCK_DIR%
+
+ - name: Configure
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ meson setup --backend ninja %MESON_COMMON_PG_CONFIG_ARGS% %MESON_FEATURES% --buildtype debug -Db_pch=true -Dextra_lib_dirs=c:\openssl\1.1\lib -Dextra_include_dirs=c:\openssl\1.1\include -DTAR=%TAR% build
+
+ - name: Build
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ ninja -C build %MBUILD_TARGET%
+ ninja -C build -t missingdeps
+
+ - name: Test world
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ meson test %MTEST_ARGS% --num-processes %TEST_JOBS%
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: windows-vs-logs-${{ github.run_id }}
+ path: |
+ ${{ env._LOG_PATHS }}
+ crashlog-*.txt
+ if-no-files-found: ignore
+
+
+ windows-mingw:
+ name: Windows - MinGW - Meson
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.mingw == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: windows-2022
+ timeout-minutes: 60
+ env:
+ TEST_JOBS: 4 # higher concurrency causes occasional failures
+ PG_TEST_USE_UNIX_SOCKETS: 1
+ PG_REGRESS_SOCK_DIR: 'c:\pgsock\'
+ TAR: "c:/windows/system32/tar.exe"
+ # for mingw plpython to find its installation
+ PYTHONHOME: D:/a/_temp/msys64/ucrt64
+
+ MSYS: winjitdebug
+ CHERE_INVOKING: 1
+
+ # Keep -Dnls explicitly disabled, as the number of files it creates
+ # causes a noticeable slowdown.
+ MESON_FEATURES: >-
+ -Dnls=disabled
+
+ CCACHE_DIR: D:/a/ccache
+ CCACHE_MAXSIZE: "500M"
+ CCACHE_SLOPPINESS: pch_defines,time_macros
+ CCACHE_DEPEND: 1
+
+ steps:
+ - name: Disable Windows Defender
+ shell: powershell
+ run: |
+ Set-MpPreference -DisableRealtimeMonitoring $true -SubmitSamplesConsent NeverSend -MAPSReporting Disable
+ # Verify Defender status
+ $status = Get-MpComputerStatus -ErrorAction SilentlyContinue
+ if ($status) {
+ Write-Host "RealTimeProtectionEnabled: $($status.RealTimeProtectionEnabled)"
+ Write-Host "AntivirusEnabled: $($status.AntivirusEnabled)"
+ }
+
+ - *checkout_step
+
+ - name: Setup MSYS2
+ uses: msys2/setup-msys2@v2
+ with:
+ msystem: UCRT64
+ update: true
+ install: >-
+ git bison flex make diffutils
+ mingw-w64-ucrt-x86_64-ccache
+ mingw-w64-ucrt-x86_64-gcc
+ mingw-w64-ucrt-x86_64-icu
+ mingw-w64-ucrt-x86_64-libbacktrace
+ mingw-w64-ucrt-x86_64-libxml2
+ mingw-w64-ucrt-x86_64-libxslt
+ mingw-w64-ucrt-x86_64-lz4
+ mingw-w64-ucrt-x86_64-make
+ mingw-w64-ucrt-x86_64-meson
+ mingw-w64-ucrt-x86_64-perl
+ mingw-w64-ucrt-x86_64-pkg-config
+ mingw-w64-ucrt-x86_64-readline
+ mingw-w64-ucrt-x86_64-zlib
+
+ - name: Install additional dependencies
+ shell: msys2 {0}
+ run: |
+ # Pin IPC::Run to NJM/IPC-Run-20250809.0; TODDR/IPC-Run-20260322.0
+ # broke postgres tap tests on Windows (pipe stdio handling).
+ # See pg-vm-images commit ff5238afa3.
+ (echo; echo o conf recommends_policy 0; echo notest install NJM/IPC-Run-20250809.0.tar.gz) | cpan
+ perl -mIPC::Run -e 1
+
+ - name: Setup socket directory
+ shell: cmd
+ run: mkdir %PG_REGRESS_SOCK_DIR%
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-mingw-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ccache-mingw-${{ github.ref_name }}-
+ ccache-mingw-
+
+ - name: Configure
+ shell: msys2 {0}
+ run: |
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ -Ddebug=true -Doptimization=g -Db_pch=true \
+ ${MESON_COMMON_FEATURES} \
+ ${MESON_FEATURES} \
+ -DTAR=${TAR} \
+ build
+
+ - name: Build
+ shell: msys2 {0}
+ run: ninja -C build ${MBUILD_TARGET}
+
+ - name: Test world
+ shell: msys2 {0}
+ run: meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: windows-mingw-logs-${{ github.run_id }}
+ path: |
+ ${{ env._LOG_PATHS }}
+ crashlog-*.txt
+ if-no-files-found: ignore
+
+ # Test that code can be built with both gcc and clang without warnings,
+ # with various combinations of cassert/dtrace flags. Trace probes have
+ # a history of getting accidentally broken; the matrix is there to
+ # catch that.
+ #
+ # The autoconf cache files (gcc.cache / clang.cache) are intentionally
+ # reused across the matrix entries that share a compiler, so we don't
+ # pay for full feature detection on every entry.
+ compiler-warnings:
+ name: CompilerWarnings
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.compilerwarnings == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ container:
+ image: ${{ needs.setup.outputs.linux_ci_image }}
+ env:
+ BUILD_JOBS: 4
+ CCACHE_DIR: /tmp/ccache_dir
+ # Use larger ccache cache as this job compiles with multiple
+ # compilers / flag combinations.
+ CCACHE_MAXSIZE: "1G"
+ steps:
+ - *checkout_step
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-compiler-warnings-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ccache-compiler-warnings-${{ github.ref_name }}-
+ ccache-compiler-warnings-
+
+ - name: Sysinfo
+ run: |
+ id
+ uname -a
+ cat /proc/cmdline
+ ulimit -a -H && ulimit -a -S
+ gcc -v
+ clang -v
+ env
+
+ - name: Setup workspace
+ run: |
+ echo "COPT=-Werror" > src/Makefile.custom
+ mkdir -p "$CCACHE_DIR"
+
+ # gcc, cassert off, dtrace on
+ - name: gcc warnings + (dtrace)
+ if: always()
+ run: |
+ ./configure \
+ --cache gcc.cache \
+ --enable-dtrace \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ # gcc, cassert on, dtrace off
+ - name: gcc warnings + (cassert)
+ if: always()
+ run: |
+ ./configure \
+ --cache gcc.cache \
+ --enable-cassert \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ # clang, cassert off, dtrace off
+ - name: clang warnings
+ if: always()
+ run: |
+ ./configure \
+ --cache clang.cache \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache clang" CXX="ccache clang++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ # clang, cassert on, dtrace on
+ - name: clang warnings + (cassert + dtrace)
+ if: always()
+ run: |
+ ./configure \
+ --cache clang.cache \
+ --enable-cassert \
+ --enable-dtrace \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache clang" CXX="ccache clang++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ - name: mingw warnings (cross compilation)
+ if: always()
+ run: |
+ ./configure \
+ --host=x86_64-w64-mingw32ucrt \
+ --enable-cassert \
+ --without-icu \
+ CC="ccache x86_64-w64-mingw32ucrt-gcc" \
+ CXX="ccache x86_64-w64-mingw32ucrt-g++"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ ###
+ # Verify docs can be built
+ ###
+ # XXX: Only do this if there have been changes in doc/ since last build
+ - name: Build documentation
+ if: always()
+ run: |
+ ./configure \
+ --cache gcc.cache \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} -C doc
+
+ ###
+ # Verify headerscheck / cpluspluscheck succeed
+ #
+ # - Run both in same script to increase parallelism, use -k to get
+ # result of both
+ # - Use -fmax-errors, as particularly cpluspluscheck can be very verbose
+ ###
+ - name: headerscheck + cpluspluscheck
+ if: always()
+ run: |
+ ./configure \
+ ${LINUX_CONFIGURE_FEATURES} \
+ --cache gcc.cache \
+ --quiet \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} -k ${CHECKFLAGS} headerscheck cpluspluscheck EXTRAFLAGS='-fmax-errors=10'
diff --git a/src/tools/ci/ci_macports_packages.sh b/src/tools/ci/ci_macports_packages.sh
index 63e97b37c78..4c79f90fed0 100755
--- a/src/tools/ci/ci_macports_packages.sh
+++ b/src/tools/ci/ci_macports_packages.sh
@@ -20,13 +20,26 @@ echo "macOS major version: $macos_major_version"
# macOS release.
macports_release_list_url="https://api.github.com/repos/macports/macports-base/releases"
macports_version_pattern="2\.10\.1"
-macports_url="$( curl -s $macports_release_list_url | grep "\"https://github.com/macports/macports-base/releases/download/v$macports_version_pattern/MacPorts-$macports_version_pattern-$macos_major_version-[A-Za-z]*\.pkg\"" | sed 's/.*: "//;s/".*//' | head -1 )"
+# Authenticate the GitHub API request when a token is available (e.g. on
+# GitHub Actions). Unauthenticated requests share a 60/hr/IP rate limit
+# with every other job on the runner's IP and frequently return an error
+# JSON, leaving $macports_url empty and breaking the subsequent curl.
+auth_header=""
+if [ -n "$GITHUB_TOKEN" ]; then
+ auth_header="Authorization: Bearer $GITHUB_TOKEN"
+fi
+macports_url="$( curl -fsSL ${auth_header:+-H "$auth_header"} "$macports_release_list_url" | grep "\"https://github.com/macports/macports-base/releases/download/v$macports_version_pattern/MacPorts-$macports_version_pattern-$macos_major_version-[A-Za-z]*\.pkg\"" | sed 's/.*: "//;s/".*//' | head -1 )"
echo "MacPorts package URL: $macports_url"
+if [ -z "$macports_url" ]; then
+ echo "error: could not determine MacPorts package URL for macOS $macos_major_version (version pattern: $macports_version_pattern)" 1>&2
+ exit 1
+fi
+
cache_dmg="macports.hfs.dmg"
-if [ "$CIRRUS_CI" != "true" ]; then
- echo "expect to be called within cirrus-ci" 1>2
+if [ "$CIRRUS_CI" != "true" ] && [ "$GITHUB_ACTIONS" != "true" ]; then
+ echo "expect to be called within cirrus-ci or github actions" 1>2
exit 1
fi
--
2.47.3
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 17:07 Nazir Bilal Yavuz <[email protected]>
parent: Zsolt Parragi <[email protected]>
0 siblings, 0 replies; 42+ messages in thread
From: Nazir Bilal Yavuz @ 2026-05-28 17:07 UTC (permalink / raw)
To: Zsolt Parragi <[email protected]>; +Cc: [email protected]
Hi,
Thank you for looking into this!
On Thu, 28 May 2026 at 02:10, Zsolt Parragi <[email protected]> wrote:
>
> Hello!
>
> I didn't try the workflow on github yet, I only have a few comments
> based on the yaml file:
>
> +on:
> + push:
> + branches: [ "*" ]
> +
>
> Should this be "**", otherwise we ignore branches with a "/" in it?
You are right. I completely removed the 'branches:' part, now it
should match with every branch.
> + SANITIZER_FLAGS: -fsanitize=address
>
> is this used anywhere? Seems like it's directly included into CFLAGS/LDFLAGS.
It wasn't used but I put it there for visibility since in Github
Actions you can't refer to other environment variables (Perhaps a
comment was needed for this). We don't use this now since all linux
tasks are merged in the v3 [1].
[1] https://postgr.es/m/CAN55FZ1-qiOWtQH5o6Q_7LJ7S3Ef_hfDE068uP0hGjB3gzwghg%40mail.gmail.com
--
Regards,
Nazir Bilal Yavuz
Microsoft
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 17:08 Nazir Bilal Yavuz <[email protected]>
parent: Peter Eisentraut <[email protected]>
0 siblings, 0 replies; 42+ messages in thread
From: Nazir Bilal Yavuz @ 2026-05-28 17:08 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; +Cc: Jelte Fennema-Nio <[email protected]>; Andres Freund <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers
Hi,
Thank you for looking into this!
On Thu, 28 May 2026 at 14:49, Peter Eisentraut <[email protected]> wrote:
>
> On 25.05.26 14:14, Nazir Bilal Yavuz wrote:
> > On Tue, 19 May 2026 at 01:27, Nazir Bilal Yavuz<[email protected]> wrote:
> >> I think we can merge these two patches and move forward that way. I am
> >> planning to review your patch and see what I can come up with to get
> >> it to a committable state.
> > Here is the v2, I took Jelte's patch and reviewed & merged it with my
> > patch.
>
> I have tested this patch and inspected the output mostly to make sure
> that there are no regressions about what features and dependency
> versions are being tested (diffed the various logs). I'm proposing a
> few minor fixups in the attached patch, but other than that (and what
> others have mentioned), this pretty much works well, and I would be
> content to proceed with this or whatever state it's on in a few days.
>
> Some comments in detail:
I addressed these feedbacks in v3 [1].
> - Others have already mentioned about the potential for this to conflict
> with downstream uses of GH Actions. I suggest renaming the file from
> ci.yml to something like postgresql-ci.yml, so that there is no file
> naming conflict or confusion.
Done.
> - As was already mentioned, the Linux/Meson job is very long (slow) and
> should be split into separate 32/64-bit jobs.
>
> - The job names are too long and get truncated in the UI. This is
> especially annoying when the important differentiator like "Autoconf" or
> "Meson" gets cut off. I'm proposing some changes to the job names that
> make them display better. (Also consider this if you make separate jobs
> for 32/64-bit. The usable space is about 20 characters.)
I think this is better. Also, I merged all Linux tasks and because of
that I needed to add 64 bit and 32 bit to task names. So, I removed
'Debian' from task names because of the same reason you mentioned.
> - On macOS, there were some dependency differences:
>
> - readline was not used.
> - tcl-tk (version 9) was used instead of tcl-tk@8.
> - [email protected] was installed but not actually used in the build.
> - zlib version differed.
>
> Maybe the zlib difference is not important and could be ignored.
> Also, maybe we don't need to use a versioned python dependency. (We
> didn't have one before we switched Cirrus from Homebrew to MacPorts.)
I used MacPorts like we did in Cirrus. So, I didn't apply these changes.
> - On macOS, the meson setup output reported a significantly different
> sysroot, which was confusing. I think the sysroot is only used if you
> build against a system perl/python/tcl, which we don't, so I added an
> option to disable the sysroot use. That way, if we do end up making use
> of the sysroot, someone is forced to investigate this issue. I don't
> know if this makes sense.
I think it makes sense.
> - For macOS, I threw in some HOMEBREW_* environment variables to disable
> some unnecessary additional output or cleanup steps.
I didn't apply these since MacPorts is used now.
> - On Windows/VS, we should install winflexbison3 not winflexbison, to
> get an up-to-date version.
Done.
> - FUTURE: On Windows/VS, we use openssl 1.1, which matches the Cirrus
> setup, so it's ok, but the equivalent buildfarm members all use openssl
> 3.*, so we should consider upgrading that sometime to make that more
> consistent.
I wondered the same thing while working on this.
> - On Windows/minGW, I dropped a few packages from the set to be
> installed, which didn't seem necessary.
Done.
[1] https://postgr.es/m/CAN55FZ1-qiOWtQH5o6Q_7LJ7S3Ef_hfDE068uP0hGjB3gzwghg%40mail.gmail.com
--
Regards,
Nazir Bilal Yavuz
Microsoft
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 18:11 Álvaro Herrera <[email protected]>
parent: Nazir Bilal Yavuz <[email protected]>
2 siblings, 1 reply; 42+ messages in thread
From: Álvaro Herrera @ 2026-05-28 18:11 UTC (permalink / raw)
To: Nazir Bilal Yavuz <[email protected]>; +Cc: Andres Freund <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers; Zsolt Parragi <[email protected]>; Peter Eisentraut <[email protected]>
Hi, I just pushed this to github to see how it would behave. In case
anyone is curious, the run is here,
https://github.com/alvherre/postgres/actions/runs/26591496806
Overall I get the impression that it's much slower than Cirrus. 20
minutes in, only the two "Linux - Meson" build finished, in 14 and 17
minutes respectively. Macos took 10 minutes just for the macports
install! Cirrus completed the same build in 18:32,
https://cirrus-ci.com/build/4817054382948352
If I read the Github docs correctly, I get 2000 run minutes for free
each month. That would mean I can run at most some ... 15 runs per
month? That sounds quite limiting. I hope we allow self-hosted runners
at some point; I have quite a bit of spare CPU capacity at home that I
could run the Linux and CompilerWarnings tasks on, leaving the Github
machines to run only the macOS and Windows ones.
--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
"I'm impressed how quickly you are fixing this obscure issue. I came from
MS SQL and it would be hard for me to put into words how much of a better job
you all are doing on [PostgreSQL]."
Steve Midgley, http://archives.postgresql.org/pgsql-sql/2008-08/msg00000.php
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 18:42 Álvaro Herrera <[email protected]>
parent: Álvaro Herrera <[email protected]>
0 siblings, 1 reply; 42+ messages in thread
From: Álvaro Herrera @ 2026-05-28 18:42 UTC (permalink / raw)
To: Nazir Bilal Yavuz <[email protected]>; +Cc: Andres Freund <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers; Zsolt Parragi <[email protected]>; Peter Eisentraut <[email protected]>
On 2026-May-28, Álvaro Herrera wrote:
> Hi, I just pushed this to github to see how it would behave. In case
> anyone is curious, the run is here,
>
> https://github.com/alvherre/postgres/actions/runs/26591496806
>
> Overall I get the impression that it's much slower than Cirrus. [...]
>
> If I read the Github docs correctly, I get 2000 run minutes for free
> each month. That would mean I can run at most some ... 15 runs per
> month? That sounds quite limiting.
It ended up taking 3 hours 3 minutes, which means I can do 10.9 of those
per month. Further runs will take less time due to ccache I suppose,
but the actual build is not a huge fraction of the total run time.
Linux+CompilerWarnings totalled 89 minutes; if I subtract those from the
total, I need 94 minutes to run the other builds, and then I can do 21.2
runs per month.
--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 19:42 Andres Freund <[email protected]>
parent: Álvaro Herrera <[email protected]>
0 siblings, 1 reply; 42+ messages in thread
From: Andres Freund @ 2026-05-28 19:42 UTC (permalink / raw)
To: Álvaro Herrera <[email protected]>; +Cc: Nazir Bilal Yavuz <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers; Zsolt Parragi <[email protected]>; Peter Eisentraut <[email protected]>
Hi,
On 2026-05-28 20:42:41 +0200, Álvaro Herrera wrote:
> On 2026-May-28, Álvaro Herrera wrote:
>
> > Hi, I just pushed this to github to see how it would behave. In case
> > anyone is curious, the run is here,
> >
> > https://github.com/alvherre/postgres/actions/runs/26591496806
> >
> > Overall I get the impression that it's much slower than Cirrus. [...]
> Macos took 10 minutes just for the macports install! Cirrus completed the
> same build in 18:32, https://cirrus-ci.com/build/4817054382948352
FWIW, the macports install should be down to ~5s on subsequent runs. Doing
that uncached was also rather slow on cirrus.
> > If I read the Github docs correctly, I get 2000 run minutes for free
> > each month. That would mean I can run at most some ... 15 runs per
> > month? That sounds quite limiting.
My understanding is that the 2000 minutes is the limit for *private*
repositories: [1]
"Use of the standard GitHub-hosted runners is free and unlimited on public
repositories."
The concurrency limits are also pretty generous: [2], 20 jobs of 4 cores each.
If you look at the limits of other providers, they are much much lower. Like
400 CPU minutes for gitlab (so about 100 minutes of 4 core VMs).
On 2026-05-28 20:11:45 +0200, Álvaro Herrera wrote:
> Hi, I just pushed this to github to see how it would behave. In case
> anyone is curious, the run is here,
>
> https://github.com/alvherre/postgres/actions/runs/26591496806
>
> Overall I get the impression that it's much slower than Cirrus. 20
> minutes in, only the two "Linux - Meson" build finished, in 14 and 17
> minutes respectively.
It's definitely slower. I've not fully analyzed why, my suspicion is that we
end up being rather terribly IO bound - we used bigger and faster disks on
cirrus than we have access to with github hosted runners (there are large
runners with more storage, but that's not free).
A full testrun on master creates about 36GB of data directories. If individual
tests are fast, that's often not *that* bad, because the tests are over before
linux decides to flush out the data, and then linux never needs to write that
data back, because we remove the data directories immediately. But once you
get to the point that several tests take more than 30s (the default time after
which linux writes dirty data back) or enough dirty data accumulates (20% of
memory IIRC), you have a lot of IO.
My buildfarm host, which hosts quite a few animals, got a new disk within the
last year. Here's what smartctl says about disk IO:
Data Units Read: 43,513,034 [22.2 TB]
Data Units Written: 6,062,401,949 [3.10 PB]
A nice indication of how much our tests end up writing...
I think we're going to have to fix that on our end to some degree. 36GB of
data being written each test run is just not reasonable. We spin up quite a
few separate data directories for tests that take well under a second. That's
just a very unfavorable ratio. In [3] I wrote
> I think we need to combine about half the modules in src/test/modules, the
> current course is absurd:
>
> 16: 37
> 17: 46
> 18: 49
> dev: 62
Greetings,
Andres Freund
[1] https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-ru...
[2] https://docs.github.com/en/actions/reference/limits#job-concurrency-limits-for-github-hosted-runners
[3] https://postgr.es/m/hp4xznm7dqt4ediyhezqysf22eljvu3mucbzsgvgehc6j2hk5v%40laslwlkyixfg
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-28 20:50 Jacob Champion <[email protected]>
parent: Nazir Bilal Yavuz <[email protected]>
2 siblings, 1 reply; 42+ messages in thread
From: Jacob Champion @ 2026-05-28 20:50 UTC (permalink / raw)
To: Nazir Bilal Yavuz <[email protected]>; +Cc: Andres Freund <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers; Zsolt Parragi <[email protected]>; Peter Eisentraut <[email protected]>
On Thu, May 28, 2026 at 10:06 AM Nazir Bilal Yavuz <[email protected]> wrote:
> > > + $prefix = (python -c "import sys; print(sys.prefix)").Trim()
> > > + Add-Content $env:GITHUB_ENV "PYTHONHOME=$prefix"
> > > + Add-Content $env:GITHUB_PATH $prefix
> > > + Write-Host "PYTHONHOME=$prefix"
> > > + Write-Host "Prepended $prefix to PATH"
> >
> > GRJGJKLJKJDFJKDF.
>
> I re-checked this since Jelte wasn't completely sure about this [2]
> but this is unfortunately correct :(
What are the chances we can strip Mercurial out of the PATH instead of
messing with PYTHONHOME? I foresee pain in the future if we override
that globally.
> v3 is attached.
> + uses: msys2/setup-msys2@v2
Should we pin this? It's the only third-party action we reference, and
Scorecard [1] complains. (I'm not convinced its other complaints in
this category are something we want to worry about, but this caught my
eye.)
We'd need to figure out how to keep it up to date, if we pinned it.
But we probably need to figure out how to keep it up to date anyway.
Scorecard doesn't report any `Dangerous-Workflow` violations, so that's good.
--Jacob
[1] https://scorecard.dev/
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-29 09:51 Nazir Bilal Yavuz <[email protected]>
parent: Jacob Champion <[email protected]>
0 siblings, 1 reply; 42+ messages in thread
From: Nazir Bilal Yavuz @ 2026-05-29 09:51 UTC (permalink / raw)
To: Jacob Champion <[email protected]>; +Cc: Andres Freund <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers; Zsolt Parragi <[email protected]>; Peter Eisentraut <[email protected]>
Hi,
Thank you for looking into this!
On Thu, 28 May 2026 at 23:50, Jacob Champion
<[email protected]> wrote:
>
> On Thu, May 28, 2026 at 10:06 AM Nazir Bilal Yavuz <[email protected]> wrote:
> > > > + $prefix = (python -c "import sys; print(sys.prefix)").Trim()
> > > > + Add-Content $env:GITHUB_ENV "PYTHONHOME=$prefix"
> > > > + Add-Content $env:GITHUB_PATH $prefix
> > > > + Write-Host "PYTHONHOME=$prefix"
> > > > + Write-Host "Prepended $prefix to PATH"
> > >
> > > GRJGJKLJKJDFJKDF.
> >
> > I re-checked this since Jelte wasn't completely sure about this [2]
> > but this is unfortunately correct :(
>
> What are the chances we can strip Mercurial out of the PATH instead of
> messing with PYTHONHOME? I foresee pain in the future if we override
> that globally.
I think your suggestion is better, done.
> > v3 is attached.
>
> > + uses: msys2/setup-msys2@v2
>
> Should we pin this? It's the only third-party action we reference, and
> Scorecard [1] complains. (I'm not convinced its other complaints in
> this category are something we want to worry about, but this caught my
> eye.)
>
> We'd need to figure out how to keep it up to date, if we pinned it.
> But we probably need to figure out how to keep it up to date anyway.
Instead of using 'msys2/setup-msys2@v2', I directly installed the
packages by using msys2's package installer (pacman). There was one
problem, it seems that default installation of msys2 is on C: drive
and C: drive is somehow lots slower compared to D: drive [1]. I am
talking about total runtime being ~15 minutes slower (22m -> 35m). So,
I moved msys2 to D: drive and used it from there as a solution.
> Scorecard doesn't report any `Dangerous-Workflow` violations, so that's good.
Nice!
v4 is attached, GA run:
https://github.com/nbyavuz/postgres/actions/runs/26628396798
[1] https://github.com/actions/runner-images/issues/8755
--
Regards,
Nazir Bilal Yavuz
Microsoft
Attachments:
[text/x-patch] v4-0001-Add-GitHub-Actions-yaml-file.patch (39.1K, 2-v4-0001-Add-GitHub-Actions-yaml-file.patch)
download | inline diff:
From 79d1320ce52a116651feebe06d1e460beff6f175 Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <[email protected]>
Date: Thu, 28 May 2026 19:31:34 +0300
Subject: [PATCH v4] Add GitHub Actions yaml file
Cirrus CI is shutting down. This is an initial attempt to get a GitHub
Actions CI working.
---
.github/workflows/postgresql-ci.yml | 1023 ++++++++++++++++++++++++++
src/tools/ci/ci_macports_packages.sh | 19 +-
2 files changed, 1039 insertions(+), 3 deletions(-)
create mode 100644 .github/workflows/postgresql-ci.yml
diff --git a/.github/workflows/postgresql-ci.yml b/.github/workflows/postgresql-ci.yml
new file mode 100644
index 00000000000..b56305f9847
--- /dev/null
+++ b/.github/workflows/postgresql-ci.yml
@@ -0,0 +1,1023 @@
+# GitHub Actions CI configuration for PostgreSQL
+
+name: Github Actions CI
+
+on:
+ push:
+
+# Restrict GITHUB_TOKEN to the minimum the jobs need: reading repo
+# contents during checkout.
+permissions:
+ contents: read
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ # Never cancel in-progress runs on master to ensure all commits are tested.
+ cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
+
+env:
+ # The lower depth accelerates git clone. Use a bit of depth so that
+ # concurrent jobs and retrying older runs have a chance of working.
+ CLONE_DEPTH: 500
+
+ CCACHE_MAXSIZE: "250M"
+
+ # check target for the autoconf builds
+ CHECK: check-world PROVE_FLAGS=--timer
+ CHECKFLAGS: -Otarget
+
+ # Build test dependencies as part of the build step, to see compiler
+ # errors/warnings in one place.
+ MBUILD_TARGET: all testprep
+ MTEST_ARGS: --print-errorlogs --no-rebuild -C build
+ PGCTLTIMEOUT: 120 # avoids spurious failures during parallel tests
+ TEMP_CONFIG: ${{ github.workspace }}/src/tools/ci/pg_ci_base.conf
+ PG_TEST_EXTRA: kerberos ldap ssl libpq_encryption load_balance oauth
+
+ # Postgres config args for the meson builds, shared between all meson tasks
+ # except the 'SanityCheck' task
+ MESON_COMMON_PG_CONFIG_ARGS: -Dcassert=true -Dinjection_points=true
+
+ # Meson feature flags shared by all meson tasks, except:
+ # SanityCheck: uses almost no dependencies.
+ # Windows - VS: has fewer dependencies than listed here, so defines its own.
+ # Linux: uses the 'auto' feature option to test meson feature autodetection.
+ MESON_COMMON_FEATURES: >-
+ -Dauto_features=disabled
+ -Dldap=enabled
+ -Dssl=openssl
+ -Dtap_tests=enabled
+ -Dplperl=enabled
+ -Dplpython=enabled
+ -Ddocs=enabled
+ -Dicu=enabled
+ -Dlibxml=enabled
+ -Dlibxslt=enabled
+ -Dlz4=enabled
+ -Dpltcl=enabled
+ -Dreadline=enabled
+ -Dzlib=enabled
+ -Dzstd=enabled
+
+ # Shared between the Linux autoconf job and the CompilerWarnings jobs
+ LINUX_CONFIGURE_FEATURES: >-
+ --with-gssapi
+ --with-icu
+ --with-ldap
+ --with-libcurl
+ --with-libxml
+ --with-libxslt
+ --with-llvm
+ --with-lz4
+ --with-pam
+ --with-perl
+ --with-python
+ --with-selinux
+ --with-ssl=openssl
+ --with-systemd
+ --with-tcl --with-tclconfig=/usr/lib/tcl8.6/
+ --with-uuid=ossp
+ --with-zstd
+
+ # Debian Trixie container image used by all Linux jobs. Built by
+ # 'https://github.com/anarazel/pg-vm-images/'.
+ LINUX_CI_IMAGE: us-docker.pkg.dev/pg-ci-images/ci/linux_debian_trixie_ci:latest
+
+ # The full set of OS / job selectors recognized by the `ci-os-only:`
+ # commit-message directive parsed in the `setup` job below.
+ CI_OS_ONLY_JOBS: "linux macos windows mingw compilerwarnings sanitycheck"
+
+ _LOG_PATHS: &log_paths |
+ build*/testrun/**/*.log
+ build*/testrun/**/*.diffs
+ build*/testrun/**/regress_log_*
+ build*/meson-logs/*.txt
+
+
+jobs:
+ # Parse "ci-os-only: ..." from the commit message and expose flags
+ # consumed by the jobs' `if:` conditions.
+ setup:
+ name: Determine enabled jobs
+ runs-on: ubuntu-latest
+ timeout-minutes: 1
+ outputs:
+ linux: ${{ steps.os.outputs.linux }}
+ macos: ${{ steps.os.outputs.macos }}
+ windows: ${{ steps.os.outputs.windows }}
+ mingw: ${{ steps.os.outputs.mingw }}
+ compilerwarnings: ${{ steps.os.outputs.compilerwarnings }}
+ sanitycheck: ${{ steps.os.outputs.sanitycheck }}
+ # Re-export workflow-level env vars that other jobs need to reference
+ # from contexts (e.g. `jobs.<id>.container.image`) where the `env`
+ # context is not available.
+ linux_ci_image: ${{ env.LINUX_CI_IMAGE }}
+ steps:
+ - id: os
+ env:
+ MSG: ${{ github.event.head_commit.message }}
+ shell: bash
+ run: |
+ set -e
+ all_os="${CI_OS_ONLY_JOBS}"
+ if printf '%s\n' "$MSG" | grep -qE '^ci-os-only: '; then
+ sel=$(printf '%s\n' "$MSG" | grep -E '^ci-os-only: ' | head -1 | sed 's/^ci-os-only: //')
+ echo "ci-os-only selection: $sel"
+ else
+ sel="$all_os"
+ fi
+ for o in $all_os; do
+ if echo " $sel " | grep -qE "[ ,]$o[ ,]"; then
+ echo "$o=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "$o=false" >> "$GITHUB_OUTPUT"
+ fi
+ done
+ cat "$GITHUB_OUTPUT"
+
+
+ # To avoid unnecessarily spinning up a lot of VMs / containers for entirely
+ # broken commits, have a minimal task that all others depend on.
+ #
+ # SPECIAL:
+ # - Builds with --auto-features=disabled and thus almost no enabled
+ # dependencies
+ sanity-check:
+ name: SanityCheck
+ needs: setup
+ if: needs.setup.outputs.sanitycheck == 'true'
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ container:
+ image: ${{ needs.setup.outputs.linux_ci_image }}
+ # --privileged is needed so the prepare step can write to sysctls
+ # under /proc/sys (it's mounted read-only without it). We use it to
+ # set kernel.core_pattern.
+ options: --privileged
+ env:
+ BUILD_JOBS: 8
+ TEST_JOBS: 8
+ CCACHE_DIR: ${{ github.workspace }}/ccache_dir
+ # no options enabled, should be small
+ CCACHE_MAXSIZE: "150M"
+ steps:
+ # Anchor reused by other jobs further down. GitHub Actions supports
+ # YAML anchors/aliases but not merge keys, so the alias copies the
+ # whole step verbatim. The anchor is resolved at YAML parse time, so the
+ # alias keeps working even if this job is skipped at runtime.
+ - &checkout_step
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: ${{ env.CLONE_DEPTH }}
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-sanitycheck-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ccache-sanitycheck-${{ github.ref_name }}-
+ ccache-sanitycheck-
+
+ - name: Prepare workspace
+ run: |
+ whoami
+ useradd -m postgres
+ chown -R postgres:postgres .
+ mkdir -p "$CCACHE_DIR"
+ chown -R postgres:postgres "$CCACHE_DIR"
+
+ - name: Configure
+ run: |
+ su postgres <<-'EOF'
+ set -e
+ meson setup \
+ --buildtype=debug \
+ --auto-features=disabled \
+ -Ddefault_library=shared \
+ -Dtap_tests=enabled \
+ build
+ EOF
+
+ - name: Build
+ run: |
+ su postgres <<EOF
+ set -e
+ ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+ EOF
+
+ # Run a minimal set of tests. The main regression tests take too long
+ # for this purpose. For now this is a random quick pg_regress style
+ # test, and a tap test that exercises both a frontend binary and the
+ # backend.
+ - name: Test
+ run: |
+ su postgres <<EOF
+ set -e
+ ulimit -c unlimited
+ meson test ${MTEST_ARGS} --suite setup
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS} \
+ cube/regress pg_ctl/001_start_stop
+ EOF
+
+ - name: Core backtraces
+ if: failure()
+ run: |
+ mkdir -m 770 /tmp/cores
+ find / -maxdepth 1 -type f -name 'core*' -exec mv '{}' /tmp/cores/ \;
+ src/tools/ci/cores_backtrace.sh linux /tmp/cores
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: sanitycheck-logs-${{ github.run_id }}
+ path: *log_paths
+ if-no-files-found: ignore
+
+
+ # Build & test postgres on Linux in three configurations.
+ #
+ # Autoconf:
+ # - Uses address sanitizer (sanitizer failures are typically printed in
+ # the server log)
+ # - Configures postgres with a small segment size
+ # - Uses PG_TEST_PG_COMBINEBACKUP_MODE=--copy-file-range
+ #
+ # Meson:
+ # - Test both 64 and 32 bit builds
+ # - Uses undefined behaviour and alignment sanitizers, (sanitizer failures
+ # are typically printed in the server log)
+ # - Uses io_method=io_uring
+ # - Uses meson feature autodetection
+ # - 32 bit build tests with LANG=C to give ICU some buildfarm-uncovered
+ # coverage. Also, newer Python insists on changing LC_CTYPE away from C,
+ # prevent that with PYTHONCOERCECLOCALE.
+ #
+ # disable_coredump=0, abort_on_error=1: for useful backtraces in case of crashes
+ # print_stacktraces=1,verbosity=2, duh
+ # detect_leaks=0: too many uninteresting leak errors in short-lived binaries
+ linux:
+ name: Linux - ${{ matrix.name }}
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.linux == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: Autoconf
+ slug: autoconf
+ cc: ccache gcc
+ cxx: ccache g++
+ sanitizer_flags: -fsanitize=address
+ pg_test_pg_combinebackup_mode: '--copy-file-range'
+ configure: |
+ ./configure \
+ --enable-cassert --enable-injection-points --enable-debug \
+ --enable-tap-tests --enable-nls \
+ --with-segsize-blocks=6 \
+ --with-libnuma \
+ --with-liburing \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CLANG="ccache clang"
+ build: |
+ make -s -j${BUILD_JOBS} world-bin
+ test: |
+ make -s ${CHECK} ${CHECKFLAGS} -j${TEST_JOBS}
+ logs_paths: |
+ **/*.log
+ **/*.diffs
+ **/regress_log_*
+
+ - name: Meson (64bit)
+ slug: meson-64
+ cc: ccache gcc
+ cxx: ccache g++
+ sanitizer_flags: -fsanitize=alignment,undefined
+ pg_test_initdb_extra_opts: '-c io_method=io_uring'
+ configure: |
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ -Duuid=e2fs \
+ --buildtype=debug \
+ -Dllvm=enabled \
+ build
+ build: |
+ ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+ ninja -C build -t missingdeps
+ test: |
+ meson test ${MTEST_ARGS} -C build --num-processes ${TEST_JOBS}
+ logs_paths: *log_paths
+
+ - name: Meson (32bit)
+ slug: meson-32
+ cc: ccache gcc -m32
+ cxx: ccache g++ -m32
+ sanitizer_flags: -fsanitize=alignment,undefined
+ pg_test_initdb_extra_opts: '-c io_method=io_uring'
+ configure: |
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ -Duuid=e2fs \
+ --buildtype=debug \
+ --pkg-config-path /usr/lib/i386-linux-gnu/pkgconfig/ \
+ -DPERL=perl5.40-i386-linux-gnu \
+ -Dlibnuma=disabled \
+ build
+ build: |
+ ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+ ninja -C build -t missingdeps
+ test: |
+ PYTHONCOERCECLOCALE=0 LANG=C \
+ meson test ${MTEST_ARGS} -C build --num-processes ${TEST_JOBS}
+ logs_paths: *log_paths
+ container:
+ image: ${{ needs.setup.outputs.linux_ci_image }}
+ # Share the host PID + IPC namespaces. 017_shm.pl rapidly creates,
+ # kill9's, and restarts postgres; with the container's small PID
+ # space a new postgres can recycle the dead postmaster's PID before
+ # pg_ctl's postmaster.pid check notices, producing spurious "node X
+ # is already running" failures. SysV shm in the test also relies on
+ # host-like IPC behavior.
+ #
+ # --ulimit raises memlock and core dump size. Memlock is needed for
+ # running the AIO tests.
+ #
+ # --privileged is needed so the prepare step can write to sysctls
+ # under /proc/sys (it's mounted read-only without it). We use it to
+ # set kernel.core_pattern and (for the meson entries) to flip
+ # kernel.io_uring_disabled (default 2 on recent GH runner kernels).
+ options: --pid=host --ipc=host --ulimit memlock=-1:-1 --privileged
+ env:
+ BUILD_JOBS: 4
+ TEST_JOBS: 8
+ CCACHE_DIR: /tmp/ccache_dir
+ DEBUGINFOD_URLS: "https://debuginfod.debian.net"
+
+ UBSAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:verbosity=2
+ ASAN_OPTIONS: print_stacktrace=1:disable_coredump=0:abort_on_error=1:detect_leaks=0:detect_stack_use_after_return=0
+ CFLAGS: -Og -ggdb -fno-sanitize-recover=all ${{ matrix.sanitizer_flags }}
+ CXXFLAGS: -Og -ggdb -fno-sanitize-recover=all ${{ matrix.sanitizer_flags }}
+ LDFLAGS: ${{ matrix.sanitizer_flags }}
+ CC: ${{ matrix.cc }}
+ CXX: ${{ matrix.cxx }}
+
+ PG_TEST_INITDB_EXTRA_OPTS: ${{ matrix.pg_test_initdb_extra_opts }}
+ PG_TEST_PG_COMBINEBACKUP_MODE: ${{ matrix.pg_test_pg_combinebackup_mode }}
+ steps:
+ - *checkout_step
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-linux-${{ matrix.slug }}-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ccache-linux-${{ matrix.slug }}-${{ github.ref_name }}-
+ ccache-linux-${{ matrix.slug }}-
+
+ - name: Prepare workspace
+ run: |
+ useradd -m postgres
+ chown -R postgres:postgres .
+ mkdir -p "$CCACHE_DIR"
+ chown -R postgres:postgres "$CCACHE_DIR"
+ mkdir -m 770 /tmp/cores
+ chown root:postgres /tmp/cores
+ sysctl kernel.core_pattern='/tmp/cores/%e-%s-%p.core'
+ # This is only needed on Linux Meson but it doesn't harm to have
+ # this enabled.
+ sysctl -w kernel.io_uring_disabled=0
+
+ cat >> /etc/hosts <<-EOF
+ 127.0.0.1 pg-loadbalancetest
+ 127.0.0.2 pg-loadbalancetest
+ 127.0.0.3 pg-loadbalancetest
+ EOF
+
+ - name: Configure
+ run: |
+ su postgres <<EOF
+ set -e
+ ${{ matrix.configure }}
+ EOF
+
+ - name: Build
+ run: |
+ su postgres <<EOF
+ set -e
+ ${{ matrix.build }}
+ EOF
+
+ - name: Test world
+ run: |
+ su postgres <<EOF
+ set -e
+ ulimit -c unlimited
+ ${{ matrix.test }}
+ EOF
+
+ - name: Core backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh linux /tmp/cores
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: linux-${{ matrix.slug }}-logs-${{ github.run_id }}
+ path: ${{ matrix.logs_paths }}
+ if-no-files-found: ignore
+
+
+ # SPECIAL:
+ # - Enables --clone for pg_upgrade and pg_combinebackup
+ # - Specifies configuration options that test reading/writing/copying of node trees
+ # - Specifies debug_parallel_query=regress, to catch related issues during CI
+ macos:
+ name: macOS - Meson
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.macos == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: macos-15
+ timeout-minutes: 60
+ env:
+ BUILD_JOBS: 4
+ # Test performance regresses noticeably when using all cores. 8 works OK.
+ # https://postgr.es/m/20220927040208.l3shfcidovpzqxfh%40awork3.anarazel.de
+ # Fix: Needs to be re-tested for Github Actions.
+ TEST_JOBS: 8
+
+ CCACHE_DIR: ${{ github.workspace }}/ccache_dir
+ MACPORTS_CACHE: ${{ github.workspace }}/macports-cache
+
+ MESON_FEATURES: >-
+ -Dbonjour=enabled
+ -Ddtrace=enabled
+ -Dgssapi=enabled
+ -Dlibcurl=enabled
+ -Dnls=enabled
+ -Duuid=e2fs
+
+ MACOS_PACKAGE_LIST: >-
+ ccache
+ icu
+ kerberos5
+ lz4
+ meson
+ openldap
+ openssl
+ p5.34-io-tty
+ p5.34-ipc-run
+ python312
+ tcl
+ zstd
+
+ CC: ccache cc
+ CXX: ccache c++
+ CFLAGS: -Og -ggdb
+ CXXFLAGS: -Og -ggdb
+ PG_TEST_PG_UPGRADE_MODE: --clone
+ PG_TEST_PG_COMBINEBACKUP_MODE: --clone
+
+ # Several buildfarm animals enable these options. Without testing them
+ # during CI, it would be easy to cause breakage on the buildfarm with CI
+ # passing.
+ PG_TEST_INITDB_EXTRA_OPTS: >-
+ -c debug_copy_parse_plan_trees=on
+ -c debug_write_read_parse_plan_trees=on
+ -c debug_raw_expression_coverage_test=on
+ -c debug_parallel_query=regress
+
+ steps:
+ - *checkout_step
+
+ - name: Sysinfo
+ run: |
+ id
+ uname -a
+ ulimit -a -H && ulimit -a -S
+ env
+
+ - name: Setup core files
+ run: |
+ mkdir -p $HOME/cores
+ sudo sysctl kern.corefile="$HOME/cores/core.%P"
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-macos-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ccache-macos-${{ github.ref_name }}-
+ ccache-macos-
+
+ - name: Compute MacPorts cache key
+ id: mpkey
+ run: |
+ macos_major=$(sw_vers -productVersion | sed 's/\..*//')
+ pkglist_hash=$(printf '%s' "$MACOS_PACKAGE_LIST" | md5 -q)
+ script_hash=$(md5 -q src/tools/ci/ci_macports_packages.sh)
+ echo "key=macports-${macos_major}-${pkglist_hash}-${script_hash}-${GITHUB_RUN_ID}" >> "$GITHUB_OUTPUT"
+ echo "restore-key=macports-${macos_major}-${pkglist_hash}-${script_hash}-" >> "$GITHUB_OUTPUT"
+
+ - name: Restore MacPorts cache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.MACPORTS_CACHE }}
+ key: ${{ steps.mpkey.outputs.key }}
+ restore-keys: ${{ steps.mpkey.outputs.restore-key }}
+
+ # Use macports, even though homebrew is installed. The installation
+ # of the additional packages we need would take quite a while with
+ # homebrew, even if we cache the downloads. We can't cache all of
+ # homebrew, because it's already large. So we use macports. To cache
+ # the installation we create a .dmg file that we mount if it already
+ # exists.
+ # XXX: The reason for the direct p5.34* references is that we'd need
+ # the large macport tree around to figure out that p5-io-tty is
+ # actually p5.34-io-tty. Using the unversioned name works, but
+ # updates macports every time.
+ - name: Install dependencies (MacPorts)
+ env:
+ # Pass token so the script's GitHub API call to list MacPorts
+ # releases isn't subject to the 60/hr/IP unauthenticated rate
+ # limit (shared across all jobs on the runner's IP).
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ sh src/tools/ci/ci_macports_packages.sh $MACOS_PACKAGE_LIST
+ # system python doesn't provide headers
+ sudo /opt/local/bin/port select python3 python312
+ # Make macports install visible to subsequent steps
+ echo /opt/local/sbin >> "$GITHUB_PATH"
+ echo /opt/local/bin >> "$GITHUB_PATH"
+
+ - name: Configure
+ run: |
+ export PKG_CONFIG_PATH="/opt/local/lib/pkgconfig/"
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ --buildtype=debug \
+ -Dextra_include_dirs=/opt/local/include \
+ -Dextra_lib_dirs=/opt/local/lib \
+ -Ddarwin_sysroot=none \
+ ${MESON_COMMON_FEATURES} \
+ ${MESON_FEATURES} \
+ build
+
+ - name: Build
+ run: ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET}
+
+ - name: Test world
+ run: |
+ ulimit -c unlimited # default is 0
+ ulimit -n 1024 # default is 256, pretty low
+ meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+
+ - name: Core backtraces
+ if: failure()
+ run: src/tools/ci/cores_backtrace.sh macos "$HOME/cores"
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: macos-logs-${{ github.run_id }}
+ path: *log_paths
+ if-no-files-found: ignore
+
+
+ windows-vs:
+ name: Windows - VS - Meson & ninja
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.windows == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: windows-2022
+ timeout-minutes: 60
+ env:
+ TEST_JOBS: 8
+ # Avoid port conflicts between concurrent tap tests
+ PG_TEST_USE_UNIX_SOCKETS: 1
+ PG_REGRESS_SOCK_DIR: 'c:\pgsock'
+
+ MESON_FEATURES: >-
+ -Dcpp_args=/std:c++20
+ -Dauto_features=disabled
+ -Dtap_tests=enabled
+ -Dldap=enabled
+ -Dssl=openssl
+ -Dplperl=enabled
+ -Dplpython=enabled
+ TAR: "c:/windows/system32/tar.exe"
+
+ defaults:
+ run:
+ shell: cmd
+ steps:
+ - name: Disable Windows Defender
+ shell: powershell
+ run: |
+ Set-MpPreference -DisableRealtimeMonitoring $true -SubmitSamplesConsent NeverSend -MAPSReporting Disable
+ # Verify Defender status
+ $status = Get-MpComputerStatus -ErrorAction SilentlyContinue
+ if ($status) {
+ Write-Host "RealTimeProtectionEnabled: $($status.RealTimeProtectionEnabled)"
+ Write-Host "AntivirusEnabled: $($status.AntivirusEnabled)"
+ }
+
+ - *checkout_step
+
+ - name: Sysinfo
+ run: |
+ chcp
+ systeminfo
+ set
+
+ # The TAP tests build an initdb template under build/tmp_install and
+ # then `robocopy` it into per-test data directories. Robocopy with the
+ # default /COPY:DAT flag doesn't copy ACLs — destinations inherit from
+ # their parent dir. On GitHub-hosted Windows runners the workspace's
+ # inherited ACL grants Administrators:(F) and Users:(RX) but does NOT
+ # grant the runner user (runneradmin) directly. That matters because
+ # pg_ctl on Windows uses CreateRestrictedProcess to drop admin
+ # privileges from postmaster, so the postmaster process has the user
+ # SID in its token but no longer the Administrators group — leaving it
+ # with only "Users:(RX)" on pg_control and friends, which causes
+ # "PANIC: could not open file global/pg_control: Permission denied".
+ #
+ # Fix it once on the workspace dir with (OI)(CI) inheritance flags so
+ # every file/dir created underneath gets an explicit grant for the
+ # current user.
+ - name: Grant workspace ACL to runner user
+ shell: pwsh
+ run: |
+ icacls "${{ github.workspace }}" /grant "${env:USERNAME}:(OI)(CI)F" /Q | Out-Null
+ Write-Host "Granted Full Control to $env:USERNAME on ${{ github.workspace }}"
+
+ # postgres' plpython3u loads python3.dll (the stable-ABI forwarder)
+ # which in turn loads whichever python3NN.dll the Windows loader finds
+ # first on PATH. On windows-2022 `C:\Program Files\Mercurial\` ships
+ # its own python3.dll + python39.dll and appears on PATH *before* the
+ # hostedtoolcache Python 3.12 — so without intervention the backend
+ # ends up running Python 3.9 while postgres' stdlib search uses 3.12,
+ # producing `ImportError: cannot import name 'text_encoding' from
+ # 'io'` (the 3.12 `io.py` calling into 3.9's `_io`).
+ #
+ # Drop Mercurial's directory from PATH so the hostedtoolcache
+ # python3.dll wins the DLL search.
+ - name: Remove Mercurial from PATH
+ shell: pwsh
+ run: |
+ $filtered = ($env:PATH -split ';' |
+ Where-Object { $_ -and ($_ -notmatch '\\Mercurial\\?$') }) -join ';'
+ Add-Content $env:GITHUB_ENV "PATH=$filtered"
+ Write-Host "Removed Mercurial entries from PATH"
+
+ - name: Install dependencies
+ shell: pwsh
+ run: |
+ choco install -y --no-progress --limitoutput diffutils winflexbison3
+ # meson + ninja aren't preinstalled on windows-2022. Install via pip
+ python -m pip install --upgrade meson ninja
+
+ # OpenSSL 1.1 via the slproweb installer (pinned to match the
+ # version used elsewhere in postgres CI).
+ curl.exe -fsSL -o openssl-setup.exe https://slproweb.com/download/Win64OpenSSL-1_1_1w.exe
+ Start-Process -Wait -FilePath ./openssl-setup.exe `
+ -ArgumentList '/DIR=d:\openssl\1.1\ /VERYSILENT /SP- /SUPPRESSMSGBOXES'
+ # The slproweb installer puts libcrypto-1_1-x64.dll / libssl-1_1-x64.dll
+ # in d:\openssl\1.1\bin\ and updates the system PATH. GH Actions
+ # snapshots PATH at job start though, so the running job won't
+ # see those DLLs and initdb.exe would crash silently at runtime.
+ # Push the bin dir onto GITHUB_PATH so it persists for later steps.
+ Add-Content $env:GITHUB_PATH "d:\openssl\1.1\bin"
+
+ # Install IPC::Run.
+ # - recommends_policy=0 keeps cpan from pulling in IO::Tty / IO::Pty,
+ # which don't build on Windows ("This module requires a POSIX
+ # compliant system to work").
+ # - Pin to NJM/IPC-Run-20250809.0 because TODDR/IPC-Run-20260322.0
+ # broke postgres tap tests on Windows (changed pipe stdio
+ # handling). See upstream pg-vm-images commit ff5238afa3 and
+ # the thread at
+ # https://postgr.es/m/CAN55FZ06xanSbJdHe-CurjX_qNuBWZDEvS1kAk36L38YCtZXnw%40mail.gmail.com
+ "o conf recommends_policy 0`no conf commit`nnotest install NJM/IPC-Run-20250809.0.tar.gz" | cpan
+ perl -mIPC::Run -e 1
+
+ - name: Setup hosts file
+ shell: pwsh
+ run: |
+ Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.1 pg-loadbalancetest"
+ Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.2 pg-loadbalancetest"
+ Add-Content c:\Windows\System32\Drivers\etc\hosts "127.0.0.3 pg-loadbalancetest"
+
+ - name: Setup socket directory
+ shell: cmd
+ run: mkdir %PG_REGRESS_SOCK_DIR%
+
+ - name: Configure
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ meson setup --backend ninja %MESON_COMMON_PG_CONFIG_ARGS% %MESON_FEATURES% --buildtype debug -Db_pch=true -Dextra_lib_dirs=d:\openssl\1.1\lib -Dextra_include_dirs=d:\openssl\1.1\include -DTAR=%TAR% build
+
+ - name: Build
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ ninja -C build %MBUILD_TARGET%
+ ninja -C build -t missingdeps
+
+ - name: Test world
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+ meson test %MTEST_ARGS% --num-processes %TEST_JOBS%
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: windows-vs-logs-${{ github.run_id }}
+ path: |
+ ${{ env._LOG_PATHS }}
+ crashlog-*.txt
+ if-no-files-found: ignore
+
+
+ windows-mingw:
+ name: Windows - MinGW - Meson
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.mingw == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: windows-2022
+ timeout-minutes: 60
+ env:
+ TEST_JOBS: 4 # higher concurrency causes occasional failures
+ PG_TEST_USE_UNIX_SOCKETS: 1
+ PG_REGRESS_SOCK_DIR: 'c:\pgsock'
+ TAR: "c:/windows/system32/tar.exe"
+
+ MSYS: winjitdebug
+ CHERE_INVOKING: 1
+ MSYSTEM: UCRT64
+
+ # Keep -Dnls explicitly disabled, as the number of files it creates
+ # causes a noticeable slowdown.
+ MESON_FEATURES: >-
+ -Dnls=disabled
+
+ CCACHE_DIR: D:/a/ccache
+ CCACHE_MAXSIZE: "500M"
+ CCACHE_SLOPPINESS: pch_defines,time_macros
+ CCACHE_DEPEND: 1
+
+ defaults:
+ run:
+ shell: 'D:\msys64\usr\bin\bash.exe --login -eo pipefail "{0}"'
+
+ steps:
+ - name: Disable Windows Defender
+ shell: powershell
+ run: |
+ Set-MpPreference -DisableRealtimeMonitoring $true -SubmitSamplesConsent NeverSend -MAPSReporting Disable
+ # Verify Defender status
+ $status = Get-MpComputerStatus -ErrorAction SilentlyContinue
+ if ($status) {
+ Write-Host "RealTimeProtectionEnabled: $($status.RealTimeProtectionEnabled)"
+ Write-Host "AntivirusEnabled: $($status.AntivirusEnabled)"
+ }
+
+ - *checkout_step
+
+ # Relocate the preinstalled MSYS2 tree from C:\ (slow system disk) to
+ # D:\ (faster ephemeral data disk). Every subsequent MSYS2 step uses
+ # D:\msys64\usr\bin\bash.exe via the job's `defaults.run.shell`.
+ #
+ # This reduces the total runtime of this task by ~15 minutes.
+ #
+ # robocopy returns 0-7 on success (with various "files copied" bits
+ # set) and 8+ on real failure, so we have to translate its exit code.
+ - name: Relocate MSYS2 to D
+ shell: powershell
+ run: |
+ robocopy C:\msys64 D:\msys64 /E /MT:16 /NJS /NJH /NFL /NDL /NP
+ if ($LASTEXITCODE -ge 8) { exit $LASTEXITCODE }
+ exit 0
+
+ - name: Setup MSYS2
+ run: |
+ pacman -S --noconfirm --needed \
+ git bison flex make diffutils \
+ mingw-w64-ucrt-x86_64-ccache \
+ mingw-w64-ucrt-x86_64-gcc \
+ mingw-w64-ucrt-x86_64-icu \
+ mingw-w64-ucrt-x86_64-libbacktrace \
+ mingw-w64-ucrt-x86_64-libxml2 \
+ mingw-w64-ucrt-x86_64-libxslt \
+ mingw-w64-ucrt-x86_64-lz4 \
+ mingw-w64-ucrt-x86_64-make \
+ mingw-w64-ucrt-x86_64-meson \
+ mingw-w64-ucrt-x86_64-perl \
+ mingw-w64-ucrt-x86_64-pkg-config \
+ mingw-w64-ucrt-x86_64-readline \
+ mingw-w64-ucrt-x86_64-zlib
+
+ - name: Install additional dependencies
+ run: |
+ # Pin IPC::Run to NJM/IPC-Run-20250809.0; TODDR/IPC-Run-20260322.0
+ # broke postgres tap tests on Windows (pipe stdio handling).
+ # See pg-vm-images commit ff5238afa3.
+ (echo; echo o conf recommends_policy 0; echo notest install NJM/IPC-Run-20250809.0.tar.gz) | cpan
+ perl -mIPC::Run -e 1
+
+ - name: Setup socket directory
+ shell: cmd
+ run: mkdir %PG_REGRESS_SOCK_DIR%
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-mingw-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ccache-mingw-${{ github.ref_name }}-
+ ccache-mingw-
+
+ - name: Configure
+ run: |
+ meson setup \
+ ${MESON_COMMON_PG_CONFIG_ARGS} \
+ -Ddebug=true -Doptimization=g -Db_pch=true \
+ ${MESON_COMMON_FEATURES} \
+ ${MESON_FEATURES} \
+ -DTAR=${TAR} \
+ build
+
+ - name: Build
+ run: ninja -C build ${MBUILD_TARGET}
+
+ - name: Test world
+ run: meson test ${MTEST_ARGS} --num-processes ${TEST_JOBS}
+
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v7
+ with:
+ name: windows-mingw-logs-${{ github.run_id }}
+ path: |
+ ${{ env._LOG_PATHS }}
+ crashlog-*.txt
+ if-no-files-found: ignore
+
+ # Test that code can be built with both gcc and clang without warnings,
+ # with various combinations of cassert/dtrace flags. Trace probes have
+ # a history of getting accidentally broken; the matrix is there to
+ # catch that.
+ #
+ # The autoconf cache files (gcc.cache / clang.cache) are intentionally
+ # reused across the matrix entries that share a compiler, so we don't
+ # pay for full feature detection on every entry.
+ compiler-warnings:
+ name: CompilerWarnings
+ needs: [setup, sanity-check]
+ if: |
+ !cancelled() &&
+ needs.setup.outputs.compilerwarnings == 'true' &&
+ needs.sanity-check.result != 'failure'
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ container:
+ image: ${{ needs.setup.outputs.linux_ci_image }}
+ env:
+ BUILD_JOBS: 4
+ CCACHE_DIR: /tmp/ccache_dir
+ # Use larger ccache cache as this job compiles with multiple
+ # compilers / flag combinations.
+ CCACHE_MAXSIZE: "1G"
+ steps:
+ - *checkout_step
+
+ - name: Restore ccache
+ uses: actions/cache@v5
+ with:
+ path: ${{ env.CCACHE_DIR }}
+ key: ccache-compiler-warnings-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ccache-compiler-warnings-${{ github.ref_name }}-
+ ccache-compiler-warnings-
+
+ - name: Sysinfo
+ run: |
+ id
+ uname -a
+ cat /proc/cmdline
+ ulimit -a -H && ulimit -a -S
+ gcc -v
+ clang -v
+ env
+
+ - name: Setup workspace
+ run: |
+ echo "COPT=-Werror" > src/Makefile.custom
+ mkdir -p "$CCACHE_DIR"
+
+ # gcc, cassert off, dtrace on
+ - name: gcc warnings + (dtrace)
+ if: always()
+ run: |
+ ./configure \
+ --cache gcc.cache \
+ --enable-dtrace \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ # gcc, cassert on, dtrace off
+ - name: gcc warnings + (cassert)
+ if: always()
+ run: |
+ ./configure \
+ --cache gcc.cache \
+ --enable-cassert \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ # clang, cassert off, dtrace off
+ - name: clang warnings
+ if: always()
+ run: |
+ ./configure \
+ --cache clang.cache \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache clang" CXX="ccache clang++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ # clang, cassert on, dtrace on
+ - name: clang warnings + (cassert + dtrace)
+ if: always()
+ run: |
+ ./configure \
+ --cache clang.cache \
+ --enable-cassert \
+ --enable-dtrace \
+ ${LINUX_CONFIGURE_FEATURES} \
+ CC="ccache clang" CXX="ccache clang++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ - name: mingw warnings (cross compilation)
+ if: always()
+ run: |
+ ./configure \
+ --host=x86_64-w64-mingw32ucrt \
+ --enable-cassert \
+ --without-icu \
+ CC="ccache x86_64-w64-mingw32ucrt-gcc" \
+ CXX="ccache x86_64-w64-mingw32ucrt-g++"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} world-bin
+
+ ###
+ # Verify docs can be built
+ ###
+ # XXX: Only do this if there have been changes in doc/ since last build
+ - name: Build documentation
+ if: always()
+ run: |
+ ./configure \
+ --cache gcc.cache \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} -C doc
+
+ ###
+ # Verify headerscheck / cpluspluscheck succeed
+ #
+ # - Run both in same script to increase parallelism, use -k to get
+ # result of both
+ # - Use -fmax-errors, as particularly cpluspluscheck can be very verbose
+ ###
+ - name: headerscheck + cpluspluscheck
+ if: always()
+ run: |
+ ./configure \
+ ${LINUX_CONFIGURE_FEATURES} \
+ --cache gcc.cache \
+ --quiet \
+ CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+ make -s -j${BUILD_JOBS} clean
+ make -s -j${BUILD_JOBS} -k ${CHECKFLAGS} headerscheck cpluspluscheck EXTRAFLAGS='-fmax-errors=10'
diff --git a/src/tools/ci/ci_macports_packages.sh b/src/tools/ci/ci_macports_packages.sh
index 63e97b37c78..4c79f90fed0 100755
--- a/src/tools/ci/ci_macports_packages.sh
+++ b/src/tools/ci/ci_macports_packages.sh
@@ -20,13 +20,26 @@ echo "macOS major version: $macos_major_version"
# macOS release.
macports_release_list_url="https://api.github.com/repos/macports/macports-base/releases"
macports_version_pattern="2\.10\.1"
-macports_url="$( curl -s $macports_release_list_url | grep "\"https://github.com/macports/macports-base/releases/download/v$macports_version_pattern/MacPorts-$macports_version_pattern-$macos_major_version-[A-Za-z]*\.pkg\"" | sed 's/.*: "//;s/".*//' | head -1 )"
+# Authenticate the GitHub API request when a token is available (e.g. on
+# GitHub Actions). Unauthenticated requests share a 60/hr/IP rate limit
+# with every other job on the runner's IP and frequently return an error
+# JSON, leaving $macports_url empty and breaking the subsequent curl.
+auth_header=""
+if [ -n "$GITHUB_TOKEN" ]; then
+ auth_header="Authorization: Bearer $GITHUB_TOKEN"
+fi
+macports_url="$( curl -fsSL ${auth_header:+-H "$auth_header"} "$macports_release_list_url" | grep "\"https://github.com/macports/macports-base/releases/download/v$macports_version_pattern/MacPorts-$macports_version_pattern-$macos_major_version-[A-Za-z]*\.pkg\"" | sed 's/.*: "//;s/".*//' | head -1 )"
echo "MacPorts package URL: $macports_url"
+if [ -z "$macports_url" ]; then
+ echo "error: could not determine MacPorts package URL for macOS $macos_major_version (version pattern: $macports_version_pattern)" 1>&2
+ exit 1
+fi
+
cache_dmg="macports.hfs.dmg"
-if [ "$CIRRUS_CI" != "true" ]; then
- echo "expect to be called within cirrus-ci" 1>2
+if [ "$CIRRUS_CI" != "true" ] && [ "$GITHUB_ACTIONS" != "true" ]; then
+ echo "expect to be called within cirrus-ci or github actions" 1>2
exit 1
fi
--
2.47.3
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-29 11:38 Jakub Wartak <[email protected]>
parent: Nazir Bilal Yavuz <[email protected]>
0 siblings, 1 reply; 42+ messages in thread
From: Jakub Wartak @ 2026-05-29 11:38 UTC (permalink / raw)
To: Nazir Bilal Yavuz <[email protected]>; +Cc: Jacob Champion <[email protected]>; Andres Freund <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers; Zsolt Parragi <[email protected]>; Peter Eisentraut <[email protected]>
On Fri, May 29, 2026 at 11:51 AM Nazir Bilal Yavuz <[email protected]> wrote:
[..]
Hi, thanks to everybody for working on this.
> https://github.com/nbyavuz/postgres/actions/runs/26628396798
Windows (runs-on: windows-2022) seems kind of slow isn't it ?
Maybe that's not related to the patch itself, but any idea why the windows
tests are so slow? Or will we able to somehow accelerate those?
Windows - VS - Meson & ninja / succeeded [..] minutes ago in 31m 28s
Processor(s): 1 Processor(s) Installed.
[..]
Total Physical Memory: 16,379 MB
[..]
but:
NUMBER_OF_PROCESSORS=4
[..]
+ TEST_JOBS: 8
vs
392/396 test_json_parser - postgresql:test_json_parser/002_inline
OK 152.56s 3712 subtests passed
393/396 pgbench - postgresql:pgbench/001_pgbench_with_server
OK 574.61s 474 subtests passed
394/396 pg_rewind - postgresql:pg_rewind/002_databases
OK 772.86s 10 subtests passed
395/396 pg_waldump - postgresql:pg_waldump/001_basic
OK 771.19s 156 subtests passed
396/396 libpq_pipeline - postgresql:libpq_pipeline/001_libpq_pipeline
OK 395.76s 23 subtests passed
while last CirrusCI run for me for Windows took 19min 21s (4 CPUs / 4 GBs,
but sysinfo reported there "Total Physical Memory: 16,380 MB").
If that's IO traffic as Andres described, maybe we could enable feature
called "Turn off Windows write-cache buffer flushing on the device"
in device manager -> disk -> policies, but dunno how much that would
help really as we seem to be already using fsync=off, maybe it helps
when saving other files too (???)
-J.
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-29 13:22 Jakub Wartak <[email protected]>
parent: Andres Freund <[email protected]>
0 siblings, 0 replies; 42+ messages in thread
From: Jakub Wartak @ 2026-05-29 13:22 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Álvaro Herrera <[email protected]>; Nazir Bilal Yavuz <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers; Zsolt Parragi <[email protected]>; Peter Eisentraut <[email protected]>
On Thu, May 28, 2026 at 9:42 PM Andres Freund <[email protected]> wrote:
[..]
> It's definitely slower. I've not fully analyzed why, my suspicion is that we
> end up being rather terribly IO bound - we used bigger and faster disks on
> cirrus than we have access to with github hosted runners (there are large
> runners with more storage, but that's not free).
>
> A full testrun on master creates about 36GB of data directories. If individual
> tests are fast, that's often not *that* bad, because the tests are over before
> linux decides to flush out the data, and then linux never needs to write that
> data back, because we remove the data directories immediately. But once you
> get to the point that several tests take more than 30s (the default time after
> which linux writes dirty data back) or enough dirty data accumulates (20% of
> memory IIRC), you have a lot of IO.
>
> My buildfarm host, which hosts quite a few animals, got a new disk within the
> last year. Here's what smartctl says about disk IO:
>
> Data Units Read: 43,513,034 [22.2 TB]
> Data Units Written: 6,062,401,949 [3.10 PB]
>
> A nice indication of how much our tests end up writing...
`nijna -C build test` (of course without compilation) that was run in
dedicated cgroup gave me this /sys/fs/cgroup/my_test_suite/io.stat
figure:
rbytes=88616960 wbytes=18406756352 rios=13843 wios=275457 dbytes=0 dios=0
~84.5 MB read
~17.1 GB written (sic!!!)
13k read ops
275k write ops
So yeah, I've really even didn't think we could generate that much IO there.
btw it's seems to be coming from block controller, so it's number of
flushed to disk (so the logically written data but removed without flush?
would be way higher; so by what Your' saying we should tweak that 30s
writeback right?) Anyway I've tried with way more relaxed dirty/writeback and
got this stil onthe same laptop with 32GB RAM:
rbytes=20934656 wbytes=5957296128 rios=3040 wios=81992 dbytes=0 dios=
~20MB read
~5.55 GB written (down from 17GB)
3k read ops
82k write ops
And that was without even trying hard:
sudo sysctl -w vm.dirty_ratio=50 # ~16GB
sudo sysctl -w vm.dirty_background_ratio=40
sudo sysctl -w vm.dirty_expire_centisecs=60000 #default was 3000 as You said
sudo sysctl -w vm.dirty_writeback_centisecs=50000
Steps were:
sudo mkdir /sys/fs/cgroup/my_test_suite
echo $$ | sudo tee /sys/fs/cgroup/my_test_suite/cgroup.procs
ninja -C build test
cat /sys/fs/cgroup/my_test_suite/io.stat
-J.
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-29 15:47 Peter Eisentraut <[email protected]>
parent: Nazir Bilal Yavuz <[email protected]>
2 siblings, 0 replies; 42+ messages in thread
From: Peter Eisentraut @ 2026-05-29 15:47 UTC (permalink / raw)
To: Nazir Bilal Yavuz <[email protected]>; Andres Freund <[email protected]>; +Cc: Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers; Zsolt Parragi <[email protected]>
On 28.05.26 19:06, Nazir Bilal Yavuz wrote:
> I found we can use matrices and merged all linux tasks. I am not sure
> that is better since it is a bit harder to read now.
Yeah, I think the way it looks now (with the matrix) is quite confusing.
^ permalink raw reply [nested|flat] 42+ messages in thread
* Re: Heads Up: cirrus-ci is shutting down June 1st
@ 2026-05-29 15:56 Andres Freund <[email protected]>
parent: Jakub Wartak <[email protected]>
0 siblings, 0 replies; 42+ messages in thread
From: Andres Freund @ 2026-05-29 15:56 UTC (permalink / raw)
To: Jakub Wartak <[email protected]>; +Cc: Nazir Bilal Yavuz <[email protected]>; Jacob Champion <[email protected]>; Jelte Fennema-Nio <[email protected]>; Thomas Munro <[email protected]>; pgsql-hackers; Zsolt Parragi <[email protected]>; Peter Eisentraut <[email protected]>
Hi,
On 2026-05-29 13:38:17 +0200, Jakub Wartak wrote:
> On Fri, May 29, 2026 at 11:51 AM Nazir Bilal Yavuz <[email protected]> wrote:
> [..]
> Hi, thanks to everybody for working on this.
>
> > https://github.com/nbyavuz/postgres/actions/runs/26628396798
>
> Windows (runs-on: windows-2022) seems kind of slow isn't it ?
>
> Maybe that's not related to the patch itself, but any idea why the windows
> tests are so slow? Or will we able to somehow accelerate those?
>
> Windows - VS - Meson & ninja / succeeded [..] minutes ago in 31m 28s
>
> Processor(s): 1 Processor(s) Installed.
> [..]
> Total Physical Memory: 16,379 MB
> [..]
>
> but:
> NUMBER_OF_PROCESSORS=4
> [..]
> + TEST_JOBS: 8
>
> vs
>
> 392/396 test_json_parser - postgresql:test_json_parser/002_inline
> OK 152.56s 3712 subtests passed
> 393/396 pgbench - postgresql:pgbench/001_pgbench_with_server
> OK 574.61s 474 subtests passed
> 394/396 pg_rewind - postgresql:pg_rewind/002_databases
> OK 772.86s 10 subtests passed
> 395/396 pg_waldump - postgresql:pg_waldump/001_basic
> OK 771.19s 156 subtests passed
> 396/396 libpq_pipeline - postgresql:libpq_pipeline/001_libpq_pipeline
> OK 395.76s 23 subtests passed
>
> while last CirrusCI run for me for Windows took 19min 21s (4 CPUs / 4 GBs,
> but sysinfo reported there "Total Physical Memory: 16,380 MB").
The difference here likely is due to the different type of CPU cores. On
cirrus, we got 4 non-SMT cores (because the type of CPU used didn't use SMT),
whereas on GHA we have 4 hardware threads, but only two real cores.
> If that's IO traffic as Andres described, maybe we could enable feature
> called "Turn off Windows write-cache buffer flushing on the device"
> in device manager -> disk -> policies, but dunno how much that would
> help really as we seem to be already using fsync=off, maybe it helps
> when saving other files too (???)
I think I was wrong about IO being the main issue. I've measured the CPU
utilization during a linux run, and basically it's 100% busy during the whole
test run (baring the first and last few seconds). Which does seem to mainly
point to the difference being simply that we just have half the real cores as
we had before.
I do see higher %sys CPU utilization than I'd expect, so that may be worth
investigating.
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 42+ messages in thread
end of thread, other threads:[~2026-05-29 15:56 UTC | newest]
Thread overview: 42+ messages (download: mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-04-09 20:55 Heads Up: cirrus-ci is shutting down June 1st Andres Freund <[email protected]>
2026-04-09 23:29 ` Thomas Munro <[email protected]>
2026-04-13 11:53 ` David Steele <[email protected]>
2026-04-14 00:57 ` Thomas Munro <[email protected]>
2026-04-10 11:31 ` Jelte Fennema-Nio <[email protected]>
2026-04-10 11:51 ` Nazir Bilal Yavuz <[email protected]>
2026-04-10 13:27 ` Bruce Momjian <[email protected]>
2026-04-10 12:23 ` Alexander Korotkov <[email protected]>
2026-04-10 12:24 ` Alexander Korotkov <[email protected]>
2026-04-10 13:05 ` Peter Eisentraut <[email protected]>
2026-04-13 08:34 ` Heikki Linnakangas <[email protected]>
2026-04-13 14:34 ` David E. Wheeler <[email protected]>
2026-04-17 18:50 ` Robert Haas <[email protected]>
2026-04-17 21:41 ` Michael Paquier <[email protected]>
2026-04-17 21:48 ` Tom Lane <[email protected]>
2026-04-18 02:19 ` Euler Taveira <[email protected]>
2026-05-18 21:22 ` Jelte Fennema-Nio <[email protected]>
2026-05-18 22:27 ` Nazir Bilal Yavuz <[email protected]>
2026-05-25 12:14 ` Nazir Bilal Yavuz <[email protected]>
2026-05-27 18:10 ` Andres Freund <[email protected]>
2026-05-27 20:33 ` Jelte Fennema-Nio <[email protected]>
2026-05-27 22:15 ` Jacob Champion <[email protected]>
2026-05-28 15:07 ` Andres Freund <[email protected]>
2026-05-28 15:51 ` Jacob Champion <[email protected]>
2026-05-28 16:13 ` Andres Freund <[email protected]>
2026-05-28 17:04 ` Jacob Champion <[email protected]>
2026-05-28 17:06 ` Nazir Bilal Yavuz <[email protected]>
2026-05-28 18:11 ` Álvaro Herrera <[email protected]>
2026-05-28 18:42 ` Álvaro Herrera <[email protected]>
2026-05-28 19:42 ` Andres Freund <[email protected]>
2026-05-29 13:22 ` Jakub Wartak <[email protected]>
2026-05-28 20:50 ` Jacob Champion <[email protected]>
2026-05-29 09:51 ` Nazir Bilal Yavuz <[email protected]>
2026-05-29 11:38 ` Jakub Wartak <[email protected]>
2026-05-29 15:56 ` Andres Freund <[email protected]>
2026-05-29 15:47 ` Peter Eisentraut <[email protected]>
2026-05-27 23:10 ` Zsolt Parragi <[email protected]>
2026-05-28 17:07 ` Nazir Bilal Yavuz <[email protected]>
2026-05-28 11:49 ` Peter Eisentraut <[email protected]>
2026-05-28 17:08 ` Nazir Bilal Yavuz <[email protected]>
2026-05-28 16:19 ` Andres Freund <[email protected]>
2026-05-27 03:54 ` Thomas Munro <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox