Skip to content

Commit 32d9ae5

Browse files
committed
fix: sort packages and filter out cached ones
1 parent 726c9f3 commit 32d9ae5

File tree

3 files changed

+49
-15
lines changed

3 files changed

+49
-15
lines changed

.github/workflows/nix-build.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ jobs:
3030
run: |
3131
set -Eeu
3232
echo matrix="$(python scripts/github-matrix.py extensions)" >> "$GITHUB_OUTPUT"
33-
# XXX debugging
34-
exit 1
3533
3634
build-extensions-aarch64-linux:
3735
name: ${{matrix.postgresql_version}}.${{ matrix.name }} (aarch64-linux)

nix/packages/postgres.nix

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,12 @@
158158
# install.
159159
# - exts: an attrset containing all the extensions, mapped to their
160160
# package names.
161-
makePostgres = version: lib.recurseIntoAttrs {
162-
bin = makePostgresBin version;
163-
exts = makeOurPostgresPkgsSet version;
164-
};
161+
makePostgres =
162+
version:
163+
lib.recurseIntoAttrs {
164+
bin = makePostgresBin version;
165+
exts = makeOurPostgresPkgsSet version;
166+
};
165167
basePackages = {
166168
psql_15 = makePostgres "15";
167169
psql_17 = makePostgres "17";

scripts/github-matrix.py

100644100755
Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env python3
22

33
import argparse
4+
from collections import defaultdict
5+
import graphlib
46
import json
57
import os
68
import subprocess
@@ -48,6 +50,9 @@ class GitHubActionPackage(TypedDict):
4850
system: str
4951
already_cached: bool
5052
runs_on: RunsOnConfig
53+
drvPath: str
54+
neededSubstitutes: List[str]
55+
neededBuilds: List[str]
5156
postgresql_version: NotRequired[str]
5257

5358

@@ -114,6 +119,9 @@ def parse_nix_eval_line(
114119
"system": data["system"],
115120
"already_cached": data.get("cacheStatus") != "notBuilt",
116121
"runs_on": runs_on_config,
122+
"drvPath": data["drvPath"],
123+
"neededSubstitutes": data.get("neededSubstitutes", []),
124+
"neededBuilds": data.get("neededBuilds", []),
117125
}
118126
except json.JSONDecodeError:
119127
print(f"Skipping invalid JSON line: {line}", file=sys.stderr)
@@ -133,8 +141,7 @@ def run_nix_eval_jobs(
133141

134142
for line in process.stdout:
135143
package = parse_nix_eval_line(line, drv_paths, target)
136-
if package and not package["already_cached"]:
137-
print(f"Found package: {package['attr']}", file=sys.stderr)
144+
if package:
138145
yield package
139146

140147
if process.returncode and process.returncode != 0:
@@ -149,6 +156,34 @@ def is_extension_pkg(pkg: GitHubActionPackage) -> bool:
149156
return attrs[-2] == "exts"
150157

151158

159+
# thank you buildbot-nix https://github.com/nix-community/buildbot-nix/blob/985d069a2a45cf4a571a4346107671adc2bd2a16/buildbot_nix/buildbot_nix/build_trigger.py#L297
160+
def sort_pkgs_by_closures(jobs: list[GitHubActionPackage]) -> list[GitHubActionPackage]:
161+
sorted_jobs = []
162+
163+
# Prepare job dependencies
164+
job_set = {job["drvPath"] for job in jobs}
165+
job_closures = {
166+
k["drvPath"]: set(k["neededSubstitutes"])
167+
.union(set(k["neededBuilds"]))
168+
.intersection(job_set)
169+
.difference({k["drvPath"]})
170+
for k in jobs
171+
}
172+
173+
sorter = graphlib.TopologicalSorter(job_closures)
174+
175+
for item in sorter.static_order():
176+
i = 0
177+
while i < len(jobs):
178+
if item == jobs[i]["drvPath"]:
179+
sorted_jobs.append(jobs[i])
180+
del jobs[i]
181+
else:
182+
i += 1
183+
184+
return sorted_jobs
185+
186+
152187
def main() -> None:
153188
parser = argparse.ArgumentParser(
154189
description="Generate GitHub Actions matrix for Nix builds"
@@ -168,23 +203,22 @@ def main() -> None:
168203

169204
cmd = build_nix_eval_command(max_workers, flake_output)
170205

171-
gh_action_packages = list(run_nix_eval_jobs(cmd, flake_output))
206+
gh_action_packages = sort_pkgs_by_closures(
207+
list(run_nix_eval_jobs(cmd, flake_output))
208+
)
172209

173210
if args.target == "extensions":
174211
# filter to only include extension packages and add postgresql_version field
175212
gh_action_packages = [
176213
{**pkg, "postgresql_version": pkg["attr"].split(".")[-3]}
177214
for pkg in gh_action_packages
178-
if is_extension_pkg(pkg)
215+
if is_extension_pkg(pkg) and not pkg["already_cached"]
179216
]
180217

181218
# Group packages by system
182-
grouped_by_system = {}
219+
grouped_by_system = defaultdict(list)
183220
for pkg in gh_action_packages:
184-
system = pkg["system"]
185-
if system not in grouped_by_system:
186-
grouped_by_system[system] = []
187-
grouped_by_system[system].append(pkg)
221+
grouped_by_system[pkg["system"]].append(pkg)
188222

189223
# Create output with system-specific matrices
190224
gh_output = {}

0 commit comments

Comments
 (0)