From 9b3b145039215d730ac626f0c25f52443b07ed8b Mon Sep 17 00:00:00 2001 From: Parnassius Date: Sat, 17 Feb 2024 01:50:14 +0100 Subject: [PATCH] CI: run tests inside the container --- .github/workflows/ci-cd.yml | 102 +++++++++++++++++++++ .github/workflows/main.yml | 116 ------------------------ .github/workflows/publish-container.yml | 40 -------- Containerfile | 26 ++++++ 4 files changed, 128 insertions(+), 156 deletions(-) create mode 100644 .github/workflows/ci-cd.yml delete mode 100644 .github/workflows/main.yml delete mode 100644 .github/workflows/publish-container.yml diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml new file mode 100644 index 00000000..cb469589 --- /dev/null +++ b/.github/workflows/ci-cd.yml @@ -0,0 +1,102 @@ +name: ci/cd + +on: + push: + pull_request: + workflow_dispatch: + schedule: + - cron: '0 0 1 * *' # monthly container rebuild + - cron: '0 6 * * 6' # weekly integration tests + +jobs: + test: + if: github.event_name != 'schedule' || github.event.schedule != '0 0 1 * *' + runs-on: ubuntu-latest + outputs: + coverage-percentage: ${{ steps.percentage.outputs.percentage }} + steps: + - uses: actions/checkout@v4 + - name: Lint and test in container + run: podman build --tag tests-${{ github.event.repository.name }}:latest --target test . + - name: Output coverage percentage + id: percentage + run: echo "percentage=$(podman run --rm tests-${{ github.event.repository.name }}:latest json -o - | jq '.totals.percent_covered_display')" >> $GITHUB_OUTPUT + - name: Save coverage report + run: podman run --rm tests-${{ github.event.repository.name }}:latest report --format=markdown >> $GITHUB_STEP_SUMMARY + + integration: + if: secrets.TESTS_BOT_USERNAME != '' && (github.event_name != 'schedule' || github.event.schedule == '0 0 1 * *') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run integration tests + run: podman build --env USERNAME --env PASSWORD --env TESTS_MOD_USERNAME --env TESTS_MOD_PASSWORD --target integration . + env: + USERNAME: ${{ secrets.TESTS_BOT_USERNAME }} + PASSWORD: ${{ secrets.TESTS_BOT_PASSWORD }} + TESTS_MOD_USERNAME: ${{ secrets.TESTS_MOD_USERNAME }} + TESTS_MOD_PASSWORD: ${{ secrets.TESTS_MOD_PASSWORD }} + + coverage-badge: + runs-on: ubuntu-latest + needs: test + if: github.event_name == 'push' && github.ref_name == 'main' + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + with: + ref: "coverage-badge" + - name: Calculate badge color + id: color + run: | + echo "color=$(python3 -Ic 'print( + min( + (percentage, color) + for percentage, color in [ + (100, "brightgreen"), + (90, "green"), + (70, "yellowgreen"), + (50, "yellow"), + (30, "orange"), + (0, "red"), + ] + if percentage >= int(${{ needs.test.outputs.coverage-percentage }}) + )[1] + )')" >> $GITHUB_OUTPUT + - name: Update JSON file + run: | + jq -n \ + --argjson schemaVersion 1 \ + --arg label coverage \ + --arg message ${{ needs.test.outputs.coverage-percentage }}% \ + --arg color ${{ steps.color.outputs.color }} \ + '$ARGS.named' > coverage-badge.json + - name: Create commit + run: | + git config user.name 'prns' + git config user.email '77806190+prnss@users.noreply.github.com' + git commit -am "Update coverage" && git push || true + + publish: + permissions: + contents: read + packages: write + needs: test + if: contains(fromJSON('["push", "workflow_dispatch", "schedule"]'), github.event_name) && github.ref_name == 'main' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Get target image name + id: image + run: echo "image_name=${GITHUB_REPOSITORY,,}" >> $GITHUB_OUTPUT + - name: Build image + run: podman build --tag ${{ steps.image.outputs.image_name }}:latest . + - name: Push to ghcr.io + run: podman push --creds=${{ github.actor }}:${{ github.token }} ${{ steps.image.outputs.image_name }}:latest ghcr.io/${{ steps.image.outputs.image_name }}:latest + - name: Delete old image versions + uses: actions/delete-package-versions@v5 + with: + package-name: ${{ github.event.repository.name }} + package-type: container + min-versions-to-keep: 10 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 9e43e544..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,116 +0,0 @@ -name: main - -on: - push: - pull_request: - schedule: - - cron: '0 6 * * 6' - -jobs: - build: - runs-on: ubuntu-latest - env: - HAS_SECRETS: ${{ secrets.TESTS_BOT_USERNAME != '' }} - outputs: - coverage-percentage: ${{ steps.percentage.outputs.percentage }} - steps: - - uses: actions/checkout@v4 - - name: Install Poetry - run: pipx install poetry - - name: Set up python 3.12 - id: setup-python - uses: actions/setup-python@v5 - with: - python-version: "3.12" - cache: "poetry" - - name: Set up node - uses: actions/setup-node@v4 - - name: Cache veekun database - id: veekun-cache - uses: actions/cache@v4 - with: - path: veekun.sqlite - key: veekun-${{ hashFiles('cerbottana/data/veekun/*.csv', 'cerbottana/databases/veekun.py', 'cerbottana/tasks/veekun.py') }} - - name: Cache pokemon-showdown instance - uses: actions/cache@v4 - with: - path: pokemon-showdown - key: pokemon-showdown-${{ github.run_id }} - restore-keys: | - pokemon-showdown- - - name: Install dependencies on a cache miss - if: steps.setup-python.outputs.cache-hit != 'true' - run: poetry install --sync - - name: Check formatting with black - if: github.event_name != 'schedule' - run: poetry run poe black --check - - name: Check docstrings with darglint - if: github.event_name != 'schedule' - run: poetry run poe darglint - - name: Type check with mypy - if: github.event_name != 'schedule' - run: poetry run poe mypy - - name: Lint with ruff - if: github.event_name != 'schedule' - run: poetry run poe ruff - - name: Test with pytest - if: github.event_name != 'schedule' - run: poetry run poe pytest --cov - - name: Output coverage percentage - if: github.event_name != 'schedule' - id: percentage - run: | - poetry run coverage json - echo "percentage=$(jq '.totals.percent_covered_display' coverage.json)" >> $GITHUB_OUTPUT - - name: Save coverage report - if: github.event_name != 'schedule' - run: poetry run coverage report --format=markdown >> $GITHUB_STEP_SUMMARY - - name: Test with pytest (integration) - if: env.HAS_SECRETS == 'true' - env: - USERNAME: ${{ secrets.TESTS_BOT_USERNAME }} - PASSWORD: ${{ secrets.TESTS_BOT_PASSWORD }} - TESTS_MOD_USERNAME: ${{ secrets.TESTS_MOD_USERNAME }} - TESTS_MOD_PASSWORD: ${{ secrets.TESTS_MOD_PASSWORD }} - run: poetry run poe pytest-real-ps-instance - - coverage-badge: - runs-on: ubuntu-latest - needs: build - if: github.event_name == 'push' && github.ref_name == 'main' - permissions: - contents: write - steps: - - uses: actions/checkout@v4 - with: - ref: "coverage-badge" - - name: Calculate badge color - id: color - run: | - echo "color=$(python3 -Ic 'print( - min( - (percentage, color) - for percentage, color in [ - (100, "brightgreen"), - (90, "green"), - (70, "yellowgreen"), - (50, "yellow"), - (30, "orange"), - (0, "red"), - ] - if percentage >= int(${{ needs.build.outputs.coverage-percentage }}) - )[1] - )')" >> $GITHUB_OUTPUT - - name: Update JSON file - run: | - jq -n \ - --argjson schemaVersion 1 \ - --arg label coverage \ - --arg message ${{ needs.build.outputs.coverage-percentage }}% \ - --arg color ${{ steps.color.outputs.color }} \ - '$ARGS.named' > coverage-badge.json - - name: Create commit - run: | - git config user.name 'prns' - git config user.email '77806190+prnss@users.noreply.github.com' - git commit -am "Update coverage" && git push || true diff --git a/.github/workflows/publish-container.yml b/.github/workflows/publish-container.yml deleted file mode 100644 index 47faf4b8..00000000 --- a/.github/workflows/publish-container.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: publish-container - -on: - push: - branches: - - main - workflow_dispatch: - schedule: - - cron: '0 0 1 * *' - -permissions: - contents: read - packages: write - -jobs: - publish-container: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Build image - id: build-image - uses: redhat-actions/buildah-build@v2 - with: - image: ${{ github.repository }} - tags: latest - containerfiles: Containerfile - - name: Push to ghcr.io - uses: redhat-actions/push-to-registry@v2 - with: - image: ${{ steps.build-image.outputs.image }} - tags: ${{ steps.build-image.outputs.tags }} - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ github.token }} - - name: Delete old image versions - uses: actions/delete-package-versions@v5 - with: - package-name: ${{ github.event.repository.name }} - package-type: container - min-versions-to-keep: 10 diff --git a/Containerfile b/Containerfile index 59fd3cf9..93d24fe0 100644 --- a/Containerfile +++ b/Containerfile @@ -22,6 +22,32 @@ RUN /opt/poetry-venv/bin/poetry build --no-interaction --format wheel RUN .venv/bin/pip install ./dist/*.whl +FROM builder as test-base + +RUN apk add --no-cache gcc musl-dev linux-headers +RUN mkdir /data + +RUN /opt/poetry-venv/bin/poetry install --no-interaction --no-root + + +FROM test-base as test + +RUN /opt/poetry-venv/bin/poetry run poe black --check +RUN /opt/poetry-venv/bin/poetry run poe darglint +RUN /opt/poetry-venv/bin/poetry run poe mypy +RUN /opt/poetry-venv/bin/poetry run poe ruff +RUN /opt/poetry-venv/bin/poetry run poe pytest --cov + +ENTRYPOINT [ "/opt/poetry-venv/bin/poetry", "run", "coverage" ] + + +FROM test-base as integration + +RUN apk add --no-cache git nodejs npm + +RUN /opt/poetry-venv/bin/poetry run poe pytest-real-ps-instance + + FROM base as final ENV PATH="/app/.venv/bin:$PATH"