fujin-cli 0.26.0__tar.gz → 0.26.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 (155) hide show
  1. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/CHANGELOG.md +6 -0
  2. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/PKG-INFO +1 -1
  3. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-1password/pyproject.toml +2 -2
  4. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-bitwarden/pyproject.toml +2 -2
  5. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-doppler/pyproject.toml +2 -2
  6. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-env/pyproject.toml +2 -2
  7. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/pyproject.toml +2 -2
  8. fujin_cli-0.26.1/src/fujin/__init__.py +1 -0
  9. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/_installer.py +37 -10
  10. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/uv.lock +5 -5
  11. fujin_cli-0.26.0/src/fujin/__init__.py +0 -1
  12. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/.github/FUNDING.yml +0 -0
  13. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/.github/workflows/publish.yml +0 -0
  14. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/.github/workflows/test.yml +0 -0
  15. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/.gitignore +0 -0
  16. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/.pre-commit-config.yaml +0 -0
  17. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/.readthedocs.yaml +0 -0
  18. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/CLAUDE.md +0 -0
  19. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/LICENSE.txt +0 -0
  20. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/README.md +0 -0
  21. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/Vagrantfile +0 -0
  22. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/app-cat-help.png +0 -0
  23. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/app-exec-help.png +0 -0
  24. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/app-help.png +0 -0
  25. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/app-logs-help.png +0 -0
  26. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/app-restart-help.png +0 -0
  27. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/app-scale-help.png +0 -0
  28. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/app-shell-help.png +0 -0
  29. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/app-start-help.png +0 -0
  30. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/app-status-help.png +0 -0
  31. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/app-stop-help.png +0 -0
  32. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/audit-help.png +0 -0
  33. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/deploy-help.png +0 -0
  34. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/down-help.png +0 -0
  35. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/fa-help.png +0 -0
  36. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/fujin-help.png +0 -0
  37. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/init-help.png +0 -0
  38. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/migrate-help.png +0 -0
  39. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/new-help.png +0 -0
  40. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/prune-help.png +0 -0
  41. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/rollback-help.png +0 -0
  42. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/server-bootstrap-help.png +0 -0
  43. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/server-create-user-help.png +0 -0
  44. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/server-exec-help.png +0 -0
  45. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/server-help.png +0 -0
  46. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/server-setup-ssh-help.png +0 -0
  47. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/server-status-help.png +0 -0
  48. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/_static/images/help/up-help.png +0 -0
  49. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/changelog.rst +0 -0
  50. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/commands/app.rst +0 -0
  51. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/commands/audit.rst +0 -0
  52. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/commands/deploy.rst +0 -0
  53. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/commands/down.rst +0 -0
  54. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/commands/index.rst +0 -0
  55. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/commands/init.rst +0 -0
  56. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/commands/migrate.rst +0 -0
  57. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/commands/new.rst +0 -0
  58. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/commands/prune.rst +0 -0
  59. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/commands/rollback.rst +0 -0
  60. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/commands/server.rst +0 -0
  61. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/commands/up.rst +0 -0
  62. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/conf.py +0 -0
  63. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/configuration.rst +0 -0
  64. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/guides/django-complete.rst +0 -0
  65. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/guides/index.rst +0 -0
  66. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/guides/templates.rst +0 -0
  67. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/howtos/binary.rst +0 -0
  68. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/howtos/django.rst +0 -0
  69. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/howtos/index.rst +0 -0
  70. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/index.rst +0 -0
  71. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/installation.rst +0 -0
  72. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/integrations.rst +0 -0
  73. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/requirements.txt +0 -0
  74. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/secrets.rst +0 -0
  75. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/docs/troubleshooting.rst +0 -0
  76. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/.fujin/Caddyfile +0 -0
  77. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/.fujin/systemd/health.service +0 -0
  78. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/.fujin/systemd/health.timer +0 -0
  79. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/.fujin/systemd/web.service +0 -0
  80. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/.fujin/systemd/worker@.service +0 -0
  81. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/README.md +0 -0
  82. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/bookstore/__init__.py +0 -0
  83. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/bookstore/__main__.py +0 -0
  84. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/bookstore/asgi.py +0 -0
  85. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/bookstore/management/commands/health.py +0 -0
  86. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/bookstore/settings.py +0 -0
  87. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/bookstore/urls.py +0 -0
  88. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/bookstore/wsgi.py +0 -0
  89. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/fujin.toml +0 -0
  90. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/manage.py +0 -0
  91. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/pyproject.toml +0 -0
  92. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/examples/django/bookstore/requirements.txt +0 -0
  93. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/justfile +0 -0
  94. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-1password/README.md +0 -0
  95. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-1password/src/fujin_secrets_1password/__init__.py +0 -0
  96. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-1password/src/fujin_secrets_1password/py.typed +0 -0
  97. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-bitwarden/README.md +0 -0
  98. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-bitwarden/src/fujin_secrets_bitwarden/__init__.py +0 -0
  99. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-bitwarden/src/fujin_secrets_bitwarden/py.typed +0 -0
  100. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-doppler/README.md +0 -0
  101. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-doppler/src/fujin_secrets_doppler/__init__.py +0 -0
  102. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-doppler/src/fujin_secrets_doppler/py.typed +0 -0
  103. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-env/README.md +0 -0
  104. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/plugins/fujin-secrets-env/src/fujin_secrets_env/__init__.py +0 -0
  105. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/__main__.py +0 -0
  106. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/audit.py +0 -0
  107. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/caddy.py +0 -0
  108. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/__init__.py +0 -0
  109. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/_base.py +0 -0
  110. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/app.py +0 -0
  111. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/audit.py +0 -0
  112. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/deploy.py +0 -0
  113. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/down.py +0 -0
  114. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/init.py +0 -0
  115. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/migrate.py +0 -0
  116. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/new.py +0 -0
  117. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/prune.py +0 -0
  118. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/rollback.py +0 -0
  119. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/server.py +0 -0
  120. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/showenv.py +0 -0
  121. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/commands/up.py +0 -0
  122. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/config.py +0 -0
  123. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/connection.py +0 -0
  124. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/discovery.py +0 -0
  125. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/errors.py +0 -0
  126. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/fa.py +0 -0
  127. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/formatting.py +0 -0
  128. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/secrets.py +0 -0
  129. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/src/fujin/templates.py +0 -0
  130. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/__init__.py +0 -0
  131. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/conftest.py +0 -0
  132. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/integration/Dockerfile +0 -0
  133. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/integration/__init__.py +0 -0
  134. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/integration/conftest.py +0 -0
  135. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/integration/helpers.py +0 -0
  136. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/integration/test_app_management.py +0 -0
  137. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/integration/test_full_deploy.py +0 -0
  138. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/integration/test_installation.py +0 -0
  139. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/integration/test_server_bootstrap.py +0 -0
  140. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_app.py +0 -0
  141. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_audit.py +0 -0
  142. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_caddy_domain.py +0 -0
  143. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_config.py +0 -0
  144. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_connection.py +0 -0
  145. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_deploy.py +0 -0
  146. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_discovery.py +0 -0
  147. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_down.py +0 -0
  148. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_init.py +0 -0
  149. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_new.py +0 -0
  150. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_prune.py +0 -0
  151. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_rollback.py +0 -0
  152. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_scale.py +0 -0
  153. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_secrets.py +0 -0
  154. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_server.py +0 -0
  155. {fujin_cli-0.26.0 → fujin_cli-0.26.1}/tests/test_up.py +0 -0
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.26.1] - 2026-06-09
8
+
9
+ ### 🐛 Bug Fixes
10
+
11
+ - *(deploy)* Skip reload-or-restart for Type=oneshot services
12
+
7
13
  ## [0.26.0] - 2026-06-05
