dycw-actions 0.8.11__py3-none-any.whl → 0.11.3__py3-none-any.whl

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 (35) hide show
  1. actions/__init__.py +1 -1
  2. actions/clean_dir/lib.py +7 -4
  3. actions/cli.py +18 -2
  4. actions/constants.py +2 -0
  5. actions/git_clone_with/__init__.py +1 -0
  6. actions/git_clone_with/cli.py +41 -0
  7. actions/git_clone_with/constants.py +7 -0
  8. actions/git_clone_with/lib.py +78 -0
  9. actions/git_clone_with/settings.py +20 -0
  10. actions/pre_commit/conformalize_repo/action_dicts.py +39 -40
  11. actions/pre_commit/conformalize_repo/cli.py +15 -3
  12. actions/pre_commit/conformalize_repo/constants.py +14 -0
  13. actions/pre_commit/conformalize_repo/lib.py +228 -117
  14. actions/pre_commit/conformalize_repo/settings.py +39 -13
  15. actions/pre_commit/format_requirements/lib.py +5 -2
  16. actions/pre_commit/replace_sequence_strs/lib.py +5 -2
  17. actions/pre_commit/touch_empty_py/lib.py +5 -2
  18. actions/pre_commit/touch_py_typed/lib.py +5 -2
  19. actions/pre_commit/update_requirements/lib.py +6 -3
  20. actions/publish_package/lib.py +16 -9
  21. actions/random_sleep/lib.py +9 -4
  22. actions/register_gitea_runner/configs/entrypoint.sh +8 -8
  23. actions/register_gitea_runner/lib.py +23 -14
  24. actions/run_hooks/lib.py +15 -4
  25. actions/setup_cronjob/lib.py +19 -13
  26. actions/setup_ssh_config/__init__.py +1 -0
  27. actions/setup_ssh_config/cli.py +17 -0
  28. actions/setup_ssh_config/constants.py +7 -0
  29. actions/setup_ssh_config/lib.py +30 -0
  30. actions/tag_commit/lib.py +16 -9
  31. actions/utilities.py +1 -16
  32. {dycw_actions-0.8.11.dist-info → dycw_actions-0.11.3.dist-info}/METADATA +3 -3
  33. {dycw_actions-0.8.11.dist-info → dycw_actions-0.11.3.dist-info}/RECORD +35 -26
  34. {dycw_actions-0.8.11.dist-info → dycw_actions-0.11.3.dist-info}/WHEEL +1 -1
  35. {dycw_actions-0.8.11.dist-info → dycw_actions-0.11.3.dist-info}/entry_points.txt +0 -0
@@ -14,13 +14,16 @@ from typing import TYPE_CHECKING, Literal, assert_never
14
14
  import tomlkit
15
15
  from tomlkit import TOMLDocument, table
16
16
  from tomlkit.exceptions import NonExistentKey
17
+ from utilities.functions import get_func_name
17
18
  from utilities.inflect import counted_noun
18
19
  from utilities.re import extract_groups
19
20
  from utilities.subprocess import ripgrep
21
+ from utilities.tabulate import func_param_desc
20
22
  from utilities.text import repr_str, strip_and_dedent
21
23
  from utilities.throttle import throttle
22
24
  from utilities.version import ParseVersionError, Version, parse_version
23
25
 
