tinybird-cli 2.0.1.dev0__tar.gz → 2.1.0.dev2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/PKG-INFO +11 -1
  2. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/__cli__.py +2 -2
  3. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/client.py +3 -0
  4. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/datafile.py +94 -7
  5. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/feedback_manager.py +13 -0
  6. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/branch.py +4 -11
  7. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/cli.py +97 -41
  8. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird_cli.egg-info/PKG-INFO +11 -1
  9. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/setup.cfg +0 -0
  10. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/ch_utils/constants.py +0 -0
  11. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/ch_utils/engine.py +0 -0
  12. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/check_pypi.py +0 -0
  13. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/config.py +0 -0
  14. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/connector_settings.py +0 -0
  15. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/connectors.py +0 -0
  16. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/context.py +0 -0
  17. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/datatypes.py +0 -0
  18. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/sql.py +0 -0
  19. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/sql_template.py +0 -0
  20. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/sql_template_fmt.py +0 -0
  21. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/sql_toolset.py +0 -0
  22. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/syncasync.py +0 -0
  23. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli.py +0 -0
  24. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/auth.py +0 -0
  25. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/cicd.py +0 -0
  26. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/common.py +0 -0
  27. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/config.py +0 -0
  28. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/connection.py +0 -0
  29. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/datasource.py +0 -0
  30. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/exceptions.py +0 -0
  31. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/job.py +0 -0
  32. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/pipe.py +0 -0
  33. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/telemetry.py +0 -0
  34. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/test.py +0 -0
  35. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  36. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  37. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/token.py +0 -0
  38. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/workspace.py +0 -0
  39. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  40. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird/tornado_template.py +0 -0
  41. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird_cli.egg-info/SOURCES.txt +0 -0
  42. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird_cli.egg-info/dependency_links.txt +0 -0
  43. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird_cli.egg-info/entry_points.txt +0 -0
  44. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird_cli.egg-info/requires.txt +0 -0
  45. {tinybird-cli-2.0.1.dev0 → tinybird-cli-2.1.0.dev2}/tinybird_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tinybird-cli
3
- Version: 2.0.1.dev0
3
+ Version: 2.1.0.dev2
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://docs.tinybird.co/cli.html
6
6
  Author: Tinybird
@@ -19,6 +19,16 @@ Changelog
19
19
 
20
20
  ---------
21
21
 
22
+ 2.1.0.dev2
23
+ ************
24
+
25
+ - `Changed` Internal changes in `tb deploy`
26
+
27
+ 2.1.0.dev1
28
+ ************
29
+
30
+ - `Added` `tb deploy` removes resources from datafiles deleted
31
+
22
32
  2.0.0
23
33
  ************
24
34
 
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
4
4
  __url__ = 'https://docs.tinybird.co/cli.html'
5
5
  __author__ = 'Tinybird'
6
6
  __author_email__ = 'support@tinybird.co'
7
- __version__ = '2.0.1.dev0'
8
- __revision__ = '40c7bee'
7
+ __version__ = '2.1.0.dev2'
8
+ __revision__ = '8400007'
@@ -1084,6 +1084,9 @@ class TinyB(object):
1084
1084
  }
1085
1085
  return await self._req(f"/v0/workspaces/{workspace_id}/releases/?{urlencode(params)}", method="POST", data="")
1086
1086
 
1087
+ async def release_failed(self, workspace_id: str, semver: str):
1088
+ return await self._req(f"/v0/workspaces/{workspace_id}/releases/{semver}?status=failed", method="PUT")
1089
+
1087
1090
  async def release_preview(self, workspace_id: str, semver: str):
1088
1091
  return await self._req(f"/v0/workspaces/{workspace_id}/releases/{semver}?status=preview", method="PUT")
1089
1092
 
@@ -52,7 +52,7 @@ from tinybird.tb_cli_modules.common import _get_tb_client, get_current_main_work
52
52
 
53
53
  from .tornado_template import UnClosedIfError
54
54
  from .sql import parse_table_structure, schema_to_sql_columns
55
- from .client import TinyB, DoesNotExistException
55
+ from .client import TinyB, DoesNotExistException, AuthException, CanNotBeDeletedException
56
56
  from .sql_template import render_sql_template, get_used_tables_in_template
