Skip to content

Commit b4fc226

Browse files
committed
fix: address all review findings across workflows and Dockerfile
Matrix correctness: - Fix broken include for runner-to-platform mapping by pre-building the full matrix in load-versions job using jq - Iterate versions.json entries directly instead of cross-product of unique arrays (prevents invalid combos if versions diverge) Dockerfile: - Collapse 4 RUN layers into single layer (~150-300MB image savings) - Preserve ca-certificates at runtime via apt-mark manual - Add HEALTHCHECK instruction - Add .dockerignore to reduce build context Security: - Add top-level permissions: contents: read to test.yml - Pass all ${{ }} values through env vars in run blocks - Add provenance and SBOM attestations to published images - Remove cache-to from publish (test workflow warms the cache)
1 parent 4b75469 commit b4fc226

File tree

4 files changed

+74
-75
lines changed

4 files changed

+74
-75
lines changed

.dockerignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.git
2+
.github
3+
.dockerignore
4+
.gitignore
5+
.env*
6+
*.md
7+
LICENSE
8+
docker-compose*.yml
9+
versions.json

.github/workflows/publish.yml

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,16 @@ jobs:
1313
load-versions:
1414
runs-on: ubuntu-latest
1515
outputs:
16-
pg_versions: ${{ steps.set-matrix.outputs.pg_versions }}
17-
postgis_versions: ${{ steps.set-matrix.outputs.postgis_versions }}
18-
pgvector_versions: ${{ steps.set-matrix.outputs.pgvector_versions }}
19-
versions: ${{ steps.set-matrix.outputs.versions }}
16+
build-matrix: ${{ steps.set-matrix.outputs.build_matrix }}
17+
merge-matrix: ${{ steps.set-matrix.outputs.merge_matrix }}
2018
steps:
2119
- uses: actions/checkout@v6
2220
- id: set-matrix
2321
run: |
24-
echo "pg_versions=$(jq -c '[.[].pg_version] | unique' versions.json)" >> "$GITHUB_OUTPUT"
25-
echo "postgis_versions=$(jq -c '[.[].postgis_version] | unique' versions.json)" >> "$GITHUB_OUTPUT"
26-
echo "pgvector_versions=$(jq -c '[.[].pgvector_version] | unique' versions.json)" >> "$GITHUB_OUTPUT"
27-
echo "versions=$(jq -c '.' versions.json)" >> "$GITHUB_OUTPUT"
22+
RUNNERS='[{"runner":"ubuntu-latest","platform":"linux/amd64"},{"runner":"ubuntu-24.04-arm","platform":"linux/arm64"}]'
23+
BUILD_MATRIX=$(jq -c --argjson runners "$RUNNERS" '{include: [.[] | . as $v | $runners[] | . + $v]}' versions.json)
24+
echo "build_matrix=$BUILD_MATRIX" >> "$GITHUB_OUTPUT"
25+
echo "merge_matrix=$(jq -c '{include: .}' versions.json)" >> "$GITHUB_OUTPUT"
2826
2927
build:
3028
needs: load-versions
@@ -36,16 +34,7 @@ jobs:
3634

3735
strategy:
3836
fail-fast: false
39-
matrix:
40-
runner: [ubuntu-latest, ubuntu-24.04-arm]
41-
pg_version: ${{ fromJSON(needs.load-versions.outputs.pg_versions) }}
42-
postgis_version: ${{ fromJSON(needs.load-versions.outputs.postgis_versions) }}
43-
pgvector_version: ${{ fromJSON(needs.load-versions.outputs.pgvector_versions) }}
44-
include:
45-
- runner: ubuntu-latest
46-
platform: linux/amd64
47-
- runner: ubuntu-24.04-arm
48-
platform: linux/arm64
37+
matrix: ${{ fromJSON(needs.load-versions.outputs.build-matrix) }}
4938

5039
steps:
5140
- name: Checkout repository
@@ -74,20 +63,22 @@ jobs:
7463
context: .
7564
push: true
7665
platforms: ${{ matrix.platform }}
66+
provenance: true
67+
sbom: true
7768
labels: ${{ steps.meta.outputs.labels }}
7869
build-args: |
7970
PG_VERSION=${{ matrix.pg_version }}
8071
POSTGIS_VERSION=${{ matrix.postgis_version }}
8172
PGVECTOR_VERSION=${{ matrix.pgvector_version }}
8273
cache-from: type=gha,scope=${{ matrix.pg_version }}-${{ matrix.runner }}
83-
cache-to: type=gha,mode=max,scope=${{ matrix.pg_version }}-${{ matrix.runner }}
8474
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
8575

8676
- name: Export digest
77+
env:
78+
DIGEST: ${{ steps.build.outputs.digest }}
8779
run: |
8880
mkdir -p /tmp/digests
89-
digest="${{ steps.build.outputs.digest }}"
90-
touch "/tmp/digests/${digest#sha256:}"
81+
touch "/tmp/digests/${DIGEST#sha256:}"
9182
9283
- name: Upload digest
9384
uses: actions/upload-artifact@v4
@@ -107,8 +98,7 @@ jobs:
10798

