Repository navigation
feat(standard-tests): lint spec structure, form rendering and OAuth config paths - #1227
Draft
Anatolii Yatsuk (tolik0) wants to merge 4 commits into
Draft
Anatolii Yatsuk (tolik0) wants to merge 4 commits into
Anatolii Yatsuk (tolik0) wants to merge 4 commits into
Conversation
…onfig paths Port CAT's structural spec checks into the spec tests (`test_spec` and `test_docker_image_build_and_spec`), next to the `airbyte_secret` marking lint. Every lint reports each problem with its JSON pointer and never prints a value. Enforced: valid JSON Schema, refs resolved, additionalProperties is true, oneOf usage, enum usage, array items, property types, display_type, duplicate order, nested group and OAuth config paths. Advisory, reported as the new `SpecLintWarning`: forbidden keywords and object not empty. Their remaining violators build their specs in code and cannot be fixed without the spec backward-compatibility check calling the fix breaking. A lint that crashes on an unexpected spec is reported as a problem of that lint instead of raising. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… crashing Three enforced spec lints crashed on keyword values that are not hashable strings: `array items` on an `items.type` list such as `[string, null]`, `display_type` on a list or object value, and `valid JSON Schema` on a non-string `$schema`. `find_spec_problems` turned the crash into "The lint could not run: TypeError." with no pointer, so the author could not find the problem. Each lint now reports the pointer like any other problem, and the schema check reuses `_catalog_checks._meta_validator`, which falls back to draft 7 for a non-string `$schema` (its meta-schema then reports it). The migration note now names the two connectors that still fail an enforced lint (archived destination-timeplus, and source-mssql in airbyte's Dockerfile Tests workflow) instead of claiming every failing connector was fixed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s that run the spec tests The note said the monorepo connectors that failed an enforced lint were fixed "with two known exceptions". source-tplcentral also fails until its separate, non-blocking spec fix merges, because its legacy `tests:` config keeps the lints from running at all. Scope the sentence to connectors whose CI runs the CDK spec tests and list source-tplcentral as a third exception. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 14, 2026
👋 Greetings, Airbyte Team Member!Here are some helpful tips and reminders for your convenience. 💡 Show Tips and TricksTesting This CDK VersionYou can test this version of the CDK using the following: # Run the CLI from this branch:
uvx 'git+https://github.com/airbytehq/airbyte-python-cdk.git@tolik0/cdk/spec-structural-lints#egg=airbyte-python-cdk[dev]' --help
# Update a connector to use the CDK from this branch ref:
cd airbyte-integrations/connectors/source-example
poe use-cdk-branch tolik0/cdk/spec-structural-lintsPR Slash CommandsAirbyte Maintainers can execute the following slash commands on your PR:
|
3 of 5 tasks
Comment on lines
+508
to
+509
| "`/advanced_auth/predicate_key` names the config path `/credentials/method`, which is " | ||
| "not a property of `connectionSpecification`.", |
Comment on lines
+510
to
+512
| "`/advanced_auth/oauth_config_specification/complete_oauth_output_specification/" | ||
| "properties/refresh_token/path_in_connector_config` names the config path " | ||
| "`/refresh_token`, which is not a property of `connectionSpecification`.", |
PyTest Results (Fast)5 817 tests +69 5 786 ✅ +68 11m 48s ⏱️ -22s Results for commit 01f7ebb. ± Comparison against base commit 2082c2d. This pull request skips 1 test.♻️ This comment has been updated with latest results. |
PyTest Results (Full)5 820 tests +69 5 789 ✅ +68 16m 36s ⏱️ -24s Results for commit 01f7ebb. ± Comparison against base commit 2082c2d. This pull request skips 1 test.♻️ This comment has been updated with latest results. |
Anatolii Yatsuk (tolik0)
marked this pull request as draft
October 14, 2026 14:12
4 of 5 tasks
Dropping the null branch of anyOf: [X, null] rejects saved configs that set the field to null. Rewrite it as X with type: [<X's type>, "null"] instead, which accepts exactly the same configs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Resolves airbytehq/airbyte-internal-issues#17136 (P1.3 of the CAT to FAST coverage epic). It ports CAT's structural spec checks into the spec tests. The tests are
test_spec(in-process) andtest_docker_image_build_and_spec(Docker). The new lints run next to theairbyte_secretmarking lint from #1219. Each lint reports every problem with the JSON pointer of where it sits in the spec, and never prints a value.Enforced lints (fail the test)
test_config_match_specconnectionSpecificationvalidates against the meta-schema of its$schemadraft (draft 7 by default)test_defined_refs_exist_in_json_spec_file$refanywhere in the emitted spec,advanced_authincludedtest_additional_properties_is_trueadditionalPropertiesistruewherever it is settest_oneof_usagetype: object, every variant hasproperties, and the variants share exactly one discriminator (see below)test_enum_usageenumvaluestest_array_typeitemsis a single schema of type object, string, number or integer (one type, not a list), or has anenumtest_property_type_is_not_arraytypeis one type, or one type followed bynulltest_display_typeoneOf, and onlydropdownorradiotest_duplicate_orderorderis unique within one object andgrouptest_nested_groupgroupis set on top-level properties onlytest_oauth_flow_parameterspredicate_keyand everypath_in_connector_configname a property ofconnectionSpecificationoneOf discriminator rules:
const.enumwith that item as itsdefault. The webapp'sschemaToFormBlocktreats that as aconst.enum, such ascompression_codec, is not a candidate. CAT treated it as one, which is a false positive on destination-aws-datalake.Advisory lints (
SpecLintWarning)forbidden keywords(test_forbidden_complex_types) andobject not empty(test_object_not_empty) report their problems as the newSpecLintWarning, exported fromairbyte_cdk.test.standard_tests. Their remaining violators cannot be fixed in a backward-compatible way:source-facebook-marketing(certified): pydantic emits a single-itemallOffor an enum-typed field.destination-ragie: pydantic v2 emitsanyOf: [X, null]for itsOptionalfields.source-smoke-test: the spec is built in PyAirbyte, and its free-formjson_schemaandrecordsobjects cannot gain properties.Inlining the single-item
allOf, or rewritinganyOf: [X, null]asXwithtype: [<X's type>, "null"], accepts exactly the same configs. Dropping thenullbranch instead would reject saved configs that set the field tonull. Even the equivalent rewrite fails the spec backward-compatibility check (#1220), which reportstype/enumadded andallOf/anyOfremoved and calls the fix breaking. Follow-up: teach the comparator that those forms are equivalent, fix the two connectors, then enforce. Running pytest with-W error::airbyte_cdk.test.standard_tests.SpecLintWarningturns the warnings into failures now.A keyword value of an unexpected type, such as an
items.typelist, a listdisplay_typeor a non-string$schema, is reported at its pointer like any other problem. A lint that still raises on an unexpected spec is reported as a problem of that lint ("The lint could not run: ."). It is never raised, so an advisory lint cannot fail a test by crashing.CAT checks not ported, and why
test_date_patternMM-DD-YYYYonformat: datefields, which contradicts the date picker and the docs (YYYY-MM-DD). Adding apatternnarrows the accepted configs. 264 connectors would flag.test_date_formatairbyte-ops local connector qaformatnarrows configs, so the connector needs a waiver.test_oauth_is_default_methodairbyte-ops local connector qaauth_default_methodbypass for this, and the standard tests have no per-connector exception.test_image_labelsairbyte-cdk image buildsetsio.airbyte.nameandio.airbyte.versionfrommetadata.yaml, so a connector cannot get them wrongtest_image_environment_variablesDockerfile.python-connectorandDockerfile.manifest-only-connectorsetAIRBYTE_ENTRYPOINTequal toENTRYPOINTFleet dry run
The lints were run on the committed specs at airbyte master
1e22e3c689c:ConcurrentDeclarativeSource.spec().spec.json,spec.yamlor the manifest spec block, or the registry spec when the spec is built in code.The registry specs were scanned as a cross-check, and the results agree. Java connectors run no CDK standard tests in connector CI, with one exception: airbyte's Dockerfile Tests workflow (
docker-connector-base-image-tests.yml) runsairbyte-cdk image test, with an unpinned CDK, on 4 Java connectors when a pull request changes the Java connector Dockerfiles. Their registrylatestspecs were linted as their own row.Remaining enforced failures, both
additionalProperties is true:@JsonAnyGettermap as a config property namedadditionalProperties, whose ownadditionalPropertiesis a schema. The fix is a Kotlin change to a certified database source that could not be built or verified here, so it is left as a known failure of the Dockerfile Tests workflow's source-mssql leg. That workflow runs only when a pull request changesdocker-images/Dockerfile.java-connector*.destination-snowflake's duplicate
order(private_key_passwordsharedorder0 withprivate_key) is fixed in airbytehq/airbyte#88929. source-postgres and destination-postgres pass every lint. source-mysql (Java) also repeats anorder, but no CDK test path runs on it, so it blocks nothing.source-tplcentral fails
additionalProperties is trueuntil airbytehq/airbyte#88928 merges, but its legacytests:config fails test collection, so the lint does not run on it either way.Every other lint (oneOf, enum, array items, property types, display_type, nested group, refs, valid JSON Schema, OAuth config paths) has 0 violators.
Tests
unit_tests/test/test_spec_structural_lints.pycovers the passing and the failing side of every lint. It also coversfind_spec_problemscrash handling,format_spec_problems, the advisory warning, and a check that no failure message prints a spec value.test_spec_lint.pygains Docker-path and in-process tests for an enforced structural failure and for an advisory warning.items.typelist, list or objectdisplay_type, list or object$schema): the problem is reported at its pointer, and the lint does not crash.poetry run pytest unit_tests/test/: 847 passed, 9 skipped. ruff and mypy are clean.Migration
The migration note is in
cdk-migrations.md, under "Upgrading to the next minor release (unreleased)". It has a table of the enforced lints with the fix for each, the advisory lints, and the checks that were not ported. This is a minor release: only the test harness changes.🤖 Generated with Claude Code