diff --git a/.ansible-lint b/.ansible-lint index 0e80b05b..4ffc0efa 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -1,10 +1,9 @@ --- -# See https://ansible-lint.readthedocs.io/en/latest/configuring.html -# for a list of the configuration elements that can exist in this -# file. +# See https://ansible-lint.readthedocs.io/configuring/ for a list of +# the configuration elements that can exist in this file. enable_list: # Useful checks that one must opt-into. See here for more details: - # https://ansible-lint.readthedocs.io/en/latest/rules.html + # https://ansible-lint.readthedocs.io/rules/ - fcqn-builtins - no-log-password - no-same-owner diff --git a/.bandit.yml b/.bandit.yml index 2b618f68..663c521c 100644 --- a/.bandit.yml +++ b/.bandit.yml @@ -3,7 +3,7 @@ # https://bandit.readthedocs.io/en/latest/config.html # Tests are first included by `tests`, and then excluded by `skips`. -# If `tests` is empty, all tests are are considered included. +# If `tests` is empty, all tests are considered included. tests: # - B101 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9c27ee6b..c75d38aa 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -3,8 +3,12 @@ # These owners will be the default owners for everything in the # repo. Unless a later match takes precedence, these owners will be # requested for review when someone opens a pull request. +<<<<<<< HEAD * @dav3r @dylanj1752 @felddy @INLGuy @itsmostafa @izzy64 @jsf9k @mcdonnnj +======= +* @dav3r @felddy @jasonodoom @jsf9k @mcdonnnj +>>>>>>> 2a163268d67444967761adf1d4eccabbde102bc4 # These folks own any files in the .github directory at the root of # the repository and any of its subdirectories. -/.github/ @dav3r @felddy @jsf9k @mcdonnnj +/.github/ @dav3r @felddy @jasonodoom @jsf9k @mcdonnnj diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d7b0166d..a6e13849 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,26 +4,27 @@ # these updates when the pull request(s) in the appropriate skeleton are merged # and Lineage processes these changes. -version: 2 updates: - - package-ecosystem: "docker" - directory: "/" + - directory: / + package-ecosystem: docker schedule: - interval: "weekly" + interval: weekly - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" + - directory: / ignore: # Managed by cisagov/skeleton-generic - dependency-name: actions/cache - dependency-name: actions/checkout - dependency-name: actions/setup-go - dependency-name: actions/setup-python + - dependency-name: crazy-max/ghaction-dump-context + - dependency-name: crazy-max/ghaction-github-labeler + - dependency-name: crazy-max/ghaction-github-status - dependency-name: hashicorp/setup-terraform - dependency-name: mxschmitt/action-tmate + - dependency-name: step-security/harden-runner # Managed by cisagov/skeleton-docker +<<<<<<< HEAD - dependency-name: actions/download-artifact - dependency-name: actions/github-script - dependency-name: actions/upload-artifact @@ -35,10 +36,27 @@ updates: - package-ecosystem: "pip" directory: "/" +======= + # - dependency-name: actions/download-artifact + # - dependency-name: actions/github-script + # - dependency-name: actions/upload-artifact + # - dependency-name: docker/build-push-action + # - dependency-name: docker/login-action + # - dependency-name: docker/setup-buildx-action + # - dependency-name: docker/setup-qemu-action + # - dependency-name: github/codeql-action + package-ecosystem: github-actions +>>>>>>> 1ea8a3fa98e790d66f8d5e10375f73c5be4d5fd5 schedule: - interval: "weekly" + interval: weekly - - package-ecosystem: "terraform" - directory: "/" + - directory: / + package-ecosystem: pip + schedule: + interval: weekly + + - directory: / + package-ecosystem: terraform schedule: - interval: "weekly" + interval: weekly +version: 2 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 466b71b2..bca960c0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,25 +47,52 @@ env: RUN_TMATE: ${{ secrets.RUN_TMATE }} jobs: + diagnostics: + name: Run diagnostics + runs-on: ubuntu-latest + steps: + # Note that a duplicate of this step must be added at the top of + # each job. + - id: harden-runner + name: Harden the runner + uses: step-security/harden-runner@v2 + with: + egress-policy: audit + - id: github-status + name: Check GitHub status + uses: crazy-max/ghaction-github-status@v3 + - id: dump-context + name: Dump context + uses: crazy-max/ghaction-dump-context@v2 lint: # Checks out the source and runs pre-commit hooks. Detects coding errors # and style deviations. - name: "Lint sources" + name: Lint sources + needs: + - diagnostics runs-on: ubuntu-latest steps: + - id: harden-runner + name: Harden the runner + uses: step-security/harden-runner@v2 + with: + egress-policy: audit - id: setup-env uses: cisagov/setup-env-github-action@develop - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - id: setup-python uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" # We need the Go version and Go cache location for the actions/cache step, # so the Go installation must happen before that. - id: setup-go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: "1.19" + # There is no expectation for actual Go code so we disable caching as + # it relies on the existence of a go.sum file. + cache: false + go-version: "1.20" - name: Lookup Go cache directory id: go-cache run: | @@ -113,11 +140,26 @@ jobs: - uses: hashicorp/setup-terraform@v2 with: terraform_version: ${{ steps.setup-env.outputs.terraform-version }} + - name: Install go-critic + env: + PACKAGE_URL: github.com/go-critic/go-critic/cmd/gocritic + PACKAGE_VERSION: ${{ steps.setup-env.outputs.go-critic-version }} + run: go install ${PACKAGE_URL}@${PACKAGE_VERSION} + - name: Install gosec + env: + PACKAGE_URL: github.com/securego/gosec/v2/cmd/gosec + PACKAGE_VERSION: ${{ steps.setup-env.outputs.gosec-version }} + run: go install ${PACKAGE_URL}@${PACKAGE_VERSION} - name: Install shfmt env: PACKAGE_URL: mvdan.cc/sh/v3/cmd/shfmt PACKAGE_VERSION: ${{ steps.setup-env.outputs.shfmt-version }} run: go install ${PACKAGE_URL}@${PACKAGE_VERSION} + - name: Install staticcheck + env: + PACKAGE_URL: honnef.co/go/tools/cmd/staticcheck + PACKAGE_VERSION: ${{ steps.setup-env.outputs.staticcheck-version }} + run: go install ${PACKAGE_URL}@${PACKAGE_VERSION} - name: Install Terraform-docs env: PACKAGE_URL: github.com/terraform-docs/terraform-docs @@ -129,7 +171,7 @@ jobs: run: cp etc/env.dist .env - name: Install dependencies run: | - python -m pip install --upgrade pip + python -m pip install --upgrade pip setuptools wheel pip install --upgrade --requirement requirements-test.txt - name: Set up pre-commit hook environments run: pre-commit install-hooks @@ -179,18 +221,25 @@ jobs: # with the value specified by the user. # # Scheduled builds are tagged with `:nightly`. - name: "Prepare build variables" - runs-on: ubuntu-latest + name: Prepare build variables + needs: + - diagnostics outputs: created: ${{ steps.prep.outputs.created }} repometa: ${{ steps.repo.outputs.result }} source_version: ${{ steps.prep.outputs.source_version }} tags: ${{ steps.prep.outputs.tags }} + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - id: harden-runner + name: Harden the runner + uses: step-security/harden-runner@v2 + with: + egress-policy: audit + - uses: actions/checkout@v4 - name: Gather repository metadata id: repo - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | const repo = await github.rest.repos.get(context.repo) @@ -241,16 +290,23 @@ jobs: build: # Builds a single test image for the native platform. This image is saved # as an artifact and loaded by the test job. - name: "Build test image" + name: Build test image + needs: + - diagnostics + - prepare runs-on: ubuntu-latest - needs: [prepare] steps: + - id: harden-runner + name: Harden the runner + uses: step-security/harden-runner@v2 + with: + egress-policy: audit - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Cache Docker layers uses: actions/cache@v3 env: @@ -264,7 +320,7 @@ jobs: run: mkdir -p dist - name: Build image id: docker_build - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: build-args: | VERSION=${{ needs.prepare.outputs.source_version }} @@ -273,8 +329,17 @@ jobs: context: . file: ./Dockerfile outputs: type=docker,dest=dist/image.tar +<<<<<<< HEAD # not to be pushed tags: ${{ env.IMAGE_NAME }}:latest +======= + # Uncomment the following option if you are building an image for use + # on Google Cloud Run or AWS Lambda. The current default image output + # is unable to run on either. Please see the following issue for more + # information: https://github.com/docker/buildx/issues/1533 + # provenance: false + tags: ${{ env.IMAGE_NAME }}:latest # not to be pushed +>>>>>>> 7e820ba36e8030eb16ed0ea94df5047c9dfbaf52 # For a list of pre-defined annotation keys and value types see: # https://github.com/opencontainers/image-spec/blob/master/annotations.md labels: "\ @@ -312,15 +377,22 @@ jobs: if: env.RUN_TMATE test: # Executes tests on the single-platform image created in the "build" job. - name: "Test image" + name: Test image + needs: + - diagnostics + - build runs-on: ubuntu-latest - needs: [build] steps: - - uses: actions/checkout@v3 + - id: harden-runner + name: Harden the runner + uses: step-security/harden-runner@v2 + with: + egress-policy: audit + - uses: actions/checkout@v4 - id: setup-python uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" - name: Cache testing environments uses: actions/cache@v3 env: @@ -339,7 +411,7 @@ jobs: run: cp etc/env.dist .env - name: Install dependencies run: | - python -m pip install --upgrade pip + python -m pip install --upgrade pip setuptools wheel pip install --upgrade --requirement requirements-test.txt - name: Download docker image artifact uses: actions/download-artifact@v3 @@ -362,32 +434,41 @@ jobs: # GitHub Container Registry. The contents of README.md are pushed as the # image's description to Docker Hub. This job is skipped when the # triggering event is a pull request. - name: "Build and push all platforms" - runs-on: ubuntu-latest - needs: [lint, prepare, test] if: github.event_name != 'pull_request' + name: Build and push all platforms + needs: + - diagnostics + - lint + - prepare + - test # When Dependabot creates a PR it requires this permission in # order to push Docker images to ghcr.io. permissions: packages: write + runs-on: ubuntu-latest steps: + - id: harden-runner + name: Harden the runner + uses: step-security/harden-runner@v2 + with: + egress-policy: audit - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Login to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Cache Docker layers uses: actions/cache@v3 env: @@ -401,7 +482,7 @@ jobs: run: ./buildx-dockerfile.sh - name: Build and push platform images to registries id: docker_build - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: build-args: | VERSION=${{ needs.prepare.outputs.source_version }} @@ -410,6 +491,11 @@ jobs: context: . file: ./Dockerfile-x platforms: ${{ env.PLATFORMS }} + # Uncomment the following option if you are building an image for use + # on Google Cloud Run or AWS Lambda. The current default image output + # is unable to run on either. Please see the following issue for more + # information: https://github.com/docker/buildx/issues/1533 + # provenance: false push: true tags: ${{ needs.prepare.outputs.tags }} # For a list of pre-defined annotation keys and value types see: diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index bf0d1489..dc492711 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -4,7 +4,7 @@ # # You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic. -name: "CodeQL" +name: CodeQL on: push: @@ -20,8 +20,27 @@ on: - cron: '0 21 * * 6' jobs: + diagnostics: + name: Run diagnostics + runs-on: ubuntu-latest + steps: + # Note that a duplicate of this step must be added at the top of + # each job. + - id: harden-runner + name: Harden the runner + uses: step-security/harden-runner@v2 + with: + egress-policy: audit + - id: github-status + name: Check GitHub status + uses: crazy-max/ghaction-github-status@v3 + - id: dump-context + name: Dump context + uses: crazy-max/ghaction-dump-context@v2 analyze: name: Analyze + needs: + - diagnostics runs-on: ubuntu-latest permissions: # required for all workflows @@ -37,8 +56,14 @@ jobs: # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection steps: + - id: harden-runner + name: Harden the runner + uses: step-security/harden-runner@v2 + with: + egress-policy: audit + - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index ae7c091b..44e8e198 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -19,10 +19,10 @@ jobs: issues: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Sync repository labels if: success() - uses: crazy-max/ghaction-github-labeler@v4 + uses: crazy-max/ghaction-github-labeler@v5 with: # This is a hideous ternary equivalent so we only do a dry run unless # this workflow is triggered by the develop branch. diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ee61d395..15267c3d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,17 +31,17 @@ repos: # Text file hooks - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.33.0 + rev: v0.36.0 hooks: - id: markdownlint args: - --config=.mdl_config.yaml - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0-alpha.4 + rev: v3.0.3 hooks: - id: prettier - repo: https://github.com/adrienverge/yamllint - rev: v1.29.0 + rev: v1.32.0 hooks: - id: yamllint args: @@ -49,17 +49,42 @@ repos: # GitHub Actions hooks - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.21.0 + rev: 0.26.3 hooks: - id: check-github-actions - id: check-github-workflows # pre-commit hooks - repo: https://github.com/pre-commit/pre-commit - rev: v3.0.2 + rev: v3.4.0 hooks: - id: validate_manifest + # Go hooks + - repo: https://github.com/TekWizely/pre-commit-golang + rev: v1.0.0-rc.1 + hooks: + # Style Checkers + - id: go-critic + # StaticCheck + - id: go-staticcheck-repo-mod + # Go Build + - id: go-build-repo-mod + # Go Mod Tidy + - id: go-mod-tidy-repo + # Go Test + - id: go-test-repo-mod + # Go Vet + - id: go-vet-repo-mod + # GoSec + - id: go-sec-repo-mod + + # Nix hooks + - repo: https://github.com/nix-community/nixpkgs-fmt + rev: v1.3.0 + hooks: + - id: nixpkgs-fmt + # Shell script hooks - repo: https://github.com/cisagov/pre-commit-shfmt rev: v0.0.2 @@ -83,7 +108,7 @@ repos: # Python hooks # Run bandit on the "tests" tree with a configuration - repo: https://github.com/PyCQA/bandit - rev: 1.7.4 + rev: 1.7.5 hooks: - id: bandit name: bandit (tests tree) @@ -92,17 +117,17 @@ repos: - --config=.bandit.yml # Run bandit on everything except the "tests" tree - repo: https://github.com/PyCQA/bandit - rev: 1.7.4 + rev: 1.7.5 hooks: - id: bandit name: bandit (everything else) exclude: tests - - repo: https://github.com/psf/black - rev: 22.12.0 + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 23.9.1 hooks: - id: black - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 additional_dependencies: @@ -112,31 +137,31 @@ repos: hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.991 + rev: v1.5.1 hooks: - id: mypy - repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 + rev: v3.10.1 hooks: - id: pyupgrade # Ansible hooks - - repo: https://github.com/ansible-community/ansible-lint - rev: v5.4.0 + - repo: https://github.com/ansible/ansible-lint + rev: v6.19.0 hooks: - id: ansible-lint # files: molecule/default/playbook.yml # Terraform hooks - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.77.0 + rev: v1.83.2 hooks: - id: terraform_fmt - id: terraform_validate # Docker hooks - repo: https://github.com/IamTheFij/docker-pre-commit - rev: v2.1.1 + rev: v3.0.1 hooks: - id: docker-compose-check diff --git a/Dockerfile b/Dockerfile index 82903633..19a0f55c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,16 @@ FROM golang:1.18.4-alpine AS build +<<<<<<< HEAD +<<<<<<< HEAD WORKDIR /src/ COPY /src/staticgen/ /src/ RUN CGO_ENABLED=0 GOOS=linux go build -o /bin/main +======= +FROM python:3.11.4-alpine +>>>>>>> 8c26a61517f4254b82bb73a78544145c62828a89 +======= +FROM python:3.12.0-alpine +>>>>>>> 1ea8a3fa98e790d66f8d5e10375f73c5be4d5fd5 FROM python:3.10.7 diff --git a/bump_version.sh b/bump_version.sh index eae91315..c65625e9 100755 --- a/bump_version.sh +++ b/bump_version.sh @@ -1,6 +1,12 @@ #!/usr/bin/env bash -# bump_version.sh (show|major|minor|patch|prerelease|build) +# Usage: +# bump_version.sh (show|major|minor|patch|finalize) +# bump_version.sh (build|prerelease) [token] +# Notes: +# - If you specify a token it will only be used if the current version is +# tokenless or if the provided token matches the token used in the current +# version. set -o nounset set -o errexit @@ -9,19 +15,46 @@ set -o pipefail VERSION_FILE=src/api/_version.py README_FILE=README.md -HELP_INFORMATION="bump_version.sh (show|major|minor|patch|prerelease|build|finalize)" +function usage { + cat << HELP +Usage: + ${0##*/} (show|major|minor|patch|finalize) + ${0##*/} (build|prerelease) [token] -old_version=$(sed -n "s/^__version__ = \"\(.*\)\"$/\1/p" $VERSION_FILE) -# Comment out periods so they are interpreted as periods and don't -# just match any character -old_version_regex=${old_version//\./\\\.} +Notes: + - If you specify a token it will only be used if the current version is + tokenless or if the provided token matches the token used in the current + version. +HELP + exit 1 +} -if [ $# -ne 1 ]; then - echo "$HELP_INFORMATION" +function update_version { + # Comment out periods so they are interpreted as periods and don't + # just match any character + old_version_regex=${1//\./\\\.} + + echo Changing version from "$1" to "$2" + tmp_file=/tmp/version.$$ + sed "s/$old_version_regex/$2/" $VERSION_FILE > $tmp_file + mv $tmp_file $VERSION_FILE + sed "s/$old_version_regex/$2/" $README_FILE > $tmp_file + mv $tmp_file $README_FILE + git add $VERSION_FILE $README_FILE + git commit --message "$3" +} + +if [ $# -lt 1 ] || [ $# -gt 2 ]; then + usage else + old_version=$(sed -n "s/^__version__ = \"\(.*\)\"$/\1/p" $VERSION_FILE) case $1 in - major | minor | patch | prerelease | build) + major | minor | patch) + if [ $# -ne 1 ]; then + usage + fi new_version=$(python -c "import semver; print(semver.bump_$1('$old_version'))") +<<<<<<< HEAD echo Changing version from "$old_version" to "$new_version" # A temp file is used to provide compatability with macOS development # as a result of macOS using the BSD version of sed @@ -33,9 +66,24 @@ else git add $VERSION_FILE $README_FILE git commit -m"Bump version from $old_version to $new_version" git push +======= + update_version "$old_version" "$new_version" "Bump version from $old_version to $new_version" + ;; + build | prerelease) + if [ $# -eq 2 ]; then + new_version=$(python -c "import semver; print(semver.bump_$1('$old_version', token='$2'))") + else + new_version=$(python -c "import semver; print(semver.bump_$1('$old_version'))") + fi + update_version "$old_version" "$new_version" "Bump version from $old_version to $new_version" +>>>>>>> 1ea8a3fa98e790d66f8d5e10375f73c5be4d5fd5 ;; finalize) + if [ $# -ne 1 ]; then + usage + fi new_version=$(python -c "import semver; print(semver.finalize_version('$old_version'))") +<<<<<<< HEAD echo Changing version from "$old_version" to "$new_version" # A temp file is used to provide compatability with macOS development # as a result of macOS using the BSD version of sed @@ -47,12 +95,15 @@ else git add $VERSION_FILE $README_FILE git commit -m"Finalize version from $old_version to $new_version" git push +======= + update_version "$old_version" "$new_version" "Finalize version from $old_version to $new_version" +>>>>>>> 1ea8a3fa98e790d66f8d5e10375f73c5be4d5fd5 ;; show) echo "$old_version" ;; *) - echo "$HELP_INFORMATION" + usage ;; esac fi diff --git a/requirements-test.txt b/requirements-test.txt index b31517bc..b531cb89 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -5,9 +5,13 @@ flake8 moto pre-commit pytest +<<<<<<< HEAD pytest-cov pytest-dockerc pytest-dotenv pytest-env pytest-mock pytest-pythonpath +======= +python-on-whales +>>>>>>> a9d6c92ea3ca2760e4a18276d06c668058dd3670 diff --git a/setup-env b/setup-env index f526cdb3..77926bf8 100644 --- a/setup-env +++ b/setup-env @@ -65,7 +65,7 @@ done eval set -- "$PARAMS" # Check to see if pyenv is installed -if [ -z "$(command -v pyenv)" ] || [ -z "$(command -v pyenv-virtualenv)" ]; then +if [ -z "$(command -v pyenv)" ] || { [ -z "$(command -v pyenv-virtualenv)" ] && [ ! -f "$(pyenv root)/plugins/pyenv-virtualenv/bin/pyenv-virtualenv" ]; }; then echo "pyenv and pyenv-virtualenv are required." if [[ "$OSTYPE" == "darwin"* ]]; then cat << 'END_OF_LINE' @@ -186,5 +186,5 @@ else: END_OF_LINE )" -# Qapla +# Qapla' echo "Success!" diff --git a/tests/conftest.py b/tests/conftest.py index 0c2facd7..36ca5939 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,6 +5,7 @@ """ # Third-Party Libraries import pytest +from python_on_whales import docker # cisagov Libraries from api.main import app @@ -26,13 +27,34 @@ def client(): ctx.pop() +@pytest.fixture(scope="session") +def dockerc(): + """Start up the Docker composition.""" + docker.compose.up(detach=True) + yield docker + docker.compose.down() + + @pytest.fixture(scope="session") def main_container(dockerc): """Return the main container from the docker composition.""" # find the container by name even if it is stopped already - return dockerc.containers(service_names=[MAIN_SERVICE_NAME], stopped=True)[0] + return dockerc.compose.ps(services=[MAIN_SERVICE_NAME], all=True)[0] + + +<<<<<<< HEAD +======= +@pytest.fixture(scope="session") +def version_container(dockerc): + """Return the version container from the Docker composition. + + The version container should just output the version of its underlying contents. + """ + # find the container by name even if it is stopped already + return dockerc.compose.ps(services=[VERSION_SERVICE_NAME], all=True)[0] +>>>>>>> a9d6c92ea3ca2760e4a18276d06c668058dd3670 def pytest_addoption(parser): """Add new commandline options to pytest.""" parser.addoption( diff --git a/tests/container_test.py b/tests/container_test.py index c37721b1..65796a67 100644 --- a/tests/container_test.py +++ b/tests/container_test.py @@ -11,10 +11,19 @@ def test_container_count(dockerc): +<<<<<<< HEAD """Verify the correct number of containers is started.""" # stopped parameter allows non-running containers in results +======= + """Verify the test composition and container.""" + # all parameter allows non-running containers in results +>>>>>>> 1ea8a3fa98e790d66f8d5e10375f73c5be4d5fd5 assert ( +<<<<<<< HEAD len(dockerc.containers(stopped=True)) == 1 +======= + len(dockerc.compose.ps(all=True)) == 2 +>>>>>>> a9d6c92ea3ca2760e4a18276d06c668058dd3670 ), "Wrong number of containers were started." @@ -22,7 +31,7 @@ def test_wait_for_ready(main_container): """Wait for container to be ready.""" TIMEOUT = 10 for i in range(TIMEOUT): - if READY_MESSAGE in main_container.logs().decode("utf-8"): + if READY_MESSAGE in main_container.logs(): break time.sleep(1) else: @@ -38,7 +47,66 @@ def test_wait_for_ready(main_container): assert main_container.is_restarting is False assert main_container.exit_code == 0 +<<<<<<< HEAD # Make a request against the base url on the container resp = requests.get("http://localhost:5000") assert resp.status_code == 200 assert "Live and healthy" in resp.text +======= +def test_wait_for_exits(dockerc, main_container, version_container): + """Wait for containers to exit.""" + assert ( + dockerc.wait(main_container.id) == 0 + ), "Container service (main) did not exit cleanly" + assert ( + dockerc.wait(version_container.id) == 0 + ), "Container service (version) did not exit cleanly" + + +def test_output(dockerc, main_container): + """Verify the container had the correct output.""" + # make sure container exited if running test isolated + dockerc.wait(main_container.id) + log_output = main_container.logs() + assert SECRET_QUOTE in log_output, "Secret not found in log output." + + +@pytest.mark.skipif( + RELEASE_TAG in [None, ""], reason="this is not a release (RELEASE_TAG not set)" +) +def test_release_version(): + """Verify that release tag version agrees with the module version.""" + pkg_vars = {} + with open(VERSION_FILE) as f: + exec(f.read(), pkg_vars) # nosec + project_version = pkg_vars["__version__"] + assert ( + RELEASE_TAG == f"v{project_version}" + ), "RELEASE_TAG does not match the project version" + + +def test_log_version(dockerc, version_container): + """Verify the container outputs the correct version to the logs.""" + # make sure container exited if running test isolated + dockerc.wait(version_container.id) + log_output = version_container.logs().strip() + pkg_vars = {} + with open(VERSION_FILE) as f: + exec(f.read(), pkg_vars) # nosec + project_version = pkg_vars["__version__"] + assert ( + log_output == project_version + ), f"Container version output to log does not match project version file {VERSION_FILE}" + + +def test_container_version_label_matches(version_container): + """Verify the container version label is the correct version.""" + pkg_vars = {} + with open(VERSION_FILE) as f: + exec(f.read(), pkg_vars) # nosec + project_version = pkg_vars["__version__"] + assert ( + version_container.config.labels["org.opencontainers.image.version"] + == project_version + ), "Dockerfile version label does not match project version" +>>>>>>> a9d6c92ea3ca2760e4a18276d06c668058dd3670