10899
strategy:
109100
fail-fast: false
110-
matrix:
111-
include: ${{ fromJSON(needs.load-versions.outputs.versions) }}
101+
matrix: ${{ fromJSON(needs.load-versions.outputs.merge-matrix) }}
112102

113103
steps:
114104
- name: Download digests
@@ -137,10 +127,13 @@ jobs:
137127
138128
- name: Create multi-arch manifest and push
139129
working-directory: /tmp/digests
130+
env:
131+
REGISTRY: ${{ env.REGISTRY }}
132+
IMAGE: ${{ env.IMAGE_NAME }}
140133
run: |
141134
docker buildx imagetools create \
142135
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
143-
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
136+
$(printf "${REGISTRY}/${IMAGE}@sha256:%s " *)
144137
145138
- name: Verify multi-arch manifest
146139
run: |

.github/workflows/test.yml

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,28 @@ on:
77
branches: [main]
88
workflow_dispatch:
99

10+
permissions:
11+
contents: read
12+
1013
jobs:
1114
load-versions:
1215
runs-on: ubuntu-latest
1316
outputs:
14-
pg_versions: ${{ steps.set-matrix.outputs.pg_versions }}
15-
postgis_versions: ${{ steps.set-matrix.outputs.postgis_versions }}
16-
pgvector_versions: ${{ steps.set-matrix.outputs.pgvector_versions }}
17+
matrix: ${{ steps.set-matrix.outputs.matrix }}
1718
steps:
1819
- uses: actions/checkout@v6
1920
- id: set-matrix
2021
run: |
21-
echo "pg_versions=$(jq -c '[.[].pg_version] | unique' versions.json)" >> "$GITHUB_OUTPUT"
22-
echo "postgis_versions=$(jq -c '[.[].postgis_version] | unique' versions.json)" >> "$GITHUB_OUTPUT"
23-
echo "pgvector_versions=$(jq -c '[.[].pgvector_version] | unique' versions.json)" >> "$GITHUB_OUTPUT"
22+
MATRIX=$(jq -c '{include: [.[] | . as $v | {runner: "ubuntu-latest"}, {runner: "ubuntu-24.04-arm"} | . + $v]}' versions.json)
23+
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"
2424
2525
test:
2626
needs: load-versions
2727
runs-on: ${{ matrix.runner }}
2828
timeout-minutes: 15
2929
strategy:
3030
fail-fast: false
31-
matrix:
32-
runner: [ubuntu-latest, ubuntu-24.04-arm]
33-
pg_version: ${{ fromJSON(needs.load-versions.outputs.pg_versions) }}
34-
postgis_version: ${{ fromJSON(needs.load-versions.outputs.postgis_versions) }}
35-
pgvector_version: ${{ fromJSON(needs.load-versions.outputs.pgvector_versions) }}
31+
matrix: ${{ fromJSON(needs.load-versions.outputs.matrix) }}
3632

3733
steps:
3834
- uses: actions/checkout@v6
@@ -54,9 +50,12 @@ jobs:
5450
cache-to: type=gha,mode=max,scope=${{ matrix.pg_version }}-${{ matrix.runner }}
5551

5652
- name: Start PostgreSQL container
53+
env:
54+
PG_VERSION: ${{ matrix.pg_version }}
55+
RUNNER: ${{ matrix.runner }}
5756
run: |
58-
IMAGE_TAG="postgres-test:pg${{ matrix.pg_version }}"
59-
echo "Testing image: $IMAGE_TAG (runner: ${{ matrix.runner }})"
57+
IMAGE_TAG="postgres-test:pg${PG_VERSION}"
58+
echo "Testing image: $IMAGE_TAG (runner: $RUNNER)"
6059
6160
docker run -d --name test-db \
6261
-e POSTGRES_PASSWORD=test \
@@ -66,7 +65,7 @@ jobs:
6665
--health-interval=2s \
6766
--health-timeout=5s \
6867
--health-retries=30 \
69-
$IMAGE_TAG \
68+
"$IMAGE_TAG" \
7069
postgres -c shared_preload_libraries=vector
7170
7271
echo "Waiting for PostgreSQL to become healthy..."
@@ -97,8 +96,10 @@ jobs:
9796
docker exec test-db psql -U test -d test -c "CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3)); INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]'); SELECT COUNT(*) FROM items;"
9897
9998
- name: Verify installed versions match requested
99+
env:
100+
EXPECTED_PGVECTOR: ${{ matrix.pgvector_version }}
101+
EXPECTED_POSTGIS: ${{ matrix.postgis_version }}
100102
run: |
101-
EXPECTED_PGVECTOR="${{ matrix.pgvector_version }}"
102103
ACTUAL_PGVECTOR=$(docker exec test-db psql -U test -d test -tAc \
103104
"SELECT extversion FROM pg_extension WHERE extname = 'vector';")
104105
if [ "$ACTUAL_PGVECTOR" != "$EXPECTED_PGVECTOR" ]; then
@@ -107,7 +108,6 @@ jobs:
107108
fi
108109
echo "pgvector version OK: $ACTUAL_PGVECTOR"
109110
110-
EXPECTED_POSTGIS="${{ matrix.postgis_version }}"
111111
ACTUAL_POSTGIS=$(docker exec test-db psql -U test -d test -tAc \
112112
"SELECT extversion FROM pg_extension WHERE extname = 'postgis';")
113113
if [ "$ACTUAL_POSTGIS" != "$EXPECTED_POSTGIS" ]; then

