Skip to content

Commit 8aabdd4

Browse files
eduralphclaude
andcommitted
CI image: hybrid PyPI / git-clone install for unreleased maintenance branches
Mirrors the same-named commit on ci/branch-neutral (951166afe). The bootstrap commit on this branch hit "No matching distribution found for gramps==6.1.*" because no 6.1 release exists on PyPI yet; this commit adds the SHA-pinned git-clone fallback to the Dockerfile and the matching SHA capture in docker-build.yml so the gramps61 image can actually build. See the parent commit (951166afe on ci/branch-neutral) for the design write-up, local verification log (gramps60 PyPI path + gramps61 fallback path + bash unit tests of the failure-mode triage), and the ::notice:: / ::warning:: log convention. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9453d99 commit 8aabdd4

2 files changed

Lines changed: 70 additions & 13 deletions

File tree

.github/docker/gramps-ci/Dockerfile

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,27 @@
1616
# `--init` (or use a container runtime that injects tini) because xvfb-run
1717
# hangs if it inherits PID 1.
1818
#
19-
# Local build:
19+
# Gramps install path. PyPI is tried first; when no gramps==${SERIES}.*
20+
# release exists (e.g. while 6.1 is still in development) the build
21+
# falls back to a SHA-pinned git clone of
22+
# gramps-project/gramps@maintenance/gramps${SERIES_NODOT}. Other pip
23+
# failures (network, etc.) are NOT silently retried so a transient
24+
# PyPI outage cannot flip a normally-released branch to "test against
25+
# moving tip" mode. docker-build.yml captures the upstream SHA via
26+
# git ls-remote and passes it in as GRAMPS_FALLBACK_SHA; the SHA
27+
# becomes part of the buildx cache key so a moved upstream tip
28+
# actually re-runs the install layer.
29+
#
30+
# Local build (released series):
2031
# docker build --build-arg GRAMPS_SERIES=6.0 .github/docker/gramps-ci
2132
#
33+
# Local build (unreleased series, e.g. 6.1):
34+
# sha=$(git ls-remote https://github.com/gramps-project/gramps.git \
35+
# refs/heads/maintenance/gramps61 | awk '{print $1}')
36+
# docker build --build-arg GRAMPS_SERIES=6.1 \
37+
# --build-arg GRAMPS_FALLBACK_SHA=$sha \
38+
# .github/docker/gramps-ci
39+
#
2240
ARG PYTHON_VERSION=3.12
2341
FROM python:${PYTHON_VERSION}-slim
2442

@@ -27,6 +45,11 @@ FROM python:${PYTHON_VERSION}-slim
2745
# for the wrong Gramps series. docker-build.yml derives this from the
2846
# branch ref.
2947
ARG GRAMPS_SERIES
48+
# Commit SHA on gramps-project/gramps@maintenance/grampsNN. Only used
49+
# when no gramps==${GRAMPS_SERIES}.* release exists on PyPI. Ignored
50+
# otherwise. Empty default is intentional — on released branches the
51+
# fallback never fires.
52+
ARG GRAMPS_FALLBACK_SHA=""
3053
RUN [ -n "$GRAMPS_SERIES" ] || { echo "GRAMPS_SERIES is required (e.g. 6.0)"; exit 1; }
3154

