Skip to content

Commit b29463a

Browse files
authored
Merge pull request #2 from eduralph/feature/ci-cd-pipeline
Consolidate CI images and fix Windows + integration tests
2 parents 9c2ac1d + 73bf4c2 commit b29463a

7 files changed

Lines changed: 121 additions & 170 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# .github/docker/gramps-ci/Dockerfile
2+
#
3+
# Unified Gramps 6.0 CI image. Includes everything jobs need:
4+
# - Python + pip-installed Gramps, PyGObject, pycairo
5+
# - GTK typelibs (so addon modules that `from gi.repository import Gtk`
6+
# at module load time are importable — widgets still need xvfb to render)
7+
# - intltool/gettext/git for make.py builds
8+
# - ruff, pytest, dbf for lint/test tooling
9+
# - xvfb + xauth for tests that actually render (wrap with `xvfb-run`)
10+
#
11+
# No display server runs by default — the image is headless unless a command
12+
# explicitly invokes `xvfb-run`. When running with docker locally, pass
13+
# `--init` (or use a container runtime that injects tini) because xvfb-run
14+
# hangs if it inherits PID 1.
15+
#
16+
ARG PYTHON_VERSION=3.12
17+
FROM python:${PYTHON_VERSION}-slim
18+
19+
LABEL org.opencontainers.image.source="https://github.com/gramps-project/addons-source"
20+
LABEL org.opencontainers.image.description="Unified Gramps 6.0 CI image (Python, Gramps, GTK typelibs, xvfb)"
21+
22+
RUN apt-get update && apt-get install -y --no-install-recommends \
23+
libgirepository-2.0-dev \
24+
gir1.2-glib-2.0 \
25+
gir1.2-gtk-3.0 \
26+
gir1.2-pango-1.0 \
27+
gir1.2-gdkpixbuf-2.0 \
28+
gir1.2-atk-1.0 \
29+
gcc \
30+
pkg-config \
31+
python3-dev \
32+
libcairo2-dev \
33+
intltool \
34+
gettext \
35+
git \
36+
xvfb \
37+
xauth \
38+
&& rm -rf /var/lib/apt/lists/*
39+
40+
RUN pip install --no-cache-dir \
41+
PyGObject \
42+
pycairo \
43+
"gramps>=6.0,<6.1" \
44+
orjson \
45+
pytest \
46+
ruff \
47+
dbf
48+
49+
RUN apt-get purge -y gcc python3-dev pkg-config && apt-get autoremove -y
50+
51+
RUN python -c "from gramps.gen.const import VERSION; print('Gramps', VERSION)" \
52+
&& python -c "import gi; gi.require_version('Gtk', '3.0'); from gi.repository import Gtk; print('GTK OK')"
53+
54+
WORKDIR /workspace

.github/docker/gramps-gtk/Dockerfile

Lines changed: 0 additions & 28 deletions
This file was deleted.

.github/docker/gramps-headless/Dockerfile

Lines changed: 0 additions & 42 deletions
This file was deleted.

.github/workflows/ci.yml

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,17 @@ on:
77
branches: [maintenance/gramps60]
88

99
env:
10-
HEADLESS_IMAGE: ghcr.io/${{ github.repository }}/gramps-headless:gramps60
11-
GTK_IMAGE: ghcr.io/${{ github.repository }}/gramps-gtk:gramps60
10+
CI_IMAGE: ghcr.io/${{ github.repository }}/gramps-ci:gramps60
1211

1312
jobs:
1413
# -----------------------------------------------------------------
15-
# Lint (headless container)
14+
# Lint (ci container)
1615
# -----------------------------------------------------------------
1716
lint:
1817
name: Lint
1918
runs-on: ubuntu-latest
2019
container:
21-
image: ghcr.io/${{ github.repository }}/gramps-headless:gramps60
20+
image: ghcr.io/${{ github.repository }}/gramps-ci:gramps60
2221
steps:
2322
- uses: actions/checkout@v4
2423

@@ -60,13 +59,13 @@ jobs:
6059
exit $failed
6160
6261
# -----------------------------------------------------------------
63-
# Compile check (headless container)
62+
# Compile check (ci container)
6463
# -----------------------------------------------------------------
6564
compile-check:
6665
name: Compile Check
6766
runs-on: ubuntu-latest
6867
container:
69-
image: ghcr.io/${{ github.repository }}/gramps-headless:gramps60
68+
image: ghcr.io/${{ github.repository }}/gramps-ci:gramps60
7069
steps:
7170
- uses: actions/checkout@v4
7271

@@ -81,13 +80,13 @@ jobs:
8180
exit $failed
8281
8382
# -----------------------------------------------------------------
84-
# Unit tests — Linux (headless container)
83+
# Unit tests — Linux (ci container)
8584
# -----------------------------------------------------------------
8685
unit-test-linux:
8786
name: Unit Tests (Linux)
8887
runs-on: ubuntu-latest
8988
container:
90-
image: ghcr.io/${{ github.repository }}/gramps-headless:gramps60
89+
image: ghcr.io/${{ github.repository }}/gramps-ci:gramps60
9190
steps:
9291
- uses: actions/checkout@v4
9392

@@ -101,71 +100,69 @@ jobs:
101100
test_dirs="$test_dirs $d"
102101
fi
103102
done
104-
for f in */test_*.py; do
105-
if [ -f "$f" ]; then
106-
test_dirs="$test_dirs $(dirname "$f")"
107-
fi
108-
done
109103
if [ -n "$test_dirs" ]; then
110104
echo "Running unit tests in: $test_dirs"
111105
python3 -m pytest $test_dirs -v --tb=short \
112106
--ignore-glob='**/test_integration*.py' \
107+
--ignore=Sqlite/tests/test_sqlite.py \
113108
-m 'not gui'
114109
else
115110
echo "No per-addon unit test files found"
116111
fi
117112
118113
# -----------------------------------------------------------------
119-
# Unit tests — Windows (bare runner, pip install)
114+
# Unit tests — Windows (conda-forge: bundles PyGObject + GTK + Gramps)
120115
# -----------------------------------------------------------------
121116
unit-test-windows:
122117
name: Unit Tests (Windows)
123118
runs-on: windows-latest
119+
defaults:
120+
run:
121+
shell: bash -el {0}
124122
steps:
125123
- uses: actions/checkout@v4
126124