Dockerfile

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,53 +13,50 @@ LABEL maintainer="TypeORM"
1313
LABEL description="PostgreSQL with PostGIS and pgvector extensions for TypeORM"
1414
LABEL org.opencontainers.image.source="https://github.com/typeorm/docker"
1515

16-
# Install base dependencies, setup PGDG repository, and install build tools
16+
# Install PostGIS, build pgvector from source, then clean up in a single layer
1717
# Note: PG_MAJOR is provided by the official postgres base image
18-
RUN apt-get update \
18+
RUN set -eux \
19+
&& apt-get update \
1920
&& apt-get install -y --no-install-recommends \
20-
lsb-release \
21-
gnupg \
22-
ca-certificates \
23-
wget \
21+
lsb-release \
22+
gnupg \
23+
ca-certificates \
24+
wget \
2425
&& wget --quiet -O /usr/share/keyrings/postgresql-archive-keyring.gpg https://www.postgresql.org/media/keys/ACCC4CF8.asc \
2526
&& sh -c 'echo "deb [signed-by=/usr/share/keyrings/postgresql-archive-keyring.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' \
2627
&& apt-get update \
2728
&& apt-get install -y --no-install-recommends \
28-
build-essential \
29-
git \
30-
make \
31-
gcc \
32-
"postgresql-server-dev-${PG_MAJOR}"
33-
34-
# Install pinned PostGIS version (apt packages use major version in name)
35-
RUN POSTGIS_MAJOR=$(echo "${POSTGIS_VERSION}" | cut -d. -f1) \
36-
&& apt-get update \
29+
build-essential \
30+
git \
31+
make \
32+
gcc \
33+
"postgresql-server-dev-${PG_MAJOR}" \
34+
&& POSTGIS_MAJOR=$(echo "${POSTGIS_VERSION}" | cut -d. -f1) \
3735
&& apt-get install -y --no-install-recommends \
38-
"postgis=${POSTGIS_VERSION}+dfsg*" \
39-
"postgresql-${PG_MAJOR}-postgis-${POSTGIS_MAJOR}=${POSTGIS_VERSION}+dfsg*" \
40-
"postgresql-${PG_MAJOR}-postgis-${POSTGIS_MAJOR}-scripts=${POSTGIS_VERSION}+dfsg*"
41-
42-
# Build and install pinned pgvector version from source
43-
RUN git clone --branch "v${PGVECTOR_VERSION}" --depth 1 https://github.com/pgvector/pgvector.git /usr/src/pgvector \
36+
"postgis=${POSTGIS_VERSION}+dfsg*" \
37+
"postgresql-${PG_MAJOR}-postgis-${POSTGIS_MAJOR}=${POSTGIS_VERSION}+dfsg*" \
38+
"postgresql-${PG_MAJOR}-postgis-${POSTGIS_MAJOR}-scripts=${POSTGIS_VERSION}+dfsg*" \
39+
&& git clone --branch "v${PGVECTOR_VERSION}" --depth 1 https://github.com/pgvector/pgvector.git /usr/src/pgvector \
4440
&& cd /usr/src/pgvector \
4541
&& make \
46-
&& make install
47-
48-
# Cleanup build dependencies
49-
RUN apt-get purge -y --auto-remove \
50-
build-essential \
51-
git \
52-
make \
53-
gcc \
54-
"postgresql-server-dev-${PG_MAJOR}" \
55-
wget \
56-
lsb-release \
57-
gnupg \
42+
&& make install \
43+
&& apt-mark manual ca-certificates \
44+
&& apt-get purge -y --auto-remove \
45+
build-essential \
46+
git \
47+
make \
48+
gcc \
49+
"postgresql-server-dev-${PG_MAJOR}" \
50+
wget \
51+
lsb-release \
52+
gnupg \
5853
&& apt-get clean \
59-
&& rm -rf /var/lib/apt/lists/* \
60-
&& rm -rf /usr/src/pgvector
54+
&& rm -rf /var/lib/apt/lists/* /usr/src/pgvector
6155

6256
# Copy initialization scripts
6357
COPY docker-entrypoint-initdb.d/ /docker-entrypoint-initdb.d/
6458

59+
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
60+
CMD pg_isready -U postgres || exit 1
61+
6562
EXPOSE 5432

0 commit comments

Comments
 (0)