Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from dataclass-wizard to mashumaro #389

Merged
merged 9 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions .github/actions/bootstrap/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ inputs:
go-version:
description: "Go version to install"
required: true
default: "1.19.x"
default: "1.21.x"
python-version:
description: "Python version to install"
required: true
default: "3.9"
# note: the caller really drives this in a matrix strategy run for unit tests.
# this default value is used for the rest of the workflow.
default: "3.11"
poetry-version:
description: "Poetry version to install"
required: true
default: "1.3.2"
default: "1.7.0"
use-poetry-cache:
description: "Restore poetry cache"
required: true
Expand All @@ -28,7 +30,7 @@ inputs:
cache-key-prefix:
description: "Prefix all cache keys with this value"
required: true
default: "12a830581c"
default: "8381c12a05"
bootstrap-apt-packages:
description: "Space delimited list of tools to install via apt"
default: ""
Expand All @@ -49,7 +51,7 @@ runs:
- name: Install poetry
shell: bash
run: |
pipx install poetry==${{ inputs.poetry-version }}
python -m pip install poetry==${{ inputs.poetry-version }}
poetry self add "poetry-dynamic-versioning[plugin]"

- name: Cache Poetry virtualenv
Expand Down Expand Up @@ -90,3 +92,10 @@ runs:
- name: Install dependencies and package
shell: bash
run: poetry install

- name: Restore tox cache
id: cache-tox
uses: actions/cache@v3
with:
path: .tox
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-${{ inputs.python-version }}-${{ hashFiles('pyproject.toml') }}-${{ hashFiles('tox.ini') }}
20 changes: 15 additions & 5 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,22 @@ jobs:
git fetch origin main
git merge-base --is-ancestor ${GITHUB_REF##*/} origin/main && echo "${GITHUB_REF##*/} is a commit on main!"

- name: Check validation results
- name: Check static analysis results
uses: fountainhead/action-wait-for-check@297be350cf8393728ea4d4b39435c7d7ae167c93 #v1.1.1
id: validations
id: static-analysis
with:
token: ${{ secrets.GITHUB_TOKEN }}
# This check name is defined as the github action job name (in .github/workflows/validations.yaml)
checkName: "Validations"
checkName: "Static Analysis"
ref: ${{ github.event.pull_request.head.sha || github.sha }}

- name: Check test results
uses: fountainhead/action-wait-for-check@297be350cf8393728ea4d4b39435c7d7ae167c93 #v1.1.1
id: test
with:
token: ${{ secrets.GITHUB_TOKEN }}
# This check name is defined as the github action job name (in .github/workflows/validations.yaml)
checkName: "Test Gate"
ref: ${{ github.event.pull_request.head.sha || github.sha }}

- name: Check nightly quality gate results
Expand All @@ -50,9 +59,10 @@ jobs:
intervalSeconds: 3

- name: Release quality gate
if: steps.validations.conclusion != 'success' || steps.nightly-quality-gate.conclusion != 'success'
if: steps.static-analysis.conclusion != 'success' || steps.test.conclusion != 'success' || steps.nightly-quality-gate.conclusion != 'success'
run: |
echo "Validations Status: ${{ steps.validations.conclusion }}"
echo "Static Analysis Status: ${{ steps.static-analysis.conclusion }}"
echo "Test Status: ${{ steps.test.conclusion }}"
echo "Nightly Quality Gate Status: ${{ steps.nightly-quality-gate.conclusion }}"
false

Expand Down
55 changes: 50 additions & 5 deletions .github/workflows/validations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ on:
jobs:

# note: the name for this check is referenced in release.yaml, do not change here without changing there
Validations:
Static-Analysis:
name: "Static Analysis"
runs-on: ubuntu-22.04
permissions:
contents: read
Expand All @@ -27,19 +28,63 @@ jobs:
- name: Run static analysis
run: poetry run make static-analysis

- name: Run unit tests
run: poetry run make unit

- name: Ensure quality gate tools are properly configured
run: |
cd tests/quality && make validate-test-tool-versions

Test:
runs-on: ubuntu-22.04
permissions:
contents: read
strategy:
matrix:
# note: this is not a single source of truth (this is also in the tox.ini)
python:
- version: '3.9'
toxEnv: py39

- version: '3.10'
toxEnv: py310

- version: '3.11'
toxEnv: py311
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1
with:
# in order to properly resolve the version from git
fetch-depth: 0

- name: Bootstrap environment
uses: ./.github/actions/bootstrap
with:
python-version: ${{ matrix.python.version }}

- name: Run unit tests
run: poetry run tox -e ${{ matrix.python.toxEnv }}

- name: Build assets
run: poetry run make build

# this is to help facilitate ensuring all checks have run with the checks API for release
# see https://github.com/orgs/community/discussions/26822#discussioncomment-3305794
# as well as the release.yaml workflow
Test-Gate:
if: ${{ always() }}
runs-on: ubuntu-22.04
name: Test Gate
needs: [test]
steps:
- run: |
result="${{ needs.Test.result }}"
if [[ $result == "success" || $result == "skipped" ]]; then
exit 0
else
exit 1
fi

Publish-PreProd:
runs-on: ubuntu-22.04
needs: [Validations]
needs: [Static-Analysis, Test]
if: github.ref == 'refs/heads/main'
permissions:
contents: read
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ check-types: virtual-env-check ## Run type checks (mypy)
unit: virtual-env-check ## Run unit tests
pytest --cov-report html --cov vunnel -v tests/unit/

.PHONY: unit-matrix
unit-matrix: virtual-env-check ## Run unit tests for all supported python versions
tox


## Build-related targets #################################

Expand Down
94 changes: 91 additions & 3 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ xxhash = "^3.1.0"
cvss = "^2.6"
python-dateutil = "^2.8.2"
defusedxml = "^0.7.1"
dataclass-wizard = "^0.22.2"
orjson = "^3.8.6"
SQLAlchemy = ">= 1.4.46, < 2.0" # note: 1.4.x currently required for enterprise
mergedeep = "^1.3.4"
future = "^0.18.3"
importlib-metadata = "^6.1.0"
xsdata = {extras = ["cli", "lxml", "soap"], version = ">=22.12,<24.0"}
pytest-snapshot = "^0.9.0"
mashumaro = "^3.10"

[tool.poetry.group.dev.dependencies]
pytest = "^7.2.2"
Expand All @@ -80,6 +80,7 @@ dunamai = "^1.15.0"
ruff = ">=0.0.254,<0.1.5"
yardstick = {git = "https://github.com/anchore/yardstick", rev = "v0.9.1"}
tabulate = "0.9.0"
tox = "^4.11.3"

[build-system]
requires = ["poetry-core>=1.3.0", "poetry-dynamic-versioning"]
Expand Down
2 changes: 2 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pytest]
addopts = -vv --color=yes
13 changes: 5 additions & 8 deletions src/vunnel/cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import mergedeep
import yaml
from dataclass_wizard import asdict, fromdict
from mashumaro.mixins.dict import DataClassDictMixin