127-
- name: Set up Python
128-
uses: actions/setup-python@v5
125+
- name: Set up Miniforge
126+
uses: conda-incubator/setup-miniconda@v3
129127
with:
128+
miniforge-version: latest
130129
python-version: "3.12"
130+
activate-environment: addons-ci
131+
channels: conda-forge
131132

132-
- name: Install dependencies
133-
run: pip install gramps orjson pytest dbf
133+
- name: Install Gramps + test deps
134+
run: mamba install -y "gramps>=6.0,<6.1" pygobject gtk3 orjson pytest dbf
134135

135136
- name: Run per-addon unit tests
136137
env:
137138
PYTHONPATH: .
138-
shell: bash
139139
run: |
140140
test_dirs=""
141141
for d in */tests/; do
142142
if ls "$d"/test_*.py 1>/dev/null 2>&1; then
143143
test_dirs="$test_dirs $d"
144144
fi
145145
done
146-
for f in */test_*.py; do
147-
if [ -f "$f" ]; then
148-
test_dirs="$test_dirs $(dirname "$f")"
149-
fi
150-
done
151146
if [ -n "$test_dirs" ]; then
152147
echo "Running unit tests in: $test_dirs"
153148
python -m pytest $test_dirs -v --tb=short \
154149
--ignore-glob='**/test_integration*.py' \
150+
--ignore=Sqlite/tests/test_sqlite.py \
155151
-m 'not gui'
156152
else
157153
echo "No per-addon unit test files found"
158154
fi
159155
160156
# -----------------------------------------------------------------
161-
# Integration tests — Gramps (GTK container)
157+
# Integration tests — Gramps (ci container, xvfb available)
162158
# -----------------------------------------------------------------
163159
integration-test:
164160
name: Integration Tests (Gramps)
165161
runs-on: ubuntu-latest
166162
needs: [unit-test-linux]
167163
container:
168-
image: ghcr.io/${{ github.repository }}/gramps-gtk:gramps60
164+
image: ghcr.io/${{ github.repository }}/gramps-ci:gramps60
165+
options: --init
169166
steps:
170167
- uses: actions/checkout@v4
171168
with:
@@ -174,7 +171,7 @@ jobs:
174171
- name: Run plugin registration tests
175172
env:
176173
PYTHONPATH: .
177-
run: xvfb-run python3 -m pytest tests/ -v --tb=short
174+
run: python3 -m pytest tests/ -v --tb=short
178175

