diff --git a/adbc_drivers_dev/generate.py b/adbc_drivers_dev/generate.py index e49e1e5..08e2b34 100644 --- a/adbc_drivers_dev/generate.py +++ b/adbc_drivers_dev/generate.py @@ -17,8 +17,13 @@ from pydantic import BaseModel, Field, PrivateAttr, field_validator, model_validator # Define workflow contexts in a single location -WorkflowContext = typing.Literal["build:release", "test", "validate"] -WORKFLOW_CONTEXTS: tuple[WorkflowContext, ...] = ("build:release", "test", "validate") +WorkflowContext = typing.Literal["build:test", "build:release", "test", "validate"] +WORKFLOW_CONTEXTS: tuple[WorkflowContext, ...] = ( + "build:test", + "build:release", + "test", + "validate", +) class SecretConfigDict(BaseModel): @@ -45,6 +50,46 @@ class AwsConfig(BaseModel): ) +class LangBuildConfig(BaseModel): + # validate_by_{name,alias} are to let us map "additional-make-args" to "additional_make_args" + model_config = { + "extra": "forbid", + "validate_by_name": True, + "validate_by_alias": True, + } + + additional_make_args: list[str] = Field( + default_factory=list, + alias="additional-make-args", + description="A list of additional arguments to pass to adbc-make.", + ) + + +class LangConfig(BaseModel): + model_config = { + "extra": "forbid", + "validate_by_name": True, + "validate_by_alias": True, + } + + build: LangBuildConfig = Field( + default_factory=LangBuildConfig, + description="Configuration for building the driver.", + ) + skip_validate: bool = Field( + default=False, + alias="skip-validate", + description="Whether to skip the validation suite in CI (this should only be used temporarily while setting up a driver)", + ) + + @model_validator(mode="before") + @classmethod + def true_is_enabled(cls, data: typing.Any) -> typing.Any: + if isinstance(data, bool): + return {} + return data + + class ValidationConfig(BaseModel): """Configuration for validation workflows.""" @@ -92,14 +137,16 @@ class GenerateConfig(BaseModel): default=False, description="Whether the driver is private. Most drivers will be not be private so you can omit this.", ) - lang: dict[str, bool] = Field( + lang: dict[str, LangConfig | None] = Field( default_factory=dict, json_schema_extra={ - "description": """Programming language(s) to enable workflows for. Only go is really supported right now. Keys should be lowercase. Set to true to enable, false to disable. Example: + "description": """Programming language(s) to enable workflows for. Only go and rust are supported. Keys should be lowercase. Set to true to enable with default config, or false (the default) to disable. Example: [lang] go = true -python = false""" + +[lang.rust.build] +additional-make-args = ["example"]""" }, ) secrets: dict[str, str | SecretConfigDict] = Field( @@ -155,6 +202,15 @@ def validate_environment(cls, v: str | None) -> str | None: raise ValueError("environment must be non-empty if provided") return v + @field_validator("lang", mode="before") + @classmethod + def lang_boolean(cls, value: typing.Any) -> typing.Any: + value = value or {} + return { + k: LangConfig() if v is True else None if v is False else v + for k, v in value.items() + } + @model_validator(mode="after") def process_secrets_and_permissions(self) -> "GenerateConfig": """Process secrets configuration and set up permissions.""" diff --git a/adbc_drivers_dev/templates/dev.yaml b/adbc_drivers_dev/templates/dev.yaml index 5901eda..bb2d94d 100644 --- a/adbc_drivers_dev/templates/dev.yaml +++ b/adbc_drivers_dev/templates/dev.yaml @@ -57,7 +57,7 @@ jobs: go-version-file: go/go.mod <% endif %> - - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" diff --git a/adbc_drivers_dev/templates/dev_daily.yaml b/adbc_drivers_dev/templates/dev_daily.yaml index 5296541..bea77d3 100644 --- a/adbc_drivers_dev/templates/dev_daily.yaml +++ b/adbc_drivers_dev/templates/dev_daily.yaml @@ -43,13 +43,13 @@ jobs: pull-requests: write steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 1 persist-credentials: true # for git operations below - name: Install uv - uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # 7.2.0. + uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0 - name: Re-generate workflows run: | diff --git a/adbc_drivers_dev/templates/test.yaml b/adbc_drivers_dev/templates/test.yaml index a45b04a..f16b27a 100644 --- a/adbc_drivers_dev/templates/test.yaml +++ b/adbc_drivers_dev/templates/test.yaml @@ -19,14 +19,14 @@ # !!!! AUTO-GENERATED FILE. DO NOT EDIT. !!!! # USE adbc-gen-workflow (see adbc-drivers/dev) TO UPDATE THIS FILE. -# This is a common workflow for building & testing Go drivers: +# This is a common workflow for building & testing drivers: # # - Build the driver # - Start dependencies # - Run tests # - Build the shared library -name: Go <{workflow_name}> +name: <{lang_human}> <{workflow_name}> on: pull_request: @@ -34,7 +34,7 @@ on: - main paths: <% if not release %> - - "go/**" + - "<{lang_subdir}>/**" <% endif %> <% for path in pull_request_trigger_paths %> - <{path}> @@ -43,12 +43,12 @@ on: push: <% if release %> tags: - - "go/v**" + - "<{lang_subdir}>/v**" <% else %> branches: - main paths: - - "go/**" + - "<{lang_subdir}>/**" <% for path in pull_request_trigger_paths %> - <{path}> <% endfor %> @@ -94,7 +94,7 @@ jobs: include: - { platform: linux, arch: amd64, runner: ubuntu-latest } - { platform: macos, arch: arm64, runner: macos-latest } - - { platform: win, arch: amd64, runner: windows-latest } + - { platform: windows, arch: amd64, runner: windows-latest } <% if environment %> environment: <{environment}> <% endif %> @@ -133,15 +133,21 @@ jobs: persist-credentials: false <% endif %> +<% if lang == "go" %> - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: cache-dependency-path: go/go.sum check-latest: true go-version-file: go/go.mod +<% elif lang == "rust" %> + - uses: actions-rust-lang/setup-rust-toolchain@1780873c7b576612439a134613cc4cc74ce5538c # v1.15.2 + with: + components: "clippy" +<% endif %> - uses: prefix-dev/setup-pixi@82d477f15f3a381dbcc8adc1206ce643fe110fb7 # v0.9.3 with: - pixi-version: v0.50.2 + pixi-version: v0.63.2 run-install: false <% if aws %> @@ -161,15 +167,32 @@ jobs: <% endif %> - name: Build - working-directory: go +<% if secrets["build:test"] %> + env: +<% for name, val in secrets["build:test"].items() %> + <{name}>: ${{ secrets.<{val}> }} +<% endfor %> +<% endif %> + working-directory: <{ lang_subdir }> run: | + if [[ -f ci/scripts/pre-build.sh ]]; then + echo "Loading pre-build" + ./ci/scripts/pre-build.sh test ${{ matrix.platform }} ${{ matrix.arch }} + fi + +<% if lang == "go" %> go build ./... +<% elif lang == "rust" %> + cargo build --locked +<% else %> +<{not_implemented(lang)}> +<% endif %> - name: Start Test Dependencies # Can't use Docker on macOS AArch64 runners, and Windows containers # work but often the container doesn't support Windows if: runner.os == 'Linux' - working-directory: go + working-directory: <{ lang_subdir }> run: | if [[ -f compose.yaml ]]; then if ! docker compose up --detach --wait test-service; then @@ -181,19 +204,21 @@ jobs: fi - name: Test - if: runner.os == 'Linux' <% if secrets["test"] %> env: <% for name, val in secrets["test"].items() %> <{name}>: ${{ secrets.<{val}> }} <% endfor %> <% endif %> - working-directory: go + working-directory: <{ lang_subdir }> run: | set -a if [[ -f .env ]]; then source .env fi + if [[ -f .env.${{ matrix.platform }} ]]; then + source .env.${{ matrix.platform }} + fi if [[ -f .env.ci ]]; then source .env.ci fi @@ -204,24 +229,27 @@ jobs: ./ci/scripts/pre-test.sh fi +<% if lang == "go" %> go test -tags assert -v ./... +<% elif lang == "rust" %> + cargo test +<% else %> +<{not_implemented(lang)}> +<% endif %> if [[ -f ci/scripts/post-test.sh ]]; then ./ci/scripts/post-test.sh fi +<% if lang == "go" %> - name: go mod tidy if: runner.os == 'Linux' - working-directory: go + working-directory: <{ lang_subdir }> run: | go mod tidy --diff +<% endif %> - - name: Test - if: runner.os != 'Linux' - working-directory: go - run: | - go test -tags assert -v ./... - +<% if not lang_config.skip_validate %> validate: name: "Validate/${{ matrix.platform }}_${{ matrix.arch }}" runs-on: ${{ matrix.runner }} @@ -269,15 +297,21 @@ jobs: persist-credentials: false <% endif %> +<% if lang == "go" %> - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: cache-dependency-path: go/go.sum check-latest: true go-version-file: go/go.mod +<% elif lang == "rust" %> + - uses: actions-rust-lang/setup-rust-toolchain@1780873c7b576612439a134613cc4cc74ce5538c # v1.15.2 + with: + components: "clippy" +<% endif %> - uses: prefix-dev/setup-pixi@82d477f15f3a381dbcc8adc1206ce643fe110fb7 # v0.9.3 with: - pixi-version: v0.50.2 + pixi-version: v0.63.2 run-install: false <% if aws %> @@ -302,7 +336,13 @@ jobs: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - name: Build Library - working-directory: go +<% if secrets["build:test"] %> + env: +<% for name, val in secrets["build:test"].items() %> + <{name}>: ${{ secrets.<{val}> }} +<% endfor %> +<% endif %> + working-directory: <{ lang_subdir }> run: | if [[ -f ci/scripts/pre-build.sh ]]; then ./ci/scripts/pre-build.sh test ${{ matrix.platform }} ${{ matrix.arch }} @@ -312,13 +352,13 @@ jobs: source .env.test fi set +a - pixi run adbc-make build DEBUG=true VERBOSE=true DRIVER=<{driver}> + pixi run adbc-make build DEBUG=true VERBOSE=true DRIVER=<{driver}> IMPL_LANG=<{lang}> <{' '.join(lang_config.build.additional_make_args) }> - name: Start Test Dependencies # Can't use Docker on macOS AArch64 runners, and Windows containers # work but often the container doesn't support Windows if: runner.os == 'Linux' - working-directory: go + working-directory: <{ lang_subdir }> run: | if [[ -f compose.yaml ]]; then if ! docker compose up --detach --wait test-service; then @@ -337,12 +377,15 @@ jobs: <{name}>: ${{ secrets.<{val}> }} <% endfor %> <% endif %> - working-directory: go + working-directory: <{ lang_subdir }> run: | set -a if [[ -f .env ]]; then source .env fi + if [[ -f .env.${{ matrix.platform }} ]]; then + source .env.${{ matrix.platform }} + fi if [[ -f .env.ci ]]; then source .env.ci fi @@ -360,16 +403,23 @@ jobs: ./ci/scripts/post-test.sh fi + - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: + name: validation-report + path: "<{ lang_subdir }>/validation-report.xml" + retention-days: 7 + - name: Generate docs - working-directory: go + working-directory: <{ lang_subdir }> run: | pixi run gendocs --output generated - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: docs - path: "go/generated/<{driver}>.md" + path: "<{ lang_subdir }>/generated/<{driver}>.md" retention-days: 2 +<% endif %> build: name: "Build <{driver}>/${{ matrix.platform }}_${{ matrix.arch }}" @@ -387,6 +437,9 @@ jobs: <% endif %> - { platform: macos, arch: arm64, runner: macos-latest } - { platform: windows, arch: amd64, runner: windows-latest } +<% if environment %> + environment: <{environment}> +<% endif %> permissions: contents: read packages: read @@ -414,19 +467,25 @@ jobs: persist-credentials: false <% endif %> +<% if lang == "go" %> - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: cache-dependency-path: go/go.sum check-latest: true go-version-file: go/go.mod +<% elif lang == "rust" %> + - uses: actions-rust-lang/setup-rust-toolchain@1780873c7b576612439a134613cc4cc74ce5538c # v1.15.2 + with: + components: "clippy" +<% endif %> - uses: prefix-dev/setup-pixi@82d477f15f3a381dbcc8adc1206ce643fe110fb7 # v0.9.3 with: - pixi-version: v0.50.2 + pixi-version: v0.63.2 run-install: false - name: Install dev tools - working-directory: go + working-directory: <{ lang_subdir }> run: | pixi install @@ -436,7 +495,7 @@ jobs: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - name: Build Library - working-directory: go + working-directory: <{ lang_subdir }> <% if secrets["build:release"] %> env: <% for name, val in secrets["build:release"].items() %> @@ -452,12 +511,12 @@ jobs: source .env.release fi set +a - pixi run adbc-make check CI=true VERBOSE=true DRIVER=<{driver}> + pixi run adbc-make check CI=true VERBOSE=true DRIVER=<{driver}> IMPL_LANG=<{lang}> <{' '.join(lang_config.build.additional_make_args) }> - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: drivers-${{ matrix.platform }}-${{ matrix.arch }} - path: "go/build/libadbc_driver_<{driver}>.*" + path: "<{ lang_subdir }>/build/libadbc_driver_<{driver}>.*" retention-days: 2 package: @@ -490,14 +549,20 @@ jobs: persist-credentials: false <% endif %> +<% if lang == "go" %> - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: check-latest: true go-version: "stable" +<% elif lang == "rust" %> + - uses: actions-rust-lang/setup-rust-toolchain@1780873c7b576612439a134613cc4cc74ce5538c # v1.15.2 + with: + components: "clippy" +<% endif %> - uses: prefix-dev/setup-pixi@82d477f15f3a381dbcc8adc1206ce643fe110fb7 # v0.9.3 with: - pixi-version: v0.50.2 + pixi-version: v0.63.2 run-install: false - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 @@ -506,8 +571,9 @@ jobs: path: "~/drivers" - name: Install tools - working-directory: go + working-directory: <{ lang_subdir }> run: | +<% if lang == "go" %> # XXX: can't install go-licenses under go 1.25 # https://github.com/google/go-licenses/issues/312 git clone --depth=1 https://github.com/google/go-licenses @@ -520,16 +586,19 @@ jobs: go mod tidy go install . popd +<% elif lang == "rust" %> + cargo install cargo-about +<% endif %> - name: Generate packages - working-directory: go + working-directory: <{ lang_subdir }> run: | pixi install pixi run adbc-gen-package \ --name <{driver}> \ --root $(pwd) \ - --manifest-template manifest.toml \ + --manifest-template $(pwd)/manifest.toml \ ${{ (inputs.release && '--release') || '' }}\ -o ~/packages \ ~/drivers/drivers-*-*/ @@ -542,6 +611,67 @@ jobs: path: ~/packages retention-days: 7 + test-packages: + name: "Test Packages/${{ matrix.platform }}_${{ matrix.arch }}" + runs-on: ${{ matrix.runner }} + needs: + - package + strategy: + fail-fast: true + matrix: + include: + - { platform: linux, arch: amd64, runner: ubuntu-latest } + - { platform: macos, arch: arm64, runner: macos-latest } + - { platform: windows, arch: amd64, runner: windows-latest } + steps: + # for now, install dbc from main + - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 + with: + go-version: 'stable' + - uses: prefix-dev/setup-pixi@82d477f15f3a381dbcc8adc1206ce643fe110fb7 # v0.9.3 + with: + pixi-version: v0.63.2 + run-install: false + - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + name: "all-packages" + path: "~/packages" + - name: install package + # dbc uses the filename as the driver name + run: | + echo "Installing dbc" + git clone --depth 1 https://github.com/columnar-tech/dbc + cd dbc + go build ./cmd/dbc + echo "Installed dbc" + driver_pkg=$(find ~/packages -name '*_${{ matrix.platform }}_${{ matrix.arch }}_*.tar.gz') + ./dbc install --no-verify "${driver_pkg}" + echo "Installed ${driver_pkg}" +<% if release or not secrets["all"] %> + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 1 + persist-credentials: false +<% else %> + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + if: github.event_name != 'workflow_dispatch' + with: + fetch-depth: 1 + persist-credentials: false + - name: "checkout remote" + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + if: github.event_name == 'workflow_dispatch' + with: + repository: ${{ inputs.repository }} + ref: ${{ inputs.ref }} + fetch-depth: 1 + persist-credentials: false +<% endif %> + - name: load package + working-directory: <{ lang_subdir }> + run: | + pixi exec -s adbc-driver-manager -s pyarrow -s pytest python -m pytest -vs ci/test_package.py + release: <% if release %> name: "Release" @@ -551,7 +681,10 @@ jobs: runs-on: ubuntu-latest needs: - package + - test-packages +<% if not lang_config.skip_validate %> - validate +<% endif %> permissions: <% if release %> contents: write @@ -589,7 +722,7 @@ jobs: - uses: prefix-dev/setup-pixi@82d477f15f3a381dbcc8adc1206ce643fe110fb7 # v0.9.3 with: - pixi-version: v0.50.2 + pixi-version: v0.63.2 run-install: false - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 @@ -597,21 +730,31 @@ jobs: name: "all-packages" path: "~/packages" +<% if not lang_config.skip_validate %> - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: "docs" path: "~/packages" +<% endif %> <% if release %> - name: Release if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - working-directory: go + working-directory: <{ lang_subdir }> run: | ref=${{ github.ref }} tag=${ref#"refs/tags/"} - +<% if lang == "rust" %> + declared_version=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version') + if [[ "${declared_version}" != "${tag#*v}" ]]; + echo "Declared driver version in Cargo.toml ${declared_version}" + echo "does not match tag ${tag#*v}" + echo "Please update the version before release." + exit 1 + fi +<% endif %> pixi run release $(pwd) $tag gh release upload $tag $(find ~/packages -name '*.tar.gz') $(find ~/packages -name 'manifest.yaml') $(find ~/packages -name '*.md') @@ -619,7 +762,7 @@ jobs: if: github.event_name != 'push' || !startsWith(github.ref, 'refs/tags/') env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - working-directory: go + working-directory: <{ lang_subdir }> run: | git tag go/v1000.0.0 tag=go/v1000.0.0 @@ -630,10 +773,10 @@ jobs: - name: Release (dry-run) env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - working-directory: go + working-directory: <{ lang_subdir }> run: | - git tag go/v1000.0.0 - tag=go/v1000.0.0 + git tag <{ lang_subdir }>/v1000.0.0 + tag=<{ lang_subdir }>/v1000.0.0 pixi run release --dry-run $(pwd) $tag echo gh release upload $tag $(find ~/packages -name '*.tar.gz') $(find ~/packages -name 'manifest.yaml') $(find ~/packages -name '*.md') diff --git a/adbc_drivers_dev/workflow.py b/adbc_drivers_dev/workflow.py index 12fc911..9ce9312 100644 --- a/adbc_drivers_dev/workflow.py +++ b/adbc_drivers_dev/workflow.py @@ -35,6 +35,9 @@ def write_workflow( root: Path, template, filename: str, params: dict[str, typing.Any] ) -> None: rendered = template.render(**params) + rendered = rendered.splitlines() + rendered = "\n".join(line.rstrip() for line in rendered) + rendered += "\n" sink = root / filename with sink.open("w") as f: f.write(rendered) @@ -54,6 +57,10 @@ def generate_schema(args) -> int: return 0 +def template_not_implemented(message: str) -> str: + raise NotImplementedError(message) + + def generate_workflows(args) -> int: env = jinja2.Environment( loader=jinja2.PackageLoader("adbc_drivers_dev"), @@ -65,6 +72,7 @@ def generate_workflows(args) -> int: trim_blocks=True, undefined=jinja2.StrictUndefined, ) + env.globals["not_implemented"] = template_not_implemented config_path = args.repository / ".github/workflows/generate.toml" try: @@ -92,31 +100,47 @@ def generate_workflows(args) -> int: return 1 params = GenerateConfig.model_validate(params) - + print(params) workflows = args.repository / ".github/workflows" + langs = { + "go": ("Go", "go"), + "rust": ("Rust", "rust"), + } + + for lang, (lang_human, lang_subdir) in langs.items(): + lang_config = params.lang.get(lang) + if not lang_config: + continue - if params.lang.get("go"): template = env.get_template("test.yaml") write_workflow( workflows, template, - "go_test.yaml", + f"{lang}_test.yaml", { **params.to_dict(), "pull_request_trigger_paths": [".github/workflows/go_test.yaml"], "release": False, "workflow_name": "Test", + "lang": lang, + "lang_human": lang_human, + "lang_subdir": lang_subdir, + "lang_config": lang_config, }, ) write_workflow( workflows, template, - "go_release.yaml", + f"{lang}_release.yaml", { **params.to_dict(), "pull_request_trigger_paths": [".github/workflows/go_release.yaml"], "release": True, "workflow_name": "Release", + "lang": lang, + "lang_human": lang_human, + "lang_subdir": lang_subdir, + "lang_config": lang_config, }, ) template = env.get_template("go_test_pr.yaml") @@ -124,7 +148,7 @@ def generate_workflows(args) -> int: write_workflow( workflows, template, - "go_test_pr.yaml", + f"{lang}_test_pr.yaml", { **params.to_dict(), }, diff --git a/tests/test_workflow.py b/tests/test_workflow.py index d01001a..d43c9de 100644 --- a/tests/test_workflow.py +++ b/tests/test_workflow.py @@ -15,7 +15,7 @@ import pytest from pydantic import ValidationError -from adbc_drivers_dev.generate import GenerateConfig +from adbc_drivers_dev.generate import GenerateConfig, LangConfig def test_model_default() -> None: @@ -27,6 +27,7 @@ def test_model_default() -> None: assert config._processed_secrets == { "all": {}, "build:release": {}, + "build:test": {}, "test": {}, "validate": {}, } @@ -43,6 +44,7 @@ def test_model_default() -> None: "secrets": { "all": {}, "build:release": {}, + "build:test": {}, "test": {}, "validate": {}, }, @@ -75,8 +77,7 @@ def test_model_custom() -> None: assert config != GenerateConfig.model_validate({}) config = GenerateConfig.model_validate({"lang": {"python": True, "java": False}}) - assert config.lang == {"python": True, "java": False} - assert config.to_dict()["lang"] == {"python": True, "java": False} + assert config.lang == {"python": LangConfig(), "java": None} assert config == config assert config != GenerateConfig.model_validate({}) @@ -94,12 +95,14 @@ def test_params_secrets() -> None: assert config._processed_secrets == { "all": {"foo": "bar", "spam": "eggs", "fizz": "buzz"}, "build:release": {"foo": "bar", "spam": "eggs"}, + "build:test": {"foo": "bar", "spam": "eggs"}, "test": {"foo": "bar", "spam": "eggs", "fizz": "buzz"}, "validate": {"foo": "bar", "spam": "eggs", "fizz": "buzz"}, } assert config.to_dict()["secrets"] == { "all": {"foo": "bar", "spam": "eggs", "fizz": "buzz"}, "build:release": {"foo": "bar", "spam": "eggs"}, + "build:test": {"foo": "bar", "spam": "eggs"}, "test": {"foo": "bar", "spam": "eggs", "fizz": "buzz"}, "validate": {"foo": "bar", "spam": "eggs", "fizz": "buzz"}, } @@ -116,6 +119,7 @@ def test_params_aws() -> None: "AWS_ROLE_SESSION_NAME": "AWS_ROLE_SESSION_NAME", }, "build:release": {}, + "build:test": {}, "test": {}, "validate": {}, } @@ -125,6 +129,7 @@ def test_params_aws() -> None: "AWS_ROLE_SESSION_NAME": "AWS_ROLE_SESSION_NAME", }, "build:release": {}, + "build:test": {}, "test": {}, "validate": {}, } @@ -141,6 +146,7 @@ def test_params_gcloud() -> None: "GCLOUD_WORKLOAD_IDENTITY_PROVIDER": "GCLOUD_WORKLOAD_IDENTITY_PROVIDER", }, "build:release": {}, + "build:test": {}, "test": {}, "validate": {}, } @@ -150,6 +156,7 @@ def test_params_gcloud() -> None: "GCLOUD_WORKLOAD_IDENTITY_PROVIDER": "GCLOUD_WORKLOAD_IDENTITY_PROVIDER", }, "build:release": {}, + "build:test": {}, "test": {}, "validate": {}, } @@ -229,6 +236,7 @@ def test_params_aws_and_gcloud() -> None: # Individual contexts should be empty too assert config._processed_secrets["build:release"] == {} + assert config._processed_secrets["build:test"] == {} assert config._processed_secrets["test"] == {} assert config._processed_secrets["validate"] == {}