8
14
 
9
15
  ### 🚀 Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fujin-cli
3
- Version: 0.26.0
3
+ Version: 0.26.1
4
4
  Summary: Get your project up and running in a few minutes on your own vps.
5
5
  Project-URL: Documentation, https://github.com/Tobi-De/fujin#readme
6
6
  Project-URL: Issues, https://github.com/Tobi-De/fujin/issues
@@ -4,7 +4,7 @@ requires = [ "uv-build>=0.9.18,<0.10" ]
4
4
 
5
5
  [project]
6
6
  name = "fujin-secrets-1password"
7
- version = "0.26.0"
7
+ version = "0.26.1"
8
8
  description = "1Password secret adapter for Fujin"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -20,7 +20,7 @@ classifiers = [
20
20
  "Programming Language :: Python :: 3.14",
21
21
  ]
22
22
  dependencies = [
23
- "fujin-cli>=0.26",
23
+ "fujin-cli>=0.26.1",
24
24
  "python-dotenv>=1.0.1",
25
25
  ]
26
26
 
@@ -4,7 +4,7 @@ requires = [ "uv-build>=0.9.18,<0.10" ]
4
4
 
5
5
  [project]
6
6
  name = "fujin-secrets-bitwarden"
7
- version = "0.26.0"
7
+ version = "0.26.1"
8
8
  description = "Bitwarden secret adapter for Fujin"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -20,7 +20,7 @@ classifiers = [
20
20
  "Programming Language :: Python :: 3.14",
21
21
  ]