from vunnel import providers

Expand Down Expand Up @@ -49,7 +49,7 @@ def __post_init__(self) -> None:


@dataclass
class Application:
class Application(DataClassDictMixin):
root: str = "./data"
log: Log = field(default_factory=Log)
providers: Providers = field(default_factory=Providers)
Expand All @@ -60,18 +60,15 @@ def load(path: str = ".vunnel.yaml") -> Application:
with open(path, encoding="utf-8") as f:
app_object = yaml.safe_load(f.read()) or {}
# we need a full default application config first then merge the loaded config on top.
# Why? dataclass_wizard.fromdict() will create instances from the dataclass default
# Why? cls.from_dict() will create instances from the dataclass default
# and NOT the field definition from the container. So it is possible to specify a
# single field in the config and all other fields would be set to the default value
# based on the dataclass definition and not any field(default_factory=...) hints
# from the containing class.
instance = asdict(Application())
instance = Application().to_dict()

mergedeep.merge(instance, app_object)
cfg = fromdict(
Application,
instance,
)
cfg = Application.from_dict(instance)
if cfg is None:
raise FileNotFoundError("parsed empty config")
except FileNotFoundError:
Expand Down
2 changes: 1 addition & 1 deletion src/vunnel/providers/amazon/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

@dataclass
class Config:
security_advisories: dict[Any, str] = field(default_factory=lambda: amazon_security_advisories)
security_advisories: dict[Any, str] = field(default_factory=lambda: amazon_security_advisories.copy())
runtime: provider.RuntimeConfig = field(
default_factory=lambda: provider.RuntimeConfig(
result_store=result.StoreStrategy.SQLITE,
Expand Down
Loading
Loading