Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 46 additions & 13 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,56 @@ name: Docker Image CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

build:
- name: Install Task
uses: arduino/setup-task@v2

- name: Run integration tests
run: task test

build:
runs-on: ubuntu-latest
needs: test
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}

steps:
- uses: actions/checkout@v2
- name: Get the version
id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Build the Docker image
run: docker build . --file Dockerfile --tag backuptools/postgres-backup-s3:${{steps.vars.outputs.sha_short}} --tag backuptools/postgres-backup-s3
- name: Login to Dockerhub
run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin
- name: Push the Docker image
run: docker push backuptools/postgres-backup-s3:${{steps.vars.outputs.sha_short}}
- name: Push the :latest Docker image
run: docker push backuptools/postgres-backup-s3
- uses: actions/checkout@v4

- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: backuptools/postgres-backup-s3
tags: |
type=raw,value=latest
type=sha,prefix=,format=short

- name: Login to Docker Hub
if: github.event_name == 'push' && env.DOCKERHUB_USERNAME != ''
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name == 'push' && env.DOCKERHUB_USERNAME != '' }}
tags: ${{ steps.meta.outputs.tags }}
39 changes: 39 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
version: '3'

vars:
IMAGE: backuptools/postgres-backup-s3

tasks:
build:
desc: "Build linux/amd64+linux/arm64 locally (no push)"
cmds:
- docker buildx build --platform linux/amd64,linux/arm64 --progress=plain .

test:
desc: "Integration test: build, run backup against postgres+minio, assert success"
cmds:
- defer: docker compose -f docker-compose.test.yml down -v
- docker compose -f docker-compose.test.yml up -d --build --wait postgres minio
- |
OUTPUT=$(docker compose -f docker-compose.test.yml run --rm --no-deps postgres-backup /entrypoint.sh 2>&1)
echo "$OUTPUT"
echo "$OUTPUT" | grep -q "Postgres backup completed successfully" \
|| (echo "FAIL: success message not found in output" && exit 1)
- |
FILES=$(docker compose -f docker-compose.test.yml run --rm --no-deps \
-e MC_HOST_backup=http://minio:minio123@minio:9000 \
postgres-backup mc ls backup/test-backup/ --recursive --insecure 2>/dev/null)
echo "$FILES"
echo "$FILES" | grep -q "\.pgdump" \
|| (echo "FAIL: no .pgdump files found in minio bucket" && exit 1)
echo "PASS: backup file verified in minio"
- |
if docker compose -f docker-compose.test.yml run --rm --no-deps \
-e MC_HOST_backup=http://minio:minio123@minio:9000 \
postgres-backup sh -c \
'mc find backup/test-backup/ --insecure 2>/dev/null | head -1 | xargs mc cat --insecure | pigz -d | grep -q "test_table"'; then
echo "PASS: backup content verified (test_table found in dump)"
else
echo "FAIL: test_table not found in backup content"
exit 1
fi
15 changes: 12 additions & 3 deletions docker-compose.test.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: "3.9"

volumes:
minio_data:
postgres_data:
Expand Down Expand Up @@ -31,6 +29,12 @@ services:
MINIO_ROOT_USER: minio
MINIO_ROOT_PASSWORD: minio123
command: server /data --console-address ":9001" --address 0.0.0.0:9000
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 2s
timeout: 5s
retries: 15
start_period: 3s

postgres:
image: postgres:15-alpine
Expand All @@ -42,4 +46,9 @@ services:
- postgres_data:/var/lib/postgresql/data
- ./test-init.sql:/docker-entrypoint-initdb.d/init-dump.sql
ports:
- "5434:5432"
- "5434:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 2s
timeout: 5s
retries: 15
2 changes: 0 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: "3"

services:
postgres-backup:
image: backuptools/postgres-backup-s3
Expand Down
121 changes: 121 additions & 0 deletions test-init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
--
-- PostgreSQL database dump
--

-- Dumped from database version 15.5
-- Dumped by pg_dump version 16.2

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

\connect postgres

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

--
-- Name: DATABASE postgres; Type: COMMENT; Schema: -; Owner: postgres
--

COMMENT ON DATABASE postgres IS 'default administrative connection database';


SET default_tablespace = '';

SET default_table_access_method = heap;

--
-- Name: test_table; Type: TABLE; Schema: public; Owner: postgres
--

CREATE TABLE public.test_table (
id integer NOT NULL,
login text NOT NULL
);


ALTER TABLE public.test_table OWNER TO postgres;

--
-- Name: test_table_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres
--

CREATE SEQUENCE public.test_table_id_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;


ALTER SEQUENCE public.test_table_id_seq OWNER TO postgres;

--
-- Name: test_table_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres
--

ALTER SEQUENCE public.test_table_id_seq OWNED BY public.test_table.id;


--
-- Name: test_table id; Type: DEFAULT; Schema: public; Owner: postgres
--

ALTER TABLE ONLY public.test_table ALTER COLUMN id SET DEFAULT nextval('public.test_table_id_seq'::regclass);


--
-- Data for Name: test_table; Type: TABLE DATA; Schema: public; Owner: postgres
--

COPY public.test_table (id, login) FROM stdin;
1 asd
2 qwe
3 zxc
4 ert
5 dfg
\.


--
-- Name: test_table_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
--

SELECT pg_catalog.setval('public.test_table_id_seq', 5, true);


--
-- Name: test_table_id_uindex; Type: INDEX; Schema: public; Owner: postgres
--

CREATE UNIQUE INDEX test_table_id_uindex ON public.test_table USING btree (id);


--
-- Name: test_table_login_uindex; Type: INDEX; Schema: public; Owner: postgres
--

CREATE UNIQUE INDEX test_table_login_uindex ON public.test_table USING btree (login);


--
-- PostgreSQL database dump complete
--

Loading