22
22
  dependencies = [
23
- "fujin-cli>=0.26",
23
+ "fujin-cli>=0.26.1",
24
24
  "python-dotenv>=1.0.1",
25
25
  ]
26
26
 
@@ -4,7 +4,7 @@ requires = [ "uv-build>=0.9.18,<0.10" ]
4
4
 
5
5
  [project]
6
6
  name = "fujin-secrets-doppler"
7
- version = "0.26.0"
7
+ version = "0.26.1"
8
8
  description = "Doppler secret adapter for Fujin"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -20,7 +20,7 @@ classifiers = [
20
20
  "Programming Language :: Python :: 3.14",
21
21
  ]
22
22
  dependencies = [
23
- "fujin-cli>=0.26",
23
+ "fujin-cli>=0.26.1",
24
24
  "python-dotenv>=1.0.1",
25
25
  ]
26
26
 
@@ -4,7 +4,7 @@ requires = [ "uv-build>=0.9.18,<0.10" ]
4
4
 
5
5
  [project]
6
6
  name = "fujin-secrets-env"
7
- version = "0.26.0"
7
+ version = "0.26.1"
8
8
  description = "Environment variable secret adapter for Fujin"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -20,7 +20,7 @@ classifiers = [
20
20
  "Programming Language :: Python :: 3.14",
21
21
  ]
22
22
  dependencies = [
23
- "fujin-cli>=0.26",
23
+ "fujin-cli>=0.26.1",
24
24
  "python-dotenv>=1.0.1",
25
25
  ]
26
26
 
@@ -5,7 +5,7 @@ requires = [ "hatchling" ]
5
5
 
6
6
  [project]
7
7
  name = "fujin-cli"
8
- version = "0.26.0"
8
+ version = "0.26.1"
9
9
  description = "Get your project up and running in a few minutes on your own vps."
10
10
  readme = "README.md"
11
11
  keywords = [
@@ -151,7 +151,7 @@ markers = [
151
151
  ]
152
152
 
153
153
  [tool.bumpversion]
154
- current_version = "0.26.0"
154
+ current_version = "0.26.1"
155
155
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
156
156
  serialize = [ "{major}.{minor}.{patch}" ]
157
157
  search = "{current_version}"
@@ -0,0 +1 @@
1
+ __version__ = "0.26.1"
@@ -373,8 +373,15 @@ export -f {config.app_name}
373
373
 
374
374
  logger.info("Restarting services...")
375
375
  active_units = []
376
+ oneshot_units = _get_oneshot_units(config.deployed_units)
377
+ if oneshot_units:
378
+ logger.info(
379
+ "Skipping restart of Type=oneshot units: %s",
380
+ ", ".join(sorted(oneshot_units)),
381
+ )
376
382
  for unit in config.deployed_units:
377
- active_units.extend(unit["service_instances"])
383
+ if unit["template_service_name"] not in oneshot_units:
384
+ active_units.extend(unit["service_instances"])
378
385
  if unit["template_socket_name"]:
379
386
  active_units.append(unit["template_socket_name"])
380
387
  if unit["template_timer_name"]:
@@ -409,16 +416,20 @@ export -f {config.app_name}
409
416
  validation_issues,
410
417
  )
411
418
 
