Skip to content

Commit 457a37a

Browse files
committed
merge with main
2 parents 38f8d18 + 99a1a96 commit 457a37a

File tree

69 files changed

+3290
-624
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+3290
-624
lines changed

.coveragerc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,13 @@ omit =
99

1010
# omit as unimplemented
1111
airbyte_cdk/base_python/cdk/streams/auth/jwt.py
12+
13+
# omit temporary files and test files
14+
/tmp/tmp*.py
15+
unit_tests/*
16+
17+
[paths]
18+
# Reconcile file paths
19+
source =
20+
./
21+
/tmp/
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# When a PR is has the auto-merge feature enabled or disabled, this workflow adds or updates
2+
# warning text at the bottom of the PR description.
3+
4+
name: "Add Auto-Merge Notification Text"
5+
on:
6+
pull_request:
7+
types: [auto_merge_enabled, auto_merge_disabled]
8+
9+
jobs:
10+
update-description:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
pull-requests: write
14+
steps:
15+
- name: Add Auto-Merge Notice
16+
if: github.event.action == 'auto_merge_enabled'
17+
uses: bcgov/[email protected]
18+
with:
19+
add_markdown: |
20+
> [!IMPORTANT]
21+
> **Auto-merge enabled.**
22+
>
23+
> _This PR is set to merge automatically when all requirements are met._
24+
25+
- name: Remove Auto-Merge Notice
26+
if: github.event.action == 'auto_merge_disabled'
27+
uses: bcgov/[email protected]
28+
with:
29+
add_markdown: |
30+
> [!NOTE]
31+
> **Auto-merge may have been disabled. Please check the PR status to confirm.**

.github/workflows/pytest_fast.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ jobs:
7070
poetry run coverage html -d htmlcov
7171
poetry run coverage xml -o htmlcov/coverage.xml
7272
73+
- name: Publish Test Results
74+
uses: EnricoMi/publish-unit-test-result-action@v2
75+
if: always() && !cancelled()
76+
continue-on-error: true
77+
with:
78+
check_name: "PyTest Results (Fast)"
79+
large_files: true
80+
files: |
81+
build/test-results/**/*.xml
7382
- name: Upload coverage to GitHub Artifacts
7483
if: always()
7584
uses: actions/upload-artifact@v4

.github/workflows/pytest_matrix.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@ jobs:
9393
poetry run coverage html -d htmlcov
9494
poetry run coverage xml -o htmlcov/coverage.xml
9595
96+
- name: Publish Test Results
97+
uses: EnricoMi/publish-unit-test-result-action@v2
98+
if: always() && !cancelled() && steps.changes.outputs.src == 'true' && matrix.python-version == '3.11'
99+
continue-on-error: true
100+
with:
101+
check_name: "PyTest Results (Full)"
102+
large_files: true
103+
files: |
104+
build/test-results/**/*.xml
96105
- name: Upload coverage to GitHub Artifacts
97106
if: always() && steps.changes.outputs.src == 'true'
98107
uses: actions/upload-artifact@v4

.github/workflows/test-command.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,15 @@ jobs:
113113
--verbose
114114
-m "flaky and not super_slow"
115115
116+
- name: Publish Test Results
117+
uses: EnricoMi/publish-unit-test-result-action@v2
118+
if: always() && !cancelled() && matrix.python-version == '3.11'
119+
continue-on-error: true
120+
with:
121+
check_name: "PyTest Results (On-Demand)"
122+
large_files: true
123+
files: |
124+
build/test-results/**/*.xml
116125
- name: Post CI Success to GitHub
117126
run: |
118127
curl --request POST \

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Build and test results
2+
build
3+
test-results
4+
15
# Node artifacts
26
node_modules
37

