Skip to content

Commit f50f0ae

Browse files
authored
Modernise project, convert from hatch to uv (#235)
## Changes This PR updates the project to use uv instead of Hatch, and includes the following changes: - All `Makefile` targets have been updated to use `uv` instead of `hatch`. - The CI/CD workflows have been updated to work with `uv` instead of `hatch`. - Locking information for all third-party dependencies has been added via `uv.lock` and `.build-constraints.txt`. - Workflow permissions are now scoped more narrowly. - Project documentation has been updated. - The release workflow has been removed to prevent confusion. ### Tests - manually tested. (Some tests fail, but these are also broken on `main`.) ### Notes for Reviewers Aside from the GHA-related changes, some of the project setup can be checked manually while CI/CD isn't available: ```shell make clean dev fmt test labs test ``` _Note: If any tests fail, verify they're working on `main` to determine whether they represent a regression introduced by this PR or not._
1 parent 4b51207 commit f50f0ae

17 files changed

Lines changed: 1863 additions & 315 deletions

.build-constraints.txt

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
hatchling==1.29.0 \
2+
--hash=sha256:50af9343281f34785fab12da82e445ed987a6efb34fd8c2fc0f6e6630dbcc1b0 \
3+
--hash=sha256:793c31816d952cee405b83488ce001c719f325d9cda69f1fc4cd750527640ea6
4+
packaging==26.0 \
5+
--hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \
6+
--hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529
7+
# via hatchling
8+
pathspec==1.0.4 \
9+
--hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \
10+
--hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723
11+
# via hatchling
12+
pluggy==1.6.0 \
13+
--hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \
14+
--hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746
15+
# via hatchling
16+
tomli==2.4.1 ; python_full_version < '3.11' \
17+
--hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \
18+
--hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \
19+
--hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \
20+
--hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \
21+
--hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \
22+
--hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \
23+
--hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \
24+
--hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \
25+
--hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \
26+
--hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \
27+
--hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \
28+
--hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \
29+
--hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \
30+
--hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \
31+
--hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \
32+
--hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \
33+
--hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \
34+
--hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \
35+
--hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \
36+
--hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \
37+
--hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \
38+
--hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \
39+
--hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \
40+
--hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \
41+
--hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \
42+
--hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \
43+
--hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \
44+
--hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \
45+
--hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \
46+
--hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \
47+
--hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \
48+
--hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \
49+
--hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \
50+
--hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \
51+
--hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \
52+
--hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \
53+
--hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \
54+
--hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \
55+
--hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \
56+
--hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \
57+
--hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \
58+
--hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \
59+
--hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \
60+
--hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \
61+
--hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \
62+
--hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \
63+
--hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049
64+
# via hatchling
65+
trove-classifiers==2026.1.14.14 \
66+
--hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \
67+
--hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d
68+
# via hatchling

.codegen.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
"src/databricks/labs/pytester/__about__.py": "__version__ = \"$VERSION\""
44
},
55
"toolchain": {
6-
"required": ["python3", "hatch"],
7-
"pre_setup": ["hatch env create"],
6+
"required": ["make", "uv"],
7+
"pre_setup": ["make dev"],
88
"prepend_path": ".venv/bin",
99
"acceptance_path": "tests/integration",
1010
"test": [
11-
"pytest -n 4 --cov src --cov-report=xml --timeout 30 tests/unit --durations 20"
11+
"make test"
1212
]
1313
}
1414
}

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ insert_final_newline = true
1515
indent_style = tab
1616
indent_size = tab
1717

