Repository navigation
Library API in FastAPI: N-tier, SQLAlchemy 2.0 and Alembic, Docker, C… #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # CI for the Library API (FastAPI): unit tests and the Docker image first, then the | |
| # conformance suite from Library_API_Contract against SQLite and against PostgreSQL 17. | |
| # name: the workflow's name on the Actions tab. | |
| name: CI | |
| # on: the events that start the workflow. Every push and every pull request. | |
| on: | |
| push: | |
| pull_request: | |
| # jobs: the work to do. Jobs run in parallel unless one "needs" another. | |
| jobs: | |
| build: | |
| # runs-on: the kind of machine GitHub starts for the job. | |
| runs-on: ubuntu-latest | |
| # steps: run in order. "uses" runs a published action, "run" runs shell commands. | |
| steps: | |
| - name: Check out this repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| # with: the inputs the action takes. | |
| with: | |
| python-version: "3.13" | |
| - name: Install the packages | |
| run: pip install -r requirements-dev.txt | |
| - name: Unit tests (service layer) | |
| run: python -m pytest | |
| - name: Models match the migrations | |
| # env: environment variables for this step only. | |
| env: | |
| DATABASE_URL: sqlite:///ci.db | |
| run: | | |
| alembic upgrade head | |
| alembic check | |
| - name: Build the Docker image | |
| run: docker build -t library-api-fastapi . | |
| conformance: | |
| # needs: wait for the build job to pass first. | |
| needs: build | |
| runs-on: ubuntu-latest | |
| # strategy.matrix: run this job once for each database. | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| database: [sqlite, postgresql] | |
| # services: containers that run next to the job. PostgreSQL 17 is started for | |
| # both rows of the matrix; the SQLite row simply does not use it. | |
| services: | |
| postgres: | |
| image: postgres:17 | |
| env: | |
| POSTGRES_USER: library | |
| POSTGRES_PASSWORD: library | |
| POSTGRES_DB: library | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd "pg_isready -U library -d library" | |
| --health-interval 5s --health-timeout 3s --health-retries 20 | |
| env: | |
| PORT: "8000" | |
| TEST_MODE: "1" | |
| # ${{ }}: an expression, worked out by GitHub before the step runs. | |
| DATABASE_URL: ${{ matrix.database == 'postgresql' && 'postgresql://library:library@localhost:5432/library' || 'sqlite:///library.db' }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Check out the contract | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: devfoundry-training/Library_API_Contract | |
| path: contract | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| - name: Install the packages | |
| run: pip install -r requirements.txt | |
| - name: Start the API | |
| run: | | |
| nohup python -m app > app.log 2>&1 & | |
| for _ in $(seq 1 60); do curl -fs http://localhost:8000/health && break; sleep 1; done | |
| - name: Conformance suite | |
| run: python contract/conformance/run.py --base-url http://localhost:8000 | |
| - name: Server log | |
| # if: failure() runs this step only when an earlier step failed. | |
| if: failure() | |
| run: cat app.log |