.pre-commit-config.yaml

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
exclude: |
44
(?x)(
55
# Python/system files
6-
^.*/__init__\.py$|
76
^.*?/\.venv/.*$|
87
^.*?/node_modules/.*$|
9-
8+
109
# Generated/test files
1110
^.*?/\.pytest_cache/.*$|
1211
^.*?/__pycache__/.*$|
1312
^.*?/\.mypy_cache/.*$|
14-
^.*?/\.ruff_cache/.*$
13+
^.*?/\.ruff_cache/.*$|
1514
1615
# Package management
1716
^.*?/poetry\.lock$|
@@ -22,7 +21,7 @@ exclude: |
2221
^.*?/build/.*$|
2322
^.*?/dist/.*$|
2423
^.*?/\.coverage$|
25-
^.*?/coverage\.xml$|
24+
^.*?/coverage\.xml$
2625
)
2726
2827
repos:
@@ -38,18 +37,15 @@ repos:
3837
- repo: https://github.com/astral-sh/ruff-pre-commit
3938
rev: v0.11.5
4039
hooks:
41-
# Run the linter with repo-defined settings
4240
- id: ruff
4341
args: [--fix]
44-
45-
# Run the formatter with repo-defined settings
4642
- id: ruff-format
4743

4844
- repo: https://github.com/pre-commit/mirrors-prettier
4945
rev: v3.0.3
5046
hooks:
5147
- id: prettier
52-
types_or: [json, yaml]
48+
args: [--write]
5349
additional_dependencies:
5450
5551

@@ -61,3 +57,20 @@ repos:
6157
language: golang
6258
additional_dependencies: [github.com/google/[email protected]]
6359
files: \.py$
60+
61+
- id: poetry-check
62+
name: Check Poetry lockfile
63+
entry: poetry check
64+
language: system
65+
pass_filenames: false
66+
always_run: true
67+
68+
- repo: https://github.com/pre-commit/mirrors-mypy
69+
rev: v1.8.0
70+
hooks:
71+
- id: mypy
72+
name: mypy
73+
entry: mypy
74+
args: [--config-file=mypy.ini, --show-column-numbers]
75+
files: ^airbyte_cdk/
76+
pass_filenames: true