18-
[*.{json,yml}]
18+
[*.{json,yaml,yml}]
1919
indent_size = 2
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: 'Authenticate for JFrog'
2+
description: 'Authenticate with JFrog using OIDC based on the GitHub repository.'
3+
# TODO: Factor out into an external action, once releases are allowed.
4+
outputs:
5+
jfrog-access-token:
6+
description: "Access token for JFrog"
7+
value: "${{ steps.jfrog-auth.outputs.jfrog-access-token }}"
8+
runs:
9+
using: "composite"
10+
steps:
11+
- id: jfrog-auth
12+
name: Authenticate against JFrog
13+
shell: bash
14+
run: |
15+
"${GITHUB_ACTION_PATH}/jfrog-auth" "${ACTIONS_ID_TOKEN_REQUEST_URL}" "${ACTIONS_ID_TOKEN_REQUEST_TOKEN}"
16+
17+
- id: detect-cmds
18+
name: Detecting python package/project managers.
19+
shell: bash
20+
run: |
21+
for cmd in pip3 uv
22+
do
23+
command -v "${cmd}" > /dev/null && found=true || found=false
24+
printf '::debug::%s\n' "Found ${cmd}: ${found}"
25+
printf '%s=%s\n' "command_${cmd}" "${found}" >> "${GITHUB_OUTPUT}"
26+
done
27+
28+
- name: Configure pip for JFrog
29+
if: "${{ steps.detect-cmds.outputs.command_pip3 == 'true' }}"
30+
shell: bash
31+
env:
32+
JFROG_ACCESS_TOKEN: "${{ steps.jfrog-auth.outputs.jfrog-access-token }}"
33+
run: |
34+
umask 077
35+
cat > "$RUNNER_TEMP/.pip.conf" <<EOF
36+
[global]
37+
index-url = https://gha-service-account:${JFROG_ACCESS_TOKEN}@databricks.jfrog.io/artifactory/api/pypi/db-pypi/simple
38+
EOF
39+
printf '%s=%s\n' 'PIP_CONFIG_FILE' "${RUNNER_TEMP}/.pip.conf" >> "${GITHUB_ENV}"
40+
41+
- name: Configure uv for JFrog
42+
if: "${{ steps.detect-cmds.outputs.command_uv == 'true' }}"
43+
shell: bash
44+
env:
45+
JFROG_ACCESS_TOKEN: "${{ steps.jfrog-auth.outputs.jfrog-access-token }}"
46+
UV_INDEX_URL: 'https://databricks.jfrog.io/artifactory/api/pypi/db-pypi/simple'
47+
run: |
48+
uv auth login "${UV_INDEX_URL}" --username gha-service-account --password "${JFROG_ACCESS_TOKEN}"
49+
printf "%s=%s\n" 'UV_INDEX_URL' "${UV_INDEX_URL}" >> "${GITHUB_ENV}"
50+
printf "%s=%s\n" 'UV_FROZEN' '1' >> "${GITHUB_ENV}"
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/sh
2+
#
3+
# Obtain a JFrog access token, assuming GitHub OIDC.
4+
#
5+
set -eu
6+
7+
_request_url="$1"
8+
_request_token="$2"
9+
10+
#
11+
# Step 1: Obtain the OIDC identifier token from GitHub.
12+
#
13+
printf '::debug::%s\n' "Fetching OIDC identifier token from GitHub..."
14+
_id_token="$(curl -sLS \
15+
-H 'User-Agent: actions/oidc-client' \
16+
-H "Authorization: Bearer ${_request_token}" \
17+
"${_request_url}&audience=jfrog-github" |
18+
jq -r .value)"
19+
printf '::add-mask::%s\n' "${_id_token}"
20+
21+
#
22+
# Step 2: Exchange it for the JFrog access token.
23+
#
24+
printf '::debug::%s\n' "Exchanging OIDC identifier token for JFrog access token..."
25+
_access_token=$(curl -sLS \
26+
--json "{\"grant_type\": \"urn:ietf:params:oauth:grant-type:token-exchange\", \"subject_token_type\":\"urn:ietf:params:oauth:token-type:id_token\", \"subject_token\": \"${_id_token}\", \"provider_name\": \"github-actions\"}" \
27+
"https://databricks.jfrog.io/access/api/v1/oidc/token" |
28+
jq -r .access_token)
29+
printf '::add-mask::%s\n' "${_access_token}"
30+
31+
if [ -z "${_access_token}" ] || [ "${_access_token}" = 'null' ]
32+
then
33+
printf '::error::%s\n' "Could not fetch JFrog access token."
34+
exit 1
35+
fi
36+
37+
printf '%s=%s\n' 'jfrog-access-token' "${_access_token}" >> "${GITHUB_OUTPUT}"

.github/dependabot.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
version: 2
22
updates:
3-
- package-ecosystem: "pip"
4-
directory: "/"
5-
schedule:
6-
interval: "daily"
7-
- package-ecosystem: "github-actions"
3+
- package-ecosystem: "uv"
84
directory: "/"
5+
cooldown:
6+
default-days: 7
7+
exclude:
8+
- "databricks*"
99
schedule:
1010
interval: "daily"

.github/workflows/acceptance.yml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,38 @@ on:
1010
- main
1111

1212
permissions:
13-
id-token: write
1413
contents: read
15-
pull-requests: write
1614

1715
concurrency:
1816
group: ${{ github.workflow }}-${{ github.ref }}
1917
cancel-in-progress: true
2018

21-
env:
22-
HATCH_VERBOSE: "2"
23-
HATCH_VERSION: "1.16.5"
24-
2519
jobs:
2620
integration:
2721
if: github.event_name == 'pull_request'
2822
environment: account-admin
29-
runs-on: larger
23+
permissions:
24+
# Access to the integration testing infrastructure.
25+
id-token: write
26+
# Write test results to the PR.
27+
pull-requests: write
28+
runs-on:
29+
group: larger-runners
30+
labels: larger
3031
steps:
3132
- name: Checkout Code
3233
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3334
with:
3435
fetch-depth: 0
3536

