Compare commits

..

15 Commits

Author SHA1 Message Date
Github Build Bot
26ed99e285 Bumping version to 1.9.0 and generate changelog 2024-12-09 17:32:07 +00:00
github-actions[bot]
9f5f002e34 Microbatch first last batch serial (#11072) (#11107)
* microbatch: split out first and last batch to run in serial

* only run pre_hook on first batch, post_hook on last batch

* refactor: internalize parallel to RunTask._submit_batch

* Add optional `force_sequential` to `_submit_batch` to allow for skipping parallelism check

* Force last batch to run sequentially

* Force first batch to run sequentially

* Remove batch_idx check in `should_run_in_parallel`

`should_run_in_parallel` shouldn't, and no longer needs to, take into
consideration where in batch exists in a larger context. The first and
last batch for a microbatch model are now forced to run sequentially
by `handle_microbatch_model`

* Begin skipping batches if first batch fails

* Write custom `on_skip` for `MicrobatchModelRunner` to better handle when batches are skipped

This was necessary specifically because the default on skip set the `X of Y` part
of the skipped log using the `node_index` and the `num_nodes`. If there was 2
nodes and we are on the 4th batch of the second node, we'd get a message like
`SKIPPED 4 of 2...` which didn't make much sense. We're likely in a future commit
going to add a custom event for logging the start, result, and skipping of batches
for better readability of the logs.

* Add microbatch pre-hook, post-hook, and sequential first/last batch tests

* Fix/Add tests around first batch failure vs latter batch failure

* Correct MicrobatchModelRunner.on_skip to handle skipping the entire node

Previously `MicrobatchModelRunner.on_skip` only handled when a _batch_ of
the model was being skipped. However, that method is also used when the
entire microbatch model is being skipped due to an upstream node error. Because
we previously _weren't_ handling this second case, it'd cause an unhandled
runtime exception. Thus, we now need to check whether we're running a batch or not,
and there is no batch, then use the super's on_skip method.

* Correct conditional logic for setting pre- and post-hooks for batches

Previously we were doing an if+elif for setting pre- and post-hooks
for batches, where in the `if` matched if the batch wasn't the first
batch, and the `elif` matched if the batch wasn't the last batch. The
issue with this is that if the `if` was hit, the `elif` _wouldn't_ be hit.
This caused the first batch to appropriately not run the `post-hook` but
then every hook after would run the `post-hook`.

* Add two new event types `LogStartBatch` and `LogBatchResult`

* Update MicrobatchModelRunner to use new batch specific log events

* Fix event testing

* Update microbatch integration tests to catch batch specific event types

---------

Co-authored-by: Quigley Malcolm <quigley.malcolm@dbtlabs.com>
(cherry picked from commit 03fdb4c157)

Co-authored-by: Michelle Ark <MichelleArk@users.noreply.github.com>
2024-12-08 20:44:36 -06:00
github-actions[bot]
4e74e69497 Implement partial parsing for singular data tests configs in yaml files (#11100) (#11101)
(cherry picked from commit e32b8a90ac)

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2024-12-05 16:42:34 -05:00
Michelle Ark
34f92a831a Access DEBUG flag through get_flags() (#11069) (#11096) 2024-12-04 12:38:03 -05:00
FishtownBuildBot
a4b3085706 [Automated] Merged prep-release/1.9.0rc2_12121325802 into target 1.9.latest during release process 2024-12-02 09:53:34 -05:00
Github Build Bot
333d600a95 Bumping version to 1.9.0rc2 and generate changelog 2024-12-02 14:25:20 +00:00
github-actions[bot]
61b6cb3864 [Tidy first] move microbatch compilation to .compile method (#11063) (#11065) 2024-11-27 23:58:39 -05:00
github-actions[bot]
6a36444dbb Add batch context object to microbatch jinja context (#11031) (#11064)
* Add `batch_id` to jinja context of microbatch batches

* Add changie doc

* Update `format_batch_start` to assume `batch_start` is always provided

* Add "runtime only" property `batch_context` to `ModelNode`

By it being "runtime only" we mean that it doesn't exist on the artifact
and thus won't be written out to the manifest artifact.

* Begin populating `batch_context` during materialization execution for microbatch batches

* Fix circular import

* Fixup MicrobatchBuilder.batch_id property method

* Ensure MicrobatchModelRunner doesn't double compile batches

We were compiling the node for each batch _twice_. Besides making microbatch
models more expensive than they needed to be, double compiling wasn't
causing any issue. However the first compilation was happening _before_ we
had added the batch context information to the model node for the batch. This
was leading to models which try to access the `batch_context` information on the
model to blow up, which was undesirable. As such, we've now gone and skipped
the first compilation. We've done this similar to how SavedQuery nodes skip
compilation.

* Add `__post_serialize__` method to `BatchContext` to ensure correct dict shape

This is weird, but necessary, I apologize. Mashumaro handles the
dictification of this class via a compile time generated `to_dict`
method based off of the _typing_ of th class. By default `datetime`
types are converted to strings. We don't want that, we want them to
stay datetimes.

* Update tests to check for `batch_context`

* Update `resolve_event_time_filter` to use new `batch_context`

* Stop testing for batchless compiled code for microbatch models

In 45daec72f4 we stopped an extra compilation
that was happening per batch prior to the batch_context being loaded. Stopping
this extra compilation means that compiled sql for the microbatch model without
the event time filter / batch context is no longer produced. We have discussed
this and _believe_ it is okay given that this is a new node type that has not
hit GA yet.

* Rename `ModelNode.batch_context` to `ModelNode.batch`

* Rename `build_batch_context` to `build_jinja_context_for_batch`

The name `build_batch_context` was confusing as
1) We have a `BatchContext` object, which the method was not building
2) The method builds the jinja context for the batch
As such it felt appropriate to rename the method to more accurately
communicate what it does.

* Rename test macro `invalid_batch_context_macro_sql` to `invalid_batch_jinja_context_macro_sql`

This rename was to make it more clear that the jinja context for a
batch was being checked, as a batch_context has a slightly different
connotation.

* Update changie doc

(cherry picked from commit c3d87b89fb)

Co-authored-by: Quigley Malcolm <QMalcolm@users.noreply.github.com>
2024-11-27 17:03:10 -06:00
github-actions[bot]
65f05e0bd2 Rename internal batch_info variable to previous_batch_results (#11056) (#11062)
* Rename `batch_info` to `previous_batch_results`

* Exclude `previous_batch_results` from serialization of model node to avoid jinja context bloat

* Drop `previous_batch_results` key from `test_manifest.py` unit tests

In 4050e377ec we began excluding
`previous_batch_results` from the serialized representation of the
ModelNode. As such, we no longer need to check for it in `test_manifest.py`.

(cherry picked from commit 0f084e16ca)

Co-authored-by: Quigley Malcolm <QMalcolm@users.noreply.github.com>
2024-11-27 16:41:50 -06:00
FishtownBuildBot
aceae51ffb [Automated] Merged prep-release/1.9.0rc1_12015575655 into target 1.9.latest during release process 2024-11-25 13:06:05 -05:00
Github Build Bot
a84a787eeb Bumping version to 1.9.0rc1 and generate changelog 2024-11-25 17:37:13 +00:00
github-actions[bot]
3d70e1b06f Fix #11012: Catch DbtRuntimeError for hooks (#11023) (#11045)
(cherry picked from commit f582ac2488)

Co-authored-by: Kshitij Aranke <kshitij.aranke@dbtlabs.com>
Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2024-11-25 12:15:46 -05:00
Peter Webb
55872497bd Add New Config Properties and Schema for Snapshot Hard Deletes (#10972) (#11037)
* Add changelog entry.

* Update schemas and test fixtures for new snapshot meta-column

* Add back comment.

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2024-11-25 11:53:45 -05:00
github-actions[bot]
d305137226 Pin mashumaro to <3.15 (#11046) (#11047)
(cherry picked from commit 407f6caa1c)

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2024-11-25 11:28:36 -05:00
Emily Rockman
bda92e7312 add 1.8 changelogs (#11028) 2024-11-21 15:59:16 -06:00
4603 changed files with 77653 additions and 63702 deletions

37
.bumpversion.cfg Normal file
View File

@@ -0,0 +1,37 @@
[bumpversion]
current_version = 1.9.0
parse = (?P<major>[\d]+) # major version number
\.(?P<minor>[\d]+) # minor version number
\.(?P<patch>[\d]+) # patch version number
(?P<prerelease> # optional pre-release - ex: a1, b2, rc25
(?P<prekind>a|b|rc) # pre-release type
(?P<num>[\d]+) # pre-release version number
)?
( # optional nightly release indicator
\.(?P<nightly>dev[0-9]+) # ex: .dev02142023
)? # expected matches: `1.15.0`, `1.5.0a11`, `1.5.0a1.dev123`, `1.5.0.dev123457`, expected failures: `1`, `1.5`, `1.5.2-a1`, `text1.5.0`
serialize =
{major}.{minor}.{patch}{prekind}{num}.{nightly}
{major}.{minor}.{patch}.{nightly}
{major}.{minor}.{patch}{prekind}{num}
{major}.{minor}.{patch}
commit = False
tag = False
[bumpversion:part:prekind]
first_value = a
optional_value = final
values =
a
b
rc
final
[bumpversion:part:num]
first_value = 1
[bumpversion:part:nightly]
[bumpversion:file:core/setup.py]
[bumpversion:file:core/dbt/version.py]

View File

@@ -3,9 +3,6 @@
For information on prior major and minor releases, see their changelogs: For information on prior major and minor releases, see their changelogs:
* [1.10](https://github.com/dbt-labs/dbt-core/blob/1.10.latest/CHANGELOG.md)
* [1.9](https://github.com/dbt-labs/dbt-core/blob/1.9.latest/CHANGELOG.md)
* [1.8](https://github.com/dbt-labs/dbt-core/blob/1.8.latest/CHANGELOG.md)
* [1.7](https://github.com/dbt-labs/dbt-core/blob/1.7.latest/CHANGELOG.md) * [1.7](https://github.com/dbt-labs/dbt-core/blob/1.7.latest/CHANGELOG.md)
* [1.6](https://github.com/dbt-labs/dbt-core/blob/1.6.latest/CHANGELOG.md) * [1.6](https://github.com/dbt-labs/dbt-core/blob/1.6.latest/CHANGELOG.md)
* [1.5](https://github.com/dbt-labs/dbt-core/blob/1.5.latest/CHANGELOG.md) * [1.5](https://github.com/dbt-labs/dbt-core/blob/1.5.latest/CHANGELOG.md)

190
.changes/1.9.0.md Normal file
View File

@@ -0,0 +1,190 @@
## dbt-core 1.9.0 - December 09, 2024
### Breaking Changes
- Fix changing the current working directory when using dpt deps, clean and init. ([#8997](https://github.com/dbt-labs/dbt-core/issues/8997))
### Features
- Parseable JSON and text output in quiet mode for `dbt show` and `dbt compile` ([#9840](https://github.com/dbt-labs/dbt-core/issues/9840))
- serialize inferred primary key ([#9824](https://github.com/dbt-labs/dbt-core/issues/9824))
- Add unit_test: selection method ([#10053](https://github.com/dbt-labs/dbt-core/issues/10053))
- Maximally parallelize dbt clone in clone command" ([#7914](https://github.com/dbt-labs/dbt-core/issues/7914))
- Add --host flag to dbt docs serve, defaulting to '127.0.0.1' ([#10229](https://github.com/dbt-labs/dbt-core/issues/10229))
- Update data_test to accept arbitrary config options ([#10197](https://github.com/dbt-labs/dbt-core/issues/10197))
- add pre_model and post_model hook calls to data and unit tests to be able to provide extra config options ([#10198](https://github.com/dbt-labs/dbt-core/issues/10198))
- add --empty value to jinja context as flags.EMPTY ([#10317](https://github.com/dbt-labs/dbt-core/issues/10317))
- Warning message for snapshot timestamp data types ([#10234](https://github.com/dbt-labs/dbt-core/issues/10234))
- Support cumulative_type_params & sub-daily granularities in semantic manifest. ([#10360](https://github.com/dbt-labs/dbt-core/issues/10360))
- Add time_granularity to metric spec. ([#10376](https://github.com/dbt-labs/dbt-core/issues/10376))
- Support standard schema/database fields for snapshots ([#10301](https://github.com/dbt-labs/dbt-core/issues/10301))
- Support ref and source in foreign key constraint expressions, bump dbt-common minimum to 1.6 ([#8062](https://github.com/dbt-labs/dbt-core/issues/8062))
- Support new semantic layer time spine configs to enable sub-daily granularity. ([#10475](https://github.com/dbt-labs/dbt-core/issues/10475))
- Add `order_by` and `limit` fields to saved queries. ([#10531](https://github.com/dbt-labs/dbt-core/issues/10531))
- Add support for behavior flags ([#10618](https://github.com/dbt-labs/dbt-core/issues/10618))
- Enable `--resource-type` and `--exclude-resource-type` CLI flags and environment variables for `dbt test` ([#10656](https://github.com/dbt-labs/dbt-core/issues/10656))
- Allow configuring snapshot column names ([#10185](https://github.com/dbt-labs/dbt-core/issues/10185))
- Add custom_granularities to YAML spec for time spines. ([#9265](https://github.com/dbt-labs/dbt-core/issues/9265))
- Add basic functionality for creating microbatch incremental models ([#9490](https://github.com/dbt-labs/dbt-core/issues/9490), [#10635](https://github.com/dbt-labs/dbt-core/issues/10635), [#10637](https://github.com/dbt-labs/dbt-core/issues/10637), [#10638](https://github.com/dbt-labs/dbt-core/issues/10638), [#10636](https://github.com/dbt-labs/dbt-core/issues/10636), [#10662](https://github.com/dbt-labs/dbt-core/issues/10662), [#10639](https://github.com/dbt-labs/dbt-core/issues/10639))
- Execute microbatch models in batches ([#10700](https://github.com/dbt-labs/dbt-core/issues/10700))
- Create 'skip_nodes_if_on_run_start_fails' behavior change flag ([#7387](https://github.com/dbt-labs/dbt-core/issues/7387))
- Allow snapshots to be defined in YAML. ([#10246](https://github.com/dbt-labs/dbt-core/issues/10246))
- Write microbatch compiled/run targets to separate files, one per batch ([#10714](https://github.com/dbt-labs/dbt-core/issues/10714))
- Track incremental_strategy as part of model_run tracking event ([#10761](https://github.com/dbt-labs/dbt-core/issues/10761))
- Support required 'begin' config for microbatch models ([#10701](https://github.com/dbt-labs/dbt-core/issues/10701))
- Parse-time validation of microbatch configs: require event_time, batch_size, lookback and validate input event_time ([#10709](https://github.com/dbt-labs/dbt-core/issues/10709))
- Added the --inline-direct parameter to 'dbt show' ([#10770](https://github.com/dbt-labs/dbt-core/issues/10770))
- Enable specification of dbt_valid_to for current records ([#10187](https://github.com/dbt-labs/dbt-core/issues/10187))
- Enable `retry` support for microbatch models ([#10715](https://github.com/dbt-labs/dbt-core/issues/10715), [#10729](https://github.com/dbt-labs/dbt-core/issues/10729))
- Use unrendered database and schema source properties during state:modified, behind state_modified_compare_more_unrendered_values behavoiur flag ([#9573](https://github.com/dbt-labs/dbt-core/issues/9573))
- Ensure microbatch models respect `full_refresh` model config ([#10785](https://github.com/dbt-labs/dbt-core/issues/10785))
- Adds validations for custom_granularities to ensure unique naming. ([#9265](https://github.com/dbt-labs/dbt-core/issues/9265))
- Enable use of multi-column unique key in snapshots ([#9992](https://github.com/dbt-labs/dbt-core/issues/9992))
- Change gating of microbatch feature to be behind project flag / behavior flag ([#10798](https://github.com/dbt-labs/dbt-core/issues/10798))
- Ensure `--event-time-start` is before `--event-time-end` ([#10786](https://github.com/dbt-labs/dbt-core/issues/10786))
- Ensure microbatch models use same `current_time` value ([#10819](https://github.com/dbt-labs/dbt-core/issues/10819))
- Emit warning when microbatch model has no input with `event_time` config ([#10926](https://github.com/dbt-labs/dbt-core/issues/10926))
- Emit debug logging event whenever artifacts are written ([#10937](https://github.com/dbt-labs/dbt-core/issues/10937))
- Support --empty for snapshots ([#10372](https://github.com/dbt-labs/dbt-core/issues/10372))
- Add new hard_deletes="new_record" mode for snapshots. ([#10235](https://github.com/dbt-labs/dbt-core/issues/10235))
- Allow microbatch batches to run in parallel ([#10853](https://github.com/dbt-labs/dbt-core/issues/10853), [#10855](https://github.com/dbt-labs/dbt-core/issues/10855))
- Add `batch` context object to model jinja context ([#11025](https://github.com/dbt-labs/dbt-core/issues/11025))
- Ensure pre/post hooks only run on first/last batch respectively for microbatch model batches ([#11094](https://github.com/dbt-labs/dbt-core/issues/11094), [#11104](https://github.com/dbt-labs/dbt-core/issues/11104))
### Fixes
- Remove unused check_new method ([#7586](https://github.com/dbt-labs/dbt-core/issues/7586))
- Test case for `merge_exclude_columns` ([#8267](https://github.com/dbt-labs/dbt-core/issues/8267))
- Convert "Skipping model due to fail_fast" message to DEBUG level ([#8774](https://github.com/dbt-labs/dbt-core/issues/8774))
- Restore previous behavior for --favor-state: only favor defer_relation if not selected in current command" ([#10107](https://github.com/dbt-labs/dbt-core/issues/10107))
- Unit test fixture (csv) returns null for empty value ([#9881](https://github.com/dbt-labs/dbt-core/issues/9881))
- Fix json format log and --quiet for ls and jinja print by converting print call to fire events ([#8756](https://github.com/dbt-labs/dbt-core/issues/8756))
- Add resource type to saved_query ([#10168](https://github.com/dbt-labs/dbt-core/issues/10168))
- Fix: Order-insensitive unit test equality assertion for expected/actual with multiple nulls ([#10167](https://github.com/dbt-labs/dbt-core/issues/10167))
- Renaming or removing a contracted model should raise a BreakingChange warning/error ([#10116](https://github.com/dbt-labs/dbt-core/issues/10116))
- prefer disabled project nodes to external node ([#10224](https://github.com/dbt-labs/dbt-core/issues/10224))
- Fix issues with selectors and inline nodes ([#8943](https://github.com/dbt-labs/dbt-core/issues/8943), [#9269](https://github.com/dbt-labs/dbt-core/issues/9269))
- Fix snapshot config to work in yaml files ([#4000](https://github.com/dbt-labs/dbt-core/issues/4000))
- Improve handling of error when loading schema file list ([#10284](https://github.com/dbt-labs/dbt-core/issues/10284))
- Use model alias for the CTE identifier generated during ephemeral materialization ([#5273](https://github.com/dbt-labs/dbt-core/issues/5273))
- Implement state:modified for saved queries ([#10294](https://github.com/dbt-labs/dbt-core/issues/10294))
- Saved Query node fail during skip ([#10029](https://github.com/dbt-labs/dbt-core/issues/10029))
- DOn't warn on `unit_test` config paths that are properly used ([#10311](https://github.com/dbt-labs/dbt-core/issues/10311))
- Fix setting `silence` of `warn_error_options` via `dbt_project.yaml` flags ([#10160](https://github.com/dbt-labs/dbt-core/issues/10160))
- Attempt to provide test fixture tables with all values to set types correctly for comparisong with source tables ([#10365](https://github.com/dbt-labs/dbt-core/issues/10365))
- Limit data_tests deprecation to root_project ([#9835](https://github.com/dbt-labs/dbt-core/issues/9835))
- CLI flags should take precedence over env var flags ([#10304](https://github.com/dbt-labs/dbt-core/issues/10304))
- Fix typing for artifact schemas ([#10442](https://github.com/dbt-labs/dbt-core/issues/10442))
- Fix over deletion of generated_metrics in partial parsing ([#10450](https://github.com/dbt-labs/dbt-core/issues/10450))
- Fix error constructing warn_error_options ([#10452](https://github.com/dbt-labs/dbt-core/issues/10452))
- Do not update varchar column definitions if a contract exists ([#10362](https://github.com/dbt-labs/dbt-core/issues/10362))
- fix all_constraints access, disabled node parsing of non-uniquely named resources ([#10509](https://github.com/dbt-labs/dbt-core/issues/10509))
- respect --quiet and --warn-error-options for flag deprecations ([#10105](https://github.com/dbt-labs/dbt-core/issues/10105))
- Propagate measure label when using create_metrics ([#10536](https://github.com/dbt-labs/dbt-core/issues/10536))
- Fix state:modified check for exports ([#10138](https://github.com/dbt-labs/dbt-core/issues/10138))
- Filter out empty nodes after graph selection to support consistent selection of nodes that depend on upstream public models ([#8987](https://github.com/dbt-labs/dbt-core/issues/8987))
- Late render pre- and post-hooks configs in properties / schema YAML files ([#10603](https://github.com/dbt-labs/dbt-core/issues/10603))
- Allow the use of env_var function in certain macros in which it was previously unavailable. ([#10609](https://github.com/dbt-labs/dbt-core/issues/10609))
- Remove deprecation for tests: to data_tests: change ([#10564](https://github.com/dbt-labs/dbt-core/issues/10564))
- Fix `--resource-type test` for `dbt list` and `dbt build` ([#10730](https://github.com/dbt-labs/dbt-core/issues/10730))
- Fix unit tests for incremental model with alias ([#10754](https://github.com/dbt-labs/dbt-core/issues/10754))
- Allow singular tests to be documented in properties.yml ([#9005](https://github.com/dbt-labs/dbt-core/issues/9005))
- Ignore --empty in unit test ref/source rendering ([#10516](https://github.com/dbt-labs/dbt-core/issues/10516))
- Ignore rendered jinja in configs for state:modified, behind state_modified_compare_more_unrendered_values behaviour flag ([#9564](https://github.com/dbt-labs/dbt-core/issues/9564))
- Improve performance of infer primary key ([#10781](https://github.com/dbt-labs/dbt-core/issues/10781))
- Pass test user config to adapter pre_hook by explicitly adding test builder config to node ([#10484](https://github.com/dbt-labs/dbt-core/issues/10484))
- Attempt to skip saved query processing when no semantic manifest changes ([#10563](https://github.com/dbt-labs/dbt-core/issues/10563))
- Ensure dbt retry of microbatch models doesn't lose prior successful state ([#10800](https://github.com/dbt-labs/dbt-core/issues/10800))
- override materialization python models ([#8520](https://github.com/dbt-labs/dbt-core/issues/8520))
- Handle edge cases when a specified `--event-time-end` is equivalent to the batch size truncated batch start time ([#10824](https://github.com/dbt-labs/dbt-core/issues/10824))
- Begin tracking execution time of microbatch model batches ([#10825](https://github.com/dbt-labs/dbt-core/issues/10825))
- Support disabling unit tests via config. ([#9109](https://github.com/dbt-labs/dbt-core/issues/9109), [#10540](https://github.com/dbt-labs/dbt-core/issues/10540))
- Allow instances of generic data tests to be documented ([#2578](https://github.com/dbt-labs/dbt-core/issues/2578))
- Fix warnings for models referring to a deprecated model ([#10833](https://github.com/dbt-labs/dbt-core/issues/10833))
- Change `lookback` default from `0` to `1` to ensure better data completeness ([#10867](https://github.com/dbt-labs/dbt-core/issues/10867))
- Make `--event-time-start` and `--event-time-end` mutually required ([#10874](https://github.com/dbt-labs/dbt-core/issues/10874))
- Ensure KeyboardInterrupt/SystemExit halts microbatch model execution ([#10862](https://github.com/dbt-labs/dbt-core/issues/10862))
- Exclude hook result from results in on-run-end context ([#7387](https://github.com/dbt-labs/dbt-core/issues/7387))
- unit tests with versioned refs ([#10880](https://github.com/dbt-labs/dbt-core/issues/10880), [#10528](https://github.com/dbt-labs/dbt-core/issues/10528), [#10623](https://github.com/dbt-labs/dbt-core/issues/10623))
- Implement partial parsing for all-yaml snapshots ([#10903](https://github.com/dbt-labs/dbt-core/issues/10903))
- Restore source quoting behaviour when quoting config provided in dbt_project.yml ([#10892](https://github.com/dbt-labs/dbt-core/issues/10892))
- Fix bug when referencing deprecated models ([#10915](https://github.com/dbt-labs/dbt-core/issues/10915))
- Fix 'model' jinja context variable type to dict ([#10927](https://github.com/dbt-labs/dbt-core/issues/10927))
- Take `end_time` for batches to the ceiling to handle edge case where `event_time` column is a date ([#10868](https://github.com/dbt-labs/dbt-core/issues/10868))
- Handle exceptions in `get_execution_status` more broadly to better ensure `run_results.json` gets written ([#10934](https://github.com/dbt-labs/dbt-core/issues/10934))
- Fix 'no attribute .config' error when ref-ing a microbatch model from non-Model context ([#10928](https://github.com/dbt-labs/dbt-core/issues/10928))
- Ensure inferred primary_key is a List[str] with no null values ([#10983](https://github.com/dbt-labs/dbt-core/issues/10983))
- Correct when custom microbatch macro deprecation warning is fired ([#10994](https://github.com/dbt-labs/dbt-core/issues/10994))
- Validate manifest has group_map during group_lookup init ([#10988](https://github.com/dbt-labs/dbt-core/issues/10988))
- Fix plural of 'partial success' in log message ([#10999](https://github.com/dbt-labs/dbt-core/issues/10999))
- Emit batch-level exception with node_info on microbatch batch run failure ([#10840](https://github.com/dbt-labs/dbt-core/issues/10840))
- Fix restrict-access to not apply within a package ([#10134](https://github.com/dbt-labs/dbt-core/issues/10134))
- Make microbatch models skippable ([#11021](https://github.com/dbt-labs/dbt-core/issues/11021))
- Catch DbtRuntimeError for hooks ([#11012](https://github.com/dbt-labs/dbt-core/issues/11012))
- Access DBUG flag more consistently with the rest of the codebase in ManifestLoader ([#11068](https://github.com/dbt-labs/dbt-core/issues/11068))
- Implement partial parsing for singular data test configs in yaml files ([#10801](https://github.com/dbt-labs/dbt-core/issues/10801))
### Docs
- Enable display of unit tests ([dbt-docs/#501](https://github.com/dbt-labs/dbt-docs/issues/501))
- Unit tests not rendering ([dbt-docs/#506](https://github.com/dbt-labs/dbt-docs/issues/506))
- Add support for Saved Query node ([dbt-docs/#486](https://github.com/dbt-labs/dbt-docs/issues/486))
- Fix npm security vulnerabilities as of June 2024 ([dbt-docs/#513](https://github.com/dbt-labs/dbt-docs/issues/513))
### Under the Hood
- Clear error message for Private package in dbt-core ([#10083](https://github.com/dbt-labs/dbt-core/issues/10083))
- Enable use of context in serialization ([#10093](https://github.com/dbt-labs/dbt-core/issues/10093))
- Make RSS high water mark measurement more accurate on Linux ([#10177](https://github.com/dbt-labs/dbt-core/issues/10177))
- Enable record filtering by type. ([#10240](https://github.com/dbt-labs/dbt-core/issues/10240))
- Remove IntermediateSnapshotNode ([#10326](https://github.com/dbt-labs/dbt-core/issues/10326))
- Additional logging for skipped ephemeral models ([#10389](https://github.com/dbt-labs/dbt-core/issues/10389))
- bump black to 24.3.0 ([#10454](https://github.com/dbt-labs/dbt-core/issues/10454))
- generate protos with protoc version 5.26.1 ([#10457](https://github.com/dbt-labs/dbt-core/issues/10457))
- Move from minimal-snowplow-tracker fork back to snowplow-tracker ([#8409](https://github.com/dbt-labs/dbt-core/issues/8409))
- Add group info to RunResultError, RunResultFailure, RunResultWarning log lines ([#](https://github.com/dbt-labs/dbt-core/issues/))
- Improve speed of tree traversal when finding children, increasing build speed for some selectors ([#10434](https://github.com/dbt-labs/dbt-core/issues/10434))
- Add test for sources tables with quotes ([#10582](https://github.com/dbt-labs/dbt-core/issues/10582))
- Additional type hints for `core/dbt/version.py` ([#10612](https://github.com/dbt-labs/dbt-core/issues/10612))
- Fix typing issues in core/dbt/contracts/sql.py ([#10614](https://github.com/dbt-labs/dbt-core/issues/10614))
- Fix type errors in `dbt/core/task/clean.py` ([#10616](https://github.com/dbt-labs/dbt-core/issues/10616))
- Add Snowplow tracking for behavior flag deprecations ([#10552](https://github.com/dbt-labs/dbt-core/issues/10552))
- Add test utility patch_microbatch_end_time for adapters testing ([#10713](https://github.com/dbt-labs/dbt-core/issues/10713))
- Replace `TestSelector` with `ResourceTypeSelector` ([#10718](https://github.com/dbt-labs/dbt-core/issues/10718))
- Standardize returning `ResourceTypeSelector` instances in `dbt list` and `dbt build` ([#10739](https://github.com/dbt-labs/dbt-core/issues/10739))
- Add group metadata info to LogModelResult and LogTestResult ([#10775](https://github.com/dbt-labs/dbt-core/issues/10775))
- Remove support and testing for Python 3.8, which is now EOL. ([#10861](https://github.com/dbt-labs/dbt-core/issues/10861))
- Behavior change for mf timespine without yaml configuration ([#10959](https://github.com/dbt-labs/dbt-core/issues/10959))
- Behavior change for cumulative metric type param ([#10960](https://github.com/dbt-labs/dbt-core/issues/10960))
- Upgrade protobuf ([#10658](https://github.com/dbt-labs/dbt-core/issues/10658))
### Dependencies
- Remove logbook dependency ([#8027](https://github.com/dbt-labs/dbt-core/issues/8027))
- Increase supported version range for dbt-semantic-interfaces. Needed to support custom calendar features. ([#9265](https://github.com/dbt-labs/dbt-core/issues/9265))
- Bump minimnum allowed dbt-adapters version to 1.8.0 ([#N/A](https://github.com/dbt-labs/dbt-core/issues/N/A))
- Bump minimum dbt-adapters version to 1.9.0 ([#10996](https://github.com/dbt-labs/dbt-core/issues/10996))
### Security
- Explicitly bind to localhost in docs serve ([#10209](https://github.com/dbt-labs/dbt-core/issues/10209))
### Contributors
- [@DevonFulcher](https://github.com/DevonFulcher) ([#10959](https://github.com/dbt-labs/dbt-core/issues/10959), [#10960](https://github.com/dbt-labs/dbt-core/issues/10960))
- [@McKnight-42](https://github.com/McKnight-42) ([#10197](https://github.com/dbt-labs/dbt-core/issues/10197), [#10198](https://github.com/dbt-labs/dbt-core/issues/10198))
- [@Threynaud](https://github.com/Threynaud) ([#11068](https://github.com/dbt-labs/dbt-core/issues/11068))
- [@TowardOliver](https://github.com/TowardOliver) ([#10656](https://github.com/dbt-labs/dbt-core/issues/10656))
- [@aliceliu](https://github.com/aliceliu) ([#10536](https://github.com/dbt-labs/dbt-core/issues/10536), [#10138](https://github.com/dbt-labs/dbt-core/issues/10138))
- [@courtneyholcomb](https://github.com/courtneyholcomb) ([#10360](https://github.com/dbt-labs/dbt-core/issues/10360), [#10376](https://github.com/dbt-labs/dbt-core/issues/10376), [#10475](https://github.com/dbt-labs/dbt-core/issues/10475), [#9265](https://github.com/dbt-labs/dbt-core/issues/9265), [#9265](https://github.com/dbt-labs/dbt-core/issues/9265), [#9265](https://github.com/dbt-labs/dbt-core/issues/9265))
- [@danlsn](https://github.com/danlsn) ([#10915](https://github.com/dbt-labs/dbt-core/issues/10915))
- [@dave-connors-3](https://github.com/dave-connors-3) ([#9824](https://github.com/dbt-labs/dbt-core/issues/9824))
- [@devmessias](https://github.com/devmessias) ([#8520](https://github.com/dbt-labs/dbt-core/issues/8520), [#10880](https://github.com/dbt-labs/dbt-core/issues/10880), [#10528](https://github.com/dbt-labs/dbt-core/issues/10528), [#10623](https://github.com/dbt-labs/dbt-core/issues/10623))
- [@jeancochrane](https://github.com/jeancochrane) ([#5273](https://github.com/dbt-labs/dbt-core/issues/5273))
- [@katsugeneration](https://github.com/katsugeneration) ([#10754](https://github.com/dbt-labs/dbt-core/issues/10754))
- [@kevinneville](https://github.com/kevinneville) ([#7586](https://github.com/dbt-labs/dbt-core/issues/7586))
- [@nakamichiworks](https://github.com/nakamichiworks) ([#10442](https://github.com/dbt-labs/dbt-core/issues/10442))
- [@plypaul](https://github.com/plypaul) ([#10531](https://github.com/dbt-labs/dbt-core/issues/10531))
- [@rariyama](https://github.com/rariyama) ([#8997](https://github.com/dbt-labs/dbt-core/issues/8997))
- [@scottgigante,nevdelap](https://github.com/scottgigante,nevdelap) ([#8774](https://github.com/dbt-labs/dbt-core/issues/8774))
- [@tsturge](https://github.com/tsturge) ([#9109](https://github.com/dbt-labs/dbt-core/issues/9109), [#10540](https://github.com/dbt-labs/dbt-core/issues/10540))
- [@ttusing](https://github.com/ttusing) ([#10434](https://github.com/dbt-labs/dbt-core/issues/10434))

View File

@@ -1,6 +0,0 @@
kind: Dependencies
body: Use EventCatcher from dbt-common instead of maintaining a local copy
time: 2025-11-18T15:53:54.284561+05:30
custom:
Author: 3loka
Issue: "12124"

View File

@@ -1,6 +0,0 @@
kind: Features
body: Support partial parsing for function nodes
time: 2025-10-06T14:03:52.258104-05:00
custom:
Author: QMalcolm
Issue: "12072"

View File

@@ -1,6 +0,0 @@
kind: Features
body: Allow for defining funciton arguments with default values
time: 2025-11-17T14:10:53.860178-06:00
custom:
Author: QMalcolm
Issue: "12044"

View File

@@ -1,6 +0,0 @@
kind: Features
body: Raise jsonschema-based deprecation warnings by default
time: 2025-12-01T16:52:09.354436-05:00
custom:
Author: michelleark
Issue: 12240

View File

@@ -1,6 +0,0 @@
kind: Features
body: ':bug: :snowman: Disable unit tests whose model is disabled'
time: 2025-12-03T12:29:26.209248-05:00
custom:
Author: michelleark
Issue: "10540"

View File

@@ -1,6 +0,0 @@
kind: Features
body: Implement config.meta_get and config.meta_require
time: 2025-12-10T20:20:01.354288-05:00
custom:
Author: gshank
Issue: "12012"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: Address Click 8.2+ deprecation warning
time: 2025-09-22T15:17:26.983151-06:00
custom:
Author: edgarrmondragon
Issue: "12038"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: Include macros in unit test parsing
time: 2025-11-17T14:06:49.518566-05:00
custom:
Author: michelleark nathanskone
Issue: "10157"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: Allow dbt deps to run when vars lack defaults in dbt_project.yml
time: 2025-11-17T18:50:25.759091+05:30
custom:
Author: 3loka
Issue: "8913"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: Restore DuplicateResourceNameError for intra-project node name duplication, behind behavior flag `require_unique_project_resource_names`
time: 2025-11-18T17:11:06.454784-05:00
custom:
Author: michelleark
Issue: "12152"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: Allow the usage of `function` with `--exclude-resource-type` flag
time: 2025-11-19T19:50:34.703236-06:00
custom:
Author: QMalcolm
Issue: "12143"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: Fix bug where schemas of functions weren't guaranteed to exist
time: 2025-11-24T15:56:29.467004-06:00
custom:
Author: QMalcolm
Issue: "12142"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: Fix generation of deprecations summary
time: 2025-11-24T15:57:56.544123-08:00
custom:
Author: asiunov
Issue: "12146"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: ':bug: :snowman: Correctly reference foreign key references when --defer and --state provided'
time: 2025-11-24T17:08:55.387946-05:00
custom:
Author: michellark
Issue: "11885"

View File

@@ -1,7 +0,0 @@
kind: Fixes
body: ':bug: :snowman: Add exception when using --state and referring to a removed
test'
time: 2025-11-25T12:02:46.635026-05:00
custom:
Author: emmyoop
Issue: "10630"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: ':bug: :snowman: Stop emitting `NoNodesForSelectionCriteria` three times during `build` command'
time: 2025-11-25T12:20:20.132379-06:00
custom:
Author: QMalcolm
Issue: "11627"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: ":bug: :snowman: Fix long Python stack traces appearing when package dependencies have incompatible version requirements"
time: 2025-11-27T14:13:08.082542-05:00
custom:
Author: emmyoop
Issue: "12049"

View File

@@ -1,7 +0,0 @@
kind: Fixes
body: ':bug: :snowman: Fixed issue where changing data type size/precision/scale (e.g.,
varchar(3) to varchar(10)) incorrectly triggered a breaking change error fo'
time: 2025-11-27T14:59:29.256274-05:00
custom:
Author: emmyoop
Issue: "11186"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: ':bug: :snowman: Support unit testing models that depend on sources with the same name'
time: 2025-11-27T17:01:24.193516-05:00
custom:
Author: michelleark
Issue: 11975 10433

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: Fix bug in partial parsing when updating a model with a schema file that is referenced by a singular test
time: 2025-11-28T10:21:29.911147Z
custom:
Author: mattogburke
Issue: "12223"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: ':bug: :snowman: Avoid retrying successful run-operation commands'
time: 2025-11-28T12:28:38.546261-05:00
custom:
Author: michelleark
Issue: "11850"

View File

@@ -1,7 +0,0 @@
kind: Fixes
body: ':bug: :snowman: Fix `dbt deps --add-package` crash when packages.yml contains `warn-unpinned:
false`'
time: 2025-11-28T16:19:37.608722-05:00
custom:
Author: emmyoop
Issue: "9104"

View File

@@ -1,7 +0,0 @@
kind: Fixes
body: ':bug: :snowman: Improve `dbt deps --add-package` duplicate detection with better
cross-source matching and word boundaries'
time: 2025-11-28T16:31:44.344099-05:00
custom:
Author: emmyoop
Issue: "12239"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: ':bug: :snowman: Fix false positive deprecation warning of pre/post-hook SQL configs'
time: 2025-12-02T13:37:05.012112-05:00
custom:
Author: michelleark
Issue: "12244"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: Ensure recent deprecation warnings include event name in message
time: 2025-12-09T17:50:31.334618-06:00
custom:
Author: QMalcolm
Issue: "12264"

View File

@@ -1,6 +0,0 @@
kind: Fixes
body: Improve error message clarity when detecting nodes with space in name
time: 2025-12-10T14:39:35.107841-08:00
custom:
Author: michelleark
Issue: "11835"

View File

@@ -1,6 +0,0 @@
kind: Under the Hood
body: Update jsonschemas for schema.yml and dbt_project.yml deprecations
time: 2025-11-19T11:01:10.616676-05:00
custom:
Author: michelleark
Issue: "12180"

View File

@@ -1,6 +0,0 @@
kind: Under the Hood
body: Replace setuptools and tox with hatch for build, test, and environment management.
time: 2025-11-21T14:05:15.838252-05:00
custom:
Author: emmyoop
Issue: "12151"

View File

@@ -1,6 +0,0 @@
kind: Under the Hood
body: Add add_catalog_integration call even if we have a pre-existing manifest
time: 2025-12-09T13:18:57.043254-08:00
custom:
Author: colin-rogers-dbt
Issue: "12262"

View File

@@ -41,26 +41,32 @@ newlines:
endOfVersion: 1 endOfVersion: 1
custom: custom:
- key: Author - key: Author
label: GitHub Username(s) (separated by a single space if multiple) label: GitHub Username(s) (separated by a single space if multiple)
type: string type: string
minLength: 3 minLength: 3
- key: Issue - key: Issue
label: GitHub Issue Number (separated by a single space if multiple) label: GitHub Issue Number (separated by a single space if multiple)
type: string type: string
minLength: 1 minLength: 1
footerFormat: | footerFormat: |
{{- $contributorDict := dict }} {{- $contributorDict := dict }}
{{- /* ensure we always skip snyk and dependabot */}} {{- /* ensure all names in this list are all lowercase for later matching purposes */}}
{{- $bots := list "dependabot[bot]" "snyk-bot"}} {{- $core_team := splitList " " .Env.CORE_TEAM }}
{{- /* ensure we always skip snyk and dependabot in addition to the core team */}}
{{- $maintainers := list "dependabot[bot]" "snyk-bot"}}
{{- range $team_member := $core_team }}
{{- $team_member_lower := lower $team_member }}
{{- $maintainers = append $maintainers $team_member_lower }}
{{- end }}
{{- range $change := .Changes }} {{- range $change := .Changes }}
{{- $authorList := splitList " " $change.Custom.Author }} {{- $authorList := splitList " " $change.Custom.Author }}
{{- /* loop through all authors for a single changelog */}} {{- /* loop through all authors for a single changelog */}}
{{- range $author := $authorList }} {{- range $author := $authorList }}
{{- $authorLower := lower $author }} {{- $authorLower := lower $author }}
{{- /* we only want to include non-bot contributors */}} {{- /* we only want to include non-core team contributors */}}
{{- if not (has $authorLower $bots)}} {{- if not (has $authorLower $maintainers)}}
{{- $changeList := splitList " " $change.Custom.Author }} {{- $changeList := splitList " " $change.Custom.Author }}
{{- $IssueList := list }} {{- $IssueList := list }}
{{- $changeLink := $change.Kind }} {{- $changeLink := $change.Kind }}

View File

@@ -10,5 +10,6 @@ ignore =
E704 # makes Flake8 work like black E704 # makes Flake8 work like black
E741 E741
E501 # long line checking is done in black E501 # long line checking is done in black
exclude = test/
per-file-ignores = per-file-ignores =
*/__init__.py: F401 */__init__.py: F401

View File

@@ -61,8 +61,8 @@ body:
label: Environment label: Environment
description: | description: |
examples: examples:
- **OS**: Ubuntu 24.04 - **OS**: Ubuntu 20.04
- **Python**: 3.10.12 (`python3 --version`) - **Python**: 3.9.12 (`python3 --version`)
- **dbt-core**: 1.1.1 (`dbt --version`) - **dbt-core**: 1.1.1 (`dbt --version`)
value: | value: |
- OS: - OS:

View File

@@ -12,6 +12,15 @@ contact_links:
- name: Participate in Discussions - name: Participate in Discussions
url: https://github.com/dbt-labs/dbt-core/discussions url: https://github.com/dbt-labs/dbt-core/discussions
about: Do you have a Big Idea for dbt? Read open discussions, or start a new one about: Do you have a Big Idea for dbt? Read open discussions, or start a new one
- name: Create an issue for adapters - name: Create an issue for dbt-redshift
url: https://github.com/dbt-labs/dbt-adapters/issues/new/choose url: https://github.com/dbt-labs/dbt-redshift/issues/new/choose
about: Report a bug or request a feature for an adapter about: Report a bug or request a feature for dbt-redshift
- name: Create an issue for dbt-bigquery
url: https://github.com/dbt-labs/dbt-bigquery/issues/new/choose
about: Report a bug or request a feature for dbt-bigquery
- name: Create an issue for dbt-snowflake
url: https://github.com/dbt-labs/dbt-snowflake/issues/new/choose
about: Report a bug or request a feature for dbt-snowflake
- name: Create an issue for dbt-spark
url: https://github.com/dbt-labs/dbt-spark/issues/new/choose
about: Report a bug or request a feature for dbt-spark

View File

@@ -55,8 +55,8 @@ body:
label: Environment label: Environment
description: | description: |
examples: examples:
- **OS**: Ubuntu 24.04 - **OS**: Ubuntu 20.04
- **Python**: 3.10.12 (`python3 --version`) - **Python**: 3.9.12 (`python3 --version`)
- **dbt-core (working version)**: 1.1.1 (`dbt --version`) - **dbt-core (working version)**: 1.1.1 (`dbt --version`)
- **dbt-core (regression version)**: 1.2.0 (`dbt --version`) - **dbt-core (regression version)**: 1.2.0 (`dbt --version`)
value: | value: |

8
.github/_README.md vendored
View File

@@ -120,7 +120,7 @@ Some triggers of note that we use:
```yaml ```yaml
jobs: jobs:
dependency_changelog: dependency_changelog:
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
steps: steps:
- name: Get File Name Timestamp - name: Get File Name Timestamp
@@ -188,12 +188,6 @@ ___
- The [GitHub CLI](https://cli.github.com/) is available in the default runners - The [GitHub CLI](https://cli.github.com/) is available in the default runners
- Actions run in your context. ie, using an action from the marketplace that uses the GITHUB_TOKEN uses the GITHUB_TOKEN generated by your workflow run. - Actions run in your context. ie, using an action from the marketplace that uses the GITHUB_TOKEN uses the GITHUB_TOKEN generated by your workflow run.
### Runners
- We dynamically set runners based on repository vars. Admins can view repository vars and reset them. Current values are the following but are subject to change:
- `vars.UBUNTU_LATEST` -> `ubuntu-latest`
- `vars.WINDOWS_LATEST` -> `windows-latest`
- `vars.MACOS_LATEST` -> `macos-14`
### Actions from the Marketplace ### Actions from the Marketplace
- Dont use external actions for things that can easily be accomplished manually. - Dont use external actions for things that can easily be accomplished manually.
- Always read through what an external action does before using it! Often an action in the GitHub Actions Marketplace can be replaced with a few lines in bash. This is much more maintainable (and wont change under us) and clear as to whats actually happening. It also prevents any - Always read through what an external action does before using it! Often an action in the GitHub Actions Marketplace can be replaced with a few lines in bash. This is much more maintainable (and wont change under us) and clear as to whats actually happening. It also prevents any

View File

@@ -33,7 +33,7 @@ on:
jobs: jobs:
build: build:
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Wrangle latest tag - name: Wrangle latest tag

View File

@@ -11,7 +11,7 @@ on:
jobs: jobs:
build: build:
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Wrangle latest tag - name: Wrangle latest tag

View File

@@ -1,10 +1,9 @@
import os import os
from packaging.version import Version, parse
import requests
import sys import sys
from typing import List from typing import List
import requests
from packaging.version import Version, parse
def main(): def main():
package_name: str = os.environ["INPUT_PACKAGE_NAME"] package_name: str = os.environ["INPUT_PACKAGE_NAME"]

View File

@@ -0,0 +1,19 @@
name: "Set up postgres (linux)"
description: "Set up postgres service on linux vm for dbt integration tests"
runs:
using: "composite"
steps:
- shell: bash
run: |
sudo apt-get --purge remove postgresql postgresql-*
sudo apt update -y
sudo apt install gnupg2 wget vim -y
sudo sh -c 'echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc|sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg
sudo apt update -y
sudo apt install postgresql-16
sudo apt-get -y install postgresql postgresql-contrib
sudo systemctl start postgresql
sudo systemctl enable postgresql
pg_isready
sudo -u postgres bash ${{ github.action_path }}/setup_db.sh

View File

@@ -0,0 +1 @@
../../../test/setup_db.sh

View File

@@ -0,0 +1,26 @@
name: "Set up postgres (macos)"
description: "Set up postgres service on macos vm for dbt integration tests"
runs:
using: "composite"
steps:
- shell: bash
run: |
brew install postgresql@16
brew link postgresql@16 --force
brew services start postgresql@16
echo "Check PostgreSQL service is running"
i=10
COMMAND='pg_isready'
while [ $i -gt -1 ]; do
if [ $i == 0 ]; then
echo "PostgreSQL service not ready, all attempts exhausted"
exit 1
fi
echo "Check PostgreSQL service status"
eval $COMMAND && break
echo "PostgreSQL service not ready, wait 10 more sec, attempts left: $i"
sleep 10
((i--))
done
createuser -s postgres
bash ${{ github.action_path }}/setup_db.sh

View File

@@ -0,0 +1 @@
../../../test/setup_db.sh

View File

@@ -1 +1 @@
../../../scripts/setup_db.sh ../../../test/setup_db.sh

View File

@@ -1,169 +0,0 @@
# **what?**
# Runs all tests in dbt-postgres with this branch of dbt-core to ensure nothing is broken
# **why?**
# Ensure dbt-core changes do not break dbt-postgres, as a basic proxy for other adapters
# **when?**
# This will run when trying to merge a PR into main.
# It can also be manually triggered.
# This workflow can be skipped by adding the "Skip Postgres Testing" label to the PR. This is
# useful when making a change in both `dbt-postgres` and `dbt-core` where the changes are dependant
# and cause the other repository to break.
name: "dbt-postgres Tests"
run-name: >-
${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')
&& format('dbt-postgres@{0} with dbt-core@{1}', inputs.dbt-postgres-ref, inputs.dbt-core-ref)
|| 'dbt-postgres@main with dbt-core branch' }}
on:
push:
branches:
- "main"
- "*.latest"
- "releases/*"
pull_request:
merge_group:
types: [checks_requested]
workflow_dispatch:
inputs:
dbt-postgres-ref:
description: "The branch of dbt-postgres to test against"
default: "main"
dbt-core-ref:
description: "The branch of dbt-core to test against"
default: "main"
workflow_call:
inputs:
dbt-postgres-ref:
description: "The branch of dbt-postgres to test against"
type: string
required: true
default: "main"
dbt-core-ref:
description: "The branch of dbt-core to test against"
type: string
required: true
default: "main"
permissions: read-all
# will cancel previous workflows triggered by the same event
# and for the same ref for PRs/merges or same SHA otherwise
# and for the same inputs on workflow_dispatch or workflow_call
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ contains(fromJson('["pull_request", "merge_group"]'), github.event_name) && github.event.pull_request.head.ref || github.sha }}-${{ contains(fromJson('["workflow_call", "workflow_dispatch"]'), github.event_name) && github.event.inputs.dbt-postgres-ref && github.event.inputs.dbt-core-ref || github.sha }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
job-prep:
# This allow us to run the workflow on pull_requests as well so we can always run unit tests
# and only run integration tests on merge for time purposes
name: Setup Repo Refs
runs-on: ubuntu-latest
outputs:
dbt-postgres-ref: ${{ steps.core-ref.outputs.ref }}
dbt-core-ref: ${{ steps.common-ref.outputs.ref }}
steps:
- name: "Input Refs"
id: job-inputs
run: |
echo "inputs.dbt-postgres-ref=${{ inputs.dbt-postgres-ref }}"
echo "inputs.dbt-core-ref=${{ inputs.dbt-core-ref }}"
- name: "Determine dbt-postgres ref"
id: core-ref
run: |
if [[ -z "${{ inputs.dbt-postgres-ref }}" ]]; then
REF="main"
else
REF=${{ inputs.dbt-postgres-ref }}
fi
echo "ref=$REF" >> $GITHUB_OUTPUT
- name: "Determine dbt-core ref"
id: common-ref
run: |
if [[ -z "${{ inputs.dbt-core-ref }}" ]]; then
# these will be commits instead of branches
if [[ "${{ github.event_name }}" == "merge_group" ]]; then
REF=${{ github.event.merge_group.head_sha }}
else
REF=${{ github.event.pull_request.base.sha }}
fi
else
REF=${{ inputs.dbt-core-ref }}
fi
echo "ref=$REF" >> $GITHUB_OUTPUT
- name: "Final Refs"
run: |
echo "dbt-postgres-ref=${{ steps.core-ref.outputs.ref }}"
echo "dbt-core-ref=${{ steps.common-ref.outputs.ref }}"
integration-tests-postgres:
name: "dbt-postgres integration tests"
needs: [job-prep]
runs-on: ubuntu-latest
defaults:
run:
working-directory: "./dbt-postgres"
environment:
name: "dbt-postgres"
env:
POSTGRES_TEST_HOST: ${{ vars.POSTGRES_TEST_HOST }}
POSTGRES_TEST_PORT: ${{ vars.POSTGRES_TEST_PORT }}
POSTGRES_TEST_USER: ${{ vars.POSTGRES_TEST_USER }}
POSTGRES_TEST_PASS: ${{ secrets.POSTGRES_TEST_PASS }}
POSTGRES_TEST_DATABASE: ${{ vars.POSTGRES_TEST_DATABASE }}
POSTGRES_TEST_THREADS: ${{ vars.POSTGRES_TEST_THREADS }}
services:
postgres:
image: postgres
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- ${{ vars.POSTGRES_TEST_PORT }}:5432
steps:
- name: "Check out dbt-adapters@${{ needs.job-prep.outputs.dbt-postgres-ref }}"
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4
with:
repository: dbt-labs/dbt-adapters
ref: ${{ needs.job-prep.outputs.dbt-postgres-ref }}
- name: "Set up Python"
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }}
- name: "Set environment variables"
run: |
echo "HATCH_PYTHON=${{ inputs.python-version }}" >> $GITHUB_ENV
echo "PIP_ONLY_BINARY=psycopg2-binary" >> $GITHUB_ENV
- name: "Setup test database"
run: psql -f ./scripts/setup_test_database.sql
env:
PGHOST: ${{ vars.POSTGRES_TEST_HOST }}
PGPORT: ${{ vars.POSTGRES_TEST_PORT }}
PGUSER: postgres
PGPASSWORD: postgres
PGDATABASE: postgres
- name: "Install hatch"
uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install
- name: "Run integration tests"
run: hatch run ${{ inputs.hatch-env }}:integration-tests

View File

@@ -1,186 +0,0 @@
# **what?**
# Enforces 2 reviews when artifact or validation files are modified.
# **why?**
# Ensure artifact changes receive proper review from designated team members. GitHub doesn't support
# multiple reviews on a single PR based on files changed, so we need to enforce this manually.
# **when?**
# This will run when reviews are submitted and dismissed.
name: "Enforce Additional Reviews on Artifact and Validations Changes"
permissions:
checks: write
pull-requests: write
contents: read
on:
# trigger check on review events. use pull_request_target for forks.
pull_request_target:
types: [opened, reopened, ready_for_review, synchronize, review_requested]
pull_request_review:
types: [submitted, edited, dismissed]
# only run this once per PR at a time
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
env:
required_approvals: 2
team: "core-group"
jobs:
check-reviews:
name: "Validate Additional Reviews"
runs-on: ubuntu-latest
steps:
- name: "Get list of changed files"
id: changed_files
run: |
# Fetch files as JSON and process with jq to sanitize output
gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files \
| jq -r '.[].filename' \
| while IFS= read -r file; do
# Sanitize the filename by removing any special characters and command injection attempts
clean_file=$(echo "$file" | sed 's/[^a-zA-Z0-9\.\/\-_]//g')
echo "$clean_file"
done > changed_files.txt
echo "CHANGED_FILES<<EOF" >> $GITHUB_OUTPUT
cat changed_files.txt >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Check if any artifact files changed"
id: artifact_files_changed
run: |
artifact_changes=false
while IFS= read -r file; do
# Only process if file path looks legitimate
if [[ "$file" =~ ^[a-zA-Z0-9\.\/\-_]+$ ]]; then
if [[ "$file" == "core/dbt/artifacts/"* ]] ; then
artifact_changes=true
break
fi
fi
done < changed_files.txt
echo "artifact_changes=$artifact_changes" >> $GITHUB_OUTPUT
- name: "Get Core Team Members"
if: steps.artifact_files_changed.outputs.artifact_changes == 'true'
id: core_members
run: |
gh api -H "Accept: application/vnd.github+json" \
/orgs/dbt-labs/teams/${{ env.team }}/members > core_members.json
# Extract usernames and set as multiline output
echo "membership<<EOF" >> $GITHUB_OUTPUT
jq -r '.[].login' core_members.json >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ secrets.IT_TEAM_MEMBERSHIP }}
- name: "Verify ${{ env.required_approvals }} core team approvals"
if: steps.artifact_files_changed.outputs.artifact_changes == 'true'
id: check_approvals
run: |
# Get all reviews
REVIEWS=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews)
echo "All reviews:"
echo "$REVIEWS"
# Count approved reviews from core team members (only most recent review per user)
CORE_APPROVALS=0
while IFS= read -r member; do
echo "Checking member: $member"
APPROVED=$(echo "$REVIEWS" | jq --arg user "$member" '
group_by(.user.login) |
map(select(.[0].user.login == $user) |
sort_by(.submitted_at) |
last) |
map(select(.state == "APPROVED" and (.state != "DISMISSED"))) |
length')
echo "Latest review state for $member: $APPROVED"
CORE_APPROVALS=$((CORE_APPROVALS + APPROVED))
echo "Running total: $CORE_APPROVALS"
done <<< "${{ steps.core_members.outputs.membership }}"
echo "CORE_APPROVALS=$CORE_APPROVALS" >> $GITHUB_OUTPUT
echo "CORE_APPROVALS=$CORE_APPROVALS"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Find Comment"
if: steps.artifact_files_changed.outputs.artifact_changes == 'true' && steps.check_approvals.outputs.CORE_APPROVALS < env.required_approvals
uses: peter-evans/find-comment@a54c31d7fa095754bfef525c0c8e5e5674c4b4b1 # peter-evans/find-comment@v2
id: find-comment
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: "### Additional Artifact Review Required"
- name: "Create Comment"
if: steps.artifact_files_changed.outputs.artifact_changes == 'true' && steps.find-comment.outputs.comment-id == '' && steps.check_approvals.outputs.CORE_APPROVALS < env.required_approvals
uses: peter-evans/create-or-update-comment@23ff15729ef2fc348714a3bb66d2f655ca9066f2 # peter-evans/create-or-update-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
body: |
### Additional Artifact Review Required
Changes to artifact directory files requires at least ${{ env.required_approvals }} approvals from core team members.
- name: "Notify if not enough approvals"
if: steps.artifact_files_changed.outputs.artifact_changes == 'true'
run: |
if [[ "${{ steps.check_approvals.outputs.CORE_APPROVALS }}" -ge "${{ env.required_approvals }}" ]]; then
title="Extra requirements met"
message="Changes to artifact directory files requires at least ${{ env.required_approvals }} approvals from core team members. Current number of core team approvals: ${{ steps.check_approvals.outputs.CORE_APPROVALS }} "
echo "::notice title=$title::$message"
echo "REVIEW_STATUS=success" >> $GITHUB_OUTPUT
else
title="PR Approval Requirements Not Met"
message="Changes to artifact directory files requires at least ${{ env.required_approvals }} approvals from core team members. Current number of core team approvals: ${{ steps.check_approvals.outputs.CORE_APPROVALS }} "
echo "::notice title=$title::$message"
echo "REVIEW_STATUS=neutral" >> $GITHUB_OUTPUT
fi
id: review_check
- name: "Set check status"
id: status_check
run: |
if [[ "${{ steps.artifact_files_changed.outputs.artifact_changes }}" == 'false' ]]; then
# no extra review required
echo "current_status=success" >> $GITHUB_OUTPUT
elif [[ "${{ steps.review_check.outputs.REVIEW_STATUS }}" == "success" ]]; then
# we have all the required reviews
echo "current_status=success" >> $GITHUB_OUTPUT
else
# neutral exit - neither success nor failure
# we can't fail here because we use multiple triggers for this workflow and they won't reset the check
# workaround is to use a neutral exit to skip the check run until it's actually successful
echo "current_status=neutral" >> $GITHUB_OUTPUT
fi
- name: "Post Event"
# This step posts the status of the check because the workflow is triggered by multiple events
# and we need to ensure the check is always updated. Otherwise we would end up with duplicate
# checks in the GitHub UI.
run: |
if [[ "${{ steps.status_check.outputs.current_status }}" == "success" ]]; then
state="success"
else
state="failure"
fi
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
/repos/${{ github.repository }}/statuses/${{ github.event.pull_request.base.sha }} \
-f state="$state" \
-f description="Artifact Review Check" \
-f context="Artifact Review Check" \
-f target_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
env:
GH_TOKEN: ${{ secrets.FISHTOWN_BOT_PAT }}

View File

@@ -1,50 +0,0 @@
# **what?**
# Check if the an issue is opened near or during an extended holiday period.
# If so, post an automatically-generated comment about the holiday for bug reports.
# Also provide specific information to customers of dbt Cloud.
# **why?**
# Explain why responses will be delayed during our holiday period.
# **when?**
# This will run when new issues are opened.
name: Auto-Respond to Bug Reports During Holiday Period
on:
issues:
types:
- opened
permissions:
contents: read
issues: write
jobs:
auto-response:
runs-on: ${{ vars.UBUNTU_LATEST }}
steps:
- name: Check if current date is within holiday period
id: date-check
run: |
current_date=$(date -u +"%Y-%m-%d")
start_date="2024-12-23"
end_date="2025-01-05"
if [[ "$current_date" < "$start_date" || "$current_date" > "$end_date" ]]; then
echo "outside_holiday=true" >> $GITHUB_ENV
else
echo "outside_holiday=false" >> $GITHUB_ENV
fi
- name: Post comment
if: ${{ env.outside_holiday == 'false' && contains(github.event.issue.labels.*.name, 'bug') }}
run: |
gh issue comment ${{ github.event.issue.number }} --repo ${{ github.repository }} --body "Thank you for your bug report! Our team is will be out of the office for [Christmas and our Global Week of Rest](https://handbook.getdbt.com/docs/time_off#2024-us-holidays), from December 25, 2024, through January 3, 2025.
We will review your issue as soon as possible after returning.
Thank you for your understanding, and happy holidays! 🎄🎉
If you are a customer of dbt Cloud, please contact our Customer Support team via the dbt Cloud web interface or email **support@dbtlabs.com**."
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -28,13 +28,13 @@ permissions:
jobs: jobs:
backport: backport:
name: Backport name: Backport
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
# Only react to merged PRs for security reasons. # Only react to merged PRs for security reasons.
# See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target. # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target.
if: > if: >
github.event.pull_request.merged github.event.pull_request.merged
&& contains(github.event.label.name, 'backport') && contains(github.event.label.name, 'backport')
steps: steps:
- uses: tibdex/backport@9565281eda0731b1d20c4025c43339fb0a23812e # tibdex/backport@v2.0.4 - uses: tibdex/backport@v2.0.4
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -41,14 +41,14 @@ jobs:
include: include:
- label: "dependencies" - label: "dependencies"
changie_kind: "Dependencies" changie_kind: "Dependencies"
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
steps: steps:
- name: Create and commit changelog on bot PR - name: Create and commit changelog on bot PR
if: ${{ contains(github.event.pull_request.labels.*.name, matrix.label) }} if: ${{ contains(github.event.pull_request.labels.*.name, matrix.label) }}
id: bot_changelog id: bot_changelog
uses: emmyoop/changie_bot@22b70618b13d0d1c64ea95212bafca2d2bf6b764 # emmyoop/changie_bot@v1.1.0 uses: emmyoop/changie_bot@v1.1.0
with: with:
GITHUB_TOKEN: ${{ secrets.FISHTOWN_BOT_PAT }} GITHUB_TOKEN: ${{ secrets.FISHTOWN_BOT_PAT }}
commit_author_name: "Github Build Bot" commit_author_name: "Github Build Bot"

View File

@@ -4,26 +4,22 @@ on:
pull_request: pull_request:
types: [ opened, reopened, labeled, unlabeled, synchronize ] types: [ opened, reopened, labeled, unlabeled, synchronize ]
paths-ignore: [ '.changes/**', '.github/**', 'tests/**', '**.md', '**.yml' ] paths-ignore: [ '.changes/**', '.github/**', 'tests/**', '**.md', '**.yml' ]
merge_group:
types: [checks_requested]
workflow_dispatch:
permissions: workflow_dispatch:
contents: read
jobs: jobs:
check-artifact-changes: check-artifact-changes:
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
if: ${{ !contains(github.event.pull_request.labels.*.name, 'artifact_minor_upgrade') }} if: ${{ !contains(github.event.pull_request.labels.*.name, 'artifact_minor_upgrade') }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Check for changes in core/dbt/artifacts - name: Check for changes in core/dbt/artifacts
# https://github.com/marketplace/actions/paths-changes-filter # https://github.com/marketplace/actions/paths-changes-filter
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # dorny/paths-filter@v3 uses: dorny/paths-filter@v3
id: check_artifact_changes id: check_artifact_changes
with: with:
filters: | filters: |

View File

@@ -7,6 +7,7 @@
# **when?** # **when?**
# When a PR is opened, not in draft or moved from draft to ready for review # When a PR is opened, not in draft or moved from draft to ready for review
name: Label community PRs name: Label community PRs
on: on:
@@ -28,15 +29,9 @@ jobs:
# If this PR is opened and not draft, determine if it needs to be labeled # If this PR is opened and not draft, determine if it needs to be labeled
# if the PR is converted out of draft, determine if it needs to be labeled # if the PR is converted out of draft, determine if it needs to be labeled
if: | if: |
( (!contains(github.event.pull_request.labels.*.name, 'community') &&
!contains(github.event.pull_request.labels.*.name, 'community') (github.event.action == 'opened' && github.event.pull_request.draft == false ) ||
&& ( github.event.action == 'ready_for_review' )
(github.event.action == 'opened' && github.event.pull_request.draft == false)
|| github.event.action == 'ready_for_review'
)
&& github.event.pull_request.user.type != 'Bot'
&& github.event.pull_request.user.login != 'dependabot[bot]'
)
uses: dbt-labs/actions/.github/workflows/label-community.yml@main uses: dbt-labs/actions/.github/workflows/label-community.yml@main
with: with:
github_team: 'core-group' github_team: 'core-group'

View File

@@ -1,44 +1,25 @@
# **what?** # **what?**
# Cuts the `*.latest` branch, bumps dependencies on it, cleans up all files in `.changes/unreleased` # Cuts a new `*.latest` branch
# and `.changes/previous verion on main and bumps main to the input version. # Also cleans up all files in `.changes/unreleased` and `.changes/previous verion on
# `main` and bumps `main` to the input version.
# **why?** # **why?**
# Clean up the main branch after a release branch is cut and automate cutting the release branch. # Generally reduces the workload of engineers and reduces error. Allow automation.
# Generally reduces the workload of engineers and reducing error.
# **when?** # **when?**
# This will run when called manually or when triggered in another workflow. # This will run when called manually.
# Example Usage including required permissions: TODO: update once finalized
# permissions:
# contents: read
# pull-requests: write
#
# name: Cut Release Branch
# jobs:
# changelog:
# uses: dbt-labs/actions/.github/workflows/cut-release-branch.yml@main
# with:
# new_branch_name: 1.7.latest
# PR_title: "Cleanup main after cutting new 1.7.latest branch"
# PR_body: "All adapter PRs will fail CI until the dbt-core PR has been merged due to release version conflicts."
# secrets:
# FISHTOWN_BOT_PAT: ${{ secrets.FISHTOWN_BOT_PAT }}
# TODOs
# add note to eventually commit changes directly and bypass checks - same as release - when we move to this model run test action after merge
name: Cut new release branch name: Cut new release branch
run-name: "Cutting New Branch: ${{ inputs.new_branch_name }}"
on: on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
new_branch_name: version_to_bump_main:
description: "The full name of the new branch (ex. 1.5.latest)" description: 'The alpha version main should bump to (ex. 1.6.0a1)'
required: true
new_branch_name:
description: 'The full name of the new branch (ex. 1.5.latest)'
required: true required: true
type: string
defaults: defaults:
run: run:
@@ -46,346 +27,15 @@ defaults:
permissions: permissions:
contents: write contents: write
pull-requests: write
env:
PYTHON_TARGET_VERSION: "3.10"
PR_TITLE: "Cleanup main after cutting new ${{ inputs.new_branch_name }} branch"
PR_BODY: "All adapter PRs will fail CI until the dbt-core PR has been merged due to release version conflicts."
jobs: jobs:
prep_work: cut_branch:
name: "Prep Work" name: "Cut branch and clean up main for dbt-core"
runs-on: ubuntu-latest uses: dbt-labs/actions/.github/workflows/cut-release-branch.yml@main
steps:
- name: "[DEBUG] Print Inputs"
run: |
echo "new_branch_name: ${{ inputs.new_branch_name }}"
echo "PR_title: ${{ env.PR_TITLE }}"
echo "PR_body: ${{ env.PR_BODY }}"
create_temp_branch:
name: "Create Temp branch off main"
runs-on: ubuntu-latest
outputs:
temp_branch_name: ${{ steps.variables.outputs.BRANCH_NAME }}
steps:
- name: "Set Branch Value"
id: variables
run: |
echo "BRANCH_NAME=cutting_release_branch/main_cleanup_$GITHUB_RUN_ID" >> $GITHUB_OUTPUT
- name: "Checkout ${{ github.repository }}"
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4
with: with:
ref: "main" version_to_bump_main: ${{ inputs.version_to_bump_main }}
token: ${{ secrets.FISHTOWN_BOT_PAT }} new_branch_name: ${{ inputs.new_branch_name }}
PR_title: "Cleanup main after cutting new ${{ inputs.new_branch_name }} branch"
- name: "Create PR Branch" PR_body: "All adapter PRs will fail CI until the dbt-core PR has been merged due to release version conflicts."
run: | secrets:
user="Github Build Bot" FISHTOWN_BOT_PAT: ${{ secrets.FISHTOWN_BOT_PAT }}
email="buildbot@fishtownanalytics.com"
git config user.name "$user"
git config user.email "$email"
git checkout -b ${{ steps.variables.outputs.BRANCH_NAME }}
git push --set-upstream origin ${{ steps.variables.outputs.BRANCH_NAME }}
- name: "[Notification] Temp branch created"
run: |
message="Temp branch ${{ steps.variables.outputs.BRANCH_NAME }} created"
echo "::notice title="Temporary branch created": $title::$message"
cleanup_changelog:
name: "Clean Up Changelog"
needs: ["create_temp_branch"]
runs-on: ubuntu-latest
outputs:
next-version: ${{ steps.semver-current.outputs.next-minor-alpha-version }}
steps:
- name: "Checkout ${{ github.repository }}"
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4
with:
ref: ${{ needs.create_temp_branch.outputs.temp_branch_name }}
token: ${{ secrets.FISHTOWN_BOT_PAT }}
- name: "Add Homebrew To PATH"
run: |
echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH
- name: "Install Homebrew Packages"
run: |
brew install pre-commit
brew tap miniscruff/changie https://github.com/miniscruff/changie
brew install changie
- name: "Check Current Version In Code"
id: determine_version
run: |
current_version=$(grep '^version = ' core/pyproject.toml | sed 's/version = "\(.*\)"/\1/')
echo "current_version=$current_version" >> $GITHUB_OUTPUT
- name: "[Notification] Check Current Version In Code"
run: |
message="The current version is ${{ steps.determine_version.outputs.current_version }}"
echo "::notice title="Version Bump Check": $title::$message"
- name: "Parse Current Version Into Parts for Changelog Directories"
id: semver-current
uses: dbt-labs/actions/parse-semver@main
with:
version: ${{ steps.determine_version.outputs.current_version }}
- name: "[Notification] Next Alpha Version"
run: |
message="The next alpha version is ${{ steps.semver-current.outputs.next-minor-alpha-version }}"
echo "::notice title="Version Bump Check": $title::$message"
- name: "Delete Unreleased Changelog YAMLs"
# removal fails if no files exist. OK to continue since we're just cleaning up the files.
continue-on-error: true
run: |
rm .changes/unreleased/*.yaml || true
- name: "Delete Pre Release Changelogs and YAMLs"
# removal fails if no files exist. OK to continue since we're just cleaning up the files.
continue-on-error: true
run: |
rm .changes/${{ steps.semver-current.outputs.base-version }}/*.yaml || true
rm .changes/${{ steps.semver-current.outputs.major }}.${{ steps.semver-current.outputs.minor }}.*.md || true
- name: "Cleanup CHANGELOG.md"
run: |
changie merge
- name: "Commit Changelog Cleanup to Branch"
run: |
user="Github Build Bot"
email="buildbot@fishtownanalytics.com"
git config user.name "$user"
git config user.email "$email"
git status
git add .
git commit -m "Clean up changelog on main"
git push
- name: "[Notification] Changelog cleaned up"
run: |
message="Changelog on ${{ needs.create_temp_branch.outputs.temp_branch_name }} cleaned up"
echo "::notice title="Changelog cleaned up": $title::$message"
bump_version:
name: "Bump to next minor version"
needs: ["cleanup_changelog", "create_temp_branch"]
runs-on: ubuntu-latest
steps:
- name: "Checkout ${{ github.repository }}"
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4
with:
ref: ${{ needs.create_temp_branch.outputs.temp_branch_name }}
token: ${{ secrets.FISHTOWN_BOT_PAT }}
- name: "Set up Python - ${{ env.PYTHON_TARGET_VERSION }}"
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # actions/setup-python@v5
with:
python-version: "${{ env.PYTHON_TARGET_VERSION }}"
- name: "Install Spark Dependencies"
if: ${{ contains(github.repository, 'dbt-labs/dbt-spark') }}
run: |
sudo apt-get update
sudo apt-get install libsasl2-dev
- name: "Install Python Dependencies"
run: |
python -m pip install --upgrade pip
python -m pip install hatch
- name: "Bump Version To ${{ needs.cleanup_changelog.outputs.next-version }}"
run: |
cd core
hatch version ${{ needs.cleanup_changelog.outputs.next-version }}
hatch run dev-req
dbt --version
- name: "Commit Version Bump to Branch"
run: |
user="Github Build Bot"
email="buildbot@fishtownanalytics.com"
git config user.name "$user"
git config user.email "$email"
git status
git add .
git commit -m "Bumping version to ${{ needs.cleanup_changelog.outputs.next-version }}"
git push
- name: "[Notification] Version Bump completed"
run: |
message="Version on ${{ needs.create_temp_branch.outputs.temp_branch_name }} bumped to ${{ needs.cleanup_changelog.outputs.next-version }}"
echo "::notice title="Version Bump Completed": $title::$message"
cleanup:
name: "Cleanup Code Quality"
needs: ["create_temp_branch", "bump_version"]
runs-on: ubuntu-latest
steps:
- name: "Checkout ${{ github.repository }}"
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4
with:
ref: ${{ needs.create_temp_branch.outputs.temp_branch_name }}
token: ${{ secrets.FISHTOWN_BOT_PAT }}
- name: "Add Homebrew To PATH"
run: |
echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH
- name: "brew install pre-commit"
run: |
brew install pre-commit
# this step will fail on whitespace errors but also correct them
- name: "Cleanup - Remove Trailing Whitespace Via Pre-commit"
continue-on-error: true
run: |
pre-commit run trailing-whitespace --files CHANGELOG.md .changes/* || true
# this step will fail on newline errors but also correct them
- name: "Cleanup - Remove Extra Newlines Via Pre-commit"
continue-on-error: true
run: |
pre-commit run end-of-file-fixer --files CHANGELOG.md .changes/* || true
- name: "Commit Version Bump to Branch"
run: |
user="Github Build Bot"
email="buildbot@fishtownanalytics.com"
git config user.name "$user"
git config user.email "$email"
git status
git add .
git commit -m "Code quality cleanup"
git push
open_pr:
name: "Open PR Against main"
needs: ["cleanup_changelog", "create_temp_branch", "cleanup"]
runs-on: ubuntu-latest
outputs:
pr_number: ${{ steps.create_pr.outputs.pull-request-number }}
steps:
- name: "Checkout ${{ github.repository }}"
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4
with:
ref: ${{ needs.create_temp_branch.outputs.temp_branch_name }}
token: ${{ secrets.FISHTOWN_BOT_PAT }}
- name: "Determine PR Title"
id: pr_title
run: |
echo "pr_title=${{ env.PR_TITLE }}" >> $GITHUB_OUTPUT
if [${{ env.PR_TITLE }} == ""]; then
echo "pr_title='Clean up changelogs and bump to version ${{ needs.cleanup_changelog.outputs.next-version }}'" >> $GITHUB_OUTPUT
fi
- name: "Determine PR Body"
id: pr_body
run: |
echo "pr_body=${{ env.PR_BODY }}" >> $GITHUB_OUTPUT
if [${{ env.PR_BODY }} == ""]; then
echo "pr_body='Clean up changelogs and bump to version ${{ needs.cleanup_changelog.outputs.next-version }}'" >> $GITHUB_OUTPUT
fi
- name: "Add Branch Details"
id: pr_body_branch
run: |
branch_details="The workflow that generated this PR also created a new branch: ${{ inputs.new_branch_name }}"
full_body="${{ steps.pr_body.outputs.pr_body }} $branch_details"
echo "pr_full_body=$full_body" >> $GITHUB_OUTPUT
- name: "Open Pull Request"
id: create_pr
run: |
pr_url=$(gh pr create -B main -H ${{ needs.create_temp_branch.outputs.temp_branch_name }} -l "Skip Changelog" -t "${{ steps.pr_title.outputs.pr_title }}" -b "${{ steps.pr_body_branch.outputs.pr_full_body }}")
echo "pr_url=$pr_url" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ secrets.FISHTOWN_BOT_PAT }}
- name: "[Notification] Pull Request Opened"
run: |
message="PR opened at ${{ steps.create_pr.outputs.pr_url }}"
echo "::notice title="Pull Request Opened": $title::$message"
cut_new_branch:
# don't cut the new branch until we're done opening the PR against main
name: "Cut New Branch ${{ inputs.new_branch_name }}"
needs: [open_pr]
runs-on: ubuntu-latest
steps:
- name: "Checkout ${{ github.repository }}"
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4
with:
token: ${{ secrets.FISHTOWN_BOT_PAT }}
fetch-depth: 0
- name: "Ensure New Branch Does Not Exist"
id: check_new_branch
run: |
title="Check New Branch Existence"
if git show-ref --quiet ${{ inputs.new_branch_name }}; then
message="Branch ${{ inputs.new_branch_name }} already exists. Exiting."
echo "::error $title::$message"
exit 1
fi
- name: "Create New Release Branch"
run: |
git checkout -b ${{ inputs.new_branch_name }}
- name: "Push up New Branch"
run: |
#Data for commit
user="Github Build Bot"
email="buildbot@fishtownanalytics.com"
git config user.name "$user"
git config user.email "$email"
git push --set-upstream origin ${{ inputs.new_branch_name }}
- name: "[Notification] New branch created"
run: |
message="New branch ${{ inputs.new_branch_name }} created"
echo "::notice title="New branch created": $title::$message"
- name: "Bump dependencies via script"
# This bumps the dependency on dbt-core in the adapters
if: ${{ !contains(github.repository, 'dbt-core') }}
run: |
echo ${{ github.repository }}
echo "running update_dependencies script"
bash ${GITHUB_WORKSPACE}/.github/scripts/update_dependencies.sh ${{ inputs.new_branch_name }}
commit_message="bumping .latest branch variable in update_dependencies.sh to ${{ inputs.new_branch_name }}"
git status
git add .
git commit -m "$commit_message"
git push
- name: "Bump env variable via script"
# bumps the RELEASE_BRANCH variable in nightly-release.yml in adapters
if: ${{ !contains(github.repository, 'dbt-core') }}
run: |
file="./.github/scripts/update_release_branch.sh"
if test -f "$file"; then
echo ${{ github.repository }}
echo "running some script yet to be written now"
bash $file ${{ inputs.new_branch_name }}
commit_message="updating env variable to ${{ inputs.new_branch_name }} in nightly-release.yml"
git status
git add .
git commit -m "$commit_message"
git push
else
echo "no $file seen skipping step"
fi

View File

@@ -20,8 +20,6 @@ on:
- "*.latest" - "*.latest"
- "releases/*" - "releases/*"
pull_request: pull_request:
merge_group:
types: [checks_requested]
workflow_dispatch: workflow_dispatch:
permissions: read-all permissions: read-all
@@ -49,33 +47,27 @@ jobs:
steps: steps:
- name: Check out the repository - name: Check out the repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: "3.10" python-version: '3.9'
- name: Install python dependencies - name: Install python dependencies
run: | run: |
python -m pip install --user --upgrade pip python -m pip install --user --upgrade pip
python -m pip --version python -m pip --version
python -m pip install hatch make dev
cd core make dev_req
hatch run setup mypy --version
dbt --version
- name: Verify dbt installation
run: |
cd core
hatch run dbt --version
- name: Run pre-commit hooks - name: Run pre-commit hooks
run: | run: pre-commit run --all-files --show-diff-on-failure
cd core
hatch run code-quality
unit: unit:
name: "unit test / python ${{ matrix.python-version }}" name: unit test / python ${{ matrix.python-version }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 10 timeout-minutes: 10
@@ -83,14 +75,17 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"] python-version: [ "3.9", "3.10", "3.11", "3.12" ]
env:
TOXENV: "unit"
steps: steps:
- name: Check out the repository - name: Check out the repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
@@ -98,15 +93,15 @@ jobs:
run: | run: |
python -m pip install --user --upgrade pip python -m pip install --user --upgrade pip
python -m pip --version python -m pip --version
python -m pip install hatch python -m pip install tox
hatch --version tox --version
- name: Run unit tests - name: Run unit tests
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # nick-fields/retry@v3 uses: nick-fields/retry@v3
with: with:
timeout_minutes: 10 timeout_minutes: 10
max_attempts: 3 max_attempts: 3
command: cd core && hatch run ci:unit-tests command: tox -e unit
- name: Get current date - name: Get current date
if: always() if: always()
@@ -117,11 +112,10 @@ jobs:
- name: Upload Unit Test Coverage to Codecov - name: Upload Unit Test Coverage to Codecov
if: ${{ matrix.python-version == '3.11' }} if: ${{ matrix.python-version == '3.11' }}
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # codecov/codecov-action@v5 uses: codecov/codecov-action@v4
with: with:
token: ${{ secrets.CODECOV_TOKEN }} token: ${{ secrets.CODECOV_TOKEN }}
flags: unit flags: unit
fail_ci_if_error: false
integration-metadata: integration-metadata:
name: integration test metadata generation name: integration test metadata generation
@@ -146,7 +140,7 @@ jobs:
- name: generate include - name: generate include
id: generate-include id: generate-include
run: | run: |
INCLUDE=('"python-version":"3.10","os":"windows-latest"' '"python-version":"3.10","os":"macos-14"' ) INCLUDE=('"python-version":"3.9","os":"windows-latest"' '"python-version":"3.9","os":"macos-14"' )
INCLUDE_GROUPS="[" INCLUDE_GROUPS="["
for include in ${INCLUDE[@]}; do for include in ${INCLUDE[@]}; do
for group in $(seq 1 ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }}); do for group in $(seq 1 ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }}); do
@@ -158,102 +152,7 @@ jobs:
echo "include=${INCLUDE_GROUPS}" echo "include=${INCLUDE_GROUPS}"
echo "include=${INCLUDE_GROUPS}" >> $GITHUB_OUTPUT echo "include=${INCLUDE_GROUPS}" >> $GITHUB_OUTPUT
integration-postgres: integration:
name: "(${{ matrix.split-group }}) integration test / python ${{ matrix.python-version }} / ${{ matrix.os }}"
runs-on: ${{ matrix.os }}
timeout-minutes: 30
needs:
- integration-metadata
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
os: ["ubuntu-latest"]
split-group: ${{ fromJson(needs.integration-metadata.outputs.split-groups) }}
env:
DBT_INVOCATION_ENV: github-actions
DBT_TEST_USER_1: dbt_test_user_1
DBT_TEST_USER_2: dbt_test_user_2
DBT_TEST_USER_3: dbt_test_user_3
DD_CIVISIBILITY_AGENTLESS_ENABLED: true
DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}
DD_SITE: datadoghq.com
DD_ENV: ci
DD_SERVICE: ${{ github.event.repository.name }}
services:
# Label used to access the service container
postgres:
# Docker Hub image
image: postgres
# Provide the password for postgres
env:
POSTGRES_PASSWORD: password
POSTGRES_USER: postgres
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out the repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Run postgres setup script
run: |
./scripts/setup_db.sh
env:
PGHOST: localhost
PGPORT: 5432
PGPASSWORD: password
- name: Install python tools
run: |
python -m pip install --user --upgrade pip
python -m pip --version
python -m pip install hatch
hatch --version
- name: Run integration tests
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
shell: bash
command: cd core && hatch run ci:integration-tests -- --ddtrace --splits ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }} --group ${{ matrix.split-group }}
- name: Get current date
if: always()
id: date
run: |
CURRENT_DATE=$(date +'%Y-%m-%dT%H_%M_%S') # no colons allowed for artifacts
echo "date=$CURRENT_DATE" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # actions/upload-artifact@v4
if: always()
with:
name: logs_${{ matrix.python-version }}_${{ matrix.os }}_${{ matrix.split-group }}_${{ steps.date.outputs.date }}
path: ./logs
- name: Upload Integration Test Coverage to Codecov
if: ${{ matrix.python-version == '3.11' }}
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: integration
fail_ci_if_error: false
integration-mac-windows:
name: (${{ matrix.split-group }}) integration test / python ${{ matrix.python-version }} / ${{ matrix.os }} name: (${{ matrix.split-group }}) integration test / python ${{ matrix.python-version }} / ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@@ -263,9 +162,12 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
# already includes split group and runs mac + windows python-version: [ "3.9", "3.10", "3.11", "3.12" ]
os: [ubuntu-20.04]
split-group: ${{ fromJson(needs.integration-metadata.outputs.split-groups) }}
include: ${{ fromJson(needs.integration-metadata.outputs.include) }} include: ${{ fromJson(needs.integration-metadata.outputs.include) }}
env: env:
TOXENV: integration
DBT_INVOCATION_ENV: github-actions DBT_INVOCATION_ENV: github-actions
DBT_TEST_USER_1: dbt_test_user_1 DBT_TEST_USER_1: dbt_test_user_1
DBT_TEST_USER_2: dbt_test_user_2 DBT_TEST_USER_2: dbt_test_user_2
@@ -278,21 +180,20 @@ jobs:
steps: steps:
- name: Check out the repository - name: Check out the repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Set up postgres (linux)
if: runner.os == 'Linux'
uses: ./.github/actions/setup-postgres-linux
- name: Set up postgres (macos) - name: Set up postgres (macos)
if: runner.os == 'macOS' if: runner.os == 'macOS'
uses: ./.github/actions/setup-postgres-macos
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: ./scripts/setup_db.sh
- name: Set up postgres (windows) - name: Set up postgres (windows)
if: runner.os == 'Windows' if: runner.os == 'Windows'
@@ -302,16 +203,17 @@ jobs:
run: | run: |
python -m pip install --user --upgrade pip python -m pip install --user --upgrade pip
python -m pip --version python -m pip --version
python -m pip install hatch python -m pip install tox
hatch --version tox --version
- name: Run integration tests - name: Run integration tests
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # nick-fields/retry@v3 uses: nick-fields/retry@v3
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
shell: bash command: tox -- --ddtrace
command: cd core && hatch run ci:integration-tests -- --ddtrace --splits ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }} --group ${{ matrix.split-group }} env:
PYTEST_ADDOPTS: ${{ format('--splits {0} --group {1}', env.PYTHON_INTEGRATION_TEST_WORKERS, matrix.split-group) }}
- name: Get current date - name: Get current date
if: always() if: always()
@@ -320,7 +222,7 @@ jobs:
CURRENT_DATE=$(date +'%Y-%m-%dT%H_%M_%S') # no colons allowed for artifacts CURRENT_DATE=$(date +'%Y-%m-%dT%H_%M_%S') # no colons allowed for artifacts
echo "date=$CURRENT_DATE" >> $GITHUB_OUTPUT echo "date=$CURRENT_DATE" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: logs_${{ matrix.python-version }}_${{ matrix.os }}_${{ matrix.split-group }}_${{ steps.date.outputs.date }} name: logs_${{ matrix.python-version }}_${{ matrix.os }}_${{ matrix.split-group }}_${{ steps.date.outputs.date }}
@@ -328,20 +230,19 @@ jobs:
- name: Upload Integration Test Coverage to Codecov - name: Upload Integration Test Coverage to Codecov
if: ${{ matrix.python-version == '3.11' }} if: ${{ matrix.python-version == '3.11' }}
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # codecov/codecov-action@v5 uses: codecov/codecov-action@v4
with: with:
token: ${{ secrets.CODECOV_TOKEN }} token: ${{ secrets.CODECOV_TOKEN }}
flags: integration flags: integration
fail_ci_if_error: false
integration-report: integration-report:
if: ${{ always() }} if: ${{ always() }}
name: Integration Test Suite name: Integration Test Suite
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [integration-mac-windows, integration-postgres] needs: integration
steps: steps:
- name: "Integration Tests Failed" - name: "Integration Tests Failed"
if: ${{ contains(needs.integration-mac-windows.result, 'failure') || contains(needs.integration-mac-windows.result, 'cancelled') || contains(needs.integration-postgres.result, 'failure') || contains(needs.integration-postgres.result, 'cancelled') }} if: ${{ contains(needs.integration.result, 'failure') || contains(needs.integration.result, 'cancelled') }}
# when this is true the next step won't execute # when this is true the next step won't execute
run: | run: |
echo "::notice title='Integration test suite failed'" echo "::notice title='Integration test suite failed'"
@@ -358,17 +259,17 @@ jobs:
steps: steps:
- name: Check out the repository - name: Check out the repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: "3.10" python-version: '3.9'
- name: Install python dependencies - name: Install python dependencies
run: | run: |
python -m pip install --user --upgrade pip python -m pip install --user --upgrade pip
python -m pip install --upgrade hatch twine check-wheel-contents python -m pip install --upgrade setuptools wheel twine check-wheel-contents
python -m pip --version python -m pip --version
- name: Build distributions - name: Build distributions
@@ -377,7 +278,27 @@ jobs:
- name: Show distributions - name: Show distributions
run: ls -lh dist/ run: ls -lh dist/
- name: Check and verify distributions - name: Check distribution descriptions
run: | run: |
cd core twine check dist/*
hatch run build:check-all
- name: Check wheel contents
run: |
check-wheel-contents dist/*.whl --ignore W007,W008
- name: Install wheel distributions
run: |
find ./dist/*.whl -maxdepth 1 -type f | xargs python -m pip install --force-reinstall --find-links=dist/
- name: Check wheel distributions
run: |
dbt --version
- name: Install source distributions
# ignore dbt-1.0.0, which intentionally raises an error when installed from source
run: |
find ./dist/*.gz -maxdepth 1 -type f | xargs python -m pip install --force-reinstall --find-links=dist/
- name: Check source distributions
run: |
dbt --version

265
.github/workflows/model_performance.yml vendored Normal file
View File

@@ -0,0 +1,265 @@
# **what?**
# This workflow models the performance characteristics of a point in time in dbt.
# It runs specific dbt commands on committed projects multiple times to create and
# commit information about the distribution to the current branch. For more information
# see the readme in the performance module at /performance/README.md.
#
# **why?**
# When developing new features, we can take quick performance samples and compare
# them against the commited baseline measurements produced by this workflow to detect
# some performance regressions at development time before they reach users.
#
# **when?**
# This is only run once directly after each release (for non-prereleases). If for some
# reason the results of a run are not satisfactory, it can also be triggered manually.
name: Model Performance Characteristics
on:
# runs after non-prereleases are published.
release:
types: [released]
# run manually from the actions tab
workflow_dispatch:
inputs:
release_id:
description: 'dbt version to model (must be non-prerelease in Pypi)'
type: string
required: true
env:
RUNNER_CACHE_PATH: performance/runner/target/release/runner
# both jobs need to write
permissions:
contents: write
pull-requests: write
jobs:
set-variables:
name: Setting Variables
runs-on: ubuntu-latest
outputs:
cache_key: ${{ steps.variables.outputs.cache_key }}
release_id: ${{ steps.semver.outputs.base-version }}
release_branch: ${{ steps.variables.outputs.release_branch }}
steps:
# explicitly checkout the performance runner from main regardless of which
# version we are modeling.
- name: Checkout
uses: actions/checkout@v4
with:
ref: main
- name: Parse version into parts
id: semver
uses: dbt-labs/actions/parse-semver@v1
with:
version: ${{ github.event.inputs.release_id || github.event.release.tag_name }}
# collect all the variables that need to be used in subsequent jobs
- name: Set variables
id: variables
run: |
# create a cache key that will be used in the next job. without this the
# next job would have to checkout from main and hash the files itself.
echo "cache_key=${{ runner.os }}-${{ hashFiles('performance/runner/Cargo.toml')}}-${{ hashFiles('performance/runner/src/*') }}" >> $GITHUB_OUTPUT
branch_name="${{steps.semver.outputs.major}}.${{steps.semver.outputs.minor}}.latest"
echo "release_branch=$branch_name" >> $GITHUB_OUTPUT
echo "release branch is inferred to be ${branch_name}"
latest-runner:
name: Build or Fetch Runner
runs-on: ubuntu-latest
needs: [set-variables]
env:
RUSTFLAGS: "-D warnings"
steps:
- name: '[DEBUG] print variables'
run: |
echo "all variables defined in set-variables"
echo "cache_key: ${{ needs.set-variables.outputs.cache_key }}"
echo "release_id: ${{ needs.set-variables.outputs.release_id }}"
echo "release_branch: ${{ needs.set-variables.outputs.release_branch }}"
# explicitly checkout the performance runner from main regardless of which
# version we are modeling.
- name: Checkout
uses: actions/checkout@v4
with:
ref: main
# attempts to access a previously cached runner
- uses: actions/cache@v4
id: cache
with:
path: ${{ env.RUNNER_CACHE_PATH }}
key: ${{ needs.set-variables.outputs.cache_key }}
- name: Fetch Rust Toolchain
if: steps.cache.outputs.cache-hit != 'true'
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Add fmt
if: steps.cache.outputs.cache-hit != 'true'
run: rustup component add rustfmt
- name: Cargo fmt
if: steps.cache.outputs.cache-hit != 'true'
uses: actions-rs/cargo@v1
with:
command: fmt
args: --manifest-path performance/runner/Cargo.toml --all -- --check
- name: Test
if: steps.cache.outputs.cache-hit != 'true'
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path performance/runner/Cargo.toml
- name: Build (optimized)
if: steps.cache.outputs.cache-hit != 'true'
uses: actions-rs/cargo@v1
with:
command: build
args: --release --manifest-path performance/runner/Cargo.toml
# the cache action automatically caches this binary at the end of the job
model:
# depends on `latest-runner` as a separate job so that failures in this job do not prevent
# a successfully tested and built binary from being cached.
needs: [set-variables, latest-runner]
name: Model a release
runs-on: ubuntu-latest
steps:
- name: '[DEBUG] print variables'
run: |
echo "all variables defined in set-variables"
echo "cache_key: ${{ needs.set-variables.outputs.cache_key }}"
echo "release_id: ${{ needs.set-variables.outputs.release_id }}"
echo "release_branch: ${{ needs.set-variables.outputs.release_branch }}"
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.9"
- name: Install dbt
run: pip install dbt-postgres==${{ needs.set-variables.outputs.release_id }}
- name: Install Hyperfine
run: wget https://github.com/sharkdp/hyperfine/releases/download/v1.11.0/hyperfine_1.11.0_amd64.deb && sudo dpkg -i hyperfine_1.11.0_amd64.deb
# explicitly checkout main to get the latest project definitions
- name: Checkout
uses: actions/checkout@v4
with:
ref: main
# this was built in the previous job so it will be there.
- name: Fetch Runner
uses: actions/cache@v4
id: cache
with:
path: ${{ env.RUNNER_CACHE_PATH }}
key: ${{ needs.set-variables.outputs.cache_key }}
- name: Move Runner
run: mv performance/runner/target/release/runner performance/app
- name: Change Runner Permissions
run: chmod +x ./performance/app
- name: '[DEBUG] ls baseline directory before run'
run: ls -R performance/baselines/
# `${{ github.workspace }}` is used to pass the absolute path
- name: Create directories
run: |
mkdir ${{ github.workspace }}/performance/tmp/
mkdir -p performance/baselines/${{ needs.set-variables.outputs.release_id }}/
# Run modeling with taking 20 samples
- name: Run Measurement
run: |
performance/app model -v ${{ needs.set-variables.outputs.release_id }} -b ${{ github.workspace }}/performance/baselines/ -p ${{ github.workspace }}/performance/projects/ -t ${{ github.workspace }}/performance/tmp/ -n 20
- name: '[DEBUG] ls baseline directory after run'
run: ls -R performance/baselines/
- uses: actions/upload-artifact@v4
with:
name: baseline
path: performance/baselines/${{ needs.set-variables.outputs.release_id }}/
create-pr:
name: Open PR for ${{ matrix.base-branch }}
# depends on `model` as a separate job so that the baseline can be committed to more than one branch
# i.e. release branch and main
needs: [set-variables, latest-runner, model]
runs-on: ubuntu-latest
strategy:
matrix:
include:
- base-branch: refs/heads/main
target-branch: performance-bot/main_${{ needs.set-variables.outputs.release_id }}_${{GITHUB.RUN_ID}}
- base-branch: refs/heads/${{ needs.set-variables.outputs.release_branch }}
target-branch: performance-bot/release_${{ needs.set-variables.outputs.release_id }}_${{GITHUB.RUN_ID}}
steps:
- name: '[DEBUG] print variables'
run: |
echo "all variables defined in set-variables"
echo "cache_key: ${{ needs.set-variables.outputs.cache_key }}"
echo "release_id: ${{ needs.set-variables.outputs.release_id }}"
echo "release_branch: ${{ needs.set-variables.outputs.release_branch }}"
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ matrix.base-branch }}
- name: Create PR branch
run: |
git checkout -b ${{ matrix.target-branch }}
git push origin ${{ matrix.target-branch }}
git branch --set-upstream-to=origin/${{ matrix.target-branch }} ${{ matrix.target-branch }}
- uses: actions/download-artifact@v4
with:
name: baseline
path: performance/baselines/${{ needs.set-variables.outputs.release_id }}
- name: '[DEBUG] ls baselines after artifact download'
run: ls -R performance/baselines/
- name: Commit baseline
uses: EndBug/add-and-commit@v9
with:
add: 'performance/baselines/*'
author_name: 'Github Build Bot'
author_email: 'buildbot@fishtownanalytics.com'
message: 'adding performance baseline for ${{ needs.set-variables.outputs.release_id }}'
push: 'origin origin/${{ matrix.target-branch }}'
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
author: 'Github Build Bot <buildbot@fishtownanalytics.com>'
base: ${{ matrix.base-branch }}
branch: '${{ matrix.target-branch }}'
title: 'Adding performance modeling for ${{needs.set-variables.outputs.release_id}} to ${{ matrix.base-branch }}'
body: 'Committing perf results for tracking for the ${{needs.set-variables.outputs.release_id}}'
labels: |
Skip Changelog
Performance

View File

@@ -31,7 +31,7 @@ env:
jobs: jobs:
aggregate-release-data: aggregate-release-data:
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
outputs: outputs:
version_number: ${{ steps.nightly-release-version.outputs.number }} version_number: ${{ steps.nightly-release-version.outputs.number }}
@@ -39,14 +39,14 @@ jobs:
steps: steps:
- name: "Checkout ${{ github.repository }} Branch ${{ env.RELEASE_BRANCH }}" - name: "Checkout ${{ github.repository }} Branch ${{ env.RELEASE_BRANCH }}"
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4 uses: actions/checkout@v4
with: with:
ref: ${{ env.RELEASE_BRANCH }} ref: ${{ env.RELEASE_BRANCH }}
- name: "Get Current Version Number" - name: "Get Current Version Number"
id: version-number-sources id: version-number-sources
run: | run: |
current_version=$(grep '^version = ' core/dbt/__version__.py | sed 's/version = "\(.*\)"/\1/') current_version=`awk -F"current_version = " '{print $2}' .bumpversion.cfg | tr '\n' ' '`
echo "current_version=$current_version" >> $GITHUB_OUTPUT echo "current_version=$current_version" >> $GITHUB_OUTPUT
- name: "Audit Version And Parse Into Parts" - name: "Audit Version And Parse Into Parts"
@@ -76,7 +76,7 @@ jobs:
echo "name=${{ env.RELEASE_BRANCH }}" >> $GITHUB_OUTPUT echo "name=${{ env.RELEASE_BRANCH }}" >> $GITHUB_OUTPUT
log-outputs-aggregate-release-data: log-outputs-aggregate-release-data:
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
needs: [aggregate-release-data] needs: [aggregate-release-data]
steps: steps:

View File

@@ -72,15 +72,12 @@ defaults:
run: run:
shell: bash shell: bash
env:
MIN_HATCH_VERSION: "1.11.0"
jobs: jobs:
job-setup: job-setup:
name: Log Inputs name: Log Inputs
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
outputs: outputs:
use_hatch: ${{ steps.use_hatch.outputs.use_hatch }} starting_sha: ${{ steps.set_sha.outputs.starting_sha }}
steps: steps:
- name: "[DEBUG] Print Variables" - name: "[DEBUG] Print Variables"
run: | run: |
@@ -91,29 +88,19 @@ jobs:
echo Nightly release: ${{ inputs.nightly_release }} echo Nightly release: ${{ inputs.nightly_release }}
echo Only Docker: ${{ inputs.only_docker }} echo Only Docker: ${{ inputs.only_docker }}
# In version env.HATCH_VERSION we started to use hatch for build tooling. Before that we used setuptools. - name: "Checkout target branch"
# This needs to check if we're using hatch or setuptools based on the version being released. We should uses: actions/checkout@v4
# check if the version is greater than or equal to env.HATCH_VERSION. If it is, we use hatch, otherwise we use setuptools. with:
- name: "Check if using hatch" ref: ${{ inputs.target_branch }}
id: use_hatch
run: |
# Extract major.minor from versions like 1.11.0a1 -> 1.11
INPUT_MAJ_MIN=$(echo "${{ inputs.version_number }}" | sed -E 's/^([0-9]+\.[0-9]+).*/\1/')
HATCH_MAJ_MIN=$(echo "${{ env.MIN_HATCH_VERSION }}" | sed -E 's/^([0-9]+\.[0-9]+).*/\1/')
if [ $(echo "$INPUT_MAJ_MIN >= $HATCH_MAJ_MIN" | bc) -eq 1 ]; then # release-prep.yml really shouldn't take in the sha but since core + all adapters
echo "use_hatch=true" >> $GITHUB_OUTPUT # depend on it now this workaround lets us not input it manually with risk of error.
else # The changes always get merged into the head so we can't use a specific commit for
echo "use_hatch=false" >> $GITHUB_OUTPUT # releases anyways.
fi - name: "Capture sha"
id: set_sha
- name: "Notify if using hatch"
run: | run: |
if [ ${{ steps.use_hatch.outputs.use_hatch }} = "true" ]; then echo "starting_sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "::notice title="Using Hatch": $title::Using Hatch for release"
else
echo "::notice title="Using Setuptools": $title::Using Setuptools for release"
fi
bump-version-generate-changelog: bump-version-generate-changelog:
name: Bump package version, Generate changelog name: Bump package version, Generate changelog
@@ -123,13 +110,12 @@ jobs:
uses: dbt-labs/dbt-release/.github/workflows/release-prep.yml@main uses: dbt-labs/dbt-release/.github/workflows/release-prep.yml@main
with: with:
sha: ${{ needs.job-setup.outputs.starting_sha }}
version_number: ${{ inputs.version_number }} version_number: ${{ inputs.version_number }}
hatch_directory: "core"
target_branch: ${{ inputs.target_branch }} target_branch: ${{ inputs.target_branch }}
env_setup_script_path: "scripts/env-setup.sh" env_setup_script_path: "scripts/env-setup.sh"
test_run: ${{ inputs.test_run }} test_run: ${{ inputs.test_run }}
nightly_release: ${{ inputs.nightly_release }} nightly_release: ${{ inputs.nightly_release }}
use_hatch: ${{ needs.job-setup.outputs.use_hatch == 'true' }} # workflow outputs are strings...
secrets: inherit secrets: inherit
@@ -139,7 +125,7 @@ jobs:
needs: [bump-version-generate-changelog] needs: [bump-version-generate-changelog]
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
steps: steps:
- name: Print variables - name: Print variables
@@ -157,13 +143,16 @@ jobs:
with: with:
sha: ${{ needs.bump-version-generate-changelog.outputs.final_sha }} sha: ${{ needs.bump-version-generate-changelog.outputs.final_sha }}
version_number: ${{ inputs.version_number }} version_number: ${{ inputs.version_number }}
hatch_directory: "core"
changelog_path: ${{ needs.bump-version-generate-changelog.outputs.changelog_path }} changelog_path: ${{ needs.bump-version-generate-changelog.outputs.changelog_path }}
build_script_path: "scripts/build-dist.sh" build_script_path: "scripts/build-dist.sh"
s3_bucket_name: "core-team-artifacts"
package_test_command: "dbt --version" package_test_command: "dbt --version"
test_run: ${{ inputs.test_run }} test_run: ${{ inputs.test_run }}
nightly_release: ${{ inputs.nightly_release }} nightly_release: ${{ inputs.nightly_release }}
use_hatch: ${{ needs.job-setup.outputs.use_hatch == 'true' }} # workflow outputs are strings...
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
github-release: github-release:
name: GitHub Release name: GitHub Release
@@ -199,7 +188,7 @@ jobs:
# determine if we need to release dbt-core or both dbt-core and dbt-postgres # determine if we need to release dbt-core or both dbt-core and dbt-postgres
name: Determine Docker Package name: Determine Docker Package
if: ${{ !failure() && !cancelled() }} if: ${{ !failure() && !cancelled() }}
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
needs: [pypi-release] needs: [pypi-release]
outputs: outputs:
matrix: ${{ steps.determine-docker-package.outputs.matrix }} matrix: ${{ steps.determine-docker-package.outputs.matrix }}

View File

@@ -9,21 +9,15 @@
# occur so we want to proactively alert to it. # occur so we want to proactively alert to it.
# #
# **when?** # **when?**
# Only can be run manually # On pushes to `develop` and release branches. Manual runs are also enabled.
name: Artifact Schema Check name: Artifact Schema Check
on: on:
# pull_request: pull_request:
# types: [ opened, reopened, labeled, unlabeled, synchronize ] types: [ opened, reopened, labeled, unlabeled, synchronize ]
# paths-ignore: [ '.changes/**', '.github/**', 'tests/**', '**.md', '**.yml' ] paths-ignore: [ '.changes/**', '.github/**', 'tests/**', '**.md', '**.yml' ]
workflow_dispatch: workflow_dispatch:
inputs:
target_branch:
description: "The branch to check against"
type: string
default: "main"
required: true
# no special access is needed # no special access is needed
permissions: read-all permissions: read-all
@@ -37,23 +31,22 @@ env:
jobs: jobs:
checking-schemas: checking-schemas:
name: "Post-merge schema changes required" name: "Post-merge schema changes required"
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
steps: steps:
- name: Set up Python - name: Set up Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: "3.10" python-version: 3.9
- name: Checkout dbt repo - name: Checkout dbt repo
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4 uses: actions/checkout@v4
with: with:
path: ${{ env.DBT_REPO_DIRECTORY }} path: ${{ env.DBT_REPO_DIRECTORY }}
ref: ${{ inputs.target_branch }}
- name: Check for changes in core/dbt/artifacts - name: Check for changes in core/dbt/artifacts
# https://github.com/marketplace/actions/paths-changes-filter # https://github.com/marketplace/actions/paths-changes-filter
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # dorny/paths-filter@v3 uses: dorny/paths-filter@v3
id: check_artifact_changes id: check_artifact_changes
with: with:
filters: | filters: |
@@ -69,19 +62,21 @@ jobs:
- name: Checkout schemas.getdbt.com repo - name: Checkout schemas.getdbt.com repo
if: steps.check_artifact_changes.outputs.artifacts_changed == 'true' if: steps.check_artifact_changes.outputs.artifacts_changed == 'true'
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4 uses: actions/checkout@v4
with: with:
repository: dbt-labs/schemas.getdbt.com repository: dbt-labs/schemas.getdbt.com
ref: "main" ref: 'main'
path: ${{ env.SCHEMA_REPO_DIRECTORY }} path: ${{ env.SCHEMA_REPO_DIRECTORY }}
- name: Generate current schema - name: Generate current schema
if: steps.check_artifact_changes.outputs.artifacts_changed == 'true' if: steps.check_artifact_changes.outputs.artifacts_changed == 'true'
run: | run: |
cd ${{ env.DBT_REPO_DIRECTORY }}/core cd ${{ env.DBT_REPO_DIRECTORY }}
pip install --upgrade pip hatch python3 -m venv env
hatch run setup source env/bin/activate
hatch run json-schema -- --path ${{ env.LATEST_SCHEMA_PATH }} pip install --upgrade pip
pip install -r dev-requirements.txt -r editable-requirements.txt
python scripts/collect-artifact-schema.py --path ${{ env.LATEST_SCHEMA_PATH }}
# Copy generated schema files into the schemas.getdbt.com repo # Copy generated schema files into the schemas.getdbt.com repo
# Do a git diff to find any changes # Do a git diff to find any changes
@@ -94,8 +89,8 @@ jobs:
git diff -I='*[0-9]{4}-[0-9]{2}-[0-9]{2}' -I='*[0-9]+\.[0-9]+\.[0-9]+' --exit-code > ${{ env.SCHEMA_DIFF_ARTIFACT }} git diff -I='*[0-9]{4}-[0-9]{2}-[0-9]{2}' -I='*[0-9]+\.[0-9]+\.[0-9]+' --exit-code > ${{ env.SCHEMA_DIFF_ARTIFACT }}
- name: Upload schema diff - name: Upload schema diff
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # actions/upload-artifact@v4 uses: actions/upload-artifact@v4
if: ${{ failure() && steps.check_artifact_changes.outputs.artifacts_changed == 'true' }} if: ${{ failure() && steps.check_artifact_changes.outputs.artifacts_changed == 'true' }}
with: with:
name: "schema_changes.txt" name: 'schema_changes.txt'
path: "${{ env.SCHEMA_DIFF_ARTIFACT }}" path: '${{ env.SCHEMA_DIFF_ARTIFACT }}'

View File

@@ -14,8 +14,6 @@ on:
- "*.latest" - "*.latest"
- "releases/*" - "releases/*"
pull_request: pull_request:
merge_group:
types: [checks_requested]
workflow_dispatch: workflow_dispatch:
permissions: read-all permissions: read-all
@@ -47,7 +45,7 @@ jobs:
# run the performance measurements on the current or default branch # run the performance measurements on the current or default branch
test-schema: test-schema:
name: Test Log Schema name: Test Log Schema
runs-on: ubuntu-latest runs-on: ubuntu-20.04
timeout-minutes: 30 timeout-minutes: 30
needs: needs:
- integration-metadata - integration-metadata
@@ -69,49 +67,26 @@ jobs:
DBT_TEST_USER_2: dbt_test_user_2 DBT_TEST_USER_2: dbt_test_user_2
DBT_TEST_USER_3: dbt_test_user_3 DBT_TEST_USER_3: dbt_test_user_3
services:
# Label used to access the service container
postgres:
# Docker Hub image
image: postgres
# Provide the password for postgres
env:
POSTGRES_PASSWORD: password
POSTGRES_USER: postgres
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps: steps:
- name: checkout dev - name: checkout dev
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4 uses: actions/checkout@v4
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Python - name: Setup Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: "3.10" python-version: "3.9"
- name: Install python dependencies - name: Install python dependencies
run: | run: |
pip install --user --upgrade pip pip install --user --upgrade pip
pip --version pip --version
pip install hatch pip install tox
hatch --version tox --version
- name: Run postgres setup script - name: Set up postgres
run: | uses: ./.github/actions/setup-postgres-linux
./scripts/setup_db.sh
env:
PGHOST: localhost
PGPORT: 5432
PGPASSWORD: password
- name: ls - name: ls
run: ls run: ls
@@ -119,11 +94,11 @@ jobs:
# integration tests generate a ton of logs in different files. the next step will find them all. # integration tests generate a ton of logs in different files. the next step will find them all.
# we actually care if these pass, because the normal test run doesn't usually include many json log outputs # we actually care if these pass, because the normal test run doesn't usually include many json log outputs
- name: Run integration tests - name: Run integration tests
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # nick-fields/retry@v3 uses: nick-fields/retry@v3
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
command: cd core && hatch run ci:integration-tests -- -nauto command: tox -e integration -- -nauto
env: env:
PYTEST_ADDOPTS: ${{ format('--splits {0} --group {1}', env.PYTHON_INTEGRATION_TEST_WORKERS, matrix.split-group) }} PYTEST_ADDOPTS: ${{ format('--splits {0} --group {1}', env.PYTHON_INTEGRATION_TEST_WORKERS, matrix.split-group) }}

View File

@@ -14,33 +14,34 @@ on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
branch: branch:
description: "Branch to check out" description: 'Branch to check out'
type: string type: string
required: true required: true
default: "main" default: 'main'
test_path: test_path:
description: "Path to single test to run (ex: tests/functional/retry/test_retry.py::TestRetry::test_fail_fast)" description: 'Path to single test to run (ex: tests/functional/retry/test_retry.py::TestRetry::test_fail_fast)'
type: string type: string
required: true required: true
default: "tests/functional/..." default: 'tests/functional/...'
python_version: python_version:
description: "Version of Python to Test Against" description: 'Version of Python to Test Against'
type: choice type: choice
options: options:
- "3.10" - '3.9'
- "3.11" - '3.10'
- '3.11'
os: os:
description: "OS to run test in" description: 'OS to run test in'
type: choice type: choice
options: options:
- "ubuntu-latest" - 'ubuntu-latest'
- "macos-14" - 'macos-14'
- "windows-latest" - 'windows-latest'
num_runs_per_batch: num_runs_per_batch:
description: "Max number of times to run the test per batch. We always run 10 batches." description: 'Max number of times to run the test per batch. We always run 10 batches.'
type: number type: number
required: true required: true
default: "50" default: '50'
permissions: read-all permissions: read-all
@@ -50,7 +51,7 @@ defaults:
jobs: jobs:
debug: debug:
runs-on: ${{ vars.UBUNTU_LATEST }} runs-on: ubuntu-latest
steps: steps:
- name: "[DEBUG] Output Inputs" - name: "[DEBUG] Output Inputs"
run: | run: |
@@ -81,37 +82,26 @@ jobs:
steps: steps:
- name: "Checkout code" - name: "Checkout code"
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: "Setup Python" - name: "Setup Python"
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: "${{ inputs.python_version }}" python-version: "${{ inputs.python_version }}"
- name: "Install hatch"
run: python -m pip install --user --upgrade pip hatch
- name: "Setup Dev Environment" - name: "Setup Dev Environment"
run: | run: make dev
cd core
hatch run setup
- name: "Set up postgres (linux)" - name: "Set up postgres (linux)"
if: inputs.os == '${{ vars.UBUNTU_LATEST }}' if: inputs.os == 'ubuntu-latest'
run: | run: make setup-db
cd core
hatch run setup-db
# mac and windows don't use make due to limitations with docker with those runners in GitHub # mac and windows don't use make due to limitations with docker with those runners in GitHub
- name: Set up postgres (macos) - name: "Set up postgres (macos)"
if: runner.os == 'macOS' if: inputs.os == 'macos-14'
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # nick-fields/retry@v3 uses: ./.github/actions/setup-postgres-macos
with:
timeout_minutes: 10
max_attempts: 3
command: ./scripts/setup_db.sh
- name: "Set up postgres (windows)" - name: "Set up postgres (windows)"
if: inputs.os == 'windows-latest' if: inputs.os == 'windows-latest'

2
.gitignore vendored
View File

@@ -15,7 +15,6 @@ build/
!core/dbt/docs/build !core/dbt/docs/build
develop-eggs/ develop-eggs/
dist/ dist/
dist-*/
downloads/ downloads/
eggs/ eggs/
.eggs/ .eggs/
@@ -96,7 +95,6 @@ target/
# pycharm # pycharm
.idea/ .idea/
venv/ venv/
.venv*/
# AWS credentials # AWS credentials
.aws/ .aws/

View File

@@ -1,14 +1,14 @@
# Configuration for pre-commit hooks (see https://pre-commit.com/). # Configuration for pre-commit hooks (see https://pre-commit.com/).
# Eventually the hooks described here will be run as tests before merging each PR. # Eventually the hooks described here will be run as tests before merging each PR.
exclude: ^(core/dbt/docs/build/|core/dbt/common/events/types_pb2.py|core/dbt/adapters/events/adapter_types_pb2.py) exclude: ^(core/dbt/docs/build/|core/dbt/common/events/types_pb2.py|core/dbt/events/core_types_pb2.py|core/dbt/adapters/events/adapter_types_pb2.py)
# Force all unspecified python hooks to run python 3.10 # Force all unspecified python hooks to run python 3.9
default_language_version: default_language_version:
python: python3 python: python3
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0 rev: v3.2.0
hooks: hooks:
- id: check-yaml - id: check-yaml
@@ -20,72 +20,52 @@ repos:
exclude_types: exclude_types:
- "markdown" - "markdown"
- id: check-case-conflict - id: check-case-conflict
# local hooks are used to run the hooks in the local environment instead of a pre-commit isolated one. - repo: https://github.com/pycqa/isort
# This ensures that the hooks are run with the same version of the dependencies as the local environment # rev must match what's in dev-requirements.txt
# without having to manually keep them in sync. rev: 5.13.2
- repo: local
hooks: hooks:
# Formatter/linter/type-checker pins live in the pyproject.dev optional dependency.
- id: isort - id: isort
name: isort - repo: https://github.com/psf/black
entry: python -m isort # rev must match what's in dev-requirements.txt
language: system rev: 24.3.0
types: [python] hooks:
- id: black - id: black
name: black - id: black
entry: python -m black alias: black-check
language: system stages: [manual]
types: [python]
- id: black-check
name: black-check
entry: python -m black
args: args:
- "--check" - "--check"
- "--diff" - "--diff"
language: system - repo: https://github.com/pycqa/flake8
stages: [manual] # rev must match what's in dev-requirements.txt
types: [python] rev: 4.0.1
hooks:
- id: flake8 - id: flake8
name: flake8 - id: flake8
entry: python -m flake8 alias: flake8-check
language: system
types: [python]
- id: flake8-check
name: flake8-check
entry: python -m flake8
language: system
stages: [manual] stages: [manual]
types: [python] - repo: https://github.com/pre-commit/mirrors-mypy
# rev must match what's in dev-requirements.txt
rev: v1.4.1
hooks:
- id: mypy
# N.B.: Mypy is... a bit fragile. # N.B.: Mypy is... a bit fragile.
# #
# By using `language: system` we run this hook in the local # By using `language: system` we run this hook in the local
# environment instead of a pre-commit isolated one. This is needed # environment instead of a pre-commit isolated one. This is needed
# to ensure mypy correctly parses the project. # to ensure mypy correctly parses the project.
#
# It may cause trouble # It may cause trouble
# in that it adds environmental variables out of our control to the # in that it adds environmental variables out of our control to the
# mix. Unfortunately, there's nothing we can do about per pre-commit's # mix. Unfortunately, there's nothing we can do about per pre-commit's
# author. # author.
# See https://github.com/pre-commit/pre-commit/issues/730 for details. # See https://github.com/pre-commit/pre-commit/issues/730 for details.
- id: mypy
name: mypy
entry: python -m mypy
args: [--show-error-codes] args: [--show-error-codes]
files: ^core/dbt/ files: ^core/dbt/
language: system language: system
types: [python] - id: mypy
- id: mypy-check alias: mypy-check
name: mypy-check stages: [manual]
entry: python -m mypy
args: [--show-error-codes, --pretty] args: [--show-error-codes, --pretty]
files: ^core/dbt/ files: ^core/dbt/
language: system language: system
stages: [manual]
types: [python]
- id: no_versioned_artifact_resource_imports
name: no_versioned_artifact_resource_imports
entry: python scripts/pre-commit-hooks/no_versioned_artifact_resource_imports.py
language: system
files: ^core/dbt/
types: [python]
pass_filenames: true

View File

@@ -6,6 +6,7 @@ Most of the python code in the repository is within the `core/dbt` directory.
- [`single python files`](core/dbt/README.md): A number of individual files, such as 'compilation.py' and 'exceptions.py' - [`single python files`](core/dbt/README.md): A number of individual files, such as 'compilation.py' and 'exceptions.py'
The main subdirectories of core/dbt: The main subdirectories of core/dbt:
- [`adapters`](core/dbt/adapters/README.md): Define base classes for behavior that is likely to differ across databases
- [`clients`](core/dbt/clients/README.md): Interface with dependencies (agate, jinja) or across operating systems - [`clients`](core/dbt/clients/README.md): Interface with dependencies (agate, jinja) or across operating systems
- [`config`](core/dbt/config/README.md): Reconcile user-supplied configuration from connection profiles, project files, and Jinja macros - [`config`](core/dbt/config/README.md): Reconcile user-supplied configuration from connection profiles, project files, and Jinja macros
- [`context`](core/dbt/context/README.md): Build and expose dbt-specific Jinja functionality - [`context`](core/dbt/context/README.md): Build and expose dbt-specific Jinja functionality
@@ -13,10 +14,14 @@ The main subdirectories of core/dbt:
- [`deps`](core/dbt/deps/README.md): Package installation and dependency resolution - [`deps`](core/dbt/deps/README.md): Package installation and dependency resolution
- [`events`](core/dbt/events/README.md): Logging events - [`events`](core/dbt/events/README.md): Logging events
- [`graph`](core/dbt/graph/README.md): Produce a `networkx` DAG of project resources, and selecting those resources given user-supplied criteria - [`graph`](core/dbt/graph/README.md): Produce a `networkx` DAG of project resources, and selecting those resources given user-supplied criteria
- [`include`](core/dbt/include/README.md): Set up the starter project scaffold. - [`include`](core/dbt/include/README.md): The dbt "global project," which defines default implementations of Jinja2 macros
- [`parser`](core/dbt/parser/README.md): Read project files, validate, construct python objects - [`parser`](core/dbt/parser/README.md): Read project files, validate, construct python objects
- [`task`](core/dbt/task/README.md): Set forth the actions that dbt can perform when invoked - [`task`](core/dbt/task/README.md): Set forth the actions that dbt can perform when invoked
Legacy tests are found in the 'test' directory:
- [`unit tests`](core/dbt/test/unit/README.md): Unit tests
- [`integration tests`](core/dbt/test/integration/README.md): Integration tests
### Invoking dbt ### Invoking dbt
The "tasks" map to top-level dbt commands. So `dbt run` => task.run.RunTask, etc. Some are more like abstract base classes (GraphRunnableTask, for example) but all the concrete types outside of task should map to tasks. Currently one executes at a time. The tasks kick off their “Runners” and those do execute in parallel. The parallelism is managed via a thread pool, in GraphRunnableTask. The "tasks" map to top-level dbt commands. So `dbt run` => task.run.RunTask, etc. Some are more like abstract base classes (GraphRunnableTask, for example) but all the concrete types outside of task should map to tasks. Currently one executes at a time. The tasks kick off their “Runners” and those do execute in parallel. The parallelism is managed via a thread pool, in GraphRunnableTask.
@@ -27,7 +32,7 @@ This is the docs website code. It comes from the dbt-docs repository, and is gen
## Adapters ## Adapters
dbt uses an adapter-plugin pattern to extend support to different databases, warehouses, query engines, etc. dbt uses an adapter-plugin pattern to extend support to different databases, warehouses, query engines, etc.
Note: dbt-postgres used to exist in dbt-core but is now in [the dbt-adapters repo](https://github.com/dbt-labs/dbt-adapters/tree/main/dbt-postgres) Note: dbt-postgres used to exist in dbt-core but is now in [its own repo](https://github.com/dbt-labs/dbt-postgres)
Each adapter is a mix of python, Jinja2, and SQL. The adapter code also makes heavy use of Jinja2 to wrap modular chunks of SQL functionality, define default implementations, and allow plugins to override it. Each adapter is a mix of python, Jinja2, and SQL. The adapter code also makes heavy use of Jinja2 to wrap modular chunks of SQL functionality, define default implementations, and allow plugins to override it.
@@ -35,15 +40,16 @@ Each adapter plugin is a standalone python package that includes:
- `dbt/include/[name]`: A "sub-global" dbt project, of YAML and SQL files, that reimplements Jinja macros to use the adapter's supported SQL syntax - `dbt/include/[name]`: A "sub-global" dbt project, of YAML and SQL files, that reimplements Jinja macros to use the adapter's supported SQL syntax
- `dbt/adapters/[name]`: Python modules that inherit, and optionally reimplement, the base adapter classes defined in dbt-core - `dbt/adapters/[name]`: Python modules that inherit, and optionally reimplement, the base adapter classes defined in dbt-core
- `pyproject.toml` - `setup.py`
The Postgres adapter code is the most central, and many of its implementations are used as the default defined in the dbt-core global project. The greater the distance of a data technology from Postgres, the more its adapter plugin may need to reimplement. The Postgres adapter code is the most central, and many of its implementations are used as the default defined in the dbt-core global project. The greater the distance of a data technology from Postgres, the more its adapter plugin may need to reimplement.
## Testing dbt ## Testing dbt
The [`tests/`](tests/) subdirectory includes unit and fuctional tests that run as continuous integration checks against open pull requests. Unit tests check mock inputs and outputs of specific python functions. Functional tests perform end-to-end dbt invocations against real adapters (Postgres) and assert that the results match expectations. See [the contributing guide](CONTRIBUTING.md) for a step-by-step walkthrough of setting up a local development and testing environment. The [`test/`](test/) subdirectory includes unit and integration tests that run as continuous integration checks against open pull requests. Unit tests check mock inputs and outputs of specific python functions. Integration tests perform end-to-end dbt invocations against real adapters (Postgres, Redshift, Snowflake, BigQuery) and assert that the results match expectations. See [the contributing guide](CONTRIBUTING.md) for a step-by-step walkthrough of setting up a local development and testing environment.
## Everything else ## Everything else
- [docker](docker/): All dbt versions are published as Docker images on DockerHub. This subfolder contains the `Dockerfile` (constant) and `requirements.txt` (one for each version). - [docker](docker/): All dbt versions are published as Docker images on DockerHub. This subfolder contains the `Dockerfile` (constant) and `requirements.txt` (one for each version).
- [etc](etc/): Images for README
- [scripts](scripts/): Helper scripts for testing, releasing, and producing JSON schemas. These are not included in distributions of dbt, nor are they rigorously tested—they're just handy tools for the dbt maintainers :) - [scripts](scripts/): Helper scripts for testing, releasing, and producing JSON schemas. These are not included in distributions of dbt, nor are they rigorously tested—they're just handy tools for the dbt maintainers :)

View File

@@ -5,14 +5,203 @@
- "Breaking changes" listed under a version may require action from end users or external maintainers when upgrading to that version. - "Breaking changes" listed under a version may require action from end users or external maintainers when upgrading to that version.
- Do not edit this file directly. This file is auto-generated using [changie](https://github.com/miniscruff/changie). For details on how to document a change, see [the contributing guide](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md#adding-changelog-entry) - Do not edit this file directly. This file is auto-generated using [changie](https://github.com/miniscruff/changie). For details on how to document a change, see [the contributing guide](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md#adding-changelog-entry)
## dbt-core 1.9.0 - December 09, 2024
### Breaking Changes
- Fix changing the current working directory when using dpt deps, clean and init. ([#8997](https://github.com/dbt-labs/dbt-core/issues/8997))
### Features
- Parseable JSON and text output in quiet mode for `dbt show` and `dbt compile` ([#9840](https://github.com/dbt-labs/dbt-core/issues/9840))
- serialize inferred primary key ([#9824](https://github.com/dbt-labs/dbt-core/issues/9824))
- Add unit_test: selection method ([#10053](https://github.com/dbt-labs/dbt-core/issues/10053))
- Maximally parallelize dbt clone in clone command" ([#7914](https://github.com/dbt-labs/dbt-core/issues/7914))
- Add --host flag to dbt docs serve, defaulting to '127.0.0.1' ([#10229](https://github.com/dbt-labs/dbt-core/issues/10229))
- Update data_test to accept arbitrary config options ([#10197](https://github.com/dbt-labs/dbt-core/issues/10197))
- add pre_model and post_model hook calls to data and unit tests to be able to provide extra config options ([#10198](https://github.com/dbt-labs/dbt-core/issues/10198))
- add --empty value to jinja context as flags.EMPTY ([#10317](https://github.com/dbt-labs/dbt-core/issues/10317))
- Warning message for snapshot timestamp data types ([#10234](https://github.com/dbt-labs/dbt-core/issues/10234))
- Support cumulative_type_params & sub-daily granularities in semantic manifest. ([#10360](https://github.com/dbt-labs/dbt-core/issues/10360))
- Add time_granularity to metric spec. ([#10376](https://github.com/dbt-labs/dbt-core/issues/10376))
- Support standard schema/database fields for snapshots ([#10301](https://github.com/dbt-labs/dbt-core/issues/10301))
- Support ref and source in foreign key constraint expressions, bump dbt-common minimum to 1.6 ([#8062](https://github.com/dbt-labs/dbt-core/issues/8062))
- Support new semantic layer time spine configs to enable sub-daily granularity. ([#10475](https://github.com/dbt-labs/dbt-core/issues/10475))
- Add `order_by` and `limit` fields to saved queries. ([#10531](https://github.com/dbt-labs/dbt-core/issues/10531))
- Add support for behavior flags ([#10618](https://github.com/dbt-labs/dbt-core/issues/10618))
- Enable `--resource-type` and `--exclude-resource-type` CLI flags and environment variables for `dbt test` ([#10656](https://github.com/dbt-labs/dbt-core/issues/10656))
- Allow configuring snapshot column names ([#10185](https://github.com/dbt-labs/dbt-core/issues/10185))
- Add custom_granularities to YAML spec for time spines. ([#9265](https://github.com/dbt-labs/dbt-core/issues/9265))
- Add basic functionality for creating microbatch incremental models ([#9490](https://github.com/dbt-labs/dbt-core/issues/9490), [#10635](https://github.com/dbt-labs/dbt-core/issues/10635), [#10637](https://github.com/dbt-labs/dbt-core/issues/10637), [#10638](https://github.com/dbt-labs/dbt-core/issues/10638), [#10636](https://github.com/dbt-labs/dbt-core/issues/10636), [#10662](https://github.com/dbt-labs/dbt-core/issues/10662), [#10639](https://github.com/dbt-labs/dbt-core/issues/10639))
- Execute microbatch models in batches ([#10700](https://github.com/dbt-labs/dbt-core/issues/10700))
- Create 'skip_nodes_if_on_run_start_fails' behavior change flag ([#7387](https://github.com/dbt-labs/dbt-core/issues/7387))
- Allow snapshots to be defined in YAML. ([#10246](https://github.com/dbt-labs/dbt-core/issues/10246))
- Write microbatch compiled/run targets to separate files, one per batch ([#10714](https://github.com/dbt-labs/dbt-core/issues/10714))
- Track incremental_strategy as part of model_run tracking event ([#10761](https://github.com/dbt-labs/dbt-core/issues/10761))
- Support required 'begin' config for microbatch models ([#10701](https://github.com/dbt-labs/dbt-core/issues/10701))
- Parse-time validation of microbatch configs: require event_time, batch_size, lookback and validate input event_time ([#10709](https://github.com/dbt-labs/dbt-core/issues/10709))
- Added the --inline-direct parameter to 'dbt show' ([#10770](https://github.com/dbt-labs/dbt-core/issues/10770))
- Enable specification of dbt_valid_to for current records ([#10187](https://github.com/dbt-labs/dbt-core/issues/10187))
- Enable `retry` support for microbatch models ([#10715](https://github.com/dbt-labs/dbt-core/issues/10715), [#10729](https://github.com/dbt-labs/dbt-core/issues/10729))
- Use unrendered database and schema source properties during state:modified, behind state_modified_compare_more_unrendered_values behavoiur flag ([#9573](https://github.com/dbt-labs/dbt-core/issues/9573))
- Ensure microbatch models respect `full_refresh` model config ([#10785](https://github.com/dbt-labs/dbt-core/issues/10785))
- Adds validations for custom_granularities to ensure unique naming. ([#9265](https://github.com/dbt-labs/dbt-core/issues/9265))
- Enable use of multi-column unique key in snapshots ([#9992](https://github.com/dbt-labs/dbt-core/issues/9992))
- Change gating of microbatch feature to be behind project flag / behavior flag ([#10798](https://github.com/dbt-labs/dbt-core/issues/10798))
- Ensure `--event-time-start` is before `--event-time-end` ([#10786](https://github.com/dbt-labs/dbt-core/issues/10786))
- Ensure microbatch models use same `current_time` value ([#10819](https://github.com/dbt-labs/dbt-core/issues/10819))
- Emit warning when microbatch model has no input with `event_time` config ([#10926](https://github.com/dbt-labs/dbt-core/issues/10926))
- Emit debug logging event whenever artifacts are written ([#10937](https://github.com/dbt-labs/dbt-core/issues/10937))
- Support --empty for snapshots ([#10372](https://github.com/dbt-labs/dbt-core/issues/10372))
- Add new hard_deletes="new_record" mode for snapshots. ([#10235](https://github.com/dbt-labs/dbt-core/issues/10235))
- Allow microbatch batches to run in parallel ([#10853](https://github.com/dbt-labs/dbt-core/issues/10853), [#10855](https://github.com/dbt-labs/dbt-core/issues/10855))
- Add `batch` context object to model jinja context ([#11025](https://github.com/dbt-labs/dbt-core/issues/11025))
- Ensure pre/post hooks only run on first/last batch respectively for microbatch model batches ([#11094](https://github.com/dbt-labs/dbt-core/issues/11094), [#11104](https://github.com/dbt-labs/dbt-core/issues/11104))
### Fixes
- Remove unused check_new method ([#7586](https://github.com/dbt-labs/dbt-core/issues/7586))
- Test case for `merge_exclude_columns` ([#8267](https://github.com/dbt-labs/dbt-core/issues/8267))
- Convert "Skipping model due to fail_fast" message to DEBUG level ([#8774](https://github.com/dbt-labs/dbt-core/issues/8774))
- Restore previous behavior for --favor-state: only favor defer_relation if not selected in current command" ([#10107](https://github.com/dbt-labs/dbt-core/issues/10107))
- Unit test fixture (csv) returns null for empty value ([#9881](https://github.com/dbt-labs/dbt-core/issues/9881))
- Fix json format log and --quiet for ls and jinja print by converting print call to fire events ([#8756](https://github.com/dbt-labs/dbt-core/issues/8756))
- Add resource type to saved_query ([#10168](https://github.com/dbt-labs/dbt-core/issues/10168))
- Fix: Order-insensitive unit test equality assertion for expected/actual with multiple nulls ([#10167](https://github.com/dbt-labs/dbt-core/issues/10167))
- Renaming or removing a contracted model should raise a BreakingChange warning/error ([#10116](https://github.com/dbt-labs/dbt-core/issues/10116))
- prefer disabled project nodes to external node ([#10224](https://github.com/dbt-labs/dbt-core/issues/10224))
- Fix issues with selectors and inline nodes ([#8943](https://github.com/dbt-labs/dbt-core/issues/8943), [#9269](https://github.com/dbt-labs/dbt-core/issues/9269))
- Fix snapshot config to work in yaml files ([#4000](https://github.com/dbt-labs/dbt-core/issues/4000))
- Improve handling of error when loading schema file list ([#10284](https://github.com/dbt-labs/dbt-core/issues/10284))
- Use model alias for the CTE identifier generated during ephemeral materialization ([#5273](https://github.com/dbt-labs/dbt-core/issues/5273))
- Implement state:modified for saved queries ([#10294](https://github.com/dbt-labs/dbt-core/issues/10294))
- Saved Query node fail during skip ([#10029](https://github.com/dbt-labs/dbt-core/issues/10029))
- DOn't warn on `unit_test` config paths that are properly used ([#10311](https://github.com/dbt-labs/dbt-core/issues/10311))
- Fix setting `silence` of `warn_error_options` via `dbt_project.yaml` flags ([#10160](https://github.com/dbt-labs/dbt-core/issues/10160))
- Attempt to provide test fixture tables with all values to set types correctly for comparisong with source tables ([#10365](https://github.com/dbt-labs/dbt-core/issues/10365))
- Limit data_tests deprecation to root_project ([#9835](https://github.com/dbt-labs/dbt-core/issues/9835))
- CLI flags should take precedence over env var flags ([#10304](https://github.com/dbt-labs/dbt-core/issues/10304))
- Fix typing for artifact schemas ([#10442](https://github.com/dbt-labs/dbt-core/issues/10442))
- Fix over deletion of generated_metrics in partial parsing ([#10450](https://github.com/dbt-labs/dbt-core/issues/10450))
- Fix error constructing warn_error_options ([#10452](https://github.com/dbt-labs/dbt-core/issues/10452))
- Do not update varchar column definitions if a contract exists ([#10362](https://github.com/dbt-labs/dbt-core/issues/10362))
- fix all_constraints access, disabled node parsing of non-uniquely named resources ([#10509](https://github.com/dbt-labs/dbt-core/issues/10509))
- respect --quiet and --warn-error-options for flag deprecations ([#10105](https://github.com/dbt-labs/dbt-core/issues/10105))
- Propagate measure label when using create_metrics ([#10536](https://github.com/dbt-labs/dbt-core/issues/10536))
- Fix state:modified check for exports ([#10138](https://github.com/dbt-labs/dbt-core/issues/10138))
- Filter out empty nodes after graph selection to support consistent selection of nodes that depend on upstream public models ([#8987](https://github.com/dbt-labs/dbt-core/issues/8987))
- Late render pre- and post-hooks configs in properties / schema YAML files ([#10603](https://github.com/dbt-labs/dbt-core/issues/10603))
- Allow the use of env_var function in certain macros in which it was previously unavailable. ([#10609](https://github.com/dbt-labs/dbt-core/issues/10609))
- Remove deprecation for tests: to data_tests: change ([#10564](https://github.com/dbt-labs/dbt-core/issues/10564))
- Fix `--resource-type test` for `dbt list` and `dbt build` ([#10730](https://github.com/dbt-labs/dbt-core/issues/10730))
- Fix unit tests for incremental model with alias ([#10754](https://github.com/dbt-labs/dbt-core/issues/10754))
- Allow singular tests to be documented in properties.yml ([#9005](https://github.com/dbt-labs/dbt-core/issues/9005))
- Ignore --empty in unit test ref/source rendering ([#10516](https://github.com/dbt-labs/dbt-core/issues/10516))
- Ignore rendered jinja in configs for state:modified, behind state_modified_compare_more_unrendered_values behaviour flag ([#9564](https://github.com/dbt-labs/dbt-core/issues/9564))
- Improve performance of infer primary key ([#10781](https://github.com/dbt-labs/dbt-core/issues/10781))
- Pass test user config to adapter pre_hook by explicitly adding test builder config to node ([#10484](https://github.com/dbt-labs/dbt-core/issues/10484))
- Attempt to skip saved query processing when no semantic manifest changes ([#10563](https://github.com/dbt-labs/dbt-core/issues/10563))
- Ensure dbt retry of microbatch models doesn't lose prior successful state ([#10800](https://github.com/dbt-labs/dbt-core/issues/10800))
- override materialization python models ([#8520](https://github.com/dbt-labs/dbt-core/issues/8520))
- Handle edge cases when a specified `--event-time-end` is equivalent to the batch size truncated batch start time ([#10824](https://github.com/dbt-labs/dbt-core/issues/10824))
- Begin tracking execution time of microbatch model batches ([#10825](https://github.com/dbt-labs/dbt-core/issues/10825))
- Support disabling unit tests via config. ([#9109](https://github.com/dbt-labs/dbt-core/issues/9109), [#10540](https://github.com/dbt-labs/dbt-core/issues/10540))
- Allow instances of generic data tests to be documented ([#2578](https://github.com/dbt-labs/dbt-core/issues/2578))
- Fix warnings for models referring to a deprecated model ([#10833](https://github.com/dbt-labs/dbt-core/issues/10833))
- Change `lookback` default from `0` to `1` to ensure better data completeness ([#10867](https://github.com/dbt-labs/dbt-core/issues/10867))
- Make `--event-time-start` and `--event-time-end` mutually required ([#10874](https://github.com/dbt-labs/dbt-core/issues/10874))
- Ensure KeyboardInterrupt/SystemExit halts microbatch model execution ([#10862](https://github.com/dbt-labs/dbt-core/issues/10862))
- Exclude hook result from results in on-run-end context ([#7387](https://github.com/dbt-labs/dbt-core/issues/7387))
- unit tests with versioned refs ([#10880](https://github.com/dbt-labs/dbt-core/issues/10880), [#10528](https://github.com/dbt-labs/dbt-core/issues/10528), [#10623](https://github.com/dbt-labs/dbt-core/issues/10623))
- Implement partial parsing for all-yaml snapshots ([#10903](https://github.com/dbt-labs/dbt-core/issues/10903))
- Restore source quoting behaviour when quoting config provided in dbt_project.yml ([#10892](https://github.com/dbt-labs/dbt-core/issues/10892))
- Fix bug when referencing deprecated models ([#10915](https://github.com/dbt-labs/dbt-core/issues/10915))
- Fix 'model' jinja context variable type to dict ([#10927](https://github.com/dbt-labs/dbt-core/issues/10927))
- Take `end_time` for batches to the ceiling to handle edge case where `event_time` column is a date ([#10868](https://github.com/dbt-labs/dbt-core/issues/10868))
- Handle exceptions in `get_execution_status` more broadly to better ensure `run_results.json` gets written ([#10934](https://github.com/dbt-labs/dbt-core/issues/10934))
- Fix 'no attribute .config' error when ref-ing a microbatch model from non-Model context ([#10928](https://github.com/dbt-labs/dbt-core/issues/10928))
- Ensure inferred primary_key is a List[str] with no null values ([#10983](https://github.com/dbt-labs/dbt-core/issues/10983))
- Correct when custom microbatch macro deprecation warning is fired ([#10994](https://github.com/dbt-labs/dbt-core/issues/10994))
- Validate manifest has group_map during group_lookup init ([#10988](https://github.com/dbt-labs/dbt-core/issues/10988))
- Fix plural of 'partial success' in log message ([#10999](https://github.com/dbt-labs/dbt-core/issues/10999))
- Emit batch-level exception with node_info on microbatch batch run failure ([#10840](https://github.com/dbt-labs/dbt-core/issues/10840))
- Fix restrict-access to not apply within a package ([#10134](https://github.com/dbt-labs/dbt-core/issues/10134))
- Make microbatch models skippable ([#11021](https://github.com/dbt-labs/dbt-core/issues/11021))
- Catch DbtRuntimeError for hooks ([#11012](https://github.com/dbt-labs/dbt-core/issues/11012))
- Access DBUG flag more consistently with the rest of the codebase in ManifestLoader ([#11068](https://github.com/dbt-labs/dbt-core/issues/11068))
- Implement partial parsing for singular data test configs in yaml files ([#10801](https://github.com/dbt-labs/dbt-core/issues/10801))
### Docs
- Enable display of unit tests ([dbt-docs/#501](https://github.com/dbt-labs/dbt-docs/issues/501))
- Unit tests not rendering ([dbt-docs/#506](https://github.com/dbt-labs/dbt-docs/issues/506))
- Add support for Saved Query node ([dbt-docs/#486](https://github.com/dbt-labs/dbt-docs/issues/486))
- Fix npm security vulnerabilities as of June 2024 ([dbt-docs/#513](https://github.com/dbt-labs/dbt-docs/issues/513))
### Under the Hood
- Clear error message for Private package in dbt-core ([#10083](https://github.com/dbt-labs/dbt-core/issues/10083))
- Enable use of context in serialization ([#10093](https://github.com/dbt-labs/dbt-core/issues/10093))
- Make RSS high water mark measurement more accurate on Linux ([#10177](https://github.com/dbt-labs/dbt-core/issues/10177))
- Enable record filtering by type. ([#10240](https://github.com/dbt-labs/dbt-core/issues/10240))
- Remove IntermediateSnapshotNode ([#10326](https://github.com/dbt-labs/dbt-core/issues/10326))
- Additional logging for skipped ephemeral models ([#10389](https://github.com/dbt-labs/dbt-core/issues/10389))
- bump black to 24.3.0 ([#10454](https://github.com/dbt-labs/dbt-core/issues/10454))
- generate protos with protoc version 5.26.1 ([#10457](https://github.com/dbt-labs/dbt-core/issues/10457))
- Move from minimal-snowplow-tracker fork back to snowplow-tracker ([#8409](https://github.com/dbt-labs/dbt-core/issues/8409))
- Add group info to RunResultError, RunResultFailure, RunResultWarning log lines ([#](https://github.com/dbt-labs/dbt-core/issues/))
- Improve speed of tree traversal when finding children, increasing build speed for some selectors ([#10434](https://github.com/dbt-labs/dbt-core/issues/10434))
- Add test for sources tables with quotes ([#10582](https://github.com/dbt-labs/dbt-core/issues/10582))
- Additional type hints for `core/dbt/version.py` ([#10612](https://github.com/dbt-labs/dbt-core/issues/10612))
- Fix typing issues in core/dbt/contracts/sql.py ([#10614](https://github.com/dbt-labs/dbt-core/issues/10614))
- Fix type errors in `dbt/core/task/clean.py` ([#10616](https://github.com/dbt-labs/dbt-core/issues/10616))
- Add Snowplow tracking for behavior flag deprecations ([#10552](https://github.com/dbt-labs/dbt-core/issues/10552))
- Add test utility patch_microbatch_end_time for adapters testing ([#10713](https://github.com/dbt-labs/dbt-core/issues/10713))
- Replace `TestSelector` with `ResourceTypeSelector` ([#10718](https://github.com/dbt-labs/dbt-core/issues/10718))
- Standardize returning `ResourceTypeSelector` instances in `dbt list` and `dbt build` ([#10739](https://github.com/dbt-labs/dbt-core/issues/10739))
- Add group metadata info to LogModelResult and LogTestResult ([#10775](https://github.com/dbt-labs/dbt-core/issues/10775))
- Remove support and testing for Python 3.8, which is now EOL. ([#10861](https://github.com/dbt-labs/dbt-core/issues/10861))
- Behavior change for mf timespine without yaml configuration ([#10959](https://github.com/dbt-labs/dbt-core/issues/10959))
- Behavior change for cumulative metric type param ([#10960](https://github.com/dbt-labs/dbt-core/issues/10960))
- Upgrade protobuf ([#10658](https://github.com/dbt-labs/dbt-core/issues/10658))
### Dependencies
- Remove logbook dependency ([#8027](https://github.com/dbt-labs/dbt-core/issues/8027))
- Increase supported version range for dbt-semantic-interfaces. Needed to support custom calendar features. ([#9265](https://github.com/dbt-labs/dbt-core/issues/9265))
- Bump minimnum allowed dbt-adapters version to 1.8.0 ([#N/A](https://github.com/dbt-labs/dbt-core/issues/N/A))
- Bump minimum dbt-adapters version to 1.9.0 ([#10996](https://github.com/dbt-labs/dbt-core/issues/10996))
### Security
- Explicitly bind to localhost in docs serve ([#10209](https://github.com/dbt-labs/dbt-core/issues/10209))
### Contributors
- [@DevonFulcher](https://github.com/DevonFulcher) ([#10959](https://github.com/dbt-labs/dbt-core/issues/10959), [#10960](https://github.com/dbt-labs/dbt-core/issues/10960))
- [@McKnight-42](https://github.com/McKnight-42) ([#10197](https://github.com/dbt-labs/dbt-core/issues/10197), [#10198](https://github.com/dbt-labs/dbt-core/issues/10198))
- [@Threynaud](https://github.com/Threynaud) ([#11068](https://github.com/dbt-labs/dbt-core/issues/11068))
- [@TowardOliver](https://github.com/TowardOliver) ([#10656](https://github.com/dbt-labs/dbt-core/issues/10656))
- [@aliceliu](https://github.com/aliceliu) ([#10536](https://github.com/dbt-labs/dbt-core/issues/10536), [#10138](https://github.com/dbt-labs/dbt-core/issues/10138))
- [@courtneyholcomb](https://github.com/courtneyholcomb) ([#10360](https://github.com/dbt-labs/dbt-core/issues/10360), [#10376](https://github.com/dbt-labs/dbt-core/issues/10376), [#10475](https://github.com/dbt-labs/dbt-core/issues/10475), [#9265](https://github.com/dbt-labs/dbt-core/issues/9265), [#9265](https://github.com/dbt-labs/dbt-core/issues/9265), [#9265](https://github.com/dbt-labs/dbt-core/issues/9265))
- [@danlsn](https://github.com/danlsn) ([#10915](https://github.com/dbt-labs/dbt-core/issues/10915))
- [@dave-connors-3](https://github.com/dave-connors-3) ([#9824](https://github.com/dbt-labs/dbt-core/issues/9824))
- [@devmessias](https://github.com/devmessias) ([#8520](https://github.com/dbt-labs/dbt-core/issues/8520), [#10880](https://github.com/dbt-labs/dbt-core/issues/10880), [#10528](https://github.com/dbt-labs/dbt-core/issues/10528), [#10623](https://github.com/dbt-labs/dbt-core/issues/10623))
- [@jeancochrane](https://github.com/jeancochrane) ([#5273](https://github.com/dbt-labs/dbt-core/issues/5273))
- [@katsugeneration](https://github.com/katsugeneration) ([#10754](https://github.com/dbt-labs/dbt-core/issues/10754))
- [@kevinneville](https://github.com/kevinneville) ([#7586](https://github.com/dbt-labs/dbt-core/issues/7586))
- [@nakamichiworks](https://github.com/nakamichiworks) ([#10442](https://github.com/dbt-labs/dbt-core/issues/10442))
- [@plypaul](https://github.com/plypaul) ([#10531](https://github.com/dbt-labs/dbt-core/issues/10531))
- [@rariyama](https://github.com/rariyama) ([#8997](https://github.com/dbt-labs/dbt-core/issues/8997))
- [@scottgigante,nevdelap](https://github.com/scottgigante,nevdelap) ([#8774](https://github.com/dbt-labs/dbt-core/issues/8774))
- [@tsturge](https://github.com/tsturge) ([#9109](https://github.com/dbt-labs/dbt-core/issues/9109), [#10540](https://github.com/dbt-labs/dbt-core/issues/10540))
- [@ttusing](https://github.com/ttusing) ([#10434](https://github.com/dbt-labs/dbt-core/issues/10434))
## Previous Releases ## Previous Releases
For information on prior major and minor releases, see their changelogs: For information on prior major and minor releases, see their changelogs:
* [1.11](https://github.com/dbt-labs/dbt-core/blob/1.11.latest/CHANGELOG.md)
* [1.10](https://github.com/dbt-labs/dbt-core/blob/1.10.latest/CHANGELOG.md)
* [1.9](https://github.com/dbt-labs/dbt-core/blob/1.9.latest/CHANGELOG.md)
* [1.8](https://github.com/dbt-labs/dbt-core/blob/1.8.latest/CHANGELOG.md)
* [1.7](https://github.com/dbt-labs/dbt-core/blob/1.7.latest/CHANGELOG.md) * [1.7](https://github.com/dbt-labs/dbt-core/blob/1.7.latest/CHANGELOG.md)
* [1.6](https://github.com/dbt-labs/dbt-core/blob/1.6.latest/CHANGELOG.md) * [1.6](https://github.com/dbt-labs/dbt-core/blob/1.6.latest/CHANGELOG.md)
* [1.5](https://github.com/dbt-labs/dbt-core/blob/1.5.latest/CHANGELOG.md) * [1.5](https://github.com/dbt-labs/dbt-core/blob/1.5.latest/CHANGELOG.md)

View File

@@ -2,39 +2,21 @@
`dbt-core` is open source software. It is what it is today because community members have opened issues, provided feedback, and [contributed to the knowledge loop](https://www.getdbt.com/dbt-labs/values/). Whether you are a seasoned open source contributor or a first-time committer, we welcome and encourage you to contribute code, documentation, ideas, or problem statements to this project. `dbt-core` is open source software. It is what it is today because community members have opened issues, provided feedback, and [contributed to the knowledge loop](https://www.getdbt.com/dbt-labs/values/). Whether you are a seasoned open source contributor or a first-time committer, we welcome and encourage you to contribute code, documentation, ideas, or problem statements to this project.
- [Contributing to `dbt-core`](#contributing-to-dbt-core) 1. [About this document](#about-this-document)
- [About this document](#about-this-document) 2. [Getting the code](#getting-the-code)
- [Notes](#notes) 3. [Setting up an environment](#setting-up-an-environment)
- [Getting the code](#getting-the-code) 4. [Running dbt-core in development](#running-dbt-core-in-development)
- [Installing git](#installing-git) 5. [Testing dbt-core](#testing)
- [External contributors](#external-contributors) 6. [Debugging](#debugging)
- [dbt Labs contributors](#dbt-labs-contributors) 7. [Adding or modifying a changelog entry](#adding-or-modifying-a-changelog-entry)
- [Setting up an environment](#setting-up-an-environment) 8. [Submitting a Pull Request](#submitting-a-pull-request)
- [Tools](#tools) 9. [Troubleshooting Tips](#troubleshooting-tips)
- [Virtual environments](#virtual-environments)
- [Docker and `docker-compose`](#docker-and-docker-compose)
- [Postgres (optional)](#postgres-optional)
- [Running `dbt-core` in development](#running-dbt-core-in-development)
- [Installation](#installation)
- [Running `dbt-core`](#running-dbt-core)
- [Testing](#testing)
- [Initial setup](#initial-setup)
- [Test commands](#test-commands)
- [Hatch scripts](#hatch-scripts)
- [`pre-commit`](#pre-commit)
- [`pytest`](#pytest)
- [Unit, Integration, Functional?](#unit-integration-functional)
- [Debugging](#debugging)
- [Assorted development tips](#assorted-development-tips)
- [Adding or modifying a CHANGELOG Entry](#adding-or-modifying-a-changelog-entry)
- [Submitting a Pull Request](#submitting-a-pull-request)
- [Troubleshooting Tips](#troubleshooting-tips)
## About this document ## About this document
There are many ways to contribute to the ongoing development of `dbt-core`, such as by participating in discussions and issues. We encourage you to first read our higher-level document: ["Expectations for Open Source Contributors"](https://docs.getdbt.com/docs/contributing/oss-expectations). There are many ways to contribute to the ongoing development of `dbt-core`, such as by participating in discussions and issues. We encourage you to first read our higher-level document: ["Expectations for Open Source Contributors"](https://docs.getdbt.com/docs/contributing/oss-expectations).
The rest of this document serves as a more granular guide for contributing code changes to `dbt-core` (this repository). It is not intended as a guide for using `dbt-core`, and some pieces assume a level of familiarity with Python development and package managers. Specific code snippets in this guide assume you are using macOS or Linux and are comfortable with the command line. The rest of this document serves as a more granular guide for contributing code changes to `dbt-core` (this repository). It is not intended as a guide for using `dbt-core`, and some pieces assume a level of familiarity with Python development (virtualenvs, `pip`, etc). Specific code snippets in this guide assume you are using macOS or Linux and are comfortable with the command line.
If you get stuck, we're happy to help! Drop us a line in the `#dbt-core-development` channel in the [dbt Community Slack](https://community.getdbt.com). If you get stuck, we're happy to help! Drop us a line in the `#dbt-core-development` channel in the [dbt Community Slack](https://community.getdbt.com).
@@ -73,22 +55,28 @@ There are some tools that will be helpful to you in developing locally. While th
These are the tools used in `dbt-core` development and testing: These are the tools used in `dbt-core` development and testing:
- [`hatch`](https://hatch.pypa.io/) for build backend, environment management, and running tests across Python versions (3.10, 3.11, 3.12, and 3.13) - [`tox`](https://tox.readthedocs.io/en/latest/) to manage virtualenvs across python versions. We currently target the latest patch releases for Python 3.8, 3.9, 3.10 and 3.11
- [`pytest`](https://docs.pytest.org/en/latest/) to define, discover, and run tests - [`pytest`](https://docs.pytest.org/en/latest/) to define, discover, and run tests
- [`flake8`](https://flake8.pycqa.org/en/latest/) for code linting - [`flake8`](https://flake8.pycqa.org/en/latest/) for code linting
- [`black`](https://github.com/psf/black) for code formatting - [`black`](https://github.com/psf/black) for code formatting
- [`mypy`](https://mypy.readthedocs.io/en/stable/) for static type checking - [`mypy`](https://mypy.readthedocs.io/en/stable/) for static type checking
- [`pre-commit`](https://pre-commit.com) to easily run those checks - [`pre-commit`](https://pre-commit.com) to easily run those checks
- [`changie`](https://changie.dev/) to create changelog entries, without merge conflicts - [`changie`](https://changie.dev/) to create changelog entries, without merge conflicts
- [`make`](https://users.cs.duke.edu/~ola/courses/programming/Makefiles/Makefiles.html) to run multiple setup or test steps in combination. Don't worry too much, nobody _really_ understands how `make` works, and our Makefile aims to be super simple.
- [GitHub Actions](https://github.com/features/actions) for automating tests and checks, once a PR is pushed to the `dbt-core` repository - [GitHub Actions](https://github.com/features/actions) for automating tests and checks, once a PR is pushed to the `dbt-core` repository
A deep understanding of these tools in not required to effectively contribute to `dbt-core`, but we recommend checking out the attached documentation if you're interested in learning more about each one. A deep understanding of these tools in not required to effectively contribute to `dbt-core`, but we recommend checking out the attached documentation if you're interested in learning more about each one.
#### Virtual environments #### Virtual environments
dbt-core uses [Hatch](https://hatch.pypa.io/) for dependency and environment management. Hatch automatically creates and manages isolated environments for development, testing, and building, so you don't need to manually create virtual environments. We strongly recommend using virtual environments when developing code in `dbt-core`. We recommend creating this virtualenv
in the root of the `dbt-core` repository. To create a new virtualenv, run:
```sh
python3 -m venv env
source env/bin/activate
```
For more information on how Hatch manages environments, see the [Hatch environment documentation](https://hatch.pypa.io/latest/environment/). This will create and activate a new Python virtual environment.
#### Docker and `docker-compose` #### Docker and `docker-compose`
@@ -107,42 +95,22 @@ brew install postgresql
### Installation ### Installation
First make sure you have Python 3.10 or later installed. Ensure you have the latest version of pip installed with `pip install --upgrade pip`. Next, install `hatch`. Finally set up `dbt-core` for development: First make sure that you set up your `virtualenv` as described in [Setting up an environment](#setting-up-an-environment). Also ensure you have the latest version of pip installed with `pip install --upgrade pip`. Next, install `dbt-core` (and its dependencies):
```sh ```sh
cd core make dev
hatch run setup
``` ```
or, alternatively:
This will install all development dependencies and set up pre-commit hooks.
By default, hatch will use whatever Python version is active in your environment. To specify a particular Python version, set the `HATCH_PYTHON` environment variable:
```sh ```sh
export HATCH_PYTHON=3.12 pip install -r dev-requirements.txt -r editable-requirements.txt
hatch env create pre-commit install
``` ```
Or add it to your shell profile (e.g., `~/.zshrc` or `~/.bashrc`) for persistence.
When installed in this way, any changes you make to your local copy of the source code will be reflected immediately in your next `dbt` run. When installed in this way, any changes you make to your local copy of the source code will be reflected immediately in your next `dbt` run.
#### Building dbt-core
dbt-core uses [Hatch](https://hatch.pypa.io/) (specifically `hatchling`) as its build backend. To build distribution packages:
```sh
cd core
hatch build
```
This will create both wheel (`.whl`) and source distribution (`.tar.gz`) files in the `dist/` directory.
The build configuration is defined in `core/pyproject.toml`. You can also use the standard `python -m build` command if you prefer.
### Running `dbt-core` ### Running `dbt-core`
Once you've run `hatch run setup`, the `dbt` command will be available in your PATH. You can verify this by running `which dbt`. With your virtualenv activated, the `dbt` script should point back to the source code you've cloned on your machine. You can verify this by running `which dbt`. This command should show you a path to an executable in your virtualenv.
Configure your [profile](https://docs.getdbt.com/docs/configure-your-profile) as necessary to connect to your target databases. It may be a good idea to add a new profile pointing to a local Postgres instance, or a specific test sandbox within your data warehouse if appropriate. Make sure to create a profile before running integration tests. Configure your [profile](https://docs.getdbt.com/docs/configure-your-profile) as necessary to connect to your target databases. It may be a good idea to add a new profile pointing to a local Postgres instance, or a specific test sandbox within your data warehouse if appropriate. Make sure to create a profile before running integration tests.
@@ -160,78 +128,45 @@ Although `dbt-core` works with a number of different databases, you won't need t
Postgres offers the easiest way to test most `dbt-core` functionality today. They are the fastest to run, and the easiest to set up. To run the Postgres integration tests, you'll have to do one extra step of setting up the test database: Postgres offers the easiest way to test most `dbt-core` functionality today. They are the fastest to run, and the easiest to set up. To run the Postgres integration tests, you'll have to do one extra step of setting up the test database:
```sh ```sh
cd core make setup-db
hatch run setup-db
``` ```
or, alternatively:
Alternatively, you can run the setup commands directly:
```sh ```sh
docker-compose up -d database docker-compose up -d database
PGHOST=localhost PGUSER=root PGPASSWORD=password PGDATABASE=postgres bash scripts/setup_db.sh PGHOST=localhost PGUSER=root PGPASSWORD=password PGDATABASE=postgres bash test/setup_db.sh
``` ```
### Test commands ### Test commands
There are a few methods for running tests locally. There are a few methods for running tests locally.
#### Hatch scripts #### Makefile
The primary way to run tests and checks is using hatch scripts (defined in `core/hatch.toml`): There are multiple targets in the Makefile to run common test suites and code
checks, most notably:
```sh ```sh
cd core # Runs unit tests with py38 and code checks in parallel.
make test
# Run all unit tests # Runs postgres integration tests with py38 in "fail fast" mode.
hatch run unit-tests make integration
# Run unit tests and all code quality checks
hatch run test
# Run integration tests
hatch run integration-tests
# Run integration tests in fail-fast mode
hatch run integration-tests-fail-fast
# Run linting checks only
hatch run lint
hatch run flake8
hatch run mypy
hatch run black
# Run all pre-commit hooks
hatch run code-quality
# Clean build artifacts
hatch run clean
``` ```
> These make targets assume you have a local installation of a recent version of [`tox`](https://tox.readthedocs.io/en/latest/) for unit/integration testing and pre-commit for code quality checks,
> unless you use choose a Docker container to run tests. Run `make help` for more info.
Hatch manages isolated environments and dependencies automatically. The commands above use the `default` environment which is recommended for most local development. Check out the other targets in the Makefile to see other commonly used test
suites.
**Using the `ci` environment (optional)**
If you need to replicate exactly what runs in GitHub Actions (e.g., with coverage reporting), use the `ci` environment:
```sh
cd core
# Run unit tests with coverage
hatch run ci:unit-tests
# Run unit tests with a specific Python version
hatch run +py=3.11 ci:unit-tests
```
> **Note:** Most developers should use the default environment (`hatch run unit-tests`). The `ci` environment is primarily for debugging CI failures or running tests with coverage.
#### `pre-commit` #### `pre-commit`
[`pre-commit`](https://pre-commit.com) takes care of running all code-checks for formatting and linting. Run `make dev` to install `pre-commit` in your local environment (we recommend running this command with a python virtual environment active). This command installs several pip executables including black, mypy, and flake8. Once this is done you can use any of the linter-based make targets as well as a git pre-commit hook that will ensure proper formatting and linting.
[`pre-commit`](https://pre-commit.com) takes care of running all code-checks for formatting and linting. Run `hatch run setup` to install `pre-commit` in your local environment (we recommend running this command with a python virtual environment active). This installs several pip executables including black, mypy, and flake8. Once installed, hooks will run automatically on `git commit`, or you can run them manually with `hatch run code-quality`. #### `tox`
[`tox`](https://tox.readthedocs.io/en/latest/) takes care of managing virtualenvs and install dependencies in order to run tests. You can also run tests in parallel, for example, you can run unit tests for Python 3.8, Python 3.9, Python 3.10 and Python 3.11 checks in parallel with `tox -p`. Also, you can run unit tests for specific python versions with `tox -e py38`. The configuration for these tests in located in `tox.ini`.
#### `pytest` #### `pytest`
Finally, you can also run a specific test or group of tests using [`pytest`](https://docs.pytest.org/en/latest/) directly. After running `hatch run setup`, you can run pytest commands like: Finally, you can also run a specific test or group of tests using [`pytest`](https://docs.pytest.org/en/latest/) directly. With a virtualenv active and dev dependencies installed you can do things like:
```sh ```sh
# run all unit tests in a file # run all unit tests in a file
@@ -289,9 +224,7 @@ Code can be merged into the current development branch `main` by opening a pull
Automated tests run via GitHub Actions. If you're a first-time contributor, all tests (including code checks and unit tests) will require a maintainer to approve. Changes in the `dbt-core` repository trigger integration tests against Postgres. dbt Labs also provides CI environments in which to test changes to other adapters, triggered by PRs in those adapters' repositories, as well as periodic maintenance checks of each adapter in concert with the latest `dbt-core` code changes. Automated tests run via GitHub Actions. If you're a first-time contributor, all tests (including code checks and unit tests) will require a maintainer to approve. Changes in the `dbt-core` repository trigger integration tests against Postgres. dbt Labs also provides CI environments in which to test changes to other adapters, triggered by PRs in those adapters' repositories, as well as periodic maintenance checks of each adapter in concert with the latest `dbt-core` code changes.
We require signed git commits. See docs [here](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits) for setting up code signing. Once all tests are passing and your PR has been approved, a `dbt-core` maintainer will merge your changes into the active development branch. And that's it! Happy developing :tada:
Once all tests are passing, all comments are resolved, and your PR has been approved, a `dbt-core` maintainer will merge your changes into the active development branch. And that's it! Happy developing :tada:
## Troubleshooting Tips ## Troubleshooting Tips

View File

@@ -33,6 +33,9 @@ RUN apt-get update \
python-is-python3 \ python-is-python3 \
python-dev-is-python3 \ python-dev-is-python3 \
python3-pip \ python3-pip \
python3.9 \
python3.9-dev \
python3.9-venv \
python3.10 \ python3.10 \
python3.10-dev \ python3.10-dev \
python3.10-venv \ python3.10-venv \
@@ -47,7 +50,7 @@ RUN curl -LO https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_V
&& tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
RUN pip3 install -U hatch wheel pre-commit RUN pip3 install -U tox wheel six setuptools
# These args are passed in via docker-compose, which reads then from the .env file. # These args are passed in via docker-compose, which reads then from the .env file.
# On Linux, run `make .env` to create the .env file for the current user. # On Linux, run `make .env` to create the .env file for the current user.
@@ -62,6 +65,7 @@ RUN if [ ${USER_ID:-0} -ne 0 ] && [ ${GROUP_ID:-0} -ne 0 ]; then \
useradd -mU -l dbt_test_user; \ useradd -mU -l dbt_test_user; \
fi fi
RUN mkdir /usr/app && chown dbt_test_user /usr/app RUN mkdir /usr/app && chown dbt_test_user /usr/app
RUN mkdir /home/tox && chown dbt_test_user /home/tox
WORKDIR /usr/app WORKDIR /usr/app
VOLUME /usr/app VOLUME /usr/app

View File

@@ -1 +0,0 @@
core/LICENSE

165
Makefile
View File

@@ -1,95 +1,150 @@
# ============================================================================
# DEPRECATED: This Makefile is maintained for backwards compatibility only.
#
# dbt-core now uses Hatch for task management and development workflows.
# Please migrate to using hatch commands directly:
#
# make dev → cd core && hatch run setup
# make unit → cd core && hatch run unit-tests
# make test → cd core && hatch run test
# make integration → cd core && hatch run integration-tests
# make lint → cd core && hatch run lint
# make code_quality → cd core && hatch run code-quality
# make setup-db → cd core && hatch run setup-db
# make clean → cd core && hatch run clean
#
# See core/pyproject.toml [tool.hatch.envs.default.scripts] for all available
# commands and CONTRIBUTING.md for detailed usage instructions.
#
# This Makefile will be removed in a future version of dbt-core.
# ============================================================================
.DEFAULT_GOAL:=help .DEFAULT_GOAL:=help
# Optional flag to run target in a docker container.
# (example `make test USE_DOCKER=true`)
ifeq ($(USE_DOCKER),true)
DOCKER_CMD := docker-compose run --rm test
endif
#
# To override CI_flags, create a file at this repo's root dir named `makefile.test.env`. Fill it
# with any ENV_VAR overrides required by your test environment, e.g.
# DBT_TEST_USER_1=user
# LOG_DIR="dir with a space in it"
#
# Warn: Restrict each line to one variable only.
#
ifeq (./makefile.test.env,$(wildcard ./makefile.test.env))
include ./makefile.test.env
endif
CI_FLAGS =\
DBT_TEST_USER_1=$(if $(DBT_TEST_USER_1),$(DBT_TEST_USER_1),dbt_test_user_1)\
DBT_TEST_USER_2=$(if $(DBT_TEST_USER_2),$(DBT_TEST_USER_2),dbt_test_user_2)\
DBT_TEST_USER_3=$(if $(DBT_TEST_USER_3),$(DBT_TEST_USER_3),dbt_test_user_3)\
RUSTFLAGS=$(if $(RUSTFLAGS),$(RUSTFLAGS),"-D warnings")\
LOG_DIR=$(if $(LOG_DIR),$(LOG_DIR),./logs)\
DBT_LOG_FORMAT=$(if $(DBT_LOG_FORMAT),$(DBT_LOG_FORMAT),json)
.PHONY: dev_req .PHONY: dev_req
dev_req: ## Installs dbt-* packages in develop mode along with only development dependencies. dev_req: ## Installs dbt-* packages in develop mode along with only development dependencies.
@cd core && hatch run dev-req @\
pip install -r dev-requirements.txt -r editable-requirements.txt
.PHONY: dev .PHONY: dev
dev: ## Installs dbt-* packages in develop mode along with development dependencies and pre-commit. dev: dev_req ## Installs dbt-* packages in develop mode along with development dependencies and pre-commit.
@cd core && hatch run setup @\
pre-commit install
.PHONY: dev-uninstall .PHONY: dev-uninstall
dev-uninstall: ## Uninstall all packages in venv except for build tools dev-uninstall: ## Uninstall all packages in venv except for build tools
@pip freeze | grep -v "^-e" | cut -d "@" -f1 | xargs pip uninstall -y; \ @\
pip freeze | grep -v "^-e" | cut -d "@" -f1 | xargs pip uninstall -y; \
pip uninstall -y dbt-core pip uninstall -y dbt-core
.PHONY: core_proto_types
core_proto_types: ## generates google protobuf python file from core_types.proto
protoc -I=./core/dbt/events --python_out=./core/dbt/events ./core/dbt/events/core_types.proto
.PHONY: mypy .PHONY: mypy
mypy: ## Runs mypy against staged changes for static type checking. mypy: .env ## Runs mypy against staged changes for static type checking.
@cd core && hatch run mypy @\
$(DOCKER_CMD) pre-commit run --hook-stage manual mypy-check | grep -v "INFO"
.PHONY: flake8 .PHONY: flake8
flake8: ## Runs flake8 against staged changes to enforce style guide. flake8: .env ## Runs flake8 against staged changes to enforce style guide.
@cd core && hatch run flake8 @\
$(DOCKER_CMD) pre-commit run --hook-stage manual flake8-check | grep -v "INFO"
.PHONY: black .PHONY: black
black: ## Runs black against staged changes to enforce style guide. black: .env ## Runs black against staged changes to enforce style guide.
@cd core && hatch run black @\
$(DOCKER_CMD) pre-commit run --hook-stage manual black-check -v | grep -v "INFO"
.PHONY: lint .PHONY: lint
lint: ## Runs flake8 and mypy code checks against staged changes. lint: .env ## Runs flake8 and mypy code checks against staged changes.
@cd core && hatch run lint @\
$(DOCKER_CMD) pre-commit run flake8-check --hook-stage manual | grep -v "INFO"; \
.PHONY: code_quality $(DOCKER_CMD) pre-commit run mypy-check --hook-stage manual | grep -v "INFO"
code_quality: ## Runs all pre-commit hooks against all files.
@cd core && hatch run code-quality
.PHONY: unit .PHONY: unit
unit: ## Runs unit tests with py unit: .env ## Runs unit tests with py
@cd core && hatch run unit-tests @\
$(DOCKER_CMD) tox -e py
.PHONY: test .PHONY: test
test: ## Runs unit tests with py and code checks against staged changes. test: .env ## Runs unit tests with py and code checks against staged changes.
@cd core && hatch run test @\
$(DOCKER_CMD) tox -e py; \
$(DOCKER_CMD) pre-commit run black-check --hook-stage manual | grep -v "INFO"; \
$(DOCKER_CMD) pre-commit run flake8-check --hook-stage manual | grep -v "INFO"; \
$(DOCKER_CMD) pre-commit run mypy-check --hook-stage manual | grep -v "INFO"
.PHONY: integration .PHONY: integration
integration: ## Runs core integration tests using postgres with py-integration integration: .env ## Runs core integration tests using postgres with py-integration
@cd core && hatch run integration-tests @\
$(CI_FLAGS) $(DOCKER_CMD) tox -e py-integration -- -nauto
.PHONY: integration-fail-fast .PHONY: integration-fail-fast
integration-fail-fast: ## Runs core integration tests using postgres with py-integration in "fail fast" mode. integration-fail-fast: .env ## Runs core integration tests using postgres with py-integration in "fail fast" mode.
@cd core && hatch run integration-tests-fail-fast @\
$(DOCKER_CMD) tox -e py-integration -- -x -nauto
.PHONY: interop
interop: clean
@\
mkdir $(LOG_DIR) && \
$(CI_FLAGS) $(DOCKER_CMD) tox -e py-integration -- -nauto && \
LOG_DIR=$(LOG_DIR) cargo run --manifest-path test/interop/log_parsing/Cargo.toml
.PHONY: setup-db .PHONY: setup-db
setup-db: ## Setup Postgres database with docker-compose for system testing. setup-db: ## Setup Postgres database with docker-compose for system testing.
@cd core && hatch run setup-db @\
docker-compose up -d database && \
PGHOST=localhost PGUSER=root PGPASSWORD=password PGDATABASE=postgres bash test/setup_db.sh
# This rule creates a file named .env that is used by docker-compose for passing
# the USER_ID and GROUP_ID arguments to the Docker image.
.env: ## Setup step for using using docker-compose with make target.
@touch .env
ifneq ($(OS),Windows_NT)
ifneq ($(shell uname -s), Darwin)
@echo USER_ID=$(shell id -u) > .env
@echo GROUP_ID=$(shell id -g) >> .env
endif
endif
.PHONY: clean .PHONY: clean
clean: ## Resets development environment. clean: ## Resets development environment.
@cd core && hatch run clean @echo 'cleaning repo...'
@rm -f .coverage
@rm -f .coverage.*
@rm -rf .eggs/
@rm -f .env
@rm -rf .tox/
@rm -rf build/
@rm -rf dbt.egg-info/
@rm -f dbt_project.yml
@rm -rf dist/
@rm -f htmlcov/*.{css,html,js,json,png}
@rm -rf logs/
@rm -rf target/
@find . -type f -name '*.pyc' -delete
@find . -type d -name '__pycache__' -depth -delete
@echo 'done.'
.PHONY: json_schema
json_schema: ## Update generated JSON schema using code changes.
@cd core && hatch run json-schema
.PHONY: help .PHONY: help
help: ## Show this help message. help: ## Show this help message.
@echo 'usage: make [target]' @echo 'usage: make [target] [USE_DOCKER=true]'
@echo
@echo 'DEPRECATED: This Makefile is a compatibility shim.'
@echo 'Please use "cd core && hatch run <command>" directly.'
@echo @echo
@echo 'targets:' @echo 'targets:'
@grep -E '^[8+a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' @grep -E '^[8+a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
@echo @echo
@echo 'For more information, see CONTRIBUTING.md' @echo 'options:'
@echo 'use USE_DOCKER=true to run target in a docker container'
.PHONY: json_schema
json_schema: ## Update generated JSON schema using code changes.
scripts/collect-artifact-schema.py --path schemas

View File

@@ -5,7 +5,6 @@
<a href="https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml"> <a href="https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml">
<img src="https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml/badge.svg?event=push" alt="CI Badge"/> <img src="https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml/badge.svg?event=push" alt="CI Badge"/>
</a> </a>
<a href="https://www.bestpractices.dev/projects/11095"><img src="https://www.bestpractices.dev/projects/11095/badge"></a>
</p> </p>
**[dbt](https://www.getdbt.com/)** enables data analysts and engineers to transform their data using the same practices that software engineers use to build applications. **[dbt](https://www.getdbt.com/)** enables data analysts and engineers to transform their data using the same practices that software engineers use to build applications.

View File

@@ -2,22 +2,37 @@ ignore:
- ".github" - ".github"
- ".changes" - ".changes"
# Disable all status checks to prevent red X's in CI
# Coverage data is still uploaded and PR comments are still posted
coverage: coverage:
status: status:
project: off project:
patch: off default:
target: auto
threshold: 0.1% # Reduce noise by ignoring rounding errors in coverage drops
patch:
default:
target: auto
threshold: 80%
comment: comment:
layout: "header, diff, flags, components" # show component info in the PR comment layout: "header, diff, flags, components" # show component info in the PR comment
component_management: component_management:
default_rules: # default rules that will be inherited by all components
statuses:
- type: project # in this case every component that doens't have a status defined will have a project type one
target: auto
threshold: 0.1%
- type: patch
target: 80%
individual_components: individual_components:
- component_id: unittests - component_id: unittests
name: "Unit Tests" name: "Unit Tests"
flag_regexes: flag_regexes:
- "unit" - "unit"
statuses:
- type: patch
target: 80%
threshold: 5%
- component_id: integrationtests - component_id: integrationtests
name: "Integration Tests" name: "Integration Tests"
flag_regexes: flag_regexes:

3
core/MANIFEST.in Normal file
View File

@@ -0,0 +1,3 @@
recursive-include dbt/include *.py *.sql *.yml *.html *.md .gitkeep .gitignore
include dbt/py.typed
recursive-include dbt/task/docs *.html

View File

@@ -1,5 +1,5 @@
<p align="center"> <p align="center">
<img src="https://raw.githubusercontent.com/dbt-labs/dbt-core/fa1ea14ddfb1d5ae319d5141844910dd53ab2834/docs/images/dbt-core.svg" alt="dbt logo" width="750"/> <img src="https://raw.githubusercontent.com/dbt-labs/dbt-core/fa1ea14ddfb1d5ae319d5141844910dd53ab2834/etc/dbt-core.svg" alt="dbt logo" width="750"/>
</p> </p>
<p align="center"> <p align="center">
<a href="https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml"> <a href="https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml">
@@ -9,7 +9,7 @@
**[dbt](https://www.getdbt.com/)** enables data analysts and engineers to transform their data using the same practices that software engineers use to build applications. **[dbt](https://www.getdbt.com/)** enables data analysts and engineers to transform their data using the same practices that software engineers use to build applications.
![architecture](https://raw.githubusercontent.com/dbt-labs/dbt-core/6c6649f9129d5d108aa3b0526f634cd8f3a9d1ed/docs/images/dbt-arch.png) ![architecture](https://raw.githubusercontent.com/dbt-labs/dbt-core/6c6649f9129d5d108aa3b0526f634cd8f3a9d1ed/etc/dbt-arch.png)
## Understanding dbt ## Understanding dbt
@@ -17,7 +17,7 @@ Analysts using dbt can transform their data by simply writing select statements,
These select statements, or "models", form a dbt project. Models frequently build on top of one another dbt makes it easy to [manage relationships](https://docs.getdbt.com/docs/ref) between models, and [visualize these relationships](https://docs.getdbt.com/docs/documentation), as well as assure the quality of your transformations through [testing](https://docs.getdbt.com/docs/testing). These select statements, or "models", form a dbt project. Models frequently build on top of one another dbt makes it easy to [manage relationships](https://docs.getdbt.com/docs/ref) between models, and [visualize these relationships](https://docs.getdbt.com/docs/documentation), as well as assure the quality of your transformations through [testing](https://docs.getdbt.com/docs/testing).
![dbt dag](https://raw.githubusercontent.com/dbt-labs/dbt-core/6c6649f9129d5d108aa3b0526f634cd8f3a9d1ed/docs/images/dbt-dag.png) ![dbt dag](https://raw.githubusercontent.com/dbt-labs/dbt-core/6c6649f9129d5d108aa3b0526f634cd8f3a9d1ed/etc/dbt-dag.png)
## Getting started ## Getting started

View File

@@ -1 +0,0 @@
version = "1.12.0a1"

View File

@@ -1,26 +0,0 @@
# type: ignore
"""Shim to allow support for both Pydantic 1 and Pydantic 2.
dbt-core must support both major versions of Pydantic because dbt-core users might be using an environment with
either version, and we can't restrict them to one or the other. Here, we essentially import all Pydantic objects
from version 1 that we use. Throughout the repo, we import these objects from this file instead of from Pydantic
directly, meaning that we essentially only use Pydantic 1 in dbt-core currently, but without forcing that restriction
on dbt users. The development environment for this repo should be pinned to Pydantic 1 to ensure devs get appropriate
type hints.
"""
from importlib.metadata import version
pydantic_version = version("pydantic")
# Pydantic uses semantic versioning, i.e. <major>.<minor>.<patch>, and we need to know the major
pydantic_major = pydantic_version.split(".")[0]
if pydantic_major == "1":
from pydantic import BaseSettings # noqa: F401
elif pydantic_major == "2":
from pydantic.v1 import BaseSettings # noqa: F401
else:
raise RuntimeError(
f"Currently only pydantic 1 and 2 are supported, found pydantic {pydantic_version}"
)

View File

@@ -1,10 +1,8 @@
from dbt.artifacts.resources.base import BaseResource, Docs, FileHash, GraphResource from dbt.artifacts.resources.base import BaseResource, Docs, FileHash, GraphResource
from dbt.artifacts.resources.v1.analysis import Analysis from dbt.artifacts.resources.v1.analysis import Analysis
from dbt.artifacts.resources.v1.catalog import Catalog, CatalogWriteIntegrationConfig
# alias to latest resource definitions # alias to latest resource definitions
from dbt.artifacts.resources.v1.components import ( from dbt.artifacts.resources.v1.components import (
ColumnConfig,
ColumnInfo, ColumnInfo,
CompiledResource, CompiledResource,
Contract, Contract,
@@ -25,8 +23,6 @@ from dbt.artifacts.resources.v1.config import (
NodeAndTestConfig, NodeAndTestConfig,
NodeConfig, NodeConfig,
TestConfig, TestConfig,
list_str,
metas,
) )
from dbt.artifacts.resources.v1.documentation import Documentation from dbt.artifacts.resources.v1.documentation import Documentation
from dbt.artifacts.resources.v1.exposure import ( from dbt.artifacts.resources.v1.exposure import (
@@ -35,15 +31,8 @@ from dbt.artifacts.resources.v1.exposure import (
ExposureType, ExposureType,
MaturityType, MaturityType,
) )
from dbt.artifacts.resources.v1.function import (
Function,
FunctionArgument,
FunctionConfig,
FunctionMandatory,
FunctionReturns,
)
from dbt.artifacts.resources.v1.generic_test import GenericTest, TestMetadata from dbt.artifacts.resources.v1.generic_test import GenericTest, TestMetadata
from dbt.artifacts.resources.v1.group import Group, GroupConfig from dbt.artifacts.resources.v1.group import Group
from dbt.artifacts.resources.v1.hook import HookNode from dbt.artifacts.resources.v1.hook import HookNode
from dbt.artifacts.resources.v1.macro import Macro, MacroArgument, MacroDependsOn from dbt.artifacts.resources.v1.macro import Macro, MacroArgument, MacroDependsOn
from dbt.artifacts.resources.v1.metric import ( from dbt.artifacts.resources.v1.metric import (
@@ -51,20 +40,13 @@ from dbt.artifacts.resources.v1.metric import (
ConversionTypeParams, ConversionTypeParams,
CumulativeTypeParams, CumulativeTypeParams,
Metric, Metric,
MetricAggregationParams,
MetricConfig, MetricConfig,
MetricInput, MetricInput,
MetricInputMeasure, MetricInputMeasure,
MetricTimeWindow, MetricTimeWindow,
MetricTypeParams, MetricTypeParams,
) )
from dbt.artifacts.resources.v1.model import ( from dbt.artifacts.resources.v1.model import Model, ModelConfig, TimeSpine
CustomGranularity,
Model,
ModelConfig,
ModelFreshness,
TimeSpine,
)
from dbt.artifacts.resources.v1.owner import Owner from dbt.artifacts.resources.v1.owner import Owner
from dbt.artifacts.resources.v1.saved_query import ( from dbt.artifacts.resources.v1.saved_query import (
Export, Export,
@@ -77,8 +59,6 @@ from dbt.artifacts.resources.v1.saved_query import (
from dbt.artifacts.resources.v1.seed import Seed, SeedConfig from dbt.artifacts.resources.v1.seed import Seed, SeedConfig
from dbt.artifacts.resources.v1.semantic_layer_components import ( from dbt.artifacts.resources.v1.semantic_layer_components import (
FileSlice, FileSlice,
MeasureAggregationParameters,
NonAdditiveDimension,
SourceFileMetadata, SourceFileMetadata,
WhereFilter, WhereFilter,
WhereFilterIntersection, WhereFilterIntersection,
@@ -90,8 +70,9 @@ from dbt.artifacts.resources.v1.semantic_model import (
DimensionValidityParams, DimensionValidityParams,
Entity, Entity,
Measure, Measure,
MeasureAggregationParameters,
NodeRelation, NodeRelation,
SemanticLayerElementConfig, NonAdditiveDimension,
SemanticModel, SemanticModel,
SemanticModelConfig, SemanticModelConfig,
) )

View File

@@ -35,7 +35,6 @@ class NodeType(StrEnum):
SemanticModel = "semantic_model" SemanticModel = "semantic_model"
Unit = "unit_test" Unit = "unit_test"
Fixture = "fixture" Fixture = "fixture"
Function = "function"
def pluralize(self) -> str: def pluralize(self) -> str:
if self is self.Analysis: if self is self.Analysis:
@@ -76,18 +75,3 @@ class BatchSize(StrEnum):
day = "day" day = "day"
month = "month" month = "month"
year = "year" year = "year"
def plural(self) -> str:
return str(self) + "s"
class FunctionType(StrEnum):
Scalar = "scalar"
Aggregate = "aggregate"
Table = "table"
class FunctionVolatility(StrEnum):
Deterministic = "deterministic"
Stable = "stable"
NonDeterministic = "non-deterministic"

View File

@@ -1,23 +0,0 @@
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional
from dbt.adapters.catalogs import CatalogIntegrationConfig
from dbt_common.dataclass_schema import dbtClassMixin
@dataclass
class CatalogWriteIntegrationConfig(CatalogIntegrationConfig):
name: str
catalog_type: str
external_volume: Optional[str] = None
table_format: Optional[str] = None
catalog_name: Optional[str] = None
file_format: Optional[str] = None
adapter_properties: Dict[str, Any] = field(default_factory=dict)
@dataclass
class Catalog(dbtClassMixin):
name: str
active_write_integration: Optional[str] = None
write_integrations: List[CatalogWriteIntegrationConfig] = field(default_factory=list)

View File

@@ -6,7 +6,6 @@ from typing import Any, Dict, List, Optional, Union
from dbt.artifacts.resources.base import Docs, FileHash, GraphResource from dbt.artifacts.resources.base import Docs, FileHash, GraphResource
from dbt.artifacts.resources.types import NodeType, TimePeriod from dbt.artifacts.resources.types import NodeType, TimePeriod
from dbt.artifacts.resources.v1.config import NodeConfig from dbt.artifacts.resources.v1.config import NodeConfig
from dbt_common.contracts.config.base import BaseConfig, MergeBehavior
from dbt_common.contracts.config.properties import AdditionalPropertiesMixin from dbt_common.contracts.config.properties import AdditionalPropertiesMixin
from dbt_common.contracts.constraints import ColumnLevelConstraint from dbt_common.contracts.constraints import ColumnLevelConstraint
from dbt_common.contracts.util import Mergeable from dbt_common.contracts.util import Mergeable
@@ -16,20 +15,6 @@ from dbt_semantic_interfaces.type_enums import TimeGranularity
NodeVersion = Union[str, float] NodeVersion = Union[str, float]
def _backcompat_doc_blocks(doc_blocks: Any) -> List[str]:
"""
Make doc_blocks backwards-compatible for scenarios where a user specifies `doc_blocks` on a model or column.
Mashumaro will raise a serialization error if the specified `doc_blocks` isn't a list of strings.
In such a scenario, this method returns an empty list to avoid a serialization error.
Further along, `_get_doc_blocks` in `manifest.py` populates the correct `doc_blocks` for the happy path.
"""
if isinstance(doc_blocks, list) and all(isinstance(x, str) for x in doc_blocks):
return doc_blocks
return []
@dataclass @dataclass
class MacroDependsOn(dbtClassMixin): class MacroDependsOn(dbtClassMixin):
macros: List[str] = field(default_factory=list) macros: List[str] = field(default_factory=list)
@@ -70,12 +55,6 @@ class RefArgs(dbtClassMixin):
return {} return {}
@dataclass
class ColumnConfig(BaseConfig):
meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta())
tags: List[str] = field(default_factory=list)
@dataclass @dataclass
class ColumnInfo(AdditionalPropertiesMixin, ExtensibleDbtClassMixin): class ColumnInfo(AdditionalPropertiesMixin, ExtensibleDbtClassMixin):
"""Used in all ManifestNodes and SourceDefinition""" """Used in all ManifestNodes and SourceDefinition"""
@@ -86,16 +65,9 @@ class ColumnInfo(AdditionalPropertiesMixin, ExtensibleDbtClassMixin):
data_type: Optional[str] = None data_type: Optional[str] = None
constraints: List[ColumnLevelConstraint] = field(default_factory=list) constraints: List[ColumnLevelConstraint] = field(default_factory=list)
quote: Optional[bool] = None quote: Optional[bool] = None
config: ColumnConfig = field(default_factory=ColumnConfig)
tags: List[str] = field(default_factory=list) tags: List[str] = field(default_factory=list)
_extra: Dict[str, Any] = field(default_factory=dict) _extra: Dict[str, Any] = field(default_factory=dict)
granularity: Optional[TimeGranularity] = None granularity: Optional[TimeGranularity] = None
doc_blocks: List[str] = field(default_factory=list)
def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None) -> dict:
dct = super().__post_serialize__(dct, context)
dct["doc_blocks"] = _backcompat_doc_blocks(dct["doc_blocks"])
return dct
@dataclass @dataclass
@@ -225,18 +197,13 @@ class ParsedResource(ParsedResourceMandatory):
unrendered_config_call_dict: Dict[str, Any] = field(default_factory=dict) unrendered_config_call_dict: Dict[str, Any] = field(default_factory=dict)
relation_name: Optional[str] = None relation_name: Optional[str] = None
raw_code: str = "" raw_code: str = ""
doc_blocks: List[str] = field(default_factory=list)
def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None): def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):
dct = super().__post_serialize__(dct, context) dct = super().__post_serialize__(dct, context)
if context and context.get("artifact") and "config_call_dict" in dct: if context and context.get("artifact") and "config_call_dict" in dct:
del dct["config_call_dict"] del dct["config_call_dict"]
if context and context.get("artifact") and "unrendered_config_call_dict" in dct: if context and context.get("artifact") and "unrendered_config_call_dict" in dct:
del dct["unrendered_config_call_dict"] del dct["unrendered_config_call_dict"]
dct["doc_blocks"] = _backcompat_doc_blocks(dct["doc_blocks"])
return dct return dct
@@ -249,7 +216,6 @@ class CompiledResource(ParsedResource):
refs: List[RefArgs] = field(default_factory=list) refs: List[RefArgs] = field(default_factory=list)
sources: List[List[str]] = field(default_factory=list) sources: List[List[str]] = field(default_factory=list)
metrics: List[List[str]] = field(default_factory=list) metrics: List[List[str]] = field(default_factory=list)
functions: List[List[str]] = field(default_factory=list)
depends_on: DependsOn = field(default_factory=DependsOn) depends_on: DependsOn = field(default_factory=DependsOn)
compiled_path: Optional[str] = None compiled_path: Optional[str] = None
compiled: bool = False compiled: bool = False

View File

@@ -181,7 +181,7 @@ class TestConfig(NodeAndTestConfig):
warn_if: str = "!= 0" warn_if: str = "!= 0"
error_if: str = "!= 0" error_if: str = "!= 0"
def finalize_and_validate(self): def __post_init__(self):
""" """
The presence of a setting for `store_failures_as` overrides any existing setting for `store_failures`, The presence of a setting for `store_failures_as` overrides any existing setting for `store_failures`,
regardless of level of granularity. If `store_failures_as` is not set, then `store_failures` takes effect. regardless of level of granularity. If `store_failures_as` is not set, then `store_failures` takes effect.
@@ -207,7 +207,6 @@ class TestConfig(NodeAndTestConfig):
but still allow for backwards compatibility for `store_failures`. but still allow for backwards compatibility for `store_failures`.
See https://github.com/dbt-labs/dbt-core/issues/6914 for more information. See https://github.com/dbt-labs/dbt-core/issues/6914 for more information.
""" """
super().finalize_and_validate()
# if `store_failures_as` is not set, it gets set by `store_failures` # if `store_failures_as` is not set, it gets set by `store_failures`
# the settings below mimic existing behavior prior to `store_failures_as` # the settings below mimic existing behavior prior to `store_failures_as`
@@ -230,8 +229,6 @@ class TestConfig(NodeAndTestConfig):
else: else:
self.store_failures = get_store_failures_map.get(self.store_failures_as, True) self.store_failures = get_store_failures_map.get(self.store_failures_as, True)
return self
@classmethod @classmethod
def same_contents(cls, unrendered: Dict[str, Any], other: Dict[str, Any]) -> bool: def same_contents(cls, unrendered: Dict[str, Any], other: Dict[str, Any]) -> bool:
"""This is like __eq__, except it explicitly checks certain fields.""" """This is like __eq__, except it explicitly checks certain fields."""

View File

@@ -27,8 +27,6 @@ class MaturityType(StrEnum):
@dataclass @dataclass
class ExposureConfig(BaseConfig): class ExposureConfig(BaseConfig):
enabled: bool = True enabled: bool = True
tags: List[str] = field(default_factory=list)
meta: Dict[str, Any] = field(default_factory=dict)
@dataclass @dataclass

View File

@@ -1,53 +0,0 @@
from dataclasses import dataclass, field
from typing import Any, List, Literal, Optional
from dbt.artifacts.resources.types import FunctionType, FunctionVolatility, NodeType
from dbt.artifacts.resources.v1.components import CompiledResource
from dbt.artifacts.resources.v1.config import NodeConfig
from dbt_common.dataclass_schema import dbtClassMixin
# =============
# Function config, and supporting classes
# =============
@dataclass
class FunctionConfig(NodeConfig):
# The fact that this is a property, that can be changed, seems wrong.
# A function's materialization should never be changed, so why allow for it?
materialized: str = "function"
type: FunctionType = FunctionType.Scalar
volatility: Optional[FunctionVolatility] = None
runtime_version: Optional[str] = None
entry_point: Optional[str] = None
# =============
# Function resource, and supporting classes
# =============
@dataclass
class FunctionArgument(dbtClassMixin):
name: str
data_type: str
description: Optional[str] = None
default_value: Optional[Any] = None
@dataclass
class FunctionReturns(dbtClassMixin):
data_type: str
description: Optional[str] = None
@dataclass
class FunctionMandatory(dbtClassMixin):
returns: FunctionReturns
@dataclass
class Function(CompiledResource, FunctionMandatory):
resource_type: Literal[NodeType.Function]
config: FunctionConfig
arguments: List[FunctionArgument] = field(default_factory=list)

View File

@@ -1,15 +1,9 @@
from dataclasses import dataclass, field from dataclasses import dataclass
from typing import Any, Dict, Literal, Optional from typing import Literal
from dbt.artifacts.resources.base import BaseResource from dbt.artifacts.resources.base import BaseResource
from dbt.artifacts.resources.types import NodeType from dbt.artifacts.resources.types import NodeType
from dbt.artifacts.resources.v1.owner import Owner from dbt.artifacts.resources.v1.owner import Owner
from dbt_common.contracts.config.base import BaseConfig, MergeBehavior
@dataclass
class GroupConfig(BaseConfig):
meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta())
@dataclass @dataclass
@@ -17,5 +11,3 @@ class Group(BaseResource):
name: str name: str
owner: Owner owner: Owner
resource_type: Literal[NodeType.Group] resource_type: Literal[NodeType.Group]
description: Optional[str] = None
config: GroupConfig = field(default_factory=GroupConfig)

View File

@@ -6,8 +6,6 @@ from dbt.artifacts.resources.base import GraphResource
from dbt.artifacts.resources.types import NodeType from dbt.artifacts.resources.types import NodeType
from dbt.artifacts.resources.v1.components import DependsOn, RefArgs from dbt.artifacts.resources.v1.components import DependsOn, RefArgs
from dbt.artifacts.resources.v1.semantic_layer_components import ( from dbt.artifacts.resources.v1.semantic_layer_components import (
MeasureAggregationParameters,
NonAdditiveDimension,
SourceFileMetadata, SourceFileMetadata,
WhereFilterIntersection, WhereFilterIntersection,
) )
@@ -15,7 +13,6 @@ from dbt_common.contracts.config.base import BaseConfig, CompareBehavior, MergeB
from dbt_common.dataclass_schema import dbtClassMixin from dbt_common.dataclass_schema import dbtClassMixin
from dbt_semantic_interfaces.references import MeasureReference, MetricReference from dbt_semantic_interfaces.references import MeasureReference, MetricReference
from dbt_semantic_interfaces.type_enums import ( from dbt_semantic_interfaces.type_enums import (
AggregationType,
ConversionCalculationType, ConversionCalculationType,
MetricType, MetricType,
PeriodAggregation, PeriodAggregation,
@@ -49,15 +46,7 @@ class MetricInputMeasure(dbtClassMixin):
@dataclass @dataclass
class MetricTimeWindow(dbtClassMixin): class MetricTimeWindow(dbtClassMixin):
count: int count: int
granularity: str granularity: TimeGranularity
@property
def window_string(self) -> str: # noqa: D
return f"{self.count} {self.granularity}"
@property
def is_standard_granularity(self) -> bool: # noqa: D
return self.granularity.casefold() in {item.value.casefold() for item in TimeGranularity}
@dataclass @dataclass
@@ -66,7 +55,7 @@ class MetricInput(dbtClassMixin):
filter: Optional[WhereFilterIntersection] = None filter: Optional[WhereFilterIntersection] = None
alias: Optional[str] = None alias: Optional[str] = None
offset_window: Optional[MetricTimeWindow] = None offset_window: Optional[MetricTimeWindow] = None
offset_to_grain: Optional[str] = None offset_to_grain: Optional[TimeGranularity] = None
def as_reference(self) -> MetricReference: def as_reference(self) -> MetricReference:
return MetricReference(element_name=self.name) return MetricReference(element_name=self.name)
@@ -94,19 +83,8 @@ class ConversionTypeParams(dbtClassMixin):
@dataclass @dataclass
class CumulativeTypeParams(dbtClassMixin): class CumulativeTypeParams(dbtClassMixin):
window: Optional[MetricTimeWindow] = None window: Optional[MetricTimeWindow] = None
grain_to_date: Optional[str] = None grain_to_date: Optional[TimeGranularity] = None
period_agg: PeriodAggregation = PeriodAggregation.FIRST period_agg: PeriodAggregation = PeriodAggregation.FIRST
metric: Optional[MetricInput] = None
@dataclass
class MetricAggregationParams(dbtClassMixin):
semantic_model: str
agg: AggregationType
agg_params: Optional[MeasureAggregationParameters] = None
agg_time_dimension: Optional[str] = None
non_additive_dimension: Optional[NonAdditiveDimension] = None
expr: Optional[str] = None
@dataclass @dataclass
@@ -117,13 +95,10 @@ class MetricTypeParams(dbtClassMixin):
denominator: Optional[MetricInput] = None denominator: Optional[MetricInput] = None
expr: Optional[str] = None expr: Optional[str] = None
window: Optional[MetricTimeWindow] = None window: Optional[MetricTimeWindow] = None
grain_to_date: Optional[TimeGranularity] = ( grain_to_date: Optional[TimeGranularity] = None
None # legacy, use cumulative_type_params.grain_to_date
)
metrics: Optional[List[MetricInput]] = None metrics: Optional[List[MetricInput]] = None
conversion_type_params: Optional[ConversionTypeParams] = None conversion_type_params: Optional[ConversionTypeParams] = None
cumulative_type_params: Optional[CumulativeTypeParams] = None cumulative_type_params: Optional[CumulativeTypeParams] = None
metric_aggregation_params: Optional[MetricAggregationParams] = None
@dataclass @dataclass
@@ -146,7 +121,7 @@ class Metric(GraphResource):
type_params: MetricTypeParams type_params: MetricTypeParams
filter: Optional[WhereFilterIntersection] = None filter: Optional[WhereFilterIntersection] = None
metadata: Optional[SourceFileMetadata] = None metadata: Optional[SourceFileMetadata] = None
time_granularity: Optional[str] = None time_granularity: Optional[TimeGranularity] = None
resource_type: Literal[NodeType.Metric] resource_type: Literal[NodeType.Metric]
meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta()) meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta())
tags: List[str] = field(default_factory=list) tags: List[str] = field(default_factory=list)

View File

@@ -1,9 +1,8 @@
import enum
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import datetime from datetime import datetime
from typing import Dict, List, Literal, Optional from typing import Dict, List, Literal, Optional
from dbt.artifacts.resources.types import AccessType, NodeType, TimePeriod from dbt.artifacts.resources.types import AccessType, NodeType
from dbt.artifacts.resources.v1.components import ( from dbt.artifacts.resources.v1.components import (
CompiledResource, CompiledResource,
DeferRelation, DeferRelation,
@@ -12,63 +11,7 @@ from dbt.artifacts.resources.v1.components import (
from dbt.artifacts.resources.v1.config import NodeConfig from dbt.artifacts.resources.v1.config import NodeConfig
from dbt_common.contracts.config.base import MergeBehavior from dbt_common.contracts.config.base import MergeBehavior
from dbt_common.contracts.constraints import ModelLevelConstraint from dbt_common.contracts.constraints import ModelLevelConstraint
from dbt_common.contracts.util import Mergeable from dbt_common.dataclass_schema import dbtClassMixin
from dbt_common.dataclass_schema import (
ExtensibleDbtClassMixin,
ValidationError,
dbtClassMixin,
)
class ModelFreshnessUpdatesOnOptions(enum.Enum):
all = "all"
any = "any"
@dataclass
class ModelBuildAfter(ExtensibleDbtClassMixin):
count: Optional[int] = None
period: Optional[TimePeriod] = None
updates_on: ModelFreshnessUpdatesOnOptions = ModelFreshnessUpdatesOnOptions.any
@dataclass
class ModelFreshness(ExtensibleDbtClassMixin, Mergeable):
build_after: ModelBuildAfter
def merge_model_freshness(*thresholds: Optional[ModelFreshness]) -> Optional[ModelFreshness]:
if not thresholds:
return None
current_merged_value: Optional[ModelFreshness] = thresholds[0]
for i in range(1, len(thresholds)):
base = current_merged_value
update = thresholds[i]
if base is not None and update is not None:
# When both base and update freshness are defined,
# create a new ModelFreshness instance using the build_after from the 'update'.
# This effectively means 'update's build_after configuration takes precedence.
merged_freshness_obj = base.merged(update)
if (
base.build_after.updates_on == ModelFreshnessUpdatesOnOptions.all
or update.build_after.updates_on == ModelFreshnessUpdatesOnOptions.all
):
merged_freshness_obj.build_after.updates_on = ModelFreshnessUpdatesOnOptions.all
current_merged_value = merged_freshness_obj
elif base is None and update is not None:
# If the current merged value is None but the new update is defined,
# take the update.
current_merged_value = update
else:
# This covers cases where 'update' is None (regardless of 'base'),
# or both 'base' and 'update' are None.
# The result of the pair-merge is None.
current_merged_value = base
return current_merged_value
@dataclass @dataclass
@@ -77,40 +20,6 @@ class ModelConfig(NodeConfig):
default=AccessType.Protected, default=AccessType.Protected,
metadata=MergeBehavior.Clobber.meta(), metadata=MergeBehavior.Clobber.meta(),
) )
freshness: Optional[ModelFreshness] = None
def __post_init__(self):
super().__post_init__()
if (
self.freshness
and self.freshness.build_after.period
and self.freshness.build_after.count is None
):
raise ValidationError(
"`freshness.build_after` must have a value for `count` if a `period` is provided"
)
elif (
self.freshness
and self.freshness.build_after.count is not None
and not self.freshness.build_after.period
):
raise ValidationError(
"`freshness.build_after` must have a value for `period` if a `count` is provided"
)
@classmethod
def __pre_deserialize__(cls, data):
data = super().__pre_deserialize__(data)
# scrub out model configs where "build_after" is not defined
if (
"freshness" in data
and isinstance(data["freshness"], dict)
and "build_after" in data["freshness"]
):
data["freshness"] = ModelFreshness.from_dict(data["freshness"]).to_dict()
else:
data.pop("freshness", None)
return data
@dataclass @dataclass

View File

@@ -1,10 +1,10 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import List, Optional, Union from typing import Optional
from dbt_common.contracts.config.properties import AdditionalPropertiesAllowed from dbt_common.contracts.config.properties import AdditionalPropertiesAllowed
@dataclass @dataclass
class Owner(AdditionalPropertiesAllowed): class Owner(AdditionalPropertiesAllowed):
email: Union[str, List[str], None] = None email: Optional[str] = None
name: Optional[str] = None name: Optional[str] = None

View File

@@ -2,18 +2,16 @@ from __future__ import annotations
import time import time
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Any, Dict, List, Literal, Optional, Union from typing import Any, Dict, List, Literal, Optional
from dbt.artifacts.resources.base import GraphResource from dbt.artifacts.resources.base import GraphResource
from dbt.artifacts.resources.types import NodeType from dbt.artifacts.resources.types import NodeType
from dbt.artifacts.resources.v1.components import DependsOn, RefArgs from dbt.artifacts.resources.v1.components import DependsOn, RefArgs
from dbt.artifacts.resources.v1.config import list_str, metas
from dbt.artifacts.resources.v1.semantic_layer_components import ( from dbt.artifacts.resources.v1.semantic_layer_components import (
SourceFileMetadata, SourceFileMetadata,
WhereFilterIntersection, WhereFilterIntersection,
) )
from dbt_common.contracts.config.base import BaseConfig, CompareBehavior, MergeBehavior from dbt_common.contracts.config.base import BaseConfig, CompareBehavior, MergeBehavior
from dbt_common.contracts.config.metadata import ShowBehavior
from dbt_common.dataclass_schema import dbtClassMixin from dbt_common.dataclass_schema import dbtClassMixin
from dbt_semantic_interfaces.type_enums.export_destination_type import ( from dbt_semantic_interfaces.type_enums.export_destination_type import (
ExportDestinationType, ExportDestinationType,
@@ -97,10 +95,6 @@ class SavedQuery(SavedQueryMandatory):
depends_on: DependsOn = field(default_factory=DependsOn) depends_on: DependsOn = field(default_factory=DependsOn)
created_at: float = field(default_factory=lambda: time.time()) created_at: float = field(default_factory=lambda: time.time())
refs: List[RefArgs] = field(default_factory=list) refs: List[RefArgs] = field(default_factory=list)
tags: Union[List[str], str] = field(
default_factory=list_str,
metadata=metas(ShowBehavior.Hide, MergeBehavior.Append, CompareBehavior.Exclude),
)
@property @property
def metrics(self) -> List[str]: def metrics(self) -> List[str]:

View File

@@ -1,36 +1,28 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import List, Optional, Sequence, Tuple from typing import List, Sequence, Tuple
from dbt_common.dataclass_schema import dbtClassMixin from dbt_common.dataclass_schema import dbtClassMixin
from dbt_semantic_interfaces.call_parameter_sets import JinjaCallParameterSets from dbt_semantic_interfaces.call_parameter_sets import FilterCallParameterSets
from dbt_semantic_interfaces.parsing.where_filter.jinja_object_parser import ( from dbt_semantic_interfaces.parsing.where_filter.where_filter_parser import (
JinjaObjectParser, WhereFilterParser,
QueryItemLocation,
) )
from dbt_semantic_interfaces.type_enums import AggregationType
@dataclass @dataclass
class WhereFilter(dbtClassMixin): class WhereFilter(dbtClassMixin):
where_sql_template: str where_sql_template: str
def call_parameter_sets( @property
self, custom_granularity_names: Sequence[str] def call_parameter_sets(self) -> FilterCallParameterSets:
) -> JinjaCallParameterSets: return WhereFilterParser.parse_call_parameter_sets(self.where_sql_template)
return JinjaObjectParser.parse_call_parameter_sets(
self.where_sql_template,
custom_granularity_names=custom_granularity_names,
query_item_location=QueryItemLocation.NON_ORDER_BY,
)
@dataclass @dataclass
class WhereFilterIntersection(dbtClassMixin): class WhereFilterIntersection(dbtClassMixin):
where_filters: List[WhereFilter] where_filters: List[WhereFilter]
def filter_expression_parameter_sets( @property
self, custom_granularity_names: Sequence[str] def filter_expression_parameter_sets(self) -> Sequence[Tuple[str, FilterCallParameterSets]]:
) -> Sequence[Tuple[str, JinjaCallParameterSets]]:
raise NotImplementedError raise NotImplementedError
@@ -56,17 +48,3 @@ class SourceFileMetadata(dbtClassMixin):
repo_file_path: str repo_file_path: str
file_slice: FileSlice file_slice: FileSlice
@dataclass
class MeasureAggregationParameters(dbtClassMixin):
percentile: Optional[float] = None
use_discrete_percentile: bool = False
use_approximate_percentile: bool = False
@dataclass
class NonAdditiveDimension(dbtClassMixin):
name: str
window_choice: AggregationType
window_groupings: List[str]

View File

@@ -5,11 +5,6 @@ from typing import Any, Dict, List, Optional, Sequence
from dbt.artifacts.resources import SourceFileMetadata from dbt.artifacts.resources import SourceFileMetadata
from dbt.artifacts.resources.base import GraphResource from dbt.artifacts.resources.base import GraphResource
from dbt.artifacts.resources.v1.components import DependsOn, RefArgs from dbt.artifacts.resources.v1.components import DependsOn, RefArgs
from dbt.artifacts.resources.v1.metric import Metric
from dbt.artifacts.resources.v1.semantic_layer_components import (
MeasureAggregationParameters,
NonAdditiveDimension,
)
from dbt_common.contracts.config.base import BaseConfig, CompareBehavior, MergeBehavior from dbt_common.contracts.config.base import BaseConfig, CompareBehavior, MergeBehavior
from dbt_common.dataclass_schema import dbtClassMixin from dbt_common.dataclass_schema import dbtClassMixin
from dbt_semantic_interfaces.references import ( from dbt_semantic_interfaces.references import (
@@ -24,7 +19,6 @@ from dbt_semantic_interfaces.type_enums import (
AggregationType, AggregationType,
DimensionType, DimensionType,
EntityType, EntityType,
MetricType,
TimeGranularity, TimeGranularity,
) )
@@ -37,14 +31,6 @@ https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/dbt_semantic_inter
""" """
@dataclass
class SemanticLayerElementConfig(dbtClassMixin):
meta: Dict[str, Any] = field(
default_factory=dict,
metadata=MergeBehavior.Update.meta(),
)
@dataclass @dataclass
class Defaults(dbtClassMixin): class Defaults(dbtClassMixin):
agg_time_dimension: Optional[str] = None agg_time_dimension: Optional[str] = None
@@ -86,7 +72,6 @@ class Dimension(dbtClassMixin):
type_params: Optional[DimensionTypeParams] = None type_params: Optional[DimensionTypeParams] = None
expr: Optional[str] = None expr: Optional[str] = None
metadata: Optional[SourceFileMetadata] = None metadata: Optional[SourceFileMetadata] = None
config: Optional[SemanticLayerElementConfig] = None
@property @property
def reference(self) -> DimensionReference: def reference(self) -> DimensionReference:
@@ -121,7 +106,6 @@ class Entity(dbtClassMixin):
label: Optional[str] = None label: Optional[str] = None
role: Optional[str] = None role: Optional[str] = None
expr: Optional[str] = None expr: Optional[str] = None
config: Optional[SemanticLayerElementConfig] = None
@property @property
def reference(self) -> EntityReference: def reference(self) -> EntityReference:
@@ -133,11 +117,25 @@ class Entity(dbtClassMixin):
# ==================================== # ====================================
# Measure object # Measure objects
# Measure protocols: https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/dbt_semantic_interfaces/protocols/measure.py # Measure protocols: https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/dbt_semantic_interfaces/protocols/measure.py
# ==================================== # ====================================
@dataclass
class MeasureAggregationParameters(dbtClassMixin):
percentile: Optional[float] = None
use_discrete_percentile: bool = False
use_approximate_percentile: bool = False
@dataclass
class NonAdditiveDimension(dbtClassMixin):
name: str
window_choice: AggregationType
window_groupings: List[str]
@dataclass @dataclass
class Measure(dbtClassMixin): class Measure(dbtClassMixin):
name: str name: str
@@ -149,7 +147,6 @@ class Measure(dbtClassMixin):
agg_params: Optional[MeasureAggregationParameters] = None agg_params: Optional[MeasureAggregationParameters] = None
non_additive_dimension: Optional[NonAdditiveDimension] = None non_additive_dimension: Optional[NonAdditiveDimension] = None
agg_time_dimension: Optional[str] = None agg_time_dimension: Optional[str] = None
config: Optional[SemanticLayerElementConfig] = None
@property @property
def reference(self) -> MeasureReference: def reference(self) -> MeasureReference:
@@ -266,45 +263,6 @@ class SemanticModel(GraphResource):
) )
return TimeDimensionReference(element_name=agg_time_dimension_name) return TimeDimensionReference(element_name=agg_time_dimension_name)
def checked_agg_time_dimension_for_simple_metric(
self, metric: Metric
) -> TimeDimensionReference:
assert (
metric.type == MetricType.SIMPLE
), "Only simple metrics can have an agg time dimension."
metric_agg_params = metric.type_params.metric_aggregation_params
# There are validations elsewhere to check this for metrics and provide messaging for it.
assert metric_agg_params, "Simple metrics must have metric_aggregation_params."
# This indicates a validation bug / dev error, not a user error that should appear
# in a user's YAML.
assert (
metric_agg_params.semantic_model == self.name
), "Cannot retrieve the agg time dimension for a metric from a different model "
f"than the one that the metric belongs to. Metric `{metric.name}` belongs to model "
f"`{metric_agg_params.semantic_model}`, but we requested the agg time dimension from model `{self.name}`."
metric_time_dimension_name = None
if (
metric.type_params
and metric.type_params.metric_aggregation_params
and metric.type_params.metric_aggregation_params.agg_time_dimension
):
metric_time_dimension_name = (
metric.type_params.metric_aggregation_params.agg_time_dimension
)
default_agg_time_dimension = (
self.defaults.agg_time_dimension if self.defaults is not None else None
)
agg_time_dimension_name = metric_time_dimension_name or default_agg_time_dimension
assert agg_time_dimension_name is not None, (
f"Aggregation time dimension for metric {metric.name} is not set! This should either be set directly on "
f"the metric specification in the model, or else defaulted to the time dimension in the data "
f"source containing the metric."
)
return TimeDimensionReference(element_name=agg_time_dimension_name)
@property @property
def primary_entity_reference(self) -> Optional[EntityReference]: def primary_entity_reference(self) -> Optional[EntityReference]:
return ( return (

View File

@@ -20,7 +20,7 @@ class SnapshotMetaColumnNames(dbtClassMixin):
class SnapshotConfig(NodeConfig): class SnapshotConfig(NodeConfig):
materialized: str = "snapshot" materialized: str = "snapshot"
strategy: Optional[str] = None strategy: Optional[str] = None
unique_key: Union[str, List[str], None] = None unique_key: Optional[Union[str, List[str]]] = None
target_schema: Optional[str] = None target_schema: Optional[str] = None
target_database: Optional[str] = None target_database: Optional[str] = None
updated_at: Optional[str] = None updated_at: Optional[str] = None

View File

@@ -10,7 +10,7 @@ from dbt.artifacts.resources.v1.components import (
HasRelationMetadata, HasRelationMetadata,
Quoting, Quoting,
) )
from dbt.artifacts.resources.v1.config import BaseConfig, MergeBehavior from dbt.artifacts.resources.v1.config import BaseConfig
from dbt_common.contracts.config.properties import AdditionalPropertiesAllowed from dbt_common.contracts.config.properties import AdditionalPropertiesAllowed
from dbt_common.contracts.util import Mergeable from dbt_common.contracts.util import Mergeable
from dbt_common.exceptions import CompilationError from dbt_common.exceptions import CompilationError
@@ -20,11 +20,6 @@ from dbt_common.exceptions import CompilationError
class SourceConfig(BaseConfig): class SourceConfig(BaseConfig):
enabled: bool = True enabled: bool = True
event_time: Any = None event_time: Any = None
freshness: Optional[FreshnessThreshold] = field(default_factory=FreshnessThreshold)
loaded_at_field: Optional[str] = None
loaded_at_query: Optional[str] = None
meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta())
tags: List[str] = field(default_factory=list)
@dataclass @dataclass
@@ -64,7 +59,6 @@ class ParsedSourceMandatory(GraphResource, HasRelationMetadata):
class SourceDefinition(ParsedSourceMandatory): class SourceDefinition(ParsedSourceMandatory):
quoting: Quoting = field(default_factory=Quoting) quoting: Quoting = field(default_factory=Quoting)
loaded_at_field: Optional[str] = None loaded_at_field: Optional[str] = None
loaded_at_query: Optional[str] = None
freshness: Optional[FreshnessThreshold] = None freshness: Optional[FreshnessThreshold] = None
external: Optional[ExternalTable] = None external: Optional[ExternalTable] = None
description: str = "" description: str = ""
@@ -79,4 +73,3 @@ class SourceDefinition(ParsedSourceMandatory):
created_at: float = field(default_factory=lambda: time.time()) created_at: float = field(default_factory=lambda: time.time())
unrendered_database: Optional[str] = None unrendered_database: Optional[str] = None
unrendered_schema: Optional[str] = None unrendered_schema: Optional[str] = None
doc_blocks: List[str] = field(default_factory=list)

View File

@@ -1,6 +1,6 @@
import dataclasses import dataclasses
import functools import functools
from datetime import datetime, timezone from datetime import datetime
from typing import Any, ClassVar, Dict, Optional, Type, TypeVar from typing import Any, ClassVar, Dict, Optional, Type, TypeVar
from mashumaro.jsonschema import build_json_schema from mashumaro.jsonschema import build_json_schema
@@ -12,7 +12,7 @@ from dbt_common.clients.system import read_json, write_json
from dbt_common.dataclass_schema import dbtClassMixin from dbt_common.dataclass_schema import dbtClassMixin
from dbt_common.events.functions import get_metadata_vars from dbt_common.events.functions import get_metadata_vars
from dbt_common.exceptions import DbtInternalError, DbtRuntimeError from dbt_common.exceptions import DbtInternalError, DbtRuntimeError
from dbt_common.invocation import get_invocation_id, get_invocation_started_at from dbt_common.invocation import get_invocation_id
BASE_SCHEMAS_URL = "https://schemas.getdbt.com/" BASE_SCHEMAS_URL = "https://schemas.getdbt.com/"
SCHEMA_PATH = "dbt/{name}/v{version}.json" SCHEMA_PATH = "dbt/{name}/v{version}.json"
@@ -55,13 +55,8 @@ class Readable:
class BaseArtifactMetadata(dbtClassMixin): class BaseArtifactMetadata(dbtClassMixin):
dbt_schema_version: str dbt_schema_version: str
dbt_version: str = __version__ dbt_version: str = __version__
generated_at: datetime = dataclasses.field( generated_at: datetime = dataclasses.field(default_factory=datetime.utcnow)
default_factory=lambda: datetime.now(timezone.utc).replace(tzinfo=None)
)
invocation_id: Optional[str] = dataclasses.field(default_factory=get_invocation_id) invocation_id: Optional[str] = dataclasses.field(default_factory=get_invocation_id)
invocation_started_at: Optional[datetime] = dataclasses.field(
default_factory=get_invocation_started_at
)
env: Dict[str, str] = dataclasses.field(default_factory=get_metadata_vars) env: Dict[str, str] = dataclasses.field(default_factory=get_metadata_vars)
def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None): def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):
@@ -181,11 +176,3 @@ def get_artifact_schema_version(dct: dict) -> int:
# 4. Convert to int # 4. Convert to int
# TODO: If this gets more complicated, turn into a regex # TODO: If this gets more complicated, turn into a regex
return int(schema_version.split("/")[-1].split(".")[0][1:]) return int(schema_version.split("/")[-1].split(".")[0][1:])
def get_artifact_dbt_version(dct: dict) -> Optional[str]:
dbt_version = dct.get("metadata", {}).get("dbt_version", None)
if dbt_version is None:
return None
return str(dbt_version)

View File

@@ -1,14 +1,11 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import datetime
from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple, Union from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple, Union
from uuid import UUID from uuid import UUID
from dbt import tracking
from dbt.artifacts.resources import ( from dbt.artifacts.resources import (
Analysis, Analysis,
Documentation, Documentation,
Exposure, Exposure,
Function,
GenericTest, GenericTest,
Group, Group,
HookNode, HookNode,
@@ -24,25 +21,25 @@ from dbt.artifacts.resources import (
SqlOperation, SqlOperation,
UnitTestDefinition, UnitTestDefinition,
) )
from dbt.artifacts.resources.v1.components import Quoting
from dbt.artifacts.schemas.base import ( from dbt.artifacts.schemas.base import (
ArtifactMixin, ArtifactMixin,
BaseArtifactMetadata, BaseArtifactMetadata,
get_artifact_dbt_version,
get_artifact_schema_version, get_artifact_schema_version,
schema_version, schema_version,
) )
from dbt.artifacts.schemas.upgrades import ( from dbt.artifacts.schemas.upgrades import upgrade_manifest_json
upgrade_manifest_json,
upgrade_manifest_json_dbt_version,
)
from dbt.version import __version__
from dbt_common.exceptions import DbtInternalError
NodeEdgeMap = Dict[str, List[str]] NodeEdgeMap = Dict[str, List[str]]
UniqueID = str UniqueID = str
ManifestResource = Union[ ManifestResource = Union[
Seed, Analysis, SingularTest, HookNode, Model, SqlOperation, GenericTest, Snapshot, Function Seed,
Analysis,
SingularTest,
HookNode,
Model,
SqlOperation,
GenericTest,
Snapshot,
] ]
DisabledManifestResource = Union[ DisabledManifestResource = Union[
ManifestResource, ManifestResource,
@@ -90,14 +87,6 @@ class ManifestMetadata(BaseArtifactMetadata):
default=None, default=None,
metadata=dict(description="The type name of the adapter"), metadata=dict(description="The type name of the adapter"),
) )
quoting: Optional[Quoting] = field(
default_factory=Quoting,
metadata=dict(description="The quoting configuration for the project"),
)
run_started_at: Optional[datetime] = field(
default=tracking.active_user.run_started_at if tracking.active_user is not None else None,
metadata=dict(description="The timestamp when the run started"),
)
@classmethod @classmethod
def default(cls): def default(cls):
@@ -169,10 +158,6 @@ class WritableManifest(ArtifactMixin):
description="The unit tests defined in the project", description="The unit tests defined in the project",
) )
) )
functions: Mapping[UniqueID, Function] = field(
default_factory=dict,
metadata=dict(description=("The functions defined in the dbt project")),
)
@classmethod @classmethod
def compatible_previous_versions(cls) -> Iterable[Tuple[str, int]]: def compatible_previous_versions(cls) -> Iterable[Tuple[str, int]]:
@@ -194,18 +179,4 @@ class WritableManifest(ArtifactMixin):
manifest_schema_version = get_artifact_schema_version(data) manifest_schema_version = get_artifact_schema_version(data)
if manifest_schema_version < cls.dbt_schema_version.version: if manifest_schema_version < cls.dbt_schema_version.version:
data = upgrade_manifest_json(data, manifest_schema_version) data = upgrade_manifest_json(data, manifest_schema_version)
manifest_dbt_version = get_artifact_dbt_version(data)
if manifest_dbt_version and manifest_dbt_version != __version__:
data = upgrade_manifest_json_dbt_version(data)
return cls.from_dict(data) return cls.from_dict(data)
@classmethod
def validate(cls, _):
# When dbt try to load an artifact with additional optional fields
# that are not present in the schema, from_dict will work fine.
# As long as validate is not called, the schema will not be enforced.
# This is intentional, as it allows for safer schema upgrades.
raise DbtInternalError(
"The WritableManifest should never be validated directly to allow for schema upgrades."
)

View File

@@ -1,5 +1,5 @@
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime, timezone from datetime import datetime
from typing import Any, Callable, Dict, List, Optional, Sequence, Union from typing import Any, Callable, Dict, List, Optional, Sequence, Union
from dbt.contracts.graph.nodes import ResultNode from dbt.contracts.graph.nodes import ResultNode
@@ -21,10 +21,10 @@ class TimingInfo(dbtClassMixin):
completed_at: Optional[datetime] = None completed_at: Optional[datetime] = None
def begin(self): def begin(self):
self.started_at = datetime.now(timezone.utc).replace(tzinfo=None) self.started_at = datetime.utcnow()
def end(self): def end(self):
self.completed_at = datetime.now(timezone.utc).replace(tzinfo=None) self.completed_at = datetime.utcnow()
def to_msg_dict(self): def to_msg_dict(self):
msg_dict = {"name": str(self.name)} msg_dict = {"name": str(self.name)}
@@ -64,7 +64,6 @@ class NodeStatus(StrEnum):
PartialSuccess = "partial success" PartialSuccess = "partial success"
Pass = "pass" Pass = "pass"
RuntimeErr = "runtime error" RuntimeErr = "runtime error"
NoOp = "no-op"
class RunStatus(StrEnum): class RunStatus(StrEnum):
@@ -72,7 +71,6 @@ class RunStatus(StrEnum):
Error = NodeStatus.Error Error = NodeStatus.Error
Skipped = NodeStatus.Skipped Skipped = NodeStatus.Skipped
PartialSuccess = NodeStatus.PartialSuccess PartialSuccess = NodeStatus.PartialSuccess
NoOp = NodeStatus.NoOp
class TestStatus(StrEnum): class TestStatus(StrEnum):

View File

@@ -3,7 +3,7 @@ from __future__ import annotations
import copy import copy
import threading import threading
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import datetime, timezone from datetime import datetime
from typing import Any, Dict, Iterable, Optional, Sequence, Tuple from typing import Any, Dict, Iterable, Optional, Sequence, Tuple
# https://github.com/dbt-labs/dbt-core/issues/10098 # https://github.com/dbt-labs/dbt-core/issues/10098
@@ -101,9 +101,7 @@ class RunExecutionResult(
): ):
results: Sequence[RunResult] results: Sequence[RunResult]
args: Dict[str, Any] = field(default_factory=dict) args: Dict[str, Any] = field(default_factory=dict)
generated_at: datetime = field( generated_at: datetime = field(default_factory=datetime.utcnow)
default_factory=lambda: datetime.now(timezone.utc).replace(tzinfo=None)
)
def write(self, path: str): def write(self, path: str):
writable = RunResultsArtifact.from_execution_results( writable = RunResultsArtifact.from_execution_results(

View File

@@ -1,4 +1 @@
from dbt.artifacts.schemas.upgrades.upgrade_manifest import upgrade_manifest_json from dbt.artifacts.schemas.upgrades.upgrade_manifest import upgrade_manifest_json
from dbt.artifacts.schemas.upgrades.upgrade_manifest_dbt_version import (
upgrade_manifest_json_dbt_version,
)

View File

@@ -1,2 +0,0 @@
def upgrade_manifest_json_dbt_version(manifest: dict) -> dict:
return manifest

View File

@@ -15,15 +15,14 @@ from dbt.cli.exceptions import DbtUsageException
from dbt.cli.resolvers import default_log_path, default_project_dir from dbt.cli.resolvers import default_log_path, default_project_dir
from dbt.cli.types import Command as CliCommand from dbt.cli.types import Command as CliCommand
from dbt.config.project import read_project_flags from dbt.config.project import read_project_flags
from dbt.config.utils import normalize_warn_error_options
from dbt.contracts.project import ProjectFlags from dbt.contracts.project import ProjectFlags
from dbt.deprecations import fire_buffered_deprecations, renamed_env_var, warn from dbt.deprecations import fire_buffered_deprecations, renamed_env_var
from dbt.events import ALL_EVENT_NAMES from dbt.events import ALL_EVENT_NAMES
from dbt_common import ui from dbt_common import ui
from dbt_common.clients import jinja from dbt_common.clients import jinja
from dbt_common.events import functions from dbt_common.events import functions
from dbt_common.exceptions import DbtInternalError from dbt_common.exceptions import DbtInternalError
from dbt_common.helper_types import WarnErrorOptionsV2 from dbt_common.helper_types import WarnErrorOptions
if os.name != "nt": if os.name != "nt":
# https://bugs.python.org/issue41567 # https://bugs.python.org/issue41567
@@ -50,8 +49,6 @@ DEPRECATED_PARAMS = {
} }
DEPRECATED_FLAGS_TO_WARNINGS = {("--models", "--model", "-m"): "model-param-usage-deprecation"}
WHICH_KEY = "which" WHICH_KEY = "which"
@@ -59,10 +56,9 @@ def convert_config(config_name, config_value):
"""Convert the values from config and original set_from_args to the correct type.""" """Convert the values from config and original set_from_args to the correct type."""
ret = config_value ret = config_value
if config_name.lower() == "warn_error_options" and type(config_value) == dict: if config_name.lower() == "warn_error_options" and type(config_value) == dict:
normalize_warn_error_options(ret) ret = WarnErrorOptions(
ret = WarnErrorOptionsV2( include=config_value.get("include", []),
error=config_value.get("error", []), exclude=config_value.get("exclude", []),
warn=config_value.get("warn", []),
silence=config_value.get("silence", []), silence=config_value.get("silence", []),
valid_error_names=ALL_EVENT_NAMES, valid_error_names=ALL_EVENT_NAMES,
) )
@@ -387,7 +383,7 @@ class Flags:
"Value for `--event-time-start` must be less than `--event-time-end`" "Value for `--event-time-start` must be less than `--event-time-end`"
) )
def fire_deprecations(self, ctx: Optional[Context] = None): def fire_deprecations(self):
"""Fires events for deprecated env_var usage.""" """Fires events for deprecated env_var usage."""
[dep_fn() for dep_fn in self.deprecated_env_var_warnings] [dep_fn() for dep_fn in self.deprecated_env_var_warnings]
# It is necessary to remove this attr from the class so it does # It is necessary to remove this attr from the class so it does
@@ -396,25 +392,12 @@ class Flags:
fire_buffered_deprecations() fire_buffered_deprecations()
# Handle firing deprecations of CLI aliases separately using argv or dbtRunner args
# because click doesn't make it possible to disambiguite which literal CLI option was used
# and only preserves the 'canonical' representation.
original_command_args = (
ctx.obj["dbt_runner_command_args"]
if (ctx and ctx.obj and "dbt_runner_command_args" in ctx.obj)
else sys.argv
)
for deprecated_flags, warning in DEPRECATED_FLAGS_TO_WARNINGS.items():
for deprecated_flag in deprecated_flags:
if deprecated_flag in original_command_args:
warn(warning)
@classmethod @classmethod
def from_dict(cls, command: CliCommand, args_dict: Dict[str, Any]) -> "Flags": def from_dict(cls, command: CliCommand, args_dict: Dict[str, Any]) -> "Flags":
command_arg_list = command_params(command, args_dict) command_arg_list = command_params(command, args_dict)
ctx = args_to_context(command_arg_list) ctx = args_to_context(command_arg_list)
flags = cls(ctx=ctx) flags = cls(ctx=ctx)
flags.fire_deprecations(ctx=ctx) flags.fire_deprecations()
return flags return flags
def set_common_global_flags(self): def set_common_global_flags(self):

View File

@@ -56,7 +56,6 @@ class dbtRunner:
dbt_ctx.obj = { dbt_ctx.obj = {
"manifest": self.manifest, "manifest": self.manifest,
"callbacks": self.callbacks, "callbacks": self.callbacks,
"dbt_runner_command_args": args,
} }
for key, value in kwargs.items(): for key, value in kwargs.items():
@@ -130,7 +129,6 @@ def global_flags(func):
@p.record_timing_info @p.record_timing_info
@p.send_anonymous_usage_stats @p.send_anonymous_usage_stats
@p.single_threaded @p.single_threaded
@p.show_all_deprecations
@p.state @p.state
@p.static_parser @p.static_parser
@p.target @p.target
@@ -142,8 +140,6 @@ def global_flags(func):
@p.warn_error @p.warn_error
@p.warn_error_options @p.warn_error_options
@p.write_json @p.write_json
@p.use_fast_test_edges
@p.upload_artifacts
@functools.wraps(func) @functools.wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
return func(*args, **kwargs) return func(*args, **kwargs)
@@ -182,7 +178,6 @@ def cli(ctx, **kwargs):
@p.project_dir @p.project_dir
@p.resource_type @p.resource_type
@p.exclude_resource_type @p.exclude_resource_type
@p.sample
@p.select @p.select
@p.selector @p.selector
@p.show @p.show
@@ -194,7 +189,6 @@ def cli(ctx, **kwargs):
@requires.preflight @requires.preflight
@requires.profile @requires.profile
@requires.project @requires.project
@requires.catalogs
@requires.runtime_config @requires.runtime_config
@requires.manifest @requires.manifest
def build(ctx, **kwargs): def build(ctx, **kwargs):
@@ -541,7 +535,6 @@ cli.add_command(ls, "ls")
@requires.preflight @requires.preflight
@requires.profile @requires.profile
@requires.project @requires.project
@requires.catalogs
@requires.runtime_config @requires.runtime_config
@requires.manifest(write_perf_info=True) @requires.manifest(write_perf_info=True)
def parse(ctx, **kwargs): def parse(ctx, **kwargs):
@@ -561,7 +554,6 @@ def parse(ctx, **kwargs):
@p.empty @p.empty
@p.event_time_start @p.event_time_start
@p.event_time_end @p.event_time_end
@p.sample
@p.select @p.select
@p.selector @p.selector
@p.target_path @p.target_path
@@ -571,7 +563,6 @@ def parse(ctx, **kwargs):
@requires.preflight @requires.preflight
@requires.profile @requires.profile
@requires.project @requires.project
@requires.catalogs
@requires.runtime_config @requires.runtime_config
@requires.manifest @requires.manifest
def run(ctx, **kwargs): def run(ctx, **kwargs):
@@ -705,7 +696,6 @@ def run_operation(ctx, **kwargs):
@requires.preflight @requires.preflight
@requires.profile @requires.profile
@requires.project @requires.project
@requires.catalogs
@requires.runtime_config @requires.runtime_config
@requires.manifest @requires.manifest
def seed(ctx, **kwargs): def seed(ctx, **kwargs):
@@ -739,7 +729,6 @@ def seed(ctx, **kwargs):
@requires.preflight @requires.preflight
@requires.profile @requires.profile
@requires.project @requires.project
@requires.catalogs
@requires.runtime_config @requires.runtime_config
@requires.manifest @requires.manifest
def snapshot(ctx, **kwargs): def snapshot(ctx, **kwargs):

Some files were not shown because too many files have changed in this diff Show More