412
- units_str = " ".join(active_units)
413
- run(
414
- f"systemctl daemon-reload && systemctl enable {units_str}",
415
- check=True,
416
- )
419
+ if not active_units:
420
+ run("systemctl daemon-reload")
421
+ restart_result = run("true")
422
+ else:
423
+ units_str = " ".join(active_units)
424
+ run(
425
+ f"systemctl daemon-reload && systemctl enable {units_str}",
426
+ check=True,
427
+ )
417
428
 
418
- restart_cmd = "restart" if full_restart else "reload-or-restart"
419
- restart_result = run(
420
- f"systemctl {restart_cmd} {units_str}",
421
- )
429
+ restart_cmd = "restart" if full_restart else "reload-or-restart"
430
+ restart_result = run(
431
+ f"systemctl {restart_cmd} {units_str}",
432
+ )
422
433
 
423
434
  # Check if services are actually running (not just restart command succeeded)
424
435
  # Only check services with no timer or socket - they should run immediately
@@ -426,6 +437,7 @@ export -f {config.app_name}
426
437
  unit["service_instances"]
427
438
  for unit in config.deployed_units
428
439
  if not (unit["template_socket_name"] or unit["template_timer_name"])
440
+ and unit["template_service_name"] not in oneshot_units
429
441
  ]
430
442
  units_to_check = list(chain.from_iterable(units_to_check))
431
443
 
@@ -607,6 +619,21 @@ def uninstall(config: InstallConfig, bundle_dir: Path) -> None:
607
619
  logger.info("Uninstall completed.")
608
620
 
609
621
 
622
+ def _get_oneshot_units(deployed_units: list[DeployedUnit]) -> set[str]:
623
+ """Identify units with Type=oneshot that should be skipped during restart.
624
+
625
+ Oneshot services have no long-running process to reload or restart — they
626
+ complete and exit. Restarting them during deploy is unnecessary and can
627
+ cause spurious failures that trigger rollbacks.
628
+ """
629
+ oneshot = set()
630
+ for unit in deployed_units:
631
+ unit_path = SYSTEMD_SYSTEM_DIR / unit["template_service_name"]
632
+ if unit_path.exists() and "Type=oneshot" in unit_path.read_text():
633
+ oneshot.add(unit["template_service_name"])
634
+ return oneshot
635
+
636
+
610
637
  def run(
611
638
  cmd: str,
612
639
  *,
@@ -346,7 +346,7 @@ wheels = [
346
346
 
347
347
  [[package]]
348
348
  name = "fujin-cli"
349
- version = "0.25.2"
349
+ version = "0.26.0"
350
350
  source = { editable = "." }
351
351
  dependencies = [
352
352
  { name = "cappa" },
@@ -402,7 +402,7 @@ docs = [
402
402
 
403
403
  [[package]]
404
404
  name = "fujin-secrets-1password"
405
- version = "0.25.2"
405
+ version = "0.26.0"
406
406
  source = { editable = "plugins/fujin-secrets-1password" }
407
407
  dependencies = [
408
408
  { name = "fujin-cli" },
@@ -417,7 +417,7 @@ requires-dist = [
417
417
 
418
418
  [[package]]
419
419
  name = "fujin-secrets-bitwarden"
420
- version = "0.25.2"
420
+ version = "0.26.0"
421
421
  source = { editable = "plugins/fujin-secrets-bitwarden" }
422
422
  dependencies = [
423
423
  { name = "fujin-cli" },
@@ -432,7 +432,7 @@ requires-dist = [
432
432
 
433
433
  [[package]]
434
434
  name = "fujin-secrets-doppler"
435
- version = "0.25.2"
435
+ version = "0.26.0"
436
436
  source = { editable = "plugins/fujin-secrets-doppler" }
437
437
  dependencies = [
438
438
  { name = "fujin-cli" },
@@ -447,7 +447,7 @@ requires-dist = [
447
447
 
448
448
  [[package]]
449
449
  name = "fujin-secrets-env"
450
- version = "0.25.2"
450
+ version = "0.26.0"
451
451
  source = { editable = "plugins/fujin-secrets-env" }
452
452
  dependencies = [
453
453
  { name = "fujin-cli" },
@@ -1 +0,0 @@
1
- __version__ = "0.26.0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes