etlplus 0.7.1__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 (144) hide show
  1. etlplus-0.7.1/.coveragerc +21 -0
  2. etlplus-0.7.1/.editorconfig +156 -0
  3. etlplus-0.7.1/.gitattributes +13 -0
  4. etlplus-0.7.1/.github/actions/python-bootstrap/action.yml +42 -0
  5. etlplus-0.7.1/.github/workflows/ci.yml +160 -0
  6. etlplus-0.7.1/.gitignore +493 -0
  7. etlplus-0.7.1/.pre-commit-config.yaml +171 -0
  8. etlplus-0.7.1/.ruff.toml +33 -0
  9. etlplus-0.7.1/CODE_OF_CONDUCT.md +132 -0
  10. etlplus-0.7.1/CONTRIBUTING.md +137 -0
  11. etlplus-0.7.1/DEMO.md +244 -0
  12. etlplus-0.7.1/LICENSE +21 -0
  13. etlplus-0.7.1/MANIFEST.in +12 -0
  14. etlplus-0.7.1/Makefile +461 -0
  15. etlplus-0.7.1/PKG-INFO +619 -0
  16. etlplus-0.7.1/README.md +574 -0
  17. etlplus-0.7.1/REFERENCES.md +115 -0
  18. etlplus-0.7.1/docs/pipeline-guide.md +508 -0
  19. etlplus-0.7.1/docs/snippets/installation_version.md +2 -0
  20. etlplus-0.7.1/etlplus/__init__.py +43 -0
  21. etlplus-0.7.1/etlplus/__main__.py +22 -0
  22. etlplus-0.7.1/etlplus/__version__.py +14 -0
  23. etlplus-0.7.1/etlplus/api/README.md +237 -0
  24. etlplus-0.7.1/etlplus/api/__init__.py +136 -0
  25. etlplus-0.7.1/etlplus/api/auth.py +432 -0
  26. etlplus-0.7.1/etlplus/api/config.py +633 -0
  27. etlplus-0.7.1/etlplus/api/endpoint_client.py +885 -0
  28. etlplus-0.7.1/etlplus/api/errors.py +170 -0
  29. etlplus-0.7.1/etlplus/api/pagination/__init__.py +47 -0
  30. etlplus-0.7.1/etlplus/api/pagination/client.py +188 -0
  31. etlplus-0.7.1/etlplus/api/pagination/config.py +440 -0
  32. etlplus-0.7.1/etlplus/api/pagination/paginator.py +775 -0
  33. etlplus-0.7.1/etlplus/api/rate_limiting/__init__.py +38 -0
  34. etlplus-0.7.1/etlplus/api/rate_limiting/config.py +343 -0
  35. etlplus-0.7.1/etlplus/api/rate_limiting/rate_limiter.py +266 -0
  36. etlplus-0.7.1/etlplus/api/request_manager.py +589 -0
  37. etlplus-0.7.1/etlplus/api/retry_manager.py +430 -0
  38. etlplus-0.7.1/etlplus/api/transport.py +325 -0
  39. etlplus-0.7.1/etlplus/api/types.py +172 -0
  40. etlplus-0.7.1/etlplus/cli/__init__.py +15 -0
  41. etlplus-0.7.1/etlplus/cli/app.py +1367 -0
  42. etlplus-0.7.1/etlplus/cli/handlers.py +774 -0
  43. etlplus-0.7.1/etlplus/cli/main.py +616 -0
  44. etlplus-0.7.1/etlplus/config/__init__.py +56 -0
  45. etlplus-0.7.1/etlplus/config/connector.py +372 -0
  46. etlplus-0.7.1/etlplus/config/jobs.py +311 -0
  47. etlplus-0.7.1/etlplus/config/pipeline.py +339 -0
  48. etlplus-0.7.1/etlplus/config/profile.py +78 -0
  49. etlplus-0.7.1/etlplus/config/types.py +204 -0
  50. etlplus-0.7.1/etlplus/config/utils.py +120 -0
  51. etlplus-0.7.1/etlplus/database/__init__.py +42 -0
  52. etlplus-0.7.1/etlplus/database/ddl.py +311 -0
  53. etlplus-0.7.1/etlplus/database/engine.py +146 -0
  54. etlplus-0.7.1/etlplus/database/orm.py +347 -0
  55. etlplus-0.7.1/etlplus/database/schema.py +273 -0
  56. etlplus-0.7.1/etlplus/enums.py +414 -0
  57. etlplus-0.7.1/etlplus/extract.py +218 -0
  58. etlplus-0.7.1/etlplus/file.py +657 -0
  59. etlplus-0.7.1/etlplus/load.py +336 -0
  60. etlplus-0.7.1/etlplus/mixins.py +62 -0
  61. etlplus-0.7.1/etlplus/py.typed +0 -0
  62. etlplus-0.7.1/etlplus/run.py +366 -0
  63. etlplus-0.7.1/etlplus/run_helpers.py +843 -0
  64. etlplus-0.7.1/etlplus/templates/__init__.py +5 -0
  65. etlplus-0.7.1/etlplus/templates/ddl.sql.j2 +128 -0
  66. etlplus-0.7.1/etlplus/templates/view.sql.j2 +69 -0
  67. etlplus-0.7.1/etlplus/transform.py +1049 -0
  68. etlplus-0.7.1/etlplus/types.py +227 -0
  69. etlplus-0.7.1/etlplus/utils.py +638 -0
  70. etlplus-0.7.1/etlplus/validate.py +493 -0
  71. etlplus-0.7.1/etlplus/validation/__init__.py +44 -0
  72. etlplus-0.7.1/etlplus/validation/utils.py +389 -0
  73. etlplus-0.7.1/etlplus.egg-info/PKG-INFO +619 -0
  74. etlplus-0.7.1/etlplus.egg-info/SOURCES.txt +142 -0
  75. etlplus-0.7.1/etlplus.egg-info/dependency_links.txt +1 -0
  76. etlplus-0.7.1/etlplus.egg-info/entry_points.txt +2 -0
  77. etlplus-0.7.1/etlplus.egg-info/requires.txt +24 -0
  78. etlplus-0.7.1/etlplus.egg-info/top_level.txt +1 -0
  79. etlplus-0.7.1/examples/README.md +72 -0
  80. etlplus-0.7.1/examples/configs/ddl_spec.yml +67 -0
  81. etlplus-0.7.1/examples/configs/pipeline.yml +448 -0
  82. etlplus-0.7.1/examples/data/sample.csv +6 -0
  83. etlplus-0.7.1/examples/data/sample.json +7 -0
  84. etlplus-0.7.1/examples/data/sample.xml +33 -0
  85. etlplus-0.7.1/examples/data/sample.xsd +26 -0
  86. etlplus-0.7.1/examples/data/sample.yaml +22 -0
  87. etlplus-0.7.1/examples/quickstart_python.py +48 -0
  88. etlplus-0.7.1/pyproject.toml +113 -0
  89. etlplus-0.7.1/pytest.ini +12 -0
  90. etlplus-0.7.1/setup.cfg +4 -0
  91. etlplus-0.7.1/setup.py +76 -0
  92. etlplus-0.7.1/tests/__init__.py +10 -0
  93. etlplus-0.7.1/tests/conftest.py +210 -0
  94. etlplus-0.7.1/tests/integration/conftest.py +397 -0
  95. etlplus-0.7.1/tests/integration/test_i_cli.py +172 -0
  96. etlplus-0.7.1/tests/integration/test_i_examples_data_parity.py +78 -0
  97. etlplus-0.7.1/tests/integration/test_i_pagination_strategy.py +556 -0
  98. etlplus-0.7.1/tests/integration/test_i_pipeline_smoke.py +110 -0
  99. etlplus-0.7.1/tests/integration/test_i_pipeline_yaml_load.py +57 -0
  100. etlplus-0.7.1/tests/integration/test_i_run.py +69 -0
  101. etlplus-0.7.1/tests/integration/test_i_run_profile_pagination_defaults.py +110 -0
  102. etlplus-0.7.1/tests/integration/test_i_run_profile_rate_limit_defaults.py +83 -0
  103. etlplus-0.7.1/tests/unit/api/conftest.py +220 -0
  104. etlplus-0.7.1/tests/unit/api/test_u_auth.py +310 -0
  105. etlplus-0.7.1/tests/unit/api/test_u_config.py +681 -0
  106. etlplus-0.7.1/tests/unit/api/test_u_endpoint_client.py +1670 -0
  107. etlplus-0.7.1/tests/unit/api/test_u_mocks.py +205 -0
  108. etlplus-0.7.1/tests/unit/api/test_u_pagination_client.py +182 -0
  109. etlplus-0.7.1/tests/unit/api/test_u_pagination_config.py +265 -0
  110. etlplus-0.7.1/tests/unit/api/test_u_paginator.py +391 -0
  111. etlplus-0.7.1/tests/unit/api/test_u_rate_limit_config.py +244 -0
  112. etlplus-0.7.1/tests/unit/api/test_u_rate_limiter.py +370 -0
  113. etlplus-0.7.1/tests/unit/api/test_u_request_manager.py +349 -0
  114. etlplus-0.7.1/tests/unit/api/test_u_retry_manager.py +79 -0
  115. etlplus-0.7.1/tests/unit/api/test_u_transport.py +199 -0
  116. etlplus-0.7.1/tests/unit/api/test_u_types.py +135 -0
  117. etlplus-0.7.1/tests/unit/cli/conftest.py +29 -0
  118. etlplus-0.7.1/tests/unit/cli/test_u_cli_app.py +582 -0
  119. etlplus-0.7.1/tests/unit/cli/test_u_cli_handlers.py +947 -0
  120. etlplus-0.7.1/tests/unit/cli/test_u_cli_main.py +293 -0
  121. etlplus-0.7.1/tests/unit/config/test_u_config_utils.py +129 -0
  122. etlplus-0.7.1/tests/unit/config/test_u_connector.py +119 -0
  123. etlplus-0.7.1/tests/unit/config/test_u_jobs.py +131 -0
  124. etlplus-0.7.1/tests/unit/config/test_u_pipeline.py +315 -0
  125. etlplus-0.7.1/tests/unit/conftest.py +798 -0
  126. etlplus-0.7.1/tests/unit/database/test_u_database_ddl.py +265 -0
  127. etlplus-0.7.1/tests/unit/database/test_u_database_engine.py +198 -0
  128. etlplus-0.7.1/tests/unit/database/test_u_database_orm.py +308 -0
  129. etlplus-0.7.1/tests/unit/database/test_u_database_schema.py +243 -0
  130. etlplus-0.7.1/tests/unit/test_u_enums.py +135 -0
  131. etlplus-0.7.1/tests/unit/test_u_extract.py +500 -0
  132. etlplus-0.7.1/tests/unit/test_u_file.py +296 -0
  133. etlplus-0.7.1/tests/unit/test_u_load.py +685 -0
  134. etlplus-0.7.1/tests/unit/test_u_main.py +58 -0
  135. etlplus-0.7.1/tests/unit/test_u_mixins.py +47 -0
  136. etlplus-0.7.1/tests/unit/test_u_run.py +602 -0
  137. etlplus-0.7.1/tests/unit/test_u_run_helpers.py +385 -0
  138. etlplus-0.7.1/tests/unit/test_u_transform.py +860 -0
  139. etlplus-0.7.1/tests/unit/test_u_utils.py +250 -0
  140. etlplus-0.7.1/tests/unit/test_u_validate.py +233 -0
  141. etlplus-0.7.1/tests/unit/test_u_version.py +53 -0
  142. etlplus-0.7.1/tests/unit/validation/test_u_validation_utils.py +183 -0
  143. etlplus-0.7.1/tools/run_pipeline.py +561 -0
  144. etlplus-0.7.1/tools/update_demo_snippets.py +186 -0