36-
- name: Install Python
37-
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
37+
- name: Setup uv
38+
uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 # v7.3.1
3839
with:
39-
cache: 'pip'
40-
cache-dependency-path: '**/pyproject.toml'
41-
python-version: '3.14'
40+
version: "0.11.2"
41+
checksum: "7ac2ca0449c8d68dae9b99e635cd3bc9b22a4cb1de64b7c43716398447d42981"
4242

43-
- name: Install hatch
44-
run: pip install "hatch==${HATCH_VERSION}"
43+
- name: Setup for JFrog
44+
uses: ./.github/actions/jfrog-auth
4545

4646
- name: Fetch relevant branches
4747
run: |

.github/workflows/downstreams.yml

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,44 @@ on:
1616
- main
1717

1818
permissions:
19-
id-token: write
2019
contents: read
21-
pull-requests: write
22-
23-
env:
24-
HATCH_VERBOSE: "2"
25-
HATCH_VERSION: "1.16.5"
2620

2721
jobs:
2822
compatibility:
23+
permissions:
24+
# Access to the integration testing infrastructure.
25+
id-token: write
26+
# Write test results to the PR.
27+
pull-requests: write
2928
strategy:
3029
fail-fast: false
3130
matrix:
3231
downstream:
3332
- name: ucx
3433
- name: remorph
35-
runs-on: ubuntu-latest
34+
runs-on:
35+
group: databrickslabs-protected-runner-group
36+
labels: linux-ubuntu-latest
3637
steps:
3738
- name: Checkout
3839
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3940
with:
4041
fetch-depth: 0
4142

42-
- name: Install Python
43-
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
43+
- name: Setup uv
44+
uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 # v7.3.1
4445
with:
45-
cache: 'pip'
46-
cache-dependency-path: '**/pyproject.toml'
47-
# Downstream currently just tests with system python rather than controlling the versions properly.
48-
python-version: '3.10'
46+
version: "0.11.2"
47+
checksum: "7ac2ca0449c8d68dae9b99e635cd3bc9b22a4cb1de64b7c43716398447d42981"
4948

50-
- name: Install toolchain
51-
run: |
52-
pip install "hatch==${HATCH_VERSION}"
49+
- name: Setup for JFrog
50+
uses: ./.github/actions/jfrog-auth
5351

5452
- name: Downstreams
55-
uses: databrickslabs/sandbox/downstreams@3313d06ce86227537b3f37f5974f7eecb2a8e59a # acceptance/v0.4.4 # downstreams/v0.0.1
56-
with:
57-
repo: ${{ matrix.downstream.name }}
58-
org: databrickslabs
59-
env:
60-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53+
run: printf '::error::%s\n' "Downstream tests disabled pending repository lockdown."
54+
#uses: databrickslabs/sandbox/downstreams@3313d06ce86227537b3f37f5974f7eecb2a8e59a # acceptance/v0.4.4 # downstreams/v0.0.1
55+
#with:
56+
# repo: ${{ matrix.downstream.name }}
57+
# org: databrickslabs
58+
#env:
59+
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/nightly.yml

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,37 +6,36 @@ on:
66
- cron: '0 5 * * *'
77

88
permissions:
9-
id-token: write
10-
issues: write
119
contents: read
12-
pull-requests: read
1310

1411
concurrency:
1512
group: single-acceptance-job-per-repo
1613

17-
env:
18-
HATCH_VERBOSE: "2"
19-
HATCH_VERSION: "1.16.5"
20-
2114
jobs:
2215
integration:
2316
environment: account-admin
24-
runs-on: larger
17+
permissions:
18+
# Access to the integration testing infrastructure.
19+
id-token: write
20+
# Create issues for nightly test failures.
21+
issues: write
22+
runs-on:
23+
group: larger-runners
24+
labels: larger
2525
steps:
2626
- name: Checkout Code
2727
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2828
with:
2929
fetch-depth: 0
3030

31-
- name: Install Python
32-
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
31+
- name: Setup uv
32+
uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 # v7.3.1
3333
with:
34-
cache: 'pip'
35-
cache-dependency-path: '**/pyproject.toml'
36-
python-version: '3.14'
34+
version: "0.11.2"
35+
checksum: "7ac2ca0449c8d68dae9b99e635cd3bc9b22a4cb1de64b7c43716398447d42981"
3736

38-
- name: Install hatch
39-
run: pip install "hatch==${HATCH_VERSION}"
37+
- name: Setup for JFrog
38+
uses: ./.github/actions/jfrog-auth
4039

4140
- name: Run nightly tests
4241
uses: databrickslabs/sandbox/acceptance@3313d06ce86227537b3f37f5974f7eecb2a8e59a # acceptance/v0.4.4

0 commit comments

Comments
 (0)