26
+ from actions import __version__
24
27
  from actions.constants import (
25
28
  ACTIONS_URL,
26
29
  BUMPVERSION_TOML,
@@ -87,7 +90,7 @@ from actions.pre_commit.utilities import (
87
90
  yield_toml_doc,
88
91
  yield_yaml_dict,
89
92
  )
90
- from actions.utilities import log_func_call, logged_run
93
+ from actions.utilities import logged_run
91
94
 
92
95
  if TYPE_CHECKING:
93
96
  from collections.abc import Iterator, MutableSet
@@ -99,9 +102,10 @@ if TYPE_CHECKING:
99
102
 
100
103
  def conformalize_repo(
101
104
  *,
102
- ci__ca_certificates: bool = SETTINGS.ci__ca_certificates,
105
+ ci__certificates: bool = SETTINGS.ci__certificates,
103
106
  ci__gitea: bool = SETTINGS.ci__gitea,
104
- ci__token: str | None = SETTINGS.ci__token,
107
+ ci__token_checkout: Secret[str] | None = SETTINGS.ci__token_checkout,
108
+ ci__token_github: Secret[str] | None = SETTINGS.ci__token_github,
105
109
  ci__pull_request__pre_commit: bool = SETTINGS.ci__pull_request__pre_commit,
106
110
  ci__pull_request__pre_commit__submodules: str
107
111
  | None = SETTINGS.ci__pull_request__pre_commit__submodules,
@@ -110,15 +114,26 @@ def conformalize_repo(
110
114
  ci__pull_request__pytest__ubuntu: bool = SETTINGS.ci__pull_request__pytest__ubuntu,
111
115
  ci__pull_request__pytest__windows: bool = SETTINGS.ci__pull_request__pytest__windows,
112
116
  ci__pull_request__pytest__all_versions: bool = SETTINGS.ci__pull_request__pytest__all_versions,
113
- ci__pull_request__pytest__sops_age_key: str
117
+ ci__pull_request__pytest__sops_age_key: Secret[str]
114
118
  | None = SETTINGS.ci__pull_request__pytest__sops_age_key,
115
119
  ci__pull_request__ruff: bool = SETTINGS.ci__pull_request__ruff,
116
- ci__push__publish: bool = SETTINGS.ci__push__publish,
117
- ci__push__publish__username: str | None = SETTINGS.ci__push__publish__username,
118
- ci__push__publish__password: Secret[str]
119
- | None = SETTINGS.ci__push__publish__password,
120
- ci__push__publish__publish_url: Secret[str]
121
- | None = SETTINGS.ci__push__publish__publish_url,
120
+ ci__push__publish__github: bool = SETTINGS.ci__push__publish__github,
121
+ ci__push__publish__primary: bool = SETTINGS.ci__push__publish__primary,
122
+ ci__push__publish__primary__job_name: str = SETTINGS.ci__push__publish__primary__job_name,
123
+ ci__push__publish__primary__username: str
124
+ | None = SETTINGS.ci__push__publish__primary__username,
125
+ ci__push__publish__primary__password: Secret[str]
126
+ | None = SETTINGS.ci__push__publish__primary__password,
127
+ ci__push__publish__primary__publish_url: str
128
+ | None = SETTINGS.ci__push__publish__primary__publish_url,
129
+ ci__push__publish__secondary: bool = SETTINGS.ci__push__publish__secondary,
130
+ ci__push__publish__secondary__job_name: str = SETTINGS.ci__push__publish__secondary__job_name,
131
+ ci__push__publish__secondary__username: str
132
+ | None = SETTINGS.ci__push__publish__secondary__username,
133
+ ci__push__publish__secondary__password: Secret[str]
134
+ | None = SETTINGS.ci__push__publish__secondary__password,
135
+ ci__push__publish__secondary__publish_url: str
136
+ | None = SETTINGS.ci__push__publish__secondary__publish_url,
122
137
  ci__push__tag: bool = SETTINGS.ci__push__tag,
123
138
  ci__push__tag__all: bool = SETTINGS.ci__push__tag__all,
124
139
  coverage: bool = SETTINGS.coverage,
@@ -153,56 +168,67 @@ def conformalize_repo(
153
168
  script: str | None = SETTINGS.script,
154
169
  uv__native_tls: bool = SETTINGS.uv__native_tls,
155
170
  ) -> None:
156
- variables = [
157
- f"{ci__ca_certificates=}",
158
- f"{ci__gitea=}",
159
- f"{ci__token=}",
160
- f"{ci__pull_request__pre_commit=}",
161
- f"{ci__pull_request__pre_commit__submodules=}",
162
- f"{ci__pull_request__pyright=}",
163
- f"{ci__pull_request__pytest__macos=}",
164
- f"{ci__pull_request__pytest__ubuntu=}",
165
- f"{ci__pull_request__pytest__windows=}",
166
- f"{ci__pull_request__pytest__all_versions=}",
167
- f"{ci__pull_request__pytest__sops_age_key=}",
168
- f"{ci__pull_request__ruff=}",
169
- f"{ci__push__publish=}",
170
- f"{ci__push__publish__username=}",
171
- f"{ci__push__publish__password=}",
172
- f"{ci__push__publish__publish_url=}",
173
- f"{ci__push__tag=}",
174
- f"{ci__push__tag__all=}",
175
- f"{coverage=}",
176
- f"{description=}",
177
- f"{envrc=}",
178
- f"{envrc__uv=}",
179
- f"{gitignore=}",
180
- f"{package_name=}",
181
- f"{pre_commit__dockerfmt=}",
182
- f"{pre_commit__prettier=}",
183
- f"{pre_commit__python=}",
184
- f"{pre_commit__ruff=}",
185
- f"{pre_commit__shell=}",
186
- f"{pre_commit__taplo=}",
187
- f"{pre_commit__uv=}",
188
- f"{pyproject=}",
189
- f"{pyproject__project__optional_dependencies__scripts=}",
190
- f"{pyproject__tool__uv__indexes=}",
191
- f"{pyright=}",
192
- f"{pytest=}",
193
- f"{pytest__asyncio=}",
194
- f"{pytest__ignore_warnings=}",
195
- f"{pytest__timeout=}",
196
- f"{python_package_name=}",
197
- f"{python_version=}",
198
- f"{readme=}",
199
- f"{repo_name=}",
200
- f"{ruff=}",
201
- f"{run_version_bump=}",
202
- f"{script=}",
203
- f"{uv__native_tls=}",
204
- ]
205
- LOGGER.info(log_func_call(conformalize_repo, *variables))
171
+ LOGGER.info(
172
+ func_param_desc(
173
+ conformalize_repo,
174
+ __version__,
175
+ f"{ci__certificates=}",
176
+ f"{ci__gitea=}",
177
+ f"{ci__token_checkout=}",
178
+ f"{ci__token_github=}",
179
+ f"{ci__pull_request__pre_commit=}",
180
+ f"{ci__pull_request__pre_commit__submodules=}",
181
+ f"{ci__pull_request__pyright=}",
182
+ f"{ci__pull_request__pytest__macos=}",
183
+ f"{ci__pull_request__pytest__ubuntu=}",
184
+ f"{ci__pull_request__pytest__windows=}",
185
+ f"{ci__pull_request__pytest__all_versions=}",
186
+ f"{ci__pull_request__pytest__sops_age_key=}",
187
+ f"{ci__pull_request__ruff=}",
188
+ f"{ci__push__publish__github=}",
189
+ f"{ci__push__publish__primary=}",
190
+ f"{ci__push__publish__primary__job_name=}",
191
+ f"{ci__push__publish__primary__username=}",
192
+ f"{ci__push__publish__primary__password=}",
193
+ f"{ci__push__publish__primary__publish_url=}",
194
+ f"{ci__push__publish__secondary=}",
195
+ f"{ci__push__publish__secondary__job_name=}",
196
+ f"{ci__push__publish__secondary__username=}",
197
+ f"{ci__push__publish__secondary__password=}",
198
+ f"{ci__push__publish__secondary__publish_url=}",
199
+ f"{ci__push__tag=}",
200
+ f"{ci__push__tag__all=}",
201
+ f"{coverage=}",
202
+ f"{description=}",
203
+ f"{envrc=}",
204
+ f"{envrc__uv=}",
205
+ f"{gitignore=}",
206
+ f"{package_name=}",
207
+ f"{pre_commit__dockerfmt=}",
208
+ f"{pre_commit__prettier=}",
209
+ f"{pre_commit__python=}",
210
+ f"{pre_commit__ruff=}",
211
+ f"{pre_commit__shell=}",
212
+ f"{pre_commit__taplo=}",
213
+ f"{pre_commit__uv=}",
214
+ f"{pyproject=}",
215
+ f"{pyproject__project__optional_dependencies__scripts=}",
216
+ f"{pyproject__tool__uv__indexes=}",
217
+ f"{pyright=}",
218
+ f"{pytest=}",
219
+ f"{pytest__asyncio=}",
220
+ f"{pytest__ignore_warnings=}",
221
+ f"{pytest__timeout=}",
222
+ f"{python_package_name=}",
223
+ f"{python_version=}",
224
+ f"{readme=}",
225
+ f"{repo_name=}",
226
+ f"{ruff=}",
227
+ f"{run_version_bump=}",
228
+ f"{script=}",
229
+ f"{uv__native_tls=}",
230
+ )
231
+ )
206
232
  modifications: set[Path] = set()
207
233
  add_bumpversion_toml(
208
234
  modifications=modifications,
@@ -233,47 +259,63 @@ def conformalize_repo(
233
259
  or ci__pull_request__pytest__macos
234
260
  or ci__pull_request__pytest__ubuntu
235
261
  or ci__pull_request__pytest__windows
262
+ or ci__pull_request__pytest__all_versions
236
263
  or (ci__pull_request__pytest__sops_age_key is not None)
237
264
  or ci__pull_request__ruff
238
265
  ):
239
266
  add_ci_pull_request_yaml(
240
- certificates=ci__ca_certificates,
241
267
  gitea=ci__gitea,
242
- token=ci__token,
243
268
  modifications=modifications,
269
+ certificates=ci__certificates,
244
270
  pre_commit=ci__pull_request__pre_commit,
245
271
  pre_commit__submodules=ci__pull_request__pre_commit__submodules,
246
272
  pyright=ci__pull_request__pyright,
247
273
  pytest__macos=ci__pull_request__pytest__macos,
248
274
  pytest__ubuntu=ci__pull_request__pytest__ubuntu,
249
275
  pytest__windows=ci__pull_request__pytest__windows,
276
+ pytest__all_versions=ci__pull_request__pytest__all_versions,
250
277
  pytest__sops_age_key=ci__pull_request__pytest__sops_age_key,
251
278
  pytest__timeout=pytest__timeout,
252
279
  python_version=python_version,
253
280
  repo_name=repo_name,
254
281
  ruff=ruff,
255
282
  script=script,
283
+ token_checkout=ci__token_checkout,
284
+ token_github=ci__token_github,
256
285
  uv__native_tls=uv__native_tls,
257
286
  )
258
287
  if (
259
- ci__push__publish
260
- or (ci__push__publish__username is not None)
261
- or (ci__push__publish__password is not None)
262
- or (ci__push__publish__publish_url is not None)
288
+ ci__push__publish__github
289
+ or ci__push__publish__primary
290
+ or (ci__push__publish__primary__username is not None)
291
+ or (ci__push__publish__primary__password is not None)
292
+ or (ci__push__publish__primary__publish_url is not None)
293
+ or ci__push__publish__secondary
294
+ or (ci__push__publish__secondary__username is not None)
295
+ or (ci__push__publish__secondary__password is not None)
296
+ or (ci__push__publish__secondary__publish_url is not None)
263
297
  or ci__push__tag
264
298
  or ci__push__tag__all
265
299
  ):
266
300
  add_ci_push_yaml(
267
- certificates=ci__ca_certificates,
268
301
  gitea=ci__gitea,
269
- token=ci__token,
270
302
  modifications=modifications,
271
- publish=ci__push__publish,
272
- publish__username=ci__push__publish__username,
273
- publish__password=ci__push__publish__password,
274
- publish__publish_url=ci__push__publish__publish_url,
303
+ certificates=ci__certificates,
304
+ publish__github=ci__push__publish__github,
305
+ publish__primary=ci__push__publish__primary,
306
+ publish__primary__job_name=ci__push__publish__primary__job_name,
307
+ publish__primary__username=ci__push__publish__primary__username,
308
+ publish__primary__password=ci__push__publish__primary__password,
309
+ publish__primary__publish_url=ci__push__publish__primary__publish_url,
310
+ publish__secondary=ci__push__publish__secondary,
311
+ publish__secondary__job_name=ci__push__publish__secondary__job_name,
312
+ publish__secondary__username=ci__push__publish__secondary__username,
313
+ publish__secondary__password=ci__push__publish__secondary__password,
314
+ publish__secondary__publish_url=ci__push__publish__secondary__publish_url,
275
315
  tag=ci__push__tag,
276
316
  tag__all=ci__push__tag__all,
317
+ token_checkout=ci__token_checkout,
318
+ token_github=ci__token_github,
277
319
  uv__native_tls=uv__native_tls,
278
320
  )
279
321
  if coverage:
@@ -338,6 +380,7 @@ def conformalize_repo(
338
380
  ", ".join(map(repr_str, sorted(modifications))),
339
381
  )
340
382
  sys.exit(1)
383
+ LOGGER.info("Finished running %r", get_func_name(conformalize_repo))
341
384
 
342
385
 
343
386
  ##
@@ -387,10 +430,9 @@ def _add_bumpversion_toml_file(path: PathLike, template: str, /) -> Table:
387
430
 
388
431
  def add_ci_pull_request_yaml(
389
432
  *,
390
- certificates: bool = SETTINGS.ci__ca_certificates,
391
433
  gitea: bool = SETTINGS.ci__gitea,
392
- token: str | None = SETTINGS.ci__token,
393
434
  modifications: MutableSet[Path] | None = None,
435
+ certificates: bool = SETTINGS.ci__certificates,
394
436
  pre_commit: bool = SETTINGS.ci__pull_request__pre_commit,
395
437
  pre_commit__submodules: str
396
438
  | None = SETTINGS.ci__pull_request__pre_commit__submodules,
@@ -399,12 +441,15 @@ def add_ci_pull_request_yaml(
399
441
  pytest__ubuntu: bool = SETTINGS.ci__pull_request__pytest__ubuntu,
400
442
  pytest__windows: bool = SETTINGS.ci__pull_request__pytest__windows,
401
443
  pytest__all_versions: bool = SETTINGS.ci__pull_request__pytest__all_versions,
402
- pytest__sops_age_key: str | None = SETTINGS.ci__pull_request__pytest__sops_age_key,
444
+ pytest__sops_age_key: Secret[str]
445
+ | None = SETTINGS.ci__pull_request__pytest__sops_age_key,
403
446
  pytest__timeout: int | None = SETTINGS.pytest__timeout,
404
447
  python_version: str = SETTINGS.python_version,
405
448
  repo_name: str | None = SETTINGS.repo_name,
406
449
  ruff: bool = SETTINGS.ci__pull_request__ruff,
407
450
  script: str | None = SETTINGS.script,
451
+ token_checkout: Secret[str] | None = SETTINGS.ci__token_checkout,
452
+ token_github: Secret[str] | None = SETTINGS.ci__token_github,
408
453
  uv__native_tls: bool = SETTINGS.uv__native_tls,
409
454
  ) -> None:
410
455
  path = GITEA_PULL_REQUEST_YAML if gitea else GITHUB_PULL_REQUEST_YAML
@@ -426,9 +471,10 @@ def add_ci_pull_request_yaml(
426
471
  ensure_contains(
427
472
  steps,
428
473
  action_run_hooks_dict(
429
- token=token,
474
+ token_checkout=token_checkout,
475
+ token_github=token_github,
430
476
  submodules=pre_commit__submodules,
431
- repos=["pre-commit/pre-commit-hooks"],
477
+ repos=["dycw/actions", "pre-commit/pre-commit-hooks"],
432
478
  gitea=gitea,
433
479
  ),
434
480
  )
@@ -441,20 +487,14 @@ def add_ci_pull_request_yaml(
441
487
  ensure_contains(
442
488
  steps,
443
489
  action_pyright_dict(
444
- token=token,
490
+ token_checkout=token_checkout,
491
+ token_github=token_github,
445
492
  python_version=python_version,
446
493
  with_requirements=script,
447
494
  native_tls=uv__native_tls,
448
495
  ),
449
496
  )
450
- if (
451
- pytest__macos
452
- or pytest__ubuntu
453
- or pytest__windows
454
- or (pytest__sops_age_key is not None)
455
- or pytest__all_versions
456
- or pytest__timeout
457
- ):
497
+ if pytest__macos or pytest__ubuntu or pytest__windows:
458
498
  pytest_dict = get_dict(jobs, "pytest")
459
499
  env = get_dict(pytest_dict, "env")
460
500
  env["CI"] = "1"
@@ -468,7 +508,8 @@ def add_ci_pull_request_yaml(
468
508
  ensure_contains(
469
509
  steps,
470
510
  action_pytest_dict(
471
- token=token,
511
+ token_checkout=token_checkout,
512
+ token_github=token_github,
472
513
  python_version="${{matrix.python-version}}",
473
514
  sops_age_key=pytest__sops_age_key,
474
515
  resolution="${{matrix.resolution}}",
@@ -503,7 +544,12 @@ def add_ci_pull_request_yaml(
503
544
  steps = get_list(ruff_dict, "steps")
504
545
  if certificates:
505
546
  ensure_contains(steps, update_ca_certificates_dict("steps"))
506
- ensure_contains(steps, action_ruff_dict(token=token))
547
+ ensure_contains(
548
+ steps,
549
+ action_ruff_dict(
550
+ token_checkout=token_checkout, token_github=token_github
551
+ ),
552
+ )
507
553
 
508
554
 
509
555
  ##
@@ -511,16 +557,30 @@ def add_ci_pull_request_yaml(
511
557
 
512
558
  def add_ci_push_yaml(
513
559
  *,
514
- certificates: bool = SETTINGS.ci__ca_certificates,
515
560
  gitea: bool = SETTINGS.ci__gitea,
516
- token: str | None = SETTINGS.ci__token,
517
561
  modifications: MutableSet[Path] | None = None,
518
- publish: bool = SETTINGS.ci__push__publish,
519
- publish__username: str | None = SETTINGS.ci__push__publish__username,
520
- publish__password: Secret[str] | None = SETTINGS.ci__push__publish__password,
521
- publish__publish_url: Secret[str] | None = SETTINGS.ci__push__publish__publish_url,
562
+ certificates: bool = SETTINGS.ci__certificates,
563
+ publish__github: bool = SETTINGS.ci__push__publish__github,
564
+ publish__primary: bool = SETTINGS.ci__push__publish__primary,
565
+ publish__primary__job_name: str = SETTINGS.ci__push__publish__primary__job_name,
566
+ publish__primary__username: str
567
+ | None = SETTINGS.ci__push__publish__primary__username,
568
+ publish__primary__password: Secret[str]
569
+ | None = SETTINGS.ci__push__publish__primary__password,
570
+ publish__primary__publish_url: str
571
+ | None = SETTINGS.ci__push__publish__primary__publish_url,
572
+ publish__secondary: bool = SETTINGS.ci__push__publish__secondary,
573
+ publish__secondary__job_name: str = SETTINGS.ci__push__publish__secondary__job_name,
574
+ publish__secondary__username: str
575
+ | None = SETTINGS.ci__push__publish__secondary__username,
576
+ publish__secondary__password: Secret[str]
577
+ | None = SETTINGS.ci__push__publish__secondary__password,
578
+ publish__secondary__publish_url: str
579
+ | None = SETTINGS.ci__push__publish__secondary__publish_url,
522
580
  tag: bool = SETTINGS.ci__push__tag,
523
581
  tag__all: bool = SETTINGS.ci__push__tag__all,
582
+ token_checkout: Secret[str] | None = SETTINGS.ci__token_checkout,
583
+ token_github: Secret[str] | None = SETTINGS.ci__token_github,
524
584
  uv__native_tls: bool = SETTINGS.uv__native_tls,
525
585
  ) -> None:
526
586
  path = GITEA_PUSH_YAML if gitea else GITHUB_PUSH_YAML
@@ -531,25 +591,37 @@ def add_ci_push_yaml(
531
591
  branches = get_list(push, "branches")
532
592
  ensure_contains(branches, "master")
533
593
  jobs = get_dict(dict_, "jobs")
534
- if publish:
535
- publish_dict = get_dict(jobs, "publish")
536
- environment = get_dict(publish_dict, "environment")
537
- environment["name"] = "pypi"
538
- permissions = get_dict(publish_dict, "permissions")
539
- permissions["id-token"] = "write"
540
- publish_dict["runs-on"] = "ubuntu-latest"
541
- steps = get_list(publish_dict, "steps")
542
- if certificates:
543
- ensure_contains(steps, update_ca_certificates_dict("publish"))
544
- ensure_contains(
545
- steps,
546
- action_publish_package_dict(
547
- token=token,
548
- username=publish__username,
549
- password=publish__password,
550
- publish_url=publish__publish_url,
551
- native_tls=uv__native_tls,
552
- ),
594
+ if publish__github:
595
+ _add_ci_push_yaml_publish_dict(
596
+ jobs,
597
+ "github",
598
+ github=True,
599
+ token_checkout=token_checkout,
600
+ token_github=token_github,
601
+ )
602
+ if publish__primary:
603
+ _add_ci_push_yaml_publish_dict(
604
+ jobs,
605
+ publish__primary__job_name,
606
+ certificates=certificates,
607
+ token_checkout=token_checkout,
608
+ token_github=token_github,
609
+ username=publish__primary__username,
610
+ password=publish__primary__password,
611
+ publish_url=publish__primary__publish_url,
612
+ uv__native_tls=uv__native_tls,
613
+ )
614
+ if publish__secondary:
615
+ _add_ci_push_yaml_publish_dict(
616
+ jobs,
617
+ publish__secondary__job_name,
618
+ certificates=certificates,
619
+ token_checkout=token_checkout,
620
+ token_github=token_github,
621
+ username=publish__secondary__username,
622
+ password=publish__secondary__password,
623
+ publish_url=publish__secondary__publish_url,
624
+ uv__native_tls=uv__native_tls,
553
625
  )
554
626
  if tag:
555
627
  tag_dict = get_dict(jobs, "tag")
@@ -565,6 +637,44 @@ def add_ci_push_yaml(
565
637
  )
566
638
 
567
639
 
640
+ def _add_ci_push_yaml_publish_dict(
641
+ jobs: StrDict,
642
+ name: str,
643
+ /,
644
+ *,
645
+ github: bool = False,
646
+ certificates: bool = SETTINGS.ci__certificates,
647
+ token_checkout: Secret[str] | None = SETTINGS.ci__token_checkout,
648
+ token_github: Secret[str] | None = SETTINGS.ci__token_github,
649
+ username: str | None = None,
650
+ password: Secret[str] | None = None,
651
+ publish_url: str | None = None,
652
+ uv__native_tls: bool = SETTINGS.uv__native_tls,
653
+ ) -> None:
654
+ publish_name = f"publish-{name}"
655
+ publish_dict = get_dict(jobs, publish_name)
656
+ if github:
657
+ environment = get_dict(publish_dict, "environment")
658
+ environment["name"] = "pypi"
659
+ permissions = get_dict(publish_dict, "permissions")
660
+ permissions["id-token"] = "write"
661
+ publish_dict["runs-on"] = "ubuntu-latest"
662
+ steps = get_list(publish_dict, "steps")
663
+ if certificates:
664
+ ensure_contains(steps, update_ca_certificates_dict(publish_name))
665
+ ensure_contains(
666
+ steps,
667
+ action_publish_package_dict(
668
+ token_checkout=token_checkout,
669
+ token_github=token_github,
670
+ username=username,
671
+ password=password,
672
+ publish_url=publish_url,
673
+ native_tls=uv__native_tls,
674
+ ),
675
+ )
676
+
677
+
568
678
  ##
569
679
 
570
680
 
@@ -615,7 +725,7 @@ def add_envrc(
615
725
  native_tls=uv__native_tls, python_version=python_version, script=script
616
726
  )
617
727
  if search(escape(uv_text), context.output, flags=MULTILINE) is None:
618
- context.output += f"\n\n{echo}"
728
+ context.output += f"\n\n{uv_text}"
619
729
 
620
730
 
621
731
  def _add_envrc_uv_text(
@@ -636,14 +746,15 @@ def _add_envrc_uv_text(
636
746
  strip_and_dedent(f"""
637
747
  export UV_PRERELEASE='disallow'
638
748
  export UV_PYTHON='{python_version}'
749
+ export UV_VENV_CLEAR=1
639
750
  if ! command -v uv >/dev/null 2>&1; then
640
- echo_date "ERROR: 'uv' not found" && exit 1
751
+ \techo_date "ERROR: 'uv' not found" && exit 1
641
752
  fi
642
753
  activate='.venv/bin/activate'
643
754
  if [ -f $activate ]; then
644
- . $activate
755
+ \t. $activate
645
756
  else
646
- uv venv
757
+ \tuv venv
647
758
  fi
648
759
  """)
649
760
  )
@@ -1,18 +1,23 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from typed_settings import Secret, load_settings, option, secret, settings
4
- from utilities.pytest import IS_CI
5
4
 
5
+ from actions.pre_commit.conformalize_repo.constants import RUN_VERSION_BUMP
6
6
  from actions.utilities import LOADER
7
7
 
8
8
 
9
9
  @settings
10
10
  class Settings:
11
- ci__ca_certificates: bool = option(
11
+ ci__certificates: bool = option(
12
12
  default=False, help="Update CA certficates before each step"
13
13
  )
14
14
  ci__gitea: bool = option(default=False, help="Set up CI on Gitea")
15
- ci__token: str | None = option(default=None, help="Set up CI with this token")
15
+ ci__token_checkout: Secret[str] | None = secret(
16
+ default=None, help="Set up CI with this checkout token"
17
+ )
18
+ ci__token_github: Secret[str] | None = secret(
19
+ default=None, help="Set up CI with this GitHub token"
20
+ )
16
21
  ci__pull_request__pre_commit: bool = option(
17
22
  default=False, help="Set up CI 'pull-request.yaml' pre-commit"
18
23
  )
@@ -34,24 +39,45 @@ class Settings:
34
39
  ci__pull_request__pytest__all_versions: bool = option(
35
40
  default=False, help="Set up CI 'pull-request.yaml' pytest with all versions"
36
41
  )
37
- ci__pull_request__pytest__sops_age_key: str | None = option(
42
+ ci__pull_request__pytest__sops_age_key: Secret[str] | None = secret(
38
43
  default=None,
39
44
  help="Set up CI 'pull-request.yaml' pytest with this 'age' key for 'sops'",
40
45
  )
41
46
  ci__pull_request__ruff: bool = option(
42
47
  default=False, help="Set up CI 'pull-request.yaml' ruff"
43
48
  )
44
- ci__push__publish: bool = option(
45
- default=False, help="Set up CI 'push.yaml' publishing"
49
+ ci__push__publish__github: bool = option(
50
+ default=False, help="Set up CI 'push.yaml' publishing to GitHub"
51
+ )
52
+ ci__push__publish__primary: bool = option(
53
+ default=False, help="Set up CI 'push.yaml' publishing #1"
54
+ )
55
+ ci__push__publish__primary__job_name: str = option(
56
+ default="pypi", help="Set up CI 'push.yaml' publishing #1 with this job name"
57
+ )
58
+ ci__push__publish__primary__username: str | None = option(
59
+ default=None, help="Set up CI 'push.yaml' publishing #1 with this username"
60
+ )
61
+ ci__push__publish__primary__password: Secret[str] | None = secret(
62
+ default=None, help="Set up CI 'push.yaml' publishing #1 with this password"
63
+ )
64
+ ci__push__publish__primary__publish_url: str | None = option(
65
+ default=None, help="Set up CI 'push.yaml' publishing #1 with this URL"
66
+ )
67
+ ci__push__publish__secondary: bool = option(
68
+ default=False, help="Set up CI 'push.yaml' publishing #2"
69
+ )
70
+ ci__push__publish__secondary__job_name: str = option(
71
+ default="pypi2", help="Set up CI 'push.yaml' publishing #2 with this job name"
46
72
  )
47
- ci__push__publish__username: str | None = option(
48
- default=None, help="Set up CI 'push.yaml' publishing with this username"
73
+ ci__push__publish__secondary__username: str | None = option(
74
+ default=None, help="Set up CI 'push.yaml' publishing #2 with this username"
49
75
  )
50
- ci__push__publish__password: Secret[str] | None = secret(
51
- default=None, help="Set up CI 'push.yaml' publishing with this password"
76
+ ci__push__publish__secondary__password: Secret[str] | None = secret(
77
+ default=None, help="Set up CI 'push.yaml' publishing #2 with this password"
52
78
  )
53
- ci__push__publish__publish_url: Secret[str] | None = secret(
54
- default=None, help="Set up CI 'push.yaml' publishing with this URL"
79
+ ci__push__publish__secondary__publish_url: str | None = option(
80
+ default=None, help="Set up CI 'push.yaml' publishing #2 with this URL"
55
81
  )
56
82
  ci__push__tag: bool = option(default=False, help="Set up CI 'push.yaml' tagging")
57
83
  ci__push__tag__all: bool = option(
@@ -108,7 +134,7 @@ class Settings:
108
134
  readme: bool = option(default=False, help="Set up 'README.md'")
109
135
  repo_name: str | None = option(default=None, help="Repo name")
110
136
  ruff: bool = option(default=False, help="Set up 'ruff.toml'")
111
- run_version_bump: bool = option(default=not IS_CI, help="Run version bump")
137
+ run_version_bump: bool = option(default=RUN_VERSION_BUMP, help="Run version bump")
112
138
  uv__native_tls: bool = option(default=False, help="Setup 'uv' with native TLS")
113
139
  script: str | None = option(
114
140
  default=None, help="Set up a script instead of a package"
@@ -3,11 +3,13 @@ from __future__ import annotations
3
3
  import sys
4
4
  from typing import TYPE_CHECKING
5
5
 
6
+ from utilities.functions import get_func_name
7
+ from utilities.tabulate import func_param_desc
6
8
  from utilities.text import repr_str
7
9
 
10
+ from actions import __version__
8
11
  from actions.logging import LOGGER
9
12
  from actions.pre_commit.utilities import get_pyproject_dependencies, yield_toml_doc
10
- from actions.utilities import log_func_call
11
13
 
12
14
  if TYPE_CHECKING:
13
15
  from collections.abc import MutableSet
@@ -18,7 +20,7 @@ if TYPE_CHECKING:
18
20
 
19
21
 
20
22
  def format_requirements(*paths: PathLike) -> None:
21
- LOGGER.info(log_func_call(format_requirements, f"{paths=}"))
23
+ LOGGER.info(func_param_desc(format_requirements, __version__, f"{paths=}"))
22
24
  modifications: set[Path] = set()
23
25
  for path in paths:
24
26
  _format_path(path, modifications=modifications)
@@ -28,6 +30,7 @@ def format_requirements(*paths: PathLike) -> None:
28
30
  ", ".join(map(repr_str, sorted(modifications))),
29
31
  )
30
32
  sys.exit(1)
33
+ LOGGER.info("Finished running %r", get_func_name(format_requirements))
31
34
 
32
35
 
33
36
  def _format_path(