@@ -0,0 +1,21 @@
1
+ # .coveragerc
2
+ # ETLPlus
3
+ #
4
+ # Copyright © 2025 Dagitali LLC. All rights reserved.
5
+ #
6
+ # An optional pytest-cov configuration file. Limits coverage measurement to the
7
+ # ETLPlus package and ignore test modules.
8
+ #
9
+ # See:
10
+ # 1. https://pytest-cov.readthedocs.io/en/latest/config.html
11
+
12
+ [run]
13
+ source = etlplus
14
+ branch = true
15
+ omit =
16
+ tests/*
17
+ */tests/*
18
+
19
+ [report]
20
+ skip_covered = true
21
+ show_missing = true
@@ -0,0 +1,156 @@
1
+ # .editorconfig
2
+ # ETLPlus
3
+ #
4
+ # Copyright © 2025 Dagitali LLC. All rights reserved.
5
+ #
6
+ # The EditorConfig file. Defines coding styles and a collection of text editor
7
+ # plugins that enable editors to read the file format and adhere to defined
8
+ # styles. Helps maintain consistent coding styles for multiple developers
9
+ # working on the same project across various editors and IDEs.
10
+ #
11
+ # See:
12
+ # 1. https://editorconfig.org/#file-format-details
13
+ # 2. https://github.com/jokeyrhyme/standard-editorconfig
14
+
15
+ # Top-most EditorConfig file
16
+ root = true
17
+
18
+ # Defaults
19
+ [*]
20
+ charset = utf-8
21
+ end_of_line = lf
22
+ insert_final_newline = true
23
+ trim_trailing_whitespace = true
24
+
25
+ # Bazel
26
+ # https://bazel.build/
27
+ # https://github.com/bazelbuild/buildtools/blob/master/BUILD.bazel
28
+ [*.{bazel,bzl}]
29
+ indent_size = 4
30
+ indent_style = space
31
+
32
+ # CSS
33
+ # https://google.github.io/styleguide/htmlcssguide.xml#General_Formatting_Rules
34
+ # http://cssguidelin.es/#syntax-and-formatting
35
+ [*.css]
36
+ indent_size = 2
37
+ indent_style = space
38
+ trim_trailing_whitespace = true
39
+
40
+ # GNU Make
41
+ # https://www.gnu.org/software/make/manual/html_node/Recipe-Syntax.html
42
+ [Makefile,*.mk]
43
+ indent_style = tab
44
+
45
+ # Go
46
+ # https://golang.org/cmd/gofmt/
47
+ [{go.mod,*.go}]
48
+ indent_style = tab
49
+
50
+ # GraphQL
51
+ # https://graphql.org/learn/
52
+ # https://prettier.io
53
+ [*.graphql]
54
+ indent_size = 2
55
+ indent_style = space
56
+
57
+ # HTML
58
+ # https://google.github.io/styleguide/htmlcssguide.xml#General_Formatting_Rules
59
+ [*.{htm,html}]
60
+ indent_size = 2
61
+ indent_style = space
62
+ trim_trailing_whitespace = true
63
+
64
+ # Java
65
+ # https://google.github.io/styleguide/javaguide.html#s4.2-block-indentation
66
+ [*.java]
67
+ indent_size = 2
68
+ indent_style = space
69
+
70
+ # JavaScript, JSON, JSX, JavaScript Modules, TypeScript
71
+ # https://github.com/feross/standard
72
+ # https://prettier.io
73
+ [*.{cjs,js,json,jsx,mjs,ts,tsx}]
74
+ indent_size = 2
75
+ indent_style = space
76
+
77
+ # Kotlin
78
+ # https://android.github.io/kotlin-guides/style.html#indentation
79
+ [*.{kt,kts}]
80
+ indent_size = 4
81
+ indent_style = space
82
+
83
+ # LESS
84
+ # https://github.com/less/less-docs#less-standards
85
+ [*.less]
86
+ indent_size = 2
87
+ indent_style = space
88
+
89
+ # Lua
90
+ # http://lua-users.org/wiki/LuaStyleGuide
91
+ [*.{lua,luacheckrc}]
92
+ indent_size = 2
93
+ indent_style = space
94
+
95
+ # PHP
96
+ # http://www.php-fig.org/psr/psr-2/
97
+ [*.php]
98
+ indent_size = 4
99
+ indent_style = space
100
+
101
+ # Python
102
+ # https://www.python.org/dev/peps/pep-0008/#code-lay-out
103
+ [*.py]
104
+ indent_size = 4
105
+ indent_style = space
106
+
107
+ # Ruby
108
+ # http://www.caliban.org/ruby/rubyguide.shtml#indentation
109
+ [*.rb]
110
+ indent_size = 2
111
+ indent_style = space
112
+
113
+ # Rust
114
+ # https://github.com/rust-lang/rust/blob/master/src/doc/style/style/whitespace.md
115
+ [*.rs]
116
+ indent_size = 4
117
+ indent_style = space
118
+ insert_final_newline = false
119
+ trim_trailing_whitespace = true
120
+
121
+ # SASS
122
+ # https://sass-guidelin.es/#syntax--formatting
123
+ [*.{sass,scss}]
124
+ indent_size = 2
125
+ indent_style = space
126
+
127
+ # Shell
128
+ # https://google.github.io/styleguide/shell.xml#Indentation
129
+ [*.{bash,sh,zsh}]
130
+ indent_size = 2
131
+ indent_style = space
132
+
133
+ # Svelte
134
+ # https://github.com/sveltejs/svelte/blob/master/.editorconfig
135
+ [*.svelte]
136
+ indent_size = 2
137
+ indent_style = tab
138
+
139
+ # TOML
140
+ # https://github.com/toml-lang/toml/tree/master/examples
141
+ [*.toml]
142
+ indent_size = 2
143
+ indent_style = space
144
+
145
+ # Vue.js
146
+ # https://eslint.vuejs.org/rules/html-indent.html
147
+ # https://eslint.vuejs.org/rules/script-indent.html
148
+ [*.vue]
149
+ indent_size = 2
150
+ indent_style = space
151
+
152
+ # YAML
153
+ # http://yaml.org/spec/1.2/2009-07-21/spec.html#id2576668
154
+ [*.{yaml,yml}]
155
+ indent_size = 2
156
+ indent_style = space
@@ -0,0 +1,13 @@
1
+ # .gitattributes
2
+ # ETLPlus
3
+ #
4
+ # Copyright © 2025 Dagitali LLC. All rights reserved.
5
+ #
6
+ # An optional Git configuration file. Defines attributes per pathname.
7
+ #
8
+ # See:
9
+ # 1. https://fileinfo.com/extension/gitattributes
10
+ # 2. https://git-scm.com/docs/gitattributes
11
+
12
+ # Auto detect text files and perform LF normalization
13
+ * text=auto
@@ -0,0 +1,42 @@
1
+ # action.yml
2
+ # ETLPlus
3
+ #
4
+ # Copyright © 2025 Dagitali LLC. All rights reserved.
5
+ #
6
+ # A GitHub Actions action to set up Python and install Python package
7
+ # dependencies.
8
+ #
9
+ # Notes
10
+ # - External GitHub Actions action references are each pinned to specific SHA
11
+ # to limit supply-chain risk.
12
+
13
+ ---
14
+
15
+ name: Setup Python and Install Dependencies
16
+
17
+ description: >-
18
+ Sets up the requested Python runtime, upgrades pip, and installs the provided
19
+ dependency list to keep workflow jobs consistent.
20
+
21
+ inputs:
22
+ python-version:
23
+ description: Python version to install via actions/setup-python
24
+ required: true
25
+ python-bootstrap:
26
+ description: Arguments passed to "pip install"
27
+ required: true
28
+
29
+ runs:
30
+ using: composite
31
+ steps:
32
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # Pinned v5
33
+ with:
34
+ python-version: ${{ inputs.python-version }}
35
+
36
+ - name: Upgrade pip
37
+ shell: bash
38
+ run: python -m pip install --upgrade pip
39
+
40
+ - name: Install dependencies
41
+ shell: bash
42
+ run: pip install ${{ inputs.python-bootstrap }}
@@ -0,0 +1,160 @@
1
+ # ci.yml
2
+ # ETLPlus
3
+ #
4
+ # Copyright © 2025 Dagitali LLC. All rights reserved.
5
+ #
6
+ # A GitHub Actions workflow configuration file for Continuous Integration (CI).
7
+ #
8
+ # Notes
9
+ # - The workflow includes jobs for linting, testing, building distributions,
10
+ # and publishing releases to GitHub and PyPI.
11
+ # - The workflow is hardened by removing global permissions and setting per-job
12
+ # scopes.
13
+ # - To harden workflow security, global permissions are absent, and per-job
14
+ # permissions are set as needed.
15
+ # - External GitHub Actions action references are each pinned to specific SHA
16
+ # to limit supply-chain risk.
17
+
18
+ ---
19
+
20
+ name: CI
21
+
22
+ on:
23
+ push:
24
+ branches:
25
+ # GitFlow branches
26
+ - main
27
+ - develop
28
+ - '**/feature/**'
29
+ - '**/bugfix/**'
30
+ - '**/release/**'
31
+ - '**/hotfix/**'
32
+
33
+ # Extended branches
34
+ - '**/chore/**'
35
+ - '**/ci/**'
36
+ - '**/docs/**'
37
+ tags: [ 'v*.*.*' ]
38
+ pull_request:
39
+ branches: [ main, develop ]
40
+
41
+ permissions: {}
42
+
43
+ jobs:
44
+ lint:
45
+ runs-on: ubuntu-latest
46
+ strategy: &python-matrix
47
+ matrix:
48
+ python-version: ['3.13', '3.14']
49
+ permissions: &permissions_read
50
+ contents: read
51
+ steps:
52
+ - &checkout_step
53
+ name: Checkout repository
54
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # Pinned v4
55
+ with:
56
+ fetch-depth: 0
57
+ - uses: ./.github/actions/python-bootstrap
58
+ with:
59
+ python-version: ${{ matrix.python-version }}
60
+ python-bootstrap: ".[dev]"
61
+ - name: Ruff check
62
+ run: |
63
+ ruff version
64
+ ruff check .
65
+ ruff format --check .
66
+
67
+ test:
68
+ runs-on: ubuntu-latest
69
+ strategy: *python-matrix
70
+ permissions: *permissions_read
71
+ steps:
72
+ - *checkout_step
73
+ - uses: ./.github/actions/python-bootstrap
74
+ with:
75
+ python-version: ${{ matrix.python-version }}
76
+ python-bootstrap: "-e .[dev,yaml]"
77
+ - name: Run tests (with coverage)
78
+ run: |
79
+ pytest -q \
80
+ --cov \
81
+ --cov-branch \
82
+ --cov-config=.coveragerc \
83
+ --cov-report=term-missing \
84
+ --cov-report=xml \
85
+ tests/
86
+
87
+ - name: Upload coverage reports to Codecov
88
+ if: matrix.python-version == '3.13'
89
+ uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # Pinned v5.5.2
90
+ with:
91
+ fail_ci_if_error: true
92
+ files: coverage.xml
93
+ flags: unit
94
+ name: etlplus
95
+ token: ${{ secrets.CODECOV_TOKEN }} # Omit for public repo
96
+ verbose: true
97
+
98
+ build:
99
+ name: Build distributions
100
+ runs-on: ubuntu-latest
101
+ if: &release_tag_condition >
102
+ startsWith(github.ref, 'refs/tags/v') ||
103
+ startsWith(github.ref, 'refs/tags/rc')
104
+ needs: [lint, test]
105
+ permissions: *permissions_read
106
+ steps:
107
+ - *checkout_step
108
+ - uses: ./.github/actions/python-bootstrap
109
+ with:
110
+ python-version: '3.13'
111
+ python-bootstrap: build
112
+ - name: Build distributions
113
+ run: |
114
+ python -m build
115
+ - name: Upload distributions
116
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # Pinned v4
117
+ with:
118
+ name: dist-artifacts
119
+ path: dist/*
120
+ if-no-files-found: error
121
+
122
+ release:
123
+ name: Publish GitHub Release
124
+ runs-on: ubuntu-latest
125
+ if: *release_tag_condition
126
+ needs: build
127
+ permissions:
128
+ contents: write
129
+ steps:
130
+ - *checkout_step
131
+ - &download_dist_step
132
+ name: Download distributions
133
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # Pinned v4
134
+ with:
135
+ name: dist-artifacts
136
+ path: dist
137
+ - name: Publish GitHub release
138
+ uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # Pinned v2
139
+ with:
140
+ files: dist/*
141
+ generate_release_notes: true
142
+
143
+ publish:
144
+ name: Publish to PyPI
145
+ runs-on: ubuntu-latest
146
+ if: *release_tag_condition
147
+ needs: build
148
+ permissions:
149
+ contents: read
150
+ id-token: write
151
+ environment:
152
+ name: pypi
153
+ url: https://pypi.org/project/etlplus/
154
+ steps:
155
+ - *checkout_step
156
+ - *download_dist_step
157
+ - name: Publish to PyPI
158
+ uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # Pinned v1
159
+ with:
160
+ verbose: true