57
57
  from tinybird.sql_template_fmt import format_sql_template
58
58
  from .feedback_manager import FeedbackManager
@@ -410,6 +410,9 @@ class CLIGitRelease:
410
410
  for filename in filenames
411
411
  }
412
412
 
413
+ def get_deleted_from_diffs(self, diffs: List[Diff]) -> List[str]:
414
+ return [diff.a_path for diff in diffs if diff.change_type == self.ChangeType.DELETED.value and diff.a_path]
415
+
413
416
  async def update_release(
414
417
  self, tb_client: TinyB, current_ws: Dict[str, Any], commit: Optional[str] = None
415
418
  ) -> Dict[str, Any]:
@@ -454,6 +457,7 @@ class Deployment:
454
457
  if not diffs:
455
458
  click.echo(FeedbackManager.info_git_release_no_diffs())
456
459
  changed = self.cli_git_release.get_changes_from_diffs(diffs, filenames)
460
+ deleted = self.cli_git_release.get_deleted_from_diffs(diffs)
457
461
 
458
462
  else:
459
463
  # only changes flow
@@ -462,7 +466,8 @@ class Deployment:
462
466
  if config
463
467
  else None
464
468
  )
465
- return changed
469
+ deleted = []
470
+ return changed, deleted
466
471
 
467
472
  def preparing_release(self):
468
473
  if not self.is_git_release:
@@ -499,11 +504,70 @@ class Deployment:
499
504
  if not self.is_git_release or self.dry_run or has_semver:
500
505
  return
501
506
  self.cli_git_release = self.cli_git_release or CLIGitRelease()
502
- release = await self.tb_client.workspace_commit_update(
503
- self.current_ws["id"], self.cli_git_release.head().commit.hexsha if not commit else commit
504
- )
507
+ release = await self.cli_git_release.update_release(self.tb_client, self.current_ws, commit)
505
508
  click.echo(FeedbackManager.success_git_release(release_commit=release["commit"]))
506
509
 
510
+ async def delete_resources(self, deleted: List[str], remote_pipes: List[Dict[str, Any]], dry_run: bool = False):
511
+ async def delete_pipe(resource_name_or_id: str, dry_run: bool = False):
512
+ if dry_run:
513
+ click.echo(
514
+ FeedbackManager.info_deleting_resource(dry_run="[DRY RUN] ", resource_name=resource_name_or_id)
515
+ )
516
+ else:
517
+ click.echo(FeedbackManager.info_deleting_resource(dry_run="", resource_name=resource_name_or_id))
518
+ try:
519
+ await self.tb_client.pipe_delete(resource_name_or_id)
520
+ except AuthException as e:
521
+ raise CLIGitReleaseException(str(e))
522
+ else:
523
+ click.echo(FeedbackManager.success_delete(name=resource_name_or_id))
524
+
525
+ async def delete_datasource(resource_name_or_id: str, dry_run: bool = False):
526
+ if dry_run:
527
+ click.echo(
528
+ FeedbackManager.info_deleting_resource(dry_run="[DRY RUN] ", resource_name=resource_name_or_id)
529
+ )
530
+ else:
531
+ click.echo(FeedbackManager.info_deleting_resource(dry_run="", resource_name=resource_name_or_id))
532
+ try:
533
+ await self.tb_client.datasource_delete(resource_name_or_id)
534
+ except CanNotBeDeletedException as e:
535
+ raise CLIGitReleaseException(str(e))
536
+ else:
537
+ click.echo(FeedbackManager.success_delete(name=resource_name_or_id))
538
+
539
+ resource_extension_processor = {".datasource": delete_datasource, ".pipe": delete_pipe}
540
+
541
+ # builds pipes deps the other way around from API to use with toposort
542
+ # i.e {'analytics_hits': ['analytics_pages', 'trend', 'analytics_sources', 'analytics_sessions']}
543
+ pipes_deps: Dict[str, List[str]] = {}
544
+ remote_pipes_type: Dict[str, str] = {}
545
+ for pipe in remote_pipes:
546
+ pipes_deps[pipe["name"]] = []
547
+ remote_pipes_type[pipe["name"]] = pipe["type"]
548
+ for node in pipe["nodes"]:
549
+ for dep in node["dependencies"]:
550
+ if dep in [pipe["name"] for pipe in remote_pipes]:
551
+ pipes_deps.setdefault(dep, []).append(pipe["name"])
552
+ deleted_resources: Dict[str, str] = {Path(resource).resolve().stem: resource for resource in deleted}
553
+
554
+ for group in toposort(pipes_deps):
555
+ # for each level keep materialized for the end
556
+ for pipe_name in sorted(group, key=lambda x: remote_pipes_type[x] == "materialized"):
557
+ if pipe_name in deleted_resources:
558
+ resource_path = deleted_resources.pop(pipe_name)
559
+ try:
560
+ await resource_extension_processor[Path(resource_path).suffix](pipe_name, dry_run)
561
+ except KeyError:
562
+ raise CLIGitReleaseException(FeedbackManager.error_file_extension(resource_path))
563
+
564
+ # Delete pending resources (datasources)
565
+ for name, path in deleted_resources.items():
566
+ try:
567
+ await resource_extension_processor[Path(path).suffix](name, dry_run)
568
+ except KeyError:
569
+ raise CLIGitReleaseException(FeedbackManager.error_file_extension(path))
570
+
507
571
 
