Skip to content

feat(backend-2fa): expose async store methods to eliminate block_on i… #616

feat(backend-2fa): expose async store methods to eliminate block_on i…

feat(backend-2fa): expose async store methods to eliminate block_on i… #616

Workflow file for this run

name: Backend 2FA
on:
push:
branches:
- main
pull_request:
permissions: read-all
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
- name: Install cargo-audit
run: cargo install cargo-audit
- name: Check RUSTSEC advisories against lockfile
working-directory: backend-2fa
run: cargo audit --deny warnings
fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
components: rustfmt
- name: Check formatting
run: cargo fmt --check
working-directory: backend-2fa
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
components: clippy
- name: Run clippy (warnings as errors)
run: cargo clippy --all-targets --all-features -- -D warnings
working-directory: backend-2fa
doc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
- name: Build documentation (warnings as errors)
run: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps
working-directory: backend-2fa
- name: Run doc-tests
run: cargo test --doc
working-directory: backend-2fa
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
- name: Build
run: cargo build
working-directory: backend-2fa
- name: Test
run: cargo test -- --test-threads=1
working-directory: backend-2fa
# #781 — Verify that applying every migration then rolling back every
# migration in reverse leaves the schema in exactly the same state as
# before any migrations were applied. A broken .down.sql would be caught
# here before it ever reaches a production emergency rollback.
migration-rollback:
name: Migration round-trip rollback safety
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: petchain
POSTGRES_PASSWORD: petchain
POSTGRES_DB: petchain_test
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U petchain"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
DATABASE_URL: postgres://petchain:petchain@localhost:5432/petchain_test
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
- name: Run migration round-trip rollback safety test
working-directory: backend-2fa
run: >
cargo test
migrations::tests::test_round_trip_migration_rollback_leaves_schema_unchanged
-- --test-threads=1 --nocapture
# #844 — Validate schema.sql matches the concatenated migrations so the
# file never drifts from the actual applied schema. If this check fails,
# run `bash backend-2fa/scripts/generate-schema.sh` to regenerate.
validate-schema:
name: Validate schema.sql matches migrations
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check schema.sql is in sync with migrations
run: |
set -euo pipefail
# Build a temporary concatenated schema from migrations
TEMP_SCHEMA=$(mktemp)
trap "rm -f $TEMP_SCHEMA" EXIT
# Take the header from schema.sql (up to the auto-gen marker comment)
awk '/Do not edit by hand/{exit} {print}' backend-2fa/schema.sql > "$TEMP_SCHEMA"
echo "" >> "$TEMP_SCHEMA"
# Concatenate up-migration SQL
for f in $(ls backend-2fa/migrations/*.sql | sort); do
basename=$(basename "$f")
case "$basename" in
*.down.sql) continue ;;
*.sql) cat "$f" >> "$TEMP_SCHEMA"; echo "" >> "$TEMP_SCHEMA" ;;
esac
done
# Append two_fa_lockouts if not present
echo "CREATE TABLE IF NOT EXISTS two_fa_lockouts (" >> "$TEMP_SCHEMA"
echo " user_id VARCHAR(255) PRIMARY KEY," >> "$TEMP_SCHEMA"
echo " failed_attempts INT NOT NULL DEFAULT 0," >> "$TEMP_SCHEMA"
echo " locked BOOLEAN NOT NULL DEFAULT FALSE," >> "$TEMP_SCHEMA"
echo " locked_at TIMESTAMP NULL," >> "$TEMP_SCHEMA"
echo " updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP" >> "$TEMP_SCHEMA"
echo ");" >> "$TEMP_SCHEMA"
# Compare normalized content (ignore whitespace-only differences)
if ! diff -u \
<(grep -v '^--' "$TEMP_SCHEMA" | sed '/^$/d') \
<(grep -v '^--' backend-2fa/schema.sql | sed '/^$/d'); then
echo ""
echo "ERROR: schema.sql is out of sync with migrations!"
echo "Run 'bash backend-2fa/scripts/generate-schema.sh' to regenerate."
exit 1
fi
echo "schema.sql is in sync with migrations."
- name: Notify if drift detected
if: failure()
run: echo "::warning::schema.sql has drifted from migrations. Run 'bash backend-2fa/scripts/generate-schema.sh' to fix."
# #691 — Validate the OpenAPI spec on every PR so docs never drift from the
# implementation. Uses Spectral (the de-facto OAS linter) with the built-in
# oas ruleset which enforces OpenAPI 3.0 structural correctness.
validate-openapi-spec:
name: Validate OpenAPI 3.0 spec
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Spectral CLI
run: npm install -g @stoplight/spectral-cli
- name: Validate docs/openapi.yaml
run: spectral lint docs/openapi.yaml --ruleset spectral:oas --fail-severity warn