179176
- name: Run per-addon integration tests
180177
env:
@@ -188,19 +185,19 @@ jobs:
188185
done
189186
if [ -n "$integration_tests" ]; then
190187
echo "Running per-addon integration tests: $integration_tests"
191-
xvfb-run python3 -m pytest $integration_tests -v --tb=short
188+
python3 -m pytest $integration_tests -v --tb=short
192189
else
193190
echo "No per-addon integration test files found"
194191
fi
195192
196193
# -----------------------------------------------------------------
197-
# Build (headless container — has intltool/gettext)
194+
# Build (ci container)
198195
# -----------------------------------------------------------------
199196
build:
200197
name: Build
201198
runs-on: ubuntu-latest
202199
container:
203-
image: ghcr.io/${{ github.repository }}/gramps-headless:gramps60
200+
image: ghcr.io/${{ github.repository }}/gramps-ci:gramps60
204201
steps:
205202
- uses: actions/checkout@v4
206203

.github/workflows/docker-build.yml

Lines changed: 5 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ permissions:
1616
packages: write
1717

1818
jobs:
19-
build-headless:
20-
name: Build gramps-headless
19+
build-ci:
20+
name: Build gramps-ci
2121
runs-on: ubuntu-latest
2222
steps:
2323
- uses: actions/checkout@v4
@@ -36,55 +36,17 @@ jobs:
3636
id: meta
3737
uses: docker/metadata-action@v5
3838
with:
39-
images: ${{ env.REGISTRY }}/${{ env.REPO }}/gramps-headless
39+
images: ${{ env.REGISTRY }}/${{ env.REPO }}/gramps-ci
4040
tags: |
4141
type=raw,value=gramps60
4242
type=sha,prefix=gramps60-
4343
44-
- name: Build and push gramps-headless
44+
- name: Build and push gramps-ci
4545
uses: docker/build-push-action@v6
4646
with:
47-
context: .github/docker/gramps-headless
47+
context: .github/docker/gramps-ci
4848
push: true
4949
tags: ${{ steps.meta.outputs.tags }}
5050
labels: ${{ steps.meta.outputs.labels }}
5151
cache-from: type=gha
5252
cache-to: type=gha,mode=max
53-
54-
build-gtk:
55-
name: Build gramps-gtk
56-
runs-on: ubuntu-latest
57-
needs: [build-headless]
58-
steps:
59-
- uses: actions/checkout@v4
60-
61-
- name: Log in to GHCR
62-
uses: docker/login-action@v3
63-
with:
64-
registry: ghcr.io
65-
username: ${{ github.actor }}
66-
password: ${{ secrets.GITHUB_TOKEN }}
67-
68-
- name: Set up Docker Buildx
69-
uses: docker/setup-buildx-action@v3
70-
71-
- name: Docker metadata
72-
id: meta
73-
uses: docker/metadata-action@v5
74-
with:
75-
images: ${{ env.REGISTRY }}/${{ env.REPO }}/gramps-gtk
76-
tags: |
77-
type=raw,value=gramps60
78-
type=sha,prefix=gramps60-
79-
80-
- name: Build and push gramps-gtk
81-
uses: docker/build-push-action@v6
82-
with:
83-
context: .github/docker/gramps-gtk
84-
push: true
85-
tags: ${{ steps.meta.outputs.tags }}
86-
labels: ${{ steps.meta.outputs.labels }}
87-
cache-from: type=gha
88-
cache-to: type=gha,mode=max
89-
build-args: |
90-
BASE_IMAGE=${{ env.REGISTRY }}/${{ env.REPO }}/gramps-headless:gramps60

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
*.py[cod]
33
__pycache__
44

5+
# Gramps runtime logs
6+
debug.log
7+
58
# Editing
69
*~
710
tags

0 commit comments

Comments
 (0)