diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 429fa5e..d15106f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,11 +3,11 @@ name: CI on: push: branches: [main] - pull_request: + workflow_dispatch: jobs: determinism: - runs-on: ubuntu-latest + runs-on: ${{ fromJSON(vars.CI_RUNNER_LABELS) }} strategy: fail-fast: false matrix: @@ -27,21 +27,9 @@ jobs: - run: npm run verify:golden test: - runs-on: ubuntu-latest - services: - postgres: - image: postgres:16 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: postgres - options: >- - --health-cmd "pg_isready -U postgres" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 + runs-on: ${{ fromJSON(vars.CI_RUNNER_LABELS) }} + env: + BIOFLOW_DATABASE_URL: postgres://postgres@127.0.0.1:55432/postgres steps: - uses: actions/checkout@v4 @@ -54,6 +42,13 @@ jobs: cache: "pnpm" - run: pnpm install --frozen-lockfile + - name: Start local Postgres + env: + PGDATA: ${{ runner.temp }}/bioflow-pgdata + PGSOCKET_DIR: ${{ runner.temp }}/bioflow-pgsocket + PGPORT: "55432" + PGLOG: ${{ runner.temp }}/bioflow-postgres.log + run: nix shell nixpkgs#postgresql_16 --command bash scripts/ci-local-postgres.sh start - run: npm run check:ci - run: npm run demo:killer:ci - run: npm run build @@ -82,7 +77,6 @@ jobs: - name: Self-serve smoke (signup -> run -> verify -> share) if: ${{ steps.hosted-scripts.outputs.enabled == 'true' }} env: - BIOFLOW_DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres BIOFLOW_SERVICE_DATA_DIR: .bioflow_smoke_service BIOFLOW_RUNNER_MODE: inline BIOFLOW_API_KEY_PEPPER: 0123456789abcdef0123456789abcdef @@ -97,7 +91,7 @@ jobs: npm run service:api >/tmp/bioflow-api.log 2>&1 & API_PID=$! trap 'status=$?; kill "$API_PID" >/dev/null 2>&1 || true; wait "$API_PID" >/dev/null 2>&1 || true; if [ "$status" -ne 0 ]; then echo "=== /tmp/bioflow-api.log ==="; cat /tmp/bioflow-api.log || true; fi' EXIT - for i in {1..60}; do + for _ in {1..60}; do if curl -fsS http://127.0.0.1:8080/readyz >/dev/null; then break fi @@ -120,4 +114,12 @@ jobs: if-no-files-found: warn - name: RLS integration if: ${{ steps.hosted-scripts.outputs.enabled == 'true' }} - run: BIOFLOW_DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres npm run test:rls + run: npm run test:rls + - name: Stop local Postgres + if: always() + env: + PGDATA: ${{ runner.temp }}/bioflow-pgdata + PGSOCKET_DIR: ${{ runner.temp }}/bioflow-pgsocket + PGPORT: "55432" + PGLOG: ${{ runner.temp }}/bioflow-postgres.log + run: nix shell nixpkgs#postgresql_16 --command bash scripts/ci-local-postgres.sh stop diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index f4bf57a..ff03018 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -10,11 +10,12 @@ on: - labeled - unlabeled - edited + workflow_dispatch: jobs: CLA: name: CLA - runs-on: ubuntu-latest + runs-on: ${{ fromJSON(vars.CI_RUNNER_LABELS) }} permissions: pull-requests: read @@ -24,6 +25,10 @@ jobs: with: script: | const pr = context.payload.pull_request; + if (!pr) { + core.notice("CLA check is only meaningful for pull request payloads."); + return; + } const association = String(pr.author_association || "").toUpperCase(); const labels = (pr.labels ?? []).map((label) => String(label.name || "").toLowerCase()); diff --git a/.github/workflows/conventional-commits.yml b/.github/workflows/conventional-commits.yml index dd242cd..469bc6e 100644 --- a/.github/workflows/conventional-commits.yml +++ b/.github/workflows/conventional-commits.yml @@ -1,21 +1,14 @@ name: Conventional Commits on: - pull_request: - branches: - - main - types: - - opened - - reopened - - synchronize - - ready_for_review - - edited + push: + branches: [main] workflow_dispatch: jobs: conventional-commits: name: Conventional Commits - runs-on: ubuntu-latest + runs-on: ${{ fromJSON(vars.CI_RUNNER_LABELS) }} timeout-minutes: 15 steps: @@ -34,9 +27,7 @@ jobs: shell: bash run: | set -euo pipefail - if [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then - range="${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}" - elif git rev-parse --verify HEAD~1 >/dev/null 2>&1; then + if git rev-parse --verify HEAD~1 >/dev/null 2>&1; then range="HEAD~1..HEAD" else range="HEAD" diff --git a/.github/workflows/release-cli.yml b/.github/workflows/release-cli.yml index 71f1bc4..7fed0e4 100644 --- a/.github/workflows/release-cli.yml +++ b/.github/workflows/release-cli.yml @@ -7,7 +7,7 @@ on: jobs: publish: - runs-on: ubuntu-latest + runs-on: ${{ fromJSON(vars.CI_RUNNER_LABELS) }} permissions: contents: read id-token: write diff --git a/scripts/ci-local-postgres.sh b/scripts/ci-local-postgres.sh new file mode 100644 index 0000000..9525cb5 --- /dev/null +++ b/scripts/ci-local-postgres.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +set -euo pipefail + +command="${1:-start}" +pgdata="${PGDATA:-${RUNNER_TEMP:-/tmp}/bioflow-pgdata}" +pgsocket_dir="${PGSOCKET_DIR:-${RUNNER_TEMP:-/tmp}/bioflow-pgsocket}" +pgport="${PGPORT:-5432}" +pghost="${PGHOST:-127.0.0.1}" +pglog="${PGLOG:-${RUNNER_TEMP:-/tmp}/bioflow-postgres.log}" + +usage() { + cat >&2 <<'EOF' +usage: ci-local-postgres.sh + +Environment: + PGDATA PostgreSQL data directory. + PGSOCKET_DIR Unix socket directory. + PGPORT TCP port to bind. Defaults to 5432. + PGHOST TCP host to bind. Defaults to 127.0.0.1. + PGLOG Log file path. +EOF +} + +start_postgres() { + rm -rf "$pgdata" "$pgsocket_dir" + mkdir -p "$pgdata" "$pgsocket_dir" + + initdb -D "$pgdata" --auth=trust --username=postgres >/dev/null + pg_ctl -D "$pgdata" -l "$pglog" -o "-F -k $pgsocket_dir -h $pghost -p $pgport" start >/dev/null + pg_isready -h "$pghost" -p "$pgport" >/dev/null +} + +stop_postgres() { + if [ -d "$pgdata" ]; then + pg_ctl -D "$pgdata" -m fast stop >/dev/null 2>&1 || true + fi +} + +status_postgres() { + pg_isready -h "$pghost" -p "$pgport" +} + +case "$command" in + start) + start_postgres + ;; + stop) + stop_postgres + ;; + status) + status_postgres + ;; + *) + usage + exit 2 + ;; +esac