508
572
  class Datafile:
509
573
  def __init__(self) -> None:
@@ -3407,7 +3471,7 @@ async def folder_push(
3407
3471
  workspace_lib_paths.append((x.name, x))
3408
3472
 
3409
3473
  datasources: List[Dict[str, Any]] = await tb_client.datasources()
3410
- pipes: List[Dict[str, Any]] = await tb_client.pipes()
3474
+ pipes: List[Dict[str, Any]] = await tb_client.pipes(dependencies=True)
3411
3475
 
3412
3476
  existing_resources: List[str] = [x["name"] for x in datasources] + [x["name"] for x in pipes]
3413
3477
  # replace workspace mapping names
@@ -3429,7 +3493,7 @@ async def folder_push(
3429
3493
  filenames = get_project_filenames(folder)
3430
3494
 
3431
3495
  # get the list of changes
3432
- changed = await deployment.detect_changes(filenames, only_changes, config)
3496
+ changed, deleted = await deployment.detect_changes(filenames, only_changes, config)
3433
3497
 
3434
3498
  deployment.preparing_release()
3435
3499
 
@@ -3668,9 +3732,12 @@ async def folder_push(
3668
3732
  if deployment.is_git_release:
3669
3733
  deployment.deploying_dry_run()
3670
3734
  await push_files(dry_run=True)
3735
+
3736
+ await deployment.delete_resources(deleted, pipes, dry_run=True)
3671
3737
  if not deployment.dry_run:
3672
3738
  deployment.deploying()
3673
3739
  await push_files(dry_run)
3740
+ await deployment.delete_resources(deleted, pipes)
3674
3741
  else:
3675
3742
  await push_files(dry_run)
3676
3743
 
@@ -4427,3 +4494,23 @@ def is_datasource(resource: Dict[str, Any]) -> bool:
4427
4494
  if resource and resource.get("resource") == "datasources":
4428
4495
  return True
4429
4496
  return False
4497
+
4498
+
4499
+ async def create_release(client: TinyB, config: Dict[str, Any], semver: str, folder: Optional[str] = None) -> None:
4500
+ if not folder:
4501
+ folder = getcwd()
4502
+ cli_git_release = None
4503
+ try:
4504
+ cli_git_release = CLIGitRelease(path=folder)
4505
+ commit = cli_git_release.head_commit()
4506
+ except CLIGitReleaseException:
4507
+ raise CLIGitReleaseException(FeedbackManager.error_no_git_repo_for_init(repo_path=folder))
4508
+
4509
+ await client.release_new(config["id"], semver, commit)
4510
+ click.echo(FeedbackManager.success_deployment_release(semver=semver))
4511
+
4512
+
4513
+ def has_internal_datafiles(folder: str) -> bool:
4514
+ folder = folder or "."
4515
+ filenames = get_project_filenames(folder)
4516
+ return any([f for f in filenames if "spans" in str(f) and "vendor" not in str(f)])
@@ -313,6 +313,15 @@ class FeedbackManager:
313
313
  "There are resources renamed. `tb deploy` can't deploy renamed resources, create new resources instead."
314
314
  )
315
315
 
316
+ info_create_release = info_message(
317
+ "** Release semver is bumped. Will use --fork-downstream to deploy changes. 💡 Hint: --fork-downstream creates new versions of the dependent downstream resources of the changed resources."
318
+ )
319
+ info_alter_release = info_message(
320
+ "** Release semver is not bumped. Changes are deployed to the current live Release. 💡 Hint: To deploy to a new Release edit the VERSION env variable in the .tinyenv file of the Data Project."
321
+ )
322
+ info_releases_detected = info_message(
323
+ "** Live Release: {current_semver} => New Release: {semver} 💡 Hint: To deploy to a new Release edit the VERSION env variable in the .tinyenv file of the Data Project."
324
+ )
316
325
  info_pre_prompt_auth_login_user_token = info_message(
317
326
  "ℹ️ In order to log into Tinybird, you need your user token. Please, go to {host}/tokens/ and paste your User Token here."
318
327
  )
@@ -436,7 +445,9 @@ Ready? """
436
445
  )
437
446
  warning_for_cicd_file = warning_message("** 🚨 Warning 🚨: {warning_message}")
438
447
  warning_unknown_response = warning_message("** Warning. Unknown response from server: {response}")
448
+ warning_resource_not_in_workspace = warning_message("** Warning: '{resource_name}' not found in workspace")
439
449
 
450
+ info_fixtures_branch = info_message("** Data Fixtures are only pushed to Branches")
440
451
  info_materialize_push_datasource_exists = warning_message("** Data Source {name} already exists")
441
452
  info_materialize_push_datasource_override = prompt_message(
442
453
  "Delete the Data Source from the workspace and push {name} again?"
@@ -589,6 +600,7 @@ Ready? """
589
600
  info_detected_changes_from_includes = info_message("** Changes from includes:")
590
601
  info_processing_from_include = info_message("\t{include_filename} => {filename}")
591
602
  info_deps_for_resource = info_message("\t{resource} => '{dep}'")
603
+ info_deleting_resource = info_message("** {dry_run}Deleting '{resource_name}'")
592
604
 
593
605
  info_cicd_generation_cancelled_by_user = info_message("** CI/CD files generation cancelled by user.")
594
606
  info_skipping_sharing_datasources_environment = info_message(
@@ -697,6 +709,7 @@ Ready? """
697
709
  success_sink_job_finished = success_message("""** Data sinked to '{bucket_path}'""")
698
710
  success_print_pipe = success_message("** Pipe: {pipe}")
699
711
  success_create = success_message("** '{name}' created")
712
+ success_delete = success_message("** '{name}' deleted")
700
713
  success_progress_blocks = success_message("** \N{front-facing baby chick} done")
701
714
  success_now_using_config = success_message("** Now using {name} ({id})")
702
715
  success_connector_config = success_message(
@@ -34,7 +34,7 @@ from tinybird.tb_cli_modules.common import (
34
34
  get_current_workspace,
35
35
  )
36
36
  from tinybird.feedback_manager import FeedbackManager
37
- from tinybird.datafile import wait_job, CLIGitRelease, CLIGitReleaseException
37
+ from tinybird.datafile import wait_job, CLIGitRelease, CLIGitReleaseException, create_release
38
38
  from tinybird.tb_cli_modules.exceptions import CLIBranchException, CLIException, CLIReleaseException
39
39
 
40
40
 
@@ -145,15 +145,7 @@ async def release_create(ctx: Context, semver: str) -> None:
145
145
  client: TinyB = ctx.ensure_object(dict)["client"]
146
146
  config = ctx.ensure_object(dict)["config"]
147
147
  folder = getcwd()
148
- cli_git_release = None
149
- try:
150
- cli_git_release = CLIGitRelease(path=folder)
151
- commit = cli_git_release.head_commit()
152
- except CLIGitReleaseException:
153
- raise CLIGitReleaseException(FeedbackManager.error_no_git_repo_for_init(repo_path=folder))
154
-
155
- await client.release_new(config["id"], semver, commit)
156
- click.echo(FeedbackManager.success_deployment_release(semver=semver))
148
+ await create_release(client, config, semver, folder)
157
149
 
158
150
 
159
151
  @release.command(name="promote", short_help="Promotes to live status a preview Release")
@@ -177,8 +169,9 @@ async def release_promote(ctx: Context, semver: str) -> None:
177
169
  client = _get_tb_client(config["token"], config["host"])
178
170
 
179
171
  try:
180
- await client.release_promote(config["id"], semver)
172
+ release = await client.release_promote(config["id"], semver)
181
173
  click.echo(FeedbackManager.success_release_promote(semver=semver))
174
+ click.echo(FeedbackManager.success_git_release(release_commit=release["commit"]))
182
175
  except Exception as e:
183
176
  raise CLIReleaseException(FeedbackManager.error_exception(error=str(e)))
184
177
 
@@ -14,6 +14,7 @@ import re
14
14
  import shutil
15
15
  import sys
16
16
  import click
17
+ from packaging import version
17
18
  from click import Context
18
19
 
19
20
  from pathlib import Path
@@ -29,6 +30,7 @@ from tinybird.datafile import (
29
30
  AlreadyExistsException,
30
31
  Datafile,
31
32
  ParseException,
33
+ create_release,
32
34
  build_graph,
33
35
  folder_push,
34
36
  folder_pull,
@@ -45,6 +47,7 @@ from tinybird.datafile import (
45
47
  peek,
46
48
  color_diff,
47
49
  parse_token,
50
+ has_internal_datafiles,
48
51
  )
49
52
  import tinybird.context as context
50
53
  from tinybird.config import FeatureFlags, get_config, VERSION, CURRENT_VERSION, SUPPORTED_CONNECTORS
@@ -114,12 +117,6 @@ DEFAULT_PATTERNS: List[Tuple[str, Union[str, Callable[[str], str]]]] = [
114
117
  default=True,
115
118
  help="Don't print version warning message if there's a new available version. You can use TB_VERSION_WARNING envar",
116
119
  )
117
- @click.option(
118
- "--hide-tokens",
119
- is_flag=True,
120
- default=False,
121
- help="Disable the output of tokens [DEPRECATED: tokens are hidden by default]",
122
- )
123
120
  @click.option("--show-tokens", is_flag=True, default=False, help="Enable the output of tokens")
124
121
  @click.version_option(version=VERSION)
125
122
  @click.pass_context
@@ -144,18 +141,11 @@ async def cli(
144
141
  sf_stage,
145
142
  with_headers: bool,
146
143
  version_warning: bool,
147
- hide_tokens: bool,
148
144
  show_tokens: bool,
149
145
  ) -> None:
150
146
  """
151
147
  Use `OBFUSCATE_REGEX_PATTERN` and `OBFUSCATE_PATTERN_SEPARATOR` environment variables to define a regex pattern and a separator (in case of a single string with multiple regex) to obfuscate secrets in the CLI output.
152
148
  """
153
- if hide_tokens:
154
- click.echo(
155
- FeedbackManager.warning_deprecated(
156
- warning="The `--hide-tokens` flag is deprecated. Tokens are hidden by default, see `tb --help` for more info."
157
- )
158
- )
159
149
 
160
150
  # We need to unpatch for our tests not to break
161
151
  if show_tokens:
@@ -586,13 +576,6 @@ def check(filenames: List[str], debug: bool) -> None:
586
576
  help="The user token is required for sharing a datasource that contains the SHARED_WITH entry.",
587
577
  type=click.types.STRING,
588
578
  )
589
- @click.option(
590
- "--is-internal",
591
- is_flag=True,
592
- default=False,
593
- help="Use when working with the Internal workspace as by default users can not create MV from internal datasources",
594
- hidden=True,
595
- )
596
579
  @click.pass_context
597
580
  @coro
598
581
  async def push(
@@ -625,12 +608,14 @@ async def push(
625
608
  check_requests_from_main: bool,
626
609
  folder: str,
627
610
  user_token: Optional[str],
628
- is_internal: bool,
629
611
  ) -> None:
630
612
  """Push files to Tinybird."""
631
613
 
632
614
  ignore_sql_errors = FeatureFlags.ignore_sql_errors()
633
615
  context.disable_template_security_validation.set(True)
616
+
617
+ is_internal = has_internal_datafiles(folder)
618
+
634
619
  await folder_push(
635
620
  create_tb_client(ctx),
636
621
  filenames,
@@ -833,25 +818,14 @@ async def fmt(
833
818
  help="Diffs local datafiles to the corresponding remote files in the main workspace. Only works when authenticated on an Environment.",
834
819
  hidden=True,
835
820
  )
836
- @click.option(
837
- "--production",
838
- is_flag=True,
839
- default=False,
840
- help="Diffs local datafiles to the corresponding remote files in the main workspace. Only works when authenticated on an Environment. (deprecated)",
841
- hidden=True,
842
- )
843
821
  @click.pass_context
844
822
  @coro
845
823
  async def diff(
846
- ctx: Context, filename: Optional[Tuple], fmt: bool, no_color: bool, no_verbose: bool, main: bool, production: bool
824
+ ctx: Context, filename: Optional[Tuple], fmt: bool, no_color: bool, no_verbose: bool, main: bool
847
825
  ) -> None:
848
826
  only_resources_changed = no_verbose
849
827
  client: TinyB = ctx.ensure_object(dict)["client"]
850
828
 
851
- if production:
852
- click.echo(FeedbackManager.warning_deprecated(warning="--production flag is deprecated, use --main instead"))
853
-
854
- main = main or production
855
829
  if not main:
856
830
  changed = await diff_command(
857
831
  list(filename) if filename else None, fmt, client, no_color, with_print=not only_resources_changed
@@ -1420,17 +1394,17 @@ async def prompt(_ctx: Context) -> None:
1420
1394
  hidden=True,
1421
1395
  )
1422
1396
  @click.option(
1423
- "--is-internal",
1397
+ "--only-changes",
1424
1398
  is_flag=True,
1425
1399
  default=False,
1426
- help="Use when working with the Internal workspace as by default users can not create MV from internal datasources",
1400
+ help="Deprecated, remove when we use `tb deploy` to deploy to main. See => https://gitlab.com/tinybird/analytics/-/issues/9669",
1427
1401
  hidden=True,
1428
1402
  )
1429
1403
  @click.option(
1430
- "--only-changes",
1404
+ "--v3",
1431
1405
  is_flag=True,
1432
1406
  default=False,
1433
- help="Deprecated, remove when we use `tb deploy` to deploy to main. See => https://gitlab.com/tinybird/analytics/-/issues/9669",
1407
+ help="Some specific logic to deploy using Releases. Will remove once we go to GA",
1434
1408
  hidden=True,
1435
1409
  )
1436
1410
  @click.pass_context
@@ -1455,13 +1429,80 @@ async def deploy(
1455
1429
  user_token: Optional[str],
1456
1430
  fork_downstream: bool,
1457
1431
  fork: bool,
1458
- is_internal: bool,
1459
1432
  only_changes: bool,
1433
+ v3: bool,
1460
1434
  ) -> None:
1461
1435
  """Deploy in tinybird pushing resources changed from previous release using git"""
1462
1436
 
1463
1437
  ignore_sql_errors = FeatureFlags.ignore_sql_errors()
1464
1438
  context.disable_template_security_validation.set(True)
1439
+
1440
+ is_internal = has_internal_datafiles(folder)
1441
+
1442
+ if not v3:
1443
+ await folder_push(
1444
+ tb_client=create_tb_client(ctx),
1445
+ dry_run=dry_run,
1446
+ check=False,
1447
+ push_deps=True,
1448
+ debug=debug,
1449
+ force=True,
1450
+ git_release=True,
1451
+ only_changes=only_changes,
1452
+ override_datasource=override_datasource,
1453
+ populate=populate,
1454
+ populate_subset=subset,
1455
+ populate_condition=sql_condition,
1456
+ unlink_on_populate_error=unlink_on_populate_error,
1457
+ upload_fixtures=fixtures,
1458
+ wait=wait,
1459
+ ignore_sql_errors=ignore_sql_errors,
1460
+ skip_confirmation=yes,
1461
+ workspace_map=dict(workspace_map),
1462
+ workspace_lib_paths=workspace,
1463
+ timeout=timeout,
1464
+ run_tests=False,
1465
+ folder=folder,
1466
+ config=ctx.ensure_object(dict)["config"],
1467
+ user_token=user_token,
1468
+ fork_downstream=fork_downstream,
1469
+ fork=fork,
1470
+ is_internal=is_internal,
1471
+ )
1472
+ return
1473
+
1474
+ client: TinyB = ctx.ensure_object(dict)["client"]
1475
+ config = ctx.ensure_object(dict)["config"]
1476
+ workspaces: List[Dict[str, Any]] = (await client.user_workspaces_and_branches()).get("workspaces", [])
1477
+ current_ws: Dict[str, Any] = next(
1478
+ (workspace for workspace in workspaces if config and workspace.get("id", ".") == config.get("id", "..")), {}
1479
+ )
1480
+
1481
+ semver = config.get("semver")
1482
+ is_environment = current_ws.get("is_branch")
1483
+ # FIXME decide when to auto-promote
1484
+ auto_promote = False
1485
+ release = current_ws.get("release", {})
1486
+ current_semver: Optional[str] = "no release in remote Workspace"
1487
+ if release and isinstance(release, dict):
1488
+ current_semver = release.get("semver")
1489
+
1490
+ if not is_environment:
1491
+ # TODO upload fixtures on tb test
1492
+ fixtures = False
1493
+ click.echo(FeedbackManager.info_fixtures_branch())
1494
+
1495
+ release_created = False
1496
+ if semver and current_semver:
1497
+ click.echo(FeedbackManager.info_releases_detected(current_semver=current_semver, semver=semver))
1498
+ if version.parse(semver.split("-snapshot")[0]) > version.parse(current_semver.split("-snapshot")[0]):
1499
+ click.echo(FeedbackManager.info_create_release())
1500
+ await create_release(client, config, semver)
1501
+ release_created = True
1502
+ fork_downstream = True
1503
+ else:
1504
+ click.echo(FeedbackManager.info_alter_release())
1505
+ yes = True
1465
1506
  try:
1466
1507
  await folder_push(
1467
1508
  tb_client=create_tb_client(ctx),
@@ -1492,9 +1533,9 @@ async def deploy(
1492
1533
  fork=fork,
1493
1534
  is_internal=is_internal,
1494
1535
  )
1495
- except click.ClickException as e:
1496
- # custom exceptions coming from the API for the git workflow
1497
- # FIXME: change this in the API
1536
+ except Exception as e:
1537
+ if release_created:
1538
+ await client.release_failed(config["id"], semver)
1498
1539
  if "--override-datasource" in str(e):
1499
1540
  new_exception = type(e)(
1500
1541
  f"{str(e).replace('. If you want to try to force override the Materialized View, please use the `--override-datasource` flag', '')} If you are creating a new Release update the related .datasource files and use --fork-downstream"
@@ -1502,3 +1543,18 @@ async def deploy(
1502
1543
  raise new_exception
1503
1544
  else:
1504
1545
  raise e
1546
+
1547
+ if release_created:
1548
+ try:
1549
+ await client.release_preview(config["id"], semver)
1550
+ click.echo(FeedbackManager.success_release_preview(semver=semver))
1551
+ if auto_promote:
1552
+ # TODO: define when auto-promote in the main Environment
1553
+ try:
1554
+ release = await client.release_promote(config["id"], semver)
1555
+ click.echo(FeedbackManager.success_release_promote(semver=semver))
1556
+ click.echo(FeedbackManager.success_git_release(release_commit=release["commit"]))
1557
+ except Exception as e:
1558
+ raise CLIException(FeedbackManager.error_exception(error=str(e)))
1559
+ except Exception as e:
1560
+ raise CLIException(FeedbackManager.error_exception(error=str(e)))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tinybird-cli
3
- Version: 2.0.1.dev0
3
+ Version: 2.1.0.dev2
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://docs.tinybird.co/cli.html
6
6
  Author: Tinybird
@@ -19,6 +19,16 @@ Changelog
19
19
 
20
20
  ---------
21
21
 
22
+ 2.1.0.dev2
23
+ ************
24
+
25
+ - `Changed` Internal changes in `tb deploy`
26
+
27
+ 2.1.0.dev1
28
+ ************
29
+
30
+ - `Added` `tb deploy` removes resources from datafiles deleted
31
+
22
32
  2.0.0
23
33
  ************
24
34