airbyte_cdk/cli/airbyte_cdk/_connector.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"""
4040

4141
import os
42+
import sys
4243
from pathlib import Path
4344
from types import ModuleType
4445

@@ -161,15 +162,22 @@ def test(
161162
pytest_args.append("--collect-only")
162163

163164
pytest_args.append(str(test_file_path))
165+
166+
test_results_dir = connector_directory / "build" / "test-results"
167+
test_results_dir.mkdir(parents=True, exist_ok=True)
168+
junit_xml_path = test_results_dir / "standard-tests-junit.xml"
169+
pytest_args.extend(["--junitxml", str(junit_xml_path)])
170+
164171
click.echo(f"Running tests from connector directory: {connector_directory}...")
165172
click.echo(f"Test file: {test_file_path}")
166173
click.echo(f"Collect only: {collect_only}")
167174
click.echo(f"Pytest args: {pytest_args}")
168175
click.echo("Invoking Pytest...")
169-
pytest.main(
176+
exit_code = pytest.main(
170177
pytest_args,
171178
plugins=[],
172179
)
180+
sys.exit(exit_code)
173181

174182

175183
__all__ = [

airbyte_cdk/cli/airbyte_cdk/_secrets.py

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,12 @@
4949
resolve_connector_name_and_directory,
5050
)
5151

52-
AIRBYTE_INTERNAL_GCP_PROJECT = "dataline-integration-testing"
52+
GCP_PROJECT_ID: str = os.environ.get("GCP_PROJECT_ID", "") or "dataline-integration-testing"
53+
# We put the `or` outside the `get()` because we want the `GCP_PROJECT_ID`
54+
# env var to be ignored if it contains an empty string, such as in CI where the
55+
# workflow might set it to a value that is itself actually missing or unset.
56+
"""The GCP project ID to use for fetching integration test secrets."""
57+
5358
CONNECTOR_LABEL = "connector"
5459
GLOBAL_MASK_KEYS_URL = "https://connectors.airbyte.com/files/registries/v0/specs_secrets_mask.yaml"
5560

@@ -83,8 +88,11 @@ def secrets_cli_group() -> None:
8388
@click.option(
8489
"--gcp-project-id",
8590
type=str,
86-
default=AIRBYTE_INTERNAL_GCP_PROJECT,
87-
help=f"GCP project ID. Defaults to '{AIRBYTE_INTERNAL_GCP_PROJECT}'.",
91+
default=GCP_PROJECT_ID,
92+
help=(
93+
"GCP project ID for retrieving integration tests credentials. "
94+
"Defaults to the value of the `GCP_PROJECT_ID` environment variable, if set."
95+
),
8896
)
8997
@click.option(
9098
"--print-ci-secrets-masks",
@@ -95,7 +103,7 @@ def secrets_cli_group() -> None:
95103
)
96104
def fetch(
97105
connector: str | Path | None = None,
98-
gcp_project_id: str = AIRBYTE_INTERNAL_GCP_PROJECT,
106+
gcp_project_id: str = GCP_PROJECT_ID,
99107
print_ci_secrets_masks: bool = False,
100108
) -> None:
101109
"""Fetch secrets for a connector from Google Secret Manager.
@@ -192,41 +200,41 @@ def fetch(
192200

193201

194202
@secrets_cli_group.command("list")
195-
@click.option(
196-
"--connector-name",
203+
@click.argument(
204+
"connector",
205+
required=False,
197206
type=str,
198-
help="Name of the connector to fetch secrets for. Ignored if --connector-directory is provided.",
199-
)
200-
@click.option(
201-
"--connector-directory",
202-
type=click.Path(exists=True, file_okay=False, path_type=Path),
203-
help="Path to the connector directory.",
207+
metavar="[CONNECTOR]",
204208
)
205209
@click.option(
206210
"--gcp-project-id",
207211
type=str,
208-
default=AIRBYTE_INTERNAL_GCP_PROJECT,
209-
help=f"GCP project ID. Defaults to '{AIRBYTE_INTERNAL_GCP_PROJECT}'.",
212+
default=GCP_PROJECT_ID,
213+
help=(
214+
"GCP project ID for retrieving integration tests credentials. "
215+
"Defaults to the value of the `GCP_PROJECT_ID` environment variable, if set."
216+
),
210217
)
211218
def list_(
212-
connector_name: str | None = None,
213-
connector_directory: Path | None = None,
214-
gcp_project_id: str = AIRBYTE_INTERNAL_GCP_PROJECT,
219+
connector: str | Path | None = None,
220+
*,
221+
gcp_project_id: str = GCP_PROJECT_ID,
215222
) -> None:
216223
"""List secrets for a connector from Google Secret Manager.
217224
218225
This command fetches secrets for a connector from Google Secret Manager and prints
219226
them as a table.
220227
228+
[CONNECTOR] can be a connector name (e.g. 'source-pokeapi'), a path to a connector directory, or omitted to use the current working directory.
229+
If a string containing '/' is provided, it is treated as a path. Otherwise, it is treated as a connector name.
230+
221231
If no connector name or directory is provided, we will look within the current working
222232
directory. If the current working directory is not a connector directory (e.g. starting
223233
with 'source-') and no connector name or path is provided, the process will fail.
224234
"""
225235
click.echo("Scanning secrets...", err=True)
226236

227-
connector_name = connector_name or resolve_connector_name(
228-
connector_directory=connector_directory or Path().resolve().absolute(),
229-
)
237+
connector_name, _ = resolve_connector_name_and_directory(connector)
230238
secrets: list[Secret] = _fetch_secret_handles( # type: ignore
231239
connector_name=connector_name,
232240
gcp_project_id=gcp_project_id,
@@ -303,7 +311,7 @@ def _get_secret_url(secret_name: str, gcp_project_id: str) -> str:
303311

304312
def _fetch_secret_handles(
305313
connector_name: str,
306-
gcp_project_id: str = AIRBYTE_INTERNAL_GCP_PROJECT,
314+
gcp_project_id: str = GCP_PROJECT_ID,
307315
) -> list["Secret"]: # type: ignore
308316
"""Fetch secrets from Google Secret Manager."""
309317
if not secretmanager:

0 commit comments

Comments
 (0)