Files
dotnet-build-test/.gitea/workflows/dotnet-build-test-postgres.yaml

132 lines
4.3 KiB
YAML

name: .NET Build & Test with PostgreSQL (Reusable)
on:
workflow_call:
inputs:
solution:
description: "Solution/project file to build (relative to working-directory). Empty = let dotnet pick the single sln/proj in working-directory"
required: false
default: ""
type: string
dotnet-version:
description: ".NET SDK version"
required: false
default: "10.0.x"
type: string
configuration:
description: "Build configuration"
required: false
default: "Release"
type: string
# string, not boolean: act_runner mangles boolean defaults. The value may still arrive as '%!t(string=…)', see Build step.
warnaserror:
description: "Treat build warnings as errors (\"true\"/\"false\")"
required: false
default: "true"
type: string
working-directory:
description: "Path where dotnet commands are executed (relative to repo root)"
required: false
default: "."
type: string
test-filter:
description: "Optional dotnet test --filter expression"
required: false
default: ""
type: string
postgres-image:
description: "PostgreSQL service image"
required: false
default: "postgres:17-alpine"
type: string
postgres-user:
description: "PostgreSQL superuser (POSTGRES_USER of the service)"
required: false
default: "postgres"
type: string
postgres-password:
description: "PostgreSQL password (throwaway CI database, not a secret)"
required: false
default: "postgres"
type: string
postgres-db:
description: "Database created on service start (POSTGRES_DB). Empty = same as postgres-user"
required: false
default: ""
type: string
jobs:
build-and-test:
runs-on: ubuntu-latest
env:
DOTNET_CLI_TELEMETRY_OPTOUT: "1"
DOTNET_NOLOGO: "1"
SOLUTION: ${{ inputs.solution }}
CONFIGURATION: ${{ inputs.configuration }}
WARNASERROR: ${{ inputs.warnaserror }}
TEST_FILTER: ${{ inputs.test-filter }}
POSTGRES_HOST: postgres
POSTGRES_PORT: "5432"
POSTGRES_USER: ${{ inputs.postgres-user }}
POSTGRES_PASSWORD: ${{ inputs.postgres-password }}
POSTGRES_DB: ${{ inputs.postgres-db || inputs.postgres-user }}
# Reached by service name on the job network (container-mode runner).
# No host port mapping, so concurrent jobs or a host PostgreSQL can't collide on 5432.
services:
postgres:
image: ${{ inputs.postgres-image }}
env:
POSTGRES_USER: ${{ inputs.postgres-user }}
POSTGRES_PASSWORD: ${{ inputs.postgres-password }}
POSTGRES_DB: ${{ inputs.postgres-db || inputs.postgres-user }}
defaults:
run:
shell: bash
working-directory: ${{ inputs.working-directory }}
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version }}
- name: Restore
run: dotnet restore ${SOLUTION:+"$SOLUTION"}
- name: Build
run: |
ARGS=(-c "$CONFIGURATION" --no-restore)
# act_runner may deliver the value mangled as '%!t(string=false)', so match by substring.
case "${WARNASERROR,,}" in
*false*) ;;
*) ARGS+=(-warnaserror) ;;
esac
set -x
dotnet build ${SOLUTION:+"$SOLUTION"} "${ARGS[@]}"
# The image's init phase listens on the unix socket only, so an open TCP port means the final server is up.
- name: Wait for PostgreSQL
run: |
for _ in $(seq 1 60); do
if (exec 3<>"/dev/tcp/$POSTGRES_HOST/$POSTGRES_PORT") 2>/dev/null; then
echo "PostgreSQL reachable at $POSTGRES_HOST:$POSTGRES_PORT"
exit 0
fi
sleep 1
done
echo "::error::PostgreSQL not reachable at $POSTGRES_HOST:$POSTGRES_PORT after 60s"
exit 1
- name: Test
run: |
ARGS=(-c "$CONFIGURATION" --no-build)
if [ -n "$TEST_FILTER" ]; then
ARGS+=(--filter "$TEST_FILTER")
fi
dotnet test ${SOLUTION:+"$SOLUTION"} "${ARGS[@]}"