3255
LABEL org.opencontainers.image.source="https://github.com/gramps-project/addons-source"
@@ -50,13 +73,34 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
5073
xauth \
5174
&& rm -rf /var/lib/apt/lists/*
5275

53-
RUN pip install --no-cache-dir \
54-
PyGObject \
55-
pycairo \
56-
"gramps==${GRAMPS_SERIES}.*" \
57-
orjson \
58-
ruff \
59-
dbf
76+
RUN pip install --no-cache-dir PyGObject pycairo orjson ruff dbf
77+
78+
# Install gramps: PyPI first, SHA-pinned git clone as fallback.
79+
RUN /bin/bash -eo pipefail <<'BASH'
80+
suffix_nodot="${GRAMPS_SERIES//./}"
81+
if pip install --no-cache-dir "gramps==${GRAMPS_SERIES}.*" 2>/tmp/pip.err; then
82+
echo "::notice::installed gramps==${GRAMPS_SERIES}.* from PyPI"
83+
elif grep -q "No matching distribution found for gramps==" /tmp/pip.err; then
84+
if [ -z "${GRAMPS_FALLBACK_SHA}" ]; then
85+
echo "::error::no gramps==${GRAMPS_SERIES}.* on PyPI and GRAMPS_FALLBACK_SHA is unset"
86+
exit 1
87+
fi
88+
echo "::warning::no gramps==${GRAMPS_SERIES}.* on PyPI; installing from gramps-project/gramps@maintenance/gramps${suffix_nodot} at ${GRAMPS_FALLBACK_SHA}"
89+
mkdir -p /tmp/gramps
90+
cd /tmp/gramps
91+
git init -q
92+
git remote add origin https://github.com/gramps-project/gramps.git
93+
git fetch --depth 1 origin "${GRAMPS_FALLBACK_SHA}"
94+
git checkout FETCH_HEAD
95+
pip install --no-cache-dir .
96+
cd /
97+
rm -rf /tmp/gramps
98+
else
99+
echo "::error::pip install gramps failed (non-version reason); aborting rather than silently switching to git tip"
100+
cat /tmp/pip.err
101+
exit 1
102+
fi
103+
BASH
60104

61105
RUN apt-get purge -y gcc python3-dev pkg-config && apt-get autoremove -y
62106

.github/workflows/docker-build.yml

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,16 @@ jobs:
3535
uses: docker/setup-buildx-action@v3
3636

3737
- name: Compute branch parameters
38-
# Derive the image-tag suffix and Gramps minor series from the
39-
# branch ref. Same validation as ci.yml's setup job: anything
40-
# outside maintenance/grampsNN fails fast.
38+
# Derive the image-tag suffix, Gramps minor series, and upstream
39+
# fallback SHA from the branch ref. Same validation as ci.yml's
40+
# setup job: anything outside maintenance/grampsNN fails fast.
41+
# The fallback SHA is the current tip of gramps-project/gramps
42+
# at the matching maintenance branch; the Dockerfile only uses
43+
# it when no gramps==${series}.* release exists on PyPI. The
44+
# SHA is part of the buildx cache key so a moved upstream tip
45+
# actually re-runs the install layer (otherwise gramps61 CI
46+
# would stay on the same stale gramps revision build after
47+
# build).
4148
id: params
4249
shell: bash
4350
run: |
@@ -49,8 +56,13 @@ jobs:
4956
esac
5057
# gramps60 → 6.0, gramps61 → 6.1, gramps62 → 6.2, …
5158
series="${suffix:6:1}.${suffix:7}"
52-
echo "suffix=$suffix" >> "$GITHUB_OUTPUT"
53-
echo "series=$series" >> "$GITHUB_OUTPUT"
59+
fallback_sha=$(git ls-remote https://github.com/gramps-project/gramps.git "refs/heads/maintenance/${suffix}" | awk '{print $1}')
60+
if [ -z "$fallback_sha" ]; then
61+
echo "::warning::upstream gramps-project/gramps has no maintenance/${suffix} branch; fallback path will fail if PyPI lacks gramps==${series}.*"
62+
fi
63+
echo "suffix=$suffix" >> "$GITHUB_OUTPUT"
64+
echo "series=$series" >> "$GITHUB_OUTPUT"
65+
echo "fallback_sha=$fallback_sha" >> "$GITHUB_OUTPUT"
5466
5567
- name: Docker metadata
5668
id: meta
@@ -70,5 +82,6 @@ jobs:
7082
labels: ${{ steps.meta.outputs.labels }}
7183
build-args: |
7284
GRAMPS_SERIES=${{ steps.params.outputs.series }}
85+
GRAMPS_FALLBACK_SHA=${{ steps.params.outputs.fallback_sha }}
7386
cache-from: type=gha
7487
cache-to: type=gha,mode=max

0 commit comments

Comments
 (0)