@@ -135,6 +135,84 @@ jobs:
135135 )
136136}
137137
138+ fn create_uv_ci_testing_linux_only_file (
139+ source_dir : & str ,
140+ min_python_version : & str ,
141+ github_action_python_test_versions : & [ String ] ,
142+ ) -> String {
143+ let python_versions = build_actions_python_test_versions ( github_action_python_test_versions) ;
144+
145+ format ! (
146+ r#"name: Testing
147+
148+ on:
149+ push:
150+ branches:
151+ - main
152+ pull_request:
153+ env:
154+ UV_CACHE_DIR: /tmp/.uv-cache
155+ jobs:
156+ linting:
157+ runs-on: ubuntu-latest
158+ steps:
159+ - uses: actions/checkout@v4
160+ - name: Install uv
161+ run: curl -LsSf https://astral.sh/uv/install.sh | sh
162+ - name: Set up Python
163+ uses: actions/setup-python@v5
164+ with:
165+ python-version: "{min_python_version}"
166+ - name: Restore uv cache
167+ uses: actions/cache@v4
168+ with:
169+ path: ${{ env.UV_CACHE_DIR }}
170+ key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
171+ restore-keys: |
172+ uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
173+ uv-${{ runner.os }}
174+ - name: Install Dependencies
175+ run: uv sync --locked
176+ - name: Ruff format check
177+ run: uv run ruff format {source_dir} tests --check
178+ - name: Lint with ruff
179+ run: uv run ruff check .
180+ - name: mypy check
181+ run: uv run mypy .
182+ - name: Minimize uv cache
183+ run: uv cache prune --ci
184+ testing:
185+ strategy:
186+ fail-fast: false
187+ matrix:
188+ python-version: [{python_versions}]
189+ runs-on: ubuntu-latest
190+ steps:
191+ - uses: actions/checkout@v4
192+ - name: Install uv
193+ run: curl -LsSf https://astral.sh/uv/install.sh | sh
194+ - name: Set up Python ${{{{ matrix.python-version }}}}
195+ uses: actions/setup-python@v5
196+ with:
197+ python-version: ${{{{ matrix.python-version }}}}
198+ - name: Restore uv cache
199+ uses: actions/cache@v4
200+ with:
201+ path: ${{ env.UV_CACHE_DIR }}
202+ key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
203+ restore-keys: |
204+ uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
205+ uv-${{ runner.os }}
206+ - name: Install Dependencies
207+ run: uv sync --locked
208+ - name: Test with pytest
209+ run: uv run pytest
210+ - name: Minimize uv cache
211+ run: uv cache prune --ci
212+ "#
213+ )
214+ }
215+
138216fn create_ci_testing_linux_only_file_pyo3 (
139217 source_dir : & str ,
140218 min_python_version : & str ,
@@ -247,6 +325,11 @@ pub fn save_ci_testing_linux_only_file(project_info: &ProjectInfo) -> Result<()>
247325 & project_info. min_python_version ,
248326 & project_info. github_actions_python_test_versions ,
249327 ) ,
328+ ProjectManager :: Uv => create_uv_ci_testing_linux_only_file (
329+ & project_info. source_dir ,
330+ & project_info. min_python_version ,
331+ & project_info. github_actions_python_test_versions ,
332+ ) ,
250333 } ;
251334
252335 save_file_with_content ( & file_path, & content) ?;
@@ -473,6 +556,90 @@ jobs:
473556 )
474557}
475558
559+ fn create_uv_ci_testing_multi_os_file (
560+ source_dir : & str ,
561+ min_python_version : & str ,
562+ github_action_python_test_versions : & [ String ] ,
563+ ) -> String {
564+ let python_versions = build_actions_python_test_versions ( github_action_python_test_versions) ;
565+
566+ format ! (
567+ r#"name: Testing
568+
569+ on:
570+ push:
571+ branches:
572+ - main
573+ pull_request:
574+ env:
575+ UV_CACHE_DIR: /tmp/.uv-cache
576+ jobs:
577+ linting:
578+ runs-on: ubuntu-latest
579+ steps:
580+ - uses: actions/checkout@v4
581+ - name: Install uv
582+ run: curl -LsSf https://astral.sh/uv/install.sh | sh
583+ - name: Set up Python
584+ uses: actions/setup-python@v5
585+ with:
586+ python-version: "{min_python_version}"
587+ - name: Restore uv cache
588+ uses: actions/cache@v4
589+ with:
590+ path: ${{ env.UV_CACHE_DIR }}
591+ key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
592+ restore-keys: |
593+ uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
594+ uv-${{ runner.os }}
595+ - name: Install Dependencies
596+ run: uv sync --locked
597+ - name: Ruff format check
598+ run: uv run ruff format {source_dir} tests --check
599+ - name: Lint with ruff
600+ run: uv run ruff check .
601+ - name: mypy check
602+ run: uv run mypy .
603+ - name: Minimize uv cache
604+ run: uv cache prune --ci
605+ testing:
606+ strategy:
607+ fail-fast: false
608+ matrix:
609+ python-version: [{python_versions}]
610+ os: [ubuntu-latest, windows-latest, macos-latest]
611+ runs-on: ${{{{ matrix.os }}}}
612+ steps:
613+ - uses: actions/checkout@v4
614+ - name: Set up uv ubuntu/mac
615+ if: ${{ matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' }}
616+ run: curl -LsSf https://astral.sh/uv/install.sh | sh
617+ - name: Set up uv windows
618+ if: ${{ matrix.os == 'windows-latest' }}
619+ run: irm https://astral.sh/uv/install.ps1 | iex
620+ shell: powershell
621+ - name: Set up Python ${{{{ matrix.python-version }}}}
622+ uses: actions/setup-python@v5
623+ with:
624+ python-version: ${{{{ matrix.python-version }}}}
625+ - name: Restore uv cache
626+ uses: actions/cache@v4
627+ with:
628+ path: ${{ env.UV_CACHE_DIR }}
629+ key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
630+ restore-keys: |
631+ uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
632+ uv-${{ runner.os }}
633+ - name: Install Dependencies
634+ run: uv sync --locked
635+ - name: Test with pytest
636+ run: uv run pytest
637+ - name: Minimize uv cache
638+ run: uv cache prune --ci
639+ "#
640+ )
641+ }
642+
476643pub fn save_ci_testing_multi_os_file ( project_info : & ProjectInfo ) -> Result < ( ) > {
477644 let file_path = project_info
478645 . base_dir ( )
@@ -493,6 +660,11 @@ pub fn save_ci_testing_multi_os_file(project_info: &ProjectInfo) -> Result<()> {
493660 & project_info. min_python_version ,
494661 & project_info. github_actions_python_test_versions ,
495662 ) ,
663+ ProjectManager :: Uv => create_uv_ci_testing_multi_os_file (
664+ & project_info. source_dir ,
665+ & project_info. min_python_version ,
666+ & project_info. github_actions_python_test_versions ,
667+ ) ,
496668 } ;
497669
498670 save_file_with_content ( & file_path, & content) ?;
@@ -791,7 +963,7 @@ jobs:
791963 python -m pip install -U pip
792964 python -m pip -r requirements-dev.txt
793965 python -m pip install build setuptools wheel twine
794- - name: Publish package
966+ - name: Build and publish package
795967 env:
796968 TWINE_USERNAME: __token__
797969 TWINE_PASSWORD: ${{{{ secrets.PYPI_API_KEY }}}}
@@ -802,6 +974,37 @@ jobs:
802974 )
803975}
804976
977+ fn create_uv_pypi_publish_file ( python_version : & str ) -> String {
978+ format ! (
979+ r#"name: PyPi Publish
980+ on:
981+ release:
982+ types:
983+ - published
984+ jobs:
985+ deploy:
986+ runs-on: ubuntu-latest
987+ steps:
988+ - uses: actions/checkout@v4
989+ - name: Install uv
990+ run: curl -LsSf https://astral.sh/uv/install.sh | sh
991+ - name: Set up Python
992+ uses: actions/setup-python@v5
993+ with:
994+ python-version: "{python_version}"
995+ - name: Install Dependencies
996+ run: uv sync --frozen
997+ - name: Build and publish package
998+ env:
999+ TWINE_USERNAME: __token__
1000+ TWINE_PASSWORD: ${{{{ secrets.PYPI_API_KEY }}}}
1001+ run: |
1002+ uvx --from build pyproject-build --installer uv
1003+ uvx twine upload dist/*
1004+ "#
1005+ )
1006+ }
1007+
8051008pub fn save_pypi_publish_file ( project_info : & ProjectInfo ) -> Result < ( ) > {
8061009 let file_path = project_info
8071010 . base_dir ( )
@@ -812,6 +1015,7 @@ pub fn save_pypi_publish_file(project_info: &ProjectInfo) -> Result<()> {
8121015 ProjectManager :: Setuptools => {
8131016 create_setuptools_pypi_publish_file ( & project_info. python_version )
8141017 }
1018+ ProjectManager :: Uv => create_uv_pypi_publish_file ( & project_info. python_version ) ,
8151019 } ;
8161020
8171021 save_file_with_content ( & file_path, & content) ?;
@@ -989,6 +1193,23 @@ mod tests {
9891193 assert_yaml_snapshot ! ( content) ;
9901194 }
9911195
1196+ #[ test]
1197+ fn test_save_uv_ci_testing_linux_only_file ( ) {
1198+ let mut project_info = project_info_dummy ( ) ;
1199+ project_info. project_manager = ProjectManager :: Uv ;
1200+ project_info. use_multi_os_ci = false ;
1201+ let base = project_info. base_dir ( ) ;
1202+ create_dir_all ( base. join ( ".github/workflows" ) ) . unwrap ( ) ;
1203+ let expected_file = base. join ( ".github/workflows/testing.yml" ) ;
1204+ save_ci_testing_linux_only_file ( & project_info) . unwrap ( ) ;
1205+
1206+ assert ! ( expected_file. is_file( ) ) ;
1207+
1208+ let content = std:: fs:: read_to_string ( expected_file) . unwrap ( ) ;
1209+
1210+ assert_yaml_snapshot ! ( content) ;
1211+ }
1212+
9921213 #[ test]
9931214 fn test_save_poetry_ci_testing_multi_os_file ( ) {
9941215 let mut project_info = project_info_dummy ( ) ;
@@ -1040,6 +1261,23 @@ mod tests {
10401261 assert_yaml_snapshot ! ( content) ;
10411262 }
10421263
1264+ #[ test]
1265+ fn test_save_uv_ci_testing_multi_os_file ( ) {
1266+ let mut project_info = project_info_dummy ( ) ;
1267+ project_info. project_manager = ProjectManager :: Uv ;
1268+ project_info. use_multi_os_ci = true ;
1269+ let base = project_info. base_dir ( ) ;
1270+ create_dir_all ( base. join ( ".github/workflows" ) ) . unwrap ( ) ;
1271+ let expected_file = base. join ( ".github/workflows/testing.yml" ) ;
1272+ save_ci_testing_multi_os_file ( & project_info) . unwrap ( ) ;
1273+
1274+ assert ! ( expected_file. is_file( ) ) ;
1275+
1276+ let content = std:: fs:: read_to_string ( expected_file) . unwrap ( ) ;
1277+
1278+ assert_yaml_snapshot ! ( content) ;
1279+ }
1280+
10431281 #[ test]
10441282 fn test_save_dependabot_file ( ) {
10451283 let mut project_info = project_info_dummy ( ) ;
0 commit comments