Skip to content
Open
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
32 changes: 32 additions & 0 deletions .github/workflows/ci-python-library-README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This reusable workflow is part of the City of Helsinki's GitHub Actions setup, s
- **Commit Linting**: Enforces commit message standards using [commitlint](https://commitlint.js.org/).
- **Code Style Checks**: Verifies code style and formatting using [pre-commit](https://pre-commit.com/).
- **Automated Testing**: Runs project tests across multiple Python versions using [hatch](https://hatch.pypa.io/).
- **Database Testing**: Optionally starts a PostgreSQL (with or without PostGIS) service and sets `DATABASE_URL` for tests that require a database.
- **Code Quality Analysis**: Performs a [SonarQube Cloud](https://sonarcloud.io/) scan.

## Requirements for Projects Using the Workflow
Expand All @@ -28,6 +29,8 @@ To use this reusable workflow, create a project-specific workflow file in your `

- **`python-version`** (string): Python version to use for pre-commit checks. Defaults to `"3.x"`.
- **`enable-sonar`** (boolean): Whether to run the SonarQube Cloud Scan job after tests. Defaults to `true`.
- **`postgres-major-version`** (string): PostgreSQL major version to use for testing. Supported versions: `13`, `14`, `17`. Optional - omit if no database is needed.
- **`use-postgis`** (boolean): Set to `true` to use the PostGIS extension. Requires `postgres-major-version` to be set. Defaults to `false`.

### Secrets

Expand Down Expand Up @@ -59,3 +62,32 @@ jobs:
with:
python-matrix: "['3.10', '3.11', '3.12', '3.13', '3.14']"
```

### Example usage with PostgreSQL (`<own project>/.github/workflows/ci.yml`)

```yaml
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
common:
uses: City-of-Helsinki/.github/.github/workflows/ci-python-library.yml@main
secrets:
sonar-token: ${{ secrets.SONAR_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
with:
python-matrix: "['3.12', '3.13']"
postgres-major-version: "17"
```

When `postgres-major-version` is set, the workflow starts a PostgreSQL service and exposes a `DATABASE_URL` environment variable (`postgres://test_user:test_password@localhost/test_db`) to the test runner.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
72 changes: 72 additions & 0 deletions .github/workflows/ci-python-library.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ on:
required: false
type: boolean
default: true
postgres-major-version:
description: "PostgreSQL major version to use for testing (supported: 13, 14, 17). Optional - omit if no database is needed."
required: false
type: string
default: ''
use-postgis:
description: "Set to true to use the PostGIS extension. Requires postgres-major-version to be set."
required: false
type: boolean
default: false
secrets:
sonar-token:
description: "Token for SonarQube Cloud Scan. Required if enable-sonar is set to true."
Expand Down Expand Up @@ -60,6 +70,52 @@ jobs:
python_version: ${{ fromJSON(inputs.python-matrix) }}

steps:
- name: Validate provided PostgreSQL major version
if: ${{ inputs.postgres-major-version != '' }}
env:
POSTGRES_MAJOR_VERSION: ${{ inputs.postgres-major-version }}
run: |
supported_versions=("13" "14" "17")
if [[ ! " ${supported_versions[*]} " == *" ${POSTGRES_MAJOR_VERSION} "* ]]; then
echo "Error: Unsupported PostgreSQL major version provided. Supported versions are 13, 14 and 17."
exit 1
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Start PostgreSQL
if: ${{ inputs.postgres-major-version != '' }}
env:
# The workflow supports only the PostgreSQL and PostGIS versions used in Platta
POSTGRES_IMAGE: ${{ inputs.use-postgis &&
(inputs.postgres-major-version == '17' && 'postgis/postgis:17-3.5-alpine' ||
inputs.postgres-major-version == '14' && 'postgis/postgis:14-3.2-alpine' ||
inputs.postgres-major-version == '13' && 'postgis/postgis:13-3.2-alpine') ||
(inputs.postgres-major-version == '17' && 'postgres:17-alpine' ||
inputs.postgres-major-version == '14' && 'postgres:14-alpine' ||
inputs.postgres-major-version == '13' && 'postgres:13-alpine') }}
run: |
docker run -d --name postgres \
-e POSTGRES_USER=test_user \
-e POSTGRES_PASSWORD=test_password \
-e POSTGRES_DB=test_db \
-p 5432:5432 \
--health-cmd pg_isready \
--health-interval 10s \
--health-timeout 5s \
--health-retries 5 \
"$POSTGRES_IMAGE"
echo "Waiting for PostgreSQL to become healthy..."
for _ in $(seq 1 30); do
status=$(docker inspect --format '{{.State.Health.Status}}' postgres)
if [[ "$status" == "healthy" ]]; then
echo "PostgreSQL is healthy."
exit 0
fi
sleep 2
done
echo "Error: PostgreSQL did not become healthy in time."
docker logs postgres
exit 1

- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up Python ${{ matrix.python_version }}
Expand All @@ -79,6 +135,22 @@ jobs:
${{ runner.os }}-build-
${{ runner.os }}-

- name: Install system packages
if: ${{ inputs.postgres-major-version != '' }}
env:
USE_POSTGIS: ${{ inputs.use-postgis }}
run: |
packages=(libpq-dev)
if [[ "${USE_POSTGIS}" == "true" ]]; then
packages+=(gdal-bin)
fi
sudo apt-get update
sudo apt-get install -y "${packages[@]}"

- name: Set database URL
if: ${{ inputs.postgres-major-version != '' }}
run: echo "DATABASE_URL=${{ inputs.use-postgis == true && 'postgis' || 'postgres' }}://test_user:test_password@localhost/test_db" >> $GITHUB_ENV

Comment thread
danipran marked this conversation as resolved.
- name: Install hatch
run: python -m pip install hatch

Expand Down