diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..855404b --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,41 @@ +name: build/deploy +on: push + +permissions: + contents: read + packages: write + +jobs: + build: + strategy: + matrix: + service: [api] + name: build ${{ matrix.service }} + runs-on: ubuntu-latest + steps: + - name: setup buildx + uses: docker/setup-buildx-action@v3 + - name: prepare build metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }}/${{ matrix.service }} + - name: checkout + uses: actions/checkout@v4 + - name: login to GitHub container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: build and push image + uses: docker/build-push-action@v6 + id: build + with: + file: ${{ matrix.service }}/Dockerfile + context: ${{ matrix.service }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha,scope=image-${{ matrix.service }} + cache-to: type=gha,mode=max,scope=image-${{ matrix.service }} + push: ${{ github.ref == 'refs/heads/main' }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..5730169 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,50 @@ +name: test +on: push + +permissions: + contents: read + packages: write + +env: + DOCKER_BUILDKIT: 1 + COMPOSE_DOCKER_CLI_BUILD: 1 + COMPOSE: docker compose -f compose-test.yaml + +jobs: + api: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v4 + - name: login to GitHub container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Build the images with BUILDKIT_INLINE_CACHE=1, so that we can + # reuse layers in a later step. This works in combination with + # cache_from (in the compose file), thus we do not need to pull here. + - name: build images + run: $COMPOSE build --build-arg BUILDKIT_INLINE_CACHE=1 + - name: push cache + run: $COMPOSE push --ignore-push-failures + + # Run linting steps + - name: flake8 + run: $COMPOSE run --rm --no-deps --entrypoint '' api flake8 + - name: isort + run: $COMPOSE run --rm --no-deps --entrypoint '' api isort --check-only --quiet --settings pyproject.toml . + if: always() + - name: black + run: $COMPOSE run --rm --no-deps --entrypoint '' api black --check . + if: always() + + # Run tests + - name: pytest + run: $COMPOSE run --rm api pytest + + - name: logs + if: always() + run: $COMPOSE logs diff --git a/api/Dockerfile b/api/Dockerfile index 00091b3..a184c52 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -25,6 +25,7 @@ USER app ENV ENVIRONMENT=Development CMD ["uvicorn", "--app-dir", "/app/", "app.server:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] + FROM builder AS test COPY --from=poetry /app/requirements.txt /app/requirements-test.txt /app/requirements-lint.txt /app/ RUN --mount=type=cache,id=test,target=/root/.cache \ diff --git a/compose-test.yaml b/compose-test.yaml new file mode 100644 index 0000000..f19e843 --- /dev/null +++ b/compose-test.yaml @@ -0,0 +1,6 @@ +name: geophotoradar-test +services: + api: + build: + context: api + target: test