Skip to content

chore: fix permission error in ci #74

chore: fix permission error in ci

chore: fix permission error in ci #74

name: Build and Test PostgreSQL Upgrade Container
on:
push:
branches: [ main ]
tags: [ 'v*' ]
pull_request:
branches: [ main ]
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}/postgres-upgrade
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
outputs:
image: ${{ steps.image.outputs.image }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: |
type=gha
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
cache-to: |
type=gha,mode=max
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
- name: Output image
id: image
run: echo "image=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}" >> $GITHUB_OUTPUT
test:
needs: build
runs-on: ubuntu-latest
strategy:
fail-fast: false # Don't cancel other tests if one fails
matrix:
include:
# AMD64 tests - full matrix
- platform: linux/amd64
test: { from: 14, to: 15, name: "14 to 15" }
- platform: linux/amd64
test: { from: 15, to: 16, name: "15 to 16" }
- platform: linux/amd64
test: { from: 16, to: 17, name: "16 to 17" }
- platform: linux/amd64
test: { from: 14, to: 16, name: "14 to 16 (multi-step)" }
- platform: linux/amd64
test: { from: 15, to: 17, name: "15 to 17 (multi-step)" }
- platform: linux/amd64
test: { from: 14, to: 17, name: "14 to 17 (full upgrade)" }
# ARM64 test - just one to verify it works
- platform: linux/arm64
test: { from: 14, to: 17, name: "14 to 17 (full upgrade)" }
name: Test ${{ matrix.platform }} - ${{ matrix.test.name }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up QEMU
if: matrix.platform == 'linux/arm64'
uses: docker/setup-qemu-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set image name
run: |
echo "TEST_IMAGE=${{ needs.build.outputs.image }}" >> $GITHUB_ENV
- name: Pull test image
run: |
echo "Pulling test image: ${{ env.TEST_IMAGE }}"
docker pull ${{ env.TEST_IMAGE }}
- name: Create test data directory
run: |
mkdir -p test-data/${{ matrix.test.from }}
chmod 777 test-data/${{ matrix.test.from }}
# Set SELinux context to allow Docker access
sudo chcon -Rt svirt_sandbox_file_t test-data/ 2>/dev/null || true
- name: Initialize PostgreSQL ${{ matrix.test.from }} with test data
run: |
docker run --rm \
-v $PWD/test-data/${{ matrix.test.from }}:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=testpass \
-e POSTGRES_DB=testdb \
postgres:${{ matrix.test.from }}-bookworm \
bash -c "
set -e
set -o pipefail
docker-entrypoint.sh postgres &
PGPID=\$!
sleep 10
# Create testuser and test database
psql -U postgres -d testdb -v ON_ERROR_STOP=1 <<EOF
CREATE USER testuser WITH PASSWORD 'testpass';
GRANT ALL PRIVILEGES ON DATABASE testdb TO testuser;
GRANT ALL ON SCHEMA public TO testuser;
GRANT CREATE ON SCHEMA public TO testuser;
EOF
# Create test data as testuser
psql -U testuser -d testdb -v ON_ERROR_STOP=1 <<EOF
CREATE TABLE test_data (
id SERIAL PRIMARY KEY,
data TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO test_data (data)
SELECT 'Test record ' || generate_series(1, 1000);
CREATE INDEX idx_test_data ON test_data(created_at);
SELECT COUNT(*) as record_count FROM test_data;
EOF
# Gracefully stop PostgreSQL
su postgres -c 'pg_ctl -D /var/lib/postgresql/data stop -m smart -w'
sleep 5
# Fix permissions for GitHub Actions runner
chown -R 999:999 /var/lib/postgresql/data
"
- name: Run upgrade from ${{ matrix.test.from }} to ${{ matrix.test.to }}
timeout-minutes: 10
run: |
CONTAINER_ID=$(docker run -d \
${{ matrix.platform == 'linux/arm64' && '--platform linux/arm64' || '' }} \
-v $PWD/test-data/${{ matrix.test.from }}:/var/lib/postgresql/data \
-e POSTGRES_INITDB_ARGS="--auth-local=trust --auth-host=md5" \
-e PG_VERSION=${{ matrix.test.to }} \
${{ env.TEST_IMAGE }})
echo "Container started: $CONTAINER_ID"
# Stream logs in real-time
docker logs -f $CONTAINER_ID &
LOGS_PID=$!
sleep 150
# Stop streaming logs
kill $LOGS_PID 2>/dev/null || true
# Stop and remove container
docker stop -t 10 $CONTAINER_ID 2>/dev/null || true
docker rm $CONTAINER_ID 2>/dev/null || true
exit 0
- name: Verify upgraded data
run: |
docker run --rm \
-v $PWD/test-data/${{ matrix.test.from }}:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=testpass \
postgres:${{ matrix.test.to }}-bookworm \
bash -c "
set -e
set -o pipefail
docker-entrypoint.sh postgres &
PGPID=\$!
sleep 10
# Verify data
psql -U testuser -d testdb -v ON_ERROR_STOP=1 <<EOF
-- Check table exists
SELECT COUNT(*) as record_count FROM test_data;
-- Check index exists
SELECT indexname FROM pg_indexes WHERE tablename = 'test_data';
-- Verify data integrity - this will fail if count is not 1000
DO \$\$
DECLARE
record_count INT;
BEGIN
SELECT COUNT(*) INTO record_count FROM test_data;
IF record_count != 10000 THEN
RAISE EXCEPTION 'FAIL: Expected 1000 records, found %', record_count;
END IF;
RAISE NOTICE 'PASS: All 1000 records present';
END \$\$;
EOF
# Stop PostgreSQL
su postgres -c 'pg_ctl -D /var/lib/postgresql/data stop -m smart -w'
sleep 5
# Fix permissions for GitHub Actions runner
chown -R $(id -u):$(id -g) /var/lib/postgresql/data
"
- name: Fix permissions after test
if: always()
run: |
# Always fix permissions after test, regardless of success/failure
sudo chown -R $USER:$USER test-data/ || true
- name: Collect and show test artifacts on failure
if: failure()
run: |
echo "=== Test failed, collecting available information ==="
# Try to fix permissions first
sudo chown -R $USER:$USER test-data/ || true
# Show directory structure
echo "Test data directory structure:"
find test-data/ -type f -name "*.log" 2>/dev/null || echo "No log files found"
# Show any pg_upgrade output if available
find test-data/ -name "pg_upgrade_output.d" -type d 2>/dev/null | while read dir; do
echo "=== Contents of $dir ==="
ls -la "$dir" 2>/dev/null || echo "Cannot access $dir"
done
# Show recent log entries
find test-data/ -name "*.log" -type f 2>/dev/null | head -5 | while read logfile; do
echo "=== Last 20 lines of $logfile ==="
tail -20 "$logfile" 2>/dev/null || echo "Cannot read $logfile"
done