easy-docker-manager 1.0.0__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 (91) hide show
  1. easy_docker_manager-1.0.0/.github/ISSUE_TEMPLATE/bug_report.yml +102 -0
  2. easy_docker_manager-1.0.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  3. easy_docker_manager-1.0.0/.github/ISSUE_TEMPLATE/feature_request.yml +45 -0
  4. easy_docker_manager-1.0.0/.github/dependabot.yml +20 -0
  5. easy_docker_manager-1.0.0/.github/pull_request_template.md +31 -0
  6. easy_docker_manager-1.0.0/.github/workflows/package.yml +92 -0
  7. easy_docker_manager-1.0.0/.github/workflows/quality.yml +113 -0
  8. easy_docker_manager-1.0.0/.github/workflows/release.yml +213 -0
  9. easy_docker_manager-1.0.0/.github/workflows/security.yml +75 -0
  10. easy_docker_manager-1.0.0/.gitignore +89 -0
  11. easy_docker_manager-1.0.0/.pre-commit-config.yaml +41 -0
  12. easy_docker_manager-1.0.0/CONTRIBUTING.md +77 -0
  13. easy_docker_manager-1.0.0/DEVELOPMENT_GUIDE.md +656 -0
  14. easy_docker_manager-1.0.0/LICENSE +21 -0
  15. easy_docker_manager-1.0.0/Makefile +57 -0
  16. easy_docker_manager-1.0.0/PKG-INFO +266 -0
  17. easy_docker_manager-1.0.0/README.md +235 -0
  18. easy_docker_manager-1.0.0/SECURITY.md +31 -0
  19. easy_docker_manager-1.0.0/docs/assets/edm-demo.gif +0 -0
  20. easy_docker_manager-1.0.0/docs/demos/edm-demo.tape +16 -0
  21. easy_docker_manager-1.0.0/pyproject.toml +123 -0
  22. easy_docker_manager-1.0.0/requirements.txt +1 -0
  23. easy_docker_manager-1.0.0/setup.cfg +4 -0
  24. easy_docker_manager-1.0.0/src/easy_docker_manager/__init__.py +0 -0
  25. easy_docker_manager-1.0.0/src/easy_docker_manager/app/__init__.py +3 -0
  26. easy_docker_manager-1.0.0/src/easy_docker_manager/app/app.py +176 -0
  27. easy_docker_manager-1.0.0/src/easy_docker_manager/app/background_notifier.py +206 -0
  28. easy_docker_manager-1.0.0/src/easy_docker_manager/app/background_task_result_handler.py +447 -0
  29. easy_docker_manager-1.0.0/src/easy_docker_manager/app/background_task_runner.py +211 -0
  30. easy_docker_manager-1.0.0/src/easy_docker_manager/app/runtime_factory.py +122 -0
  31. easy_docker_manager-1.0.0/src/easy_docker_manager/app/scheduler.py +422 -0
  32. easy_docker_manager-1.0.0/src/easy_docker_manager/config/__init__.py +3 -0
  33. easy_docker_manager-1.0.0/src/easy_docker_manager/config/app_config_store.py +143 -0
  34. easy_docker_manager-1.0.0/src/easy_docker_manager/constants.py +3 -0
  35. easy_docker_manager-1.0.0/src/easy_docker_manager/core/__init__.py +16 -0
  36. easy_docker_manager-1.0.0/src/easy_docker_manager/core/config.py +54 -0
  37. easy_docker_manager-1.0.0/src/easy_docker_manager/core/containers.py +25 -0
  38. easy_docker_manager-1.0.0/src/easy_docker_manager/core/content_cache.py +129 -0
  39. easy_docker_manager-1.0.0/src/easy_docker_manager/core/log_text.py +103 -0
  40. easy_docker_manager-1.0.0/src/easy_docker_manager/core/tabs.py +17 -0
  41. easy_docker_manager-1.0.0/src/easy_docker_manager/core/ui_session_state.py +142 -0
  42. easy_docker_manager-1.0.0/src/easy_docker_manager/docker/__init__.py +0 -0
  43. easy_docker_manager-1.0.0/src/easy_docker_manager/docker/base.py +143 -0
  44. easy_docker_manager-1.0.0/src/easy_docker_manager/docker/client_factory.py +34 -0
  45. easy_docker_manager-1.0.0/src/easy_docker_manager/docker/container_mapper.py +31 -0
  46. easy_docker_manager-1.0.0/src/easy_docker_manager/docker/error_mapping.py +34 -0
  47. easy_docker_manager-1.0.0/src/easy_docker_manager/docker/local.py +222 -0
  48. easy_docker_manager-1.0.0/src/easy_docker_manager/docker/log_availability.py +60 -0
  49. easy_docker_manager-1.0.0/src/easy_docker_manager/logging/__init__.py +3 -0
  50. easy_docker_manager-1.0.0/src/easy_docker_manager/logging/app_logging.py +94 -0
  51. easy_docker_manager-1.0.0/src/easy_docker_manager/main.py +24 -0
  52. easy_docker_manager-1.0.0/src/easy_docker_manager/tabs/__init__.py +3 -0
  53. easy_docker_manager-1.0.0/src/easy_docker_manager/tabs/config_tab_formatter.py +356 -0
  54. easy_docker_manager-1.0.0/src/easy_docker_manager/tabs/tab_data_loader.py +145 -0
  55. easy_docker_manager-1.0.0/src/easy_docker_manager/ui/__init__.py +5 -0
  56. easy_docker_manager-1.0.0/src/easy_docker_manager/ui/formatting.py +358 -0
  57. easy_docker_manager-1.0.0/src/easy_docker_manager/ui/keyboard_controller.py +167 -0
  58. easy_docker_manager-1.0.0/src/easy_docker_manager/ui/terminal_layout.py +423 -0
  59. easy_docker_manager-1.0.0/src/easy_docker_manager/ui/ui_controller.py +272 -0
  60. easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/PKG-INFO +266 -0
  61. easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/SOURCES.txt +89 -0
  62. easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/dependency_links.txt +1 -0
  63. easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/entry_points.txt +2 -0
  64. easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/requires.txt +3 -0
  65. easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/scm_file_list.json +85 -0
  66. easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/scm_version.json +8 -0
  67. easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/top_level.txt +1 -0
  68. easy_docker_manager-1.0.0/tests/__init__.py +0 -0
  69. easy_docker_manager-1.0.0/tests/unit_tests/__init__.py +0 -0
  70. easy_docker_manager-1.0.0/tests/unit_tests/conftest.py +66 -0
  71. easy_docker_manager-1.0.0/tests/unit_tests/test_app.py +255 -0
  72. easy_docker_manager-1.0.0/tests/unit_tests/test_app_config_store.py +94 -0
  73. easy_docker_manager-1.0.0/tests/unit_tests/test_app_logging.py +90 -0
  74. easy_docker_manager-1.0.0/tests/unit_tests/test_background_notifier.py +144 -0
  75. easy_docker_manager-1.0.0/tests/unit_tests/test_background_task_result_handler.py +457 -0
  76. easy_docker_manager-1.0.0/tests/unit_tests/test_background_task_runner.py +91 -0
  77. easy_docker_manager-1.0.0/tests/unit_tests/test_config_tab_formatter.py +141 -0
  78. easy_docker_manager-1.0.0/tests/unit_tests/test_content_cache.py +107 -0
  79. easy_docker_manager-1.0.0/tests/unit_tests/test_core_config.py +76 -0
  80. easy_docker_manager-1.0.0/tests/unit_tests/test_docker_helpers.py +200 -0
  81. easy_docker_manager-1.0.0/tests/unit_tests/test_formatting.py +157 -0
  82. easy_docker_manager-1.0.0/tests/unit_tests/test_keyboard_controller.py +177 -0
  83. easy_docker_manager-1.0.0/tests/unit_tests/test_local_container_data_source.py +312 -0
  84. easy_docker_manager-1.0.0/tests/unit_tests/test_log_text.py +51 -0
  85. easy_docker_manager-1.0.0/tests/unit_tests/test_main.py +27 -0
  86. easy_docker_manager-1.0.0/tests/unit_tests/test_runtime_factory.py +60 -0
  87. easy_docker_manager-1.0.0/tests/unit_tests/test_scheduler.py +402 -0
  88. easy_docker_manager-1.0.0/tests/unit_tests/test_tab_data_loader.py +117 -0
  89. easy_docker_manager-1.0.0/tests/unit_tests/test_terminal_layout.py +137 -0
  90. easy_docker_manager-1.0.0/tests/unit_tests/test_ui_controller.py +299 -0
  91. easy_docker_manager-1.0.0/tests/unit_tests/test_ui_session_state.py +89 -0
@@ -0,0 +1,102 @@
1
+ name: Bug report
2
+ description: Report behavior that is broken or unexpected
3
+ title: "[Bug]: "
4
+ labels:
5
+ - bug
6
+ body:
7
+ - type: markdown
8
+ attributes:
9
+ value: |
10
+ Thank you for reporting a problem. Please remove passwords, tokens,
11
+ private container data, and other secrets before submitting this form.
12
+
13
+ - type: input
14
+ id: edm-version
15
+ attributes:
16
+ label: EDM version
17
+ description: Run `python -m pip show easy-docker-manager` to find it.
18
+ placeholder: Paste the value shown after Version
19
+ validations:
20
+ required: true
21
+
22
+ - type: dropdown
23
+ id: python-version
24
+ attributes:
25
+ label: Python version
26
+ options:
27
+ - "3.9"
28
+ - "3.10"
29
+ - "3.11"
30
+ - "3.12"
31
+ - "3.13"
32
+ - "3.14"
33
+ - Other
34
+ validations:
35
+ required: true
36
+
37
+ - type: dropdown
38
+ id: operating-system
39
+ attributes:
40
+ label: Operating system
41
+ options:
42
+ - Linux
43
+ - macOS
44
+ - Windows
45
+ - Other
46
+ validations:
47
+ required: true
48
+
49
+ - type: input
50
+ id: docker-version
51
+ attributes:
52
+ label: Docker version
53
+ description: Run `docker version` and provide the client and server versions.
54
+ placeholder: Client 27.0.0, Server 27.0.0
55
+ validations:
56
+ required: true
57
+
58
+ - type: textarea
59
+ id: problem
60
+ attributes:
61
+ label: What happened?
62
+ description: Describe the problem and what you were doing when it occurred.
63
+ validations:
64
+ required: true
65
+
66
+ - type: textarea
67
+ id: steps
68
+ attributes:
69
+ label: Steps to reproduce
70
+ description: List the shortest sequence that consistently shows the problem.
71
+ placeholder: |
72
+ 1. Start EDM
73
+ 2. Select ...
74
+ 3. Press ...
75
+ 4. See ...
76
+ validations:
77
+ required: true
78
+
79
+ - type: textarea
80
+ id: expected
81
+ attributes:
82
+ label: Expected behavior
83
+ description: Explain what you expected EDM to do.
84
+ validations:
85
+ required: true
86
+
87
+ - type: textarea
88
+ id: logs
89
+ attributes:
90
+ label: Relevant output
91
+ description: Paste sanitized terminal output or EDM log entries, if available.
92
+ render: shell
93
+
94
+ - type: checkboxes
95
+ id: checks
96
+ attributes:
97
+ label: Before submitting
98
+ options:
99
+ - label: I searched existing issues for this problem.
100
+ required: true
101
+ - label: I removed passwords, tokens, and other sensitive data.
102
+ required: true
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Report a security vulnerability
4
+ url: https://github.com/arabnejad/edm/security/advisories/new
5
+ about: Send security reports privately instead of opening a public issue.
@@ -0,0 +1,45 @@
1
+ name: Feature request
2
+ description: Suggest an improvement to EDM
3
+ title: "[Feature]: "
4
+ labels:
5
+ - enhancement
6
+ body:
7
+ - type: markdown
8
+ attributes:
9
+ value: Thank you for taking the time to suggest an improvement.
10
+
11
+ - type: textarea
12
+ id: problem
13
+ attributes:
14
+ label: What problem would this solve?
15
+ description: Describe the workflow or limitation behind the request.
16
+ validations:
17
+ required: true
18
+
19
+ - type: textarea
20
+ id: proposal
21
+ attributes:
22
+ label: Proposed behavior
23
+ description: Explain how you would like EDM to behave.
24
+ validations:
25
+ required: true
26
+
27
+ - type: textarea
28
+ id: alternatives
29
+ attributes:
30
+ label: Alternatives considered
31
+ description: Describe any workarounds or other approaches you considered.
32
+
33
+ - type: textarea
34
+ id: context
35
+ attributes:
36
+ label: Additional context
37
+ description: Add sanitized examples, screenshots, or related links if useful.
38
+
39
+ - type: checkboxes
40
+ id: checks
41
+ attributes:
42
+ label: Before submitting
43
+ options:
44
+ - label: I searched existing issues for a similar request.
45
+ required: true
@@ -0,0 +1,20 @@
1
+ version: 2
2
+
3
+ updates:
4
+ - package-ecosystem: pip
5
+ directory: "/"
6
+ schedule:
7
+ interval: weekly
8
+ day: monday
9
+ time: "06:00"
10
+ timezone: Europe/London
11
+ open-pull-requests-limit: 5
12
+
13
+ - package-ecosystem: github-actions
14
+ directory: "/"
15
+ schedule:
16
+ interval: weekly
17
+ day: monday
18
+ time: "06:15"
19
+ timezone: Europe/London
20
+ open-pull-requests-limit: 5
@@ -0,0 +1,31 @@
1
+ ## Why
2
+
3
+ <!-- What problem does this pull request solve? -->
4
+
5
+ ## What Changed
6
+
7
+ <!-- Summarize the implementation. A short bullet list is welcome. -->
8
+
9
+ ## Related Issues
10
+
11
+ <!-- Use "Closes #123" when merging should close an issue, or write "None". -->
12
+
13
+ ## Testing
14
+
15
+ <!-- List the automated commands and manual checks you ran. -->
16
+
17
+ ## Screenshots
18
+
19
+ <!-- Add before-and-after images for terminal UI changes, or remove this section. -->
20
+
21
+ ## Notes For Reviewers
22
+
23
+ <!-- Point out important design choices, risks, or areas needing close review. -->
24
+
25
+ ## Checklist
26
+
27
+ - [ ] I read and followed `CONTRIBUTING.md`.
28
+ - [ ] I added or updated tests, or this change does not need tests.
29
+ - [ ] I ran `make check` successfully.
30
+ - [ ] I updated the relevant documentation, or no documentation change is needed.
31
+ - [ ] I removed secrets and private container data from output and screenshots.
@@ -0,0 +1,92 @@
1
+ name: Package
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ concurrency:
14
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ build:
19
+ name: Build distributions
20
+ runs-on: ubuntu-latest
21
+ timeout-minutes: 15
22
+
23
+ steps:
24
+ - name: Check out repository and version tags
25
+ uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
26
+ with:
27
+ fetch-depth: 0
28
+ persist-credentials: false
29
+
30
+ - name: Set up Python
31
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
32
+ with:
33
+ python-version: "3.12"
34
+ cache: pip
35
+
36
+ - name: Install packaging tools
37
+ run: |
38
+ python -m pip install --upgrade pip
39
+ python -m pip install --group dev -e .
40
+
41
+ - name: Build and validate distributions
42
+ run: make package-check
43
+
44
+ - name: Upload distributions
45
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
46
+ with:
47
+ name: distributions
48
+ path: dist/
49
+ if-no-files-found: error
50
+ retention-days: 7
51
+
52
+ install-wheel:
53
+ name: Install wheel on Python ${{ matrix.python-version }}
54
+ needs: build
55
+ runs-on: ubuntu-latest
56
+ timeout-minutes: 15
57
+
58
+ strategy:
59
+ fail-fast: false
60
+ matrix:
61
+ python-version:
62
+ - "3.9"
63
+ - "3.10"
64
+ - "3.11"
65
+ - "3.12"
66
+ - "3.13"
67
+ - "3.14"
68
+
69
+ steps:
70
+ - name: Set up Python
71
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
72
+ with:
73
+ python-version: ${{ matrix.python-version }}
74
+
75
+ - name: Download distributions
76
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
77
+ with:
78
+ name: distributions
79
+ path: dist/
80
+
81
+ - name: Install wheel
82
+ run: |
83
+ python -m pip install --upgrade pip
84
+ python -m pip install dist/*.whl
85
+
86
+ - name: Check installed dependencies
87
+ run: python -m pip check
88
+
89
+ - name: Import installed package
90
+ run: >-
91
+ python -c "import easy_docker_manager;
92
+ from easy_docker_manager.main import main"
@@ -0,0 +1,113 @@
1
+ name: Quality
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ concurrency:
13
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ jobs:
17
+ static-analysis:
18
+ name: Static analysis (Python 3.12)
19
+ runs-on: ubuntu-latest
20
+ timeout-minutes: 15
21
+
22
+ steps:
23
+ - name: Check out repository
24
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
25
+
26
+ - name: Set up Python
27
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
28
+ with:
29
+ python-version: "3.12"
30
+ cache: pip
31
+
32
+ - name: Install development dependencies
33
+ run: |
34
+ python -m pip install --upgrade pip
35
+ python -m pip install --group dev -e .
36
+
37
+ - name: Check formatting with Black
38
+ run: make black-check
39
+
40
+ - name: Lint with Ruff
41
+ run: make ruff
42
+
43
+ - name: Check types with mypy
44
+ run: make mypy
45
+
46
+ - name: Scan source code with Bandit
47
+ run: make bandit
48
+
49
+ unit-tests:
50
+ name: Unit tests (Python ${{ matrix.python-version }})
51
+ runs-on: ubuntu-latest
52
+ timeout-minutes: 15
53
+
54
+ strategy:
55
+ fail-fast: false
56
+ matrix:
57
+ python-version:
58
+ - "3.9"
59
+ - "3.10"
60
+ - "3.11"
61
+ - "3.12"
62
+ - "3.13"
63
+ - "3.14"
64
+
65
+ steps:
66
+ - name: Check out repository
67
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
68
+
69
+ - name: Set up Python
70
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
71
+ with:
72
+ python-version: ${{ matrix.python-version }}
73
+ cache: pip
74
+
75
+ - name: Install development dependencies
76
+ run: |
77
+ python -m pip install --upgrade pip
78
+ python -m pip install --group dev -e .
79
+
80
+ - name: Run unit tests with coverage
81
+ run: make test
82
+
83
+ minimum-runtime-dependencies:
84
+ name: Minimum runtime dependencies (Python 3.9)
85
+ runs-on: ubuntu-latest
86
+ timeout-minutes: 15
87
+
88
+ steps:
89
+ - name: Check out repository
90
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
91
+
92
+ - name: Set up Python
93
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
94
+ with:
95
+ python-version: "3.9"
96
+ cache: pip
97
+
98
+ - name: Install minimum runtime dependencies and test tools
99
+ run: |
100
+ python -m pip install --upgrade pip
101
+ python -m pip install --no-deps -e .
102
+ python -m pip install \
103
+ "docker==7.0.0" \
104
+ "platformdirs==4.0.0" \
105
+ "pytest==8.4.2" \
106
+ "pytest-cov==7.0.0" \
107
+ "urwid==2.6.0"
108
+
109
+ - name: Check installed dependencies
110
+ run: python -m pip check
111
+
112
+ - name: Run unit tests with minimum runtime dependencies
113
+ run: make test
@@ -0,0 +1,213 @@
1
+ name: Release package
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ concurrency:
9
+ group: release-${{ github.ref }}
10
+ cancel-in-progress: false
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ build:
17
+ name: Build and validate distributions
18
+ runs-on: ubuntu-latest
19
+ timeout-minutes: 20
20
+
21
+ steps:
22
+ - name: Check out the release tag and Git history
23
+ uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
24
+ with:
25
+ fetch-depth: 0
26
+ persist-credentials: false
27
+
28
+ - name: Set up Python
29
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
30
+ with:
31
+ python-version: "3.12"
32
+ cache: pip
33
+
34
+ - name: Install development tools
35
+ run: |
36
+ python -m pip install --upgrade pip
37
+ python -m pip install --group dev -e .
38
+
39
+ - name: Validate the release tag
40
+ env:
41
+ RELEASE_TAG: ${{ github.ref_name }}
42
+ run: |
43
+ python - <<'PY'
44
+ import os
45
+ import re
46
+
47
+ release_tag = os.environ["RELEASE_TAG"]
48
+ if not re.fullmatch(r"v\d+\.\d+\.\d+", release_tag):
49
+ raise SystemExit(
50
+ "Release tags must use vX.Y.Z format, for example v1.0.1"
51
+ )
52
+ PY
53
+
54
+ - name: Confirm the tagged commit belongs to main
55
+ run: |
56
+ git fetch --no-tags origin main
57
+ git merge-base --is-ancestor "$GITHUB_SHA" origin/main
58
+
59
+ - name: Run quality checks and unit tests
60
+ run: make check
61
+
62
+ - name: Build and validate distributions
63
+ run: |
64
+ rm -rf build dist
65
+ make package-check
66
+
67
+ - name: Confirm the built version matches the tag
68
+ env:
69
+ RELEASE_TAG: ${{ github.ref_name }}
70
+ run: |
71
+ python - <<'PY'
72
+ import os
73
+ from pathlib import Path
74
+
75
+ from packaging.utils import parse_sdist_filename, parse_wheel_filename
76
+ from packaging.version import Version
77
+
78
+ expected_version = Version(os.environ["RELEASE_TAG"].removeprefix("v"))
79
+ wheels = list(Path("dist").glob("*.whl"))
80
+ source_archives = list(Path("dist").glob("*.tar.gz"))
81
+
82
+ if len(wheels) != 1 or len(source_archives) != 1:
83
+ raise SystemExit("Expected one wheel and one source distribution")
84
+
85
+ wheel_version = parse_wheel_filename(wheels[0].name)[1]
86
+ source_version = parse_sdist_filename(source_archives[0].name)[1]
87
+
88
+ if wheel_version != expected_version or source_version != expected_version:
89
+ raise SystemExit(
90
+ "Built version does not match release tag: "
91
+ f"tag={expected_version}, wheel={wheel_version}, "
92
+ f"source={source_version}"
93
+ )
94
+ PY
95
+
96
+ - name: Store distribution files
97
+ uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
98
+ with:
99
+ name: python-package-distributions
100
+ path: dist/
101
+ if-no-files-found: error
102
+ retention-days: 7
103
+
104
+ test-wheel:
105
+ name: Test wheel on Python ${{ matrix.python-version }}
106
+ needs: build
107
+ runs-on: ubuntu-latest
108
+ timeout-minutes: 15
109
+
110
+ strategy:
111
+ fail-fast: false
112
+ matrix:
113
+ python-version:
114
+ - "3.9"
115
+ - "3.10"
116
+ - "3.11"
117
+ - "3.12"
118
+ - "3.13"
119
+ - "3.14"
120
+
121
+ steps:
122
+ - name: Set up Python
123
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
124
+ with:
125
+ python-version: ${{ matrix.python-version }}
126
+
127
+ - name: Download distribution files
128
+ uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
129
+ with:
130
+ name: python-package-distributions
131
+ path: dist/
132
+
133
+ - name: Install the built wheel
134
+ run: |
135
+ python -m pip install --upgrade pip
136
+ python -m pip install dist/*.whl
137
+
138
+ - name: Check the installed package and version
139
+ env:
140
+ RELEASE_TAG: ${{ github.ref_name }}
141
+ run: |
142
+ python -m pip check
143
+ python - <<'PY'
144
+ import os
145
+ from importlib.metadata import distribution
146
+
147
+ expected_version = os.environ["RELEASE_TAG"].removeprefix("v")
148
+ installed_distribution = distribution("easy-docker-manager")
149
+
150
+ if installed_distribution.version != expected_version:
151
+ raise SystemExit(
152
+ f"Installed {installed_distribution.version}, "
153
+ f"expected {expected_version}"
154
+ )
155
+
156
+ commands = {
157
+ item.name
158
+ for item in installed_distribution.entry_points
159
+ if item.group == "console_scripts"
160
+ }
161
+ if "edm" not in commands:
162
+ raise SystemExit("The edm console command is missing")
163
+
164
+ import easy_docker_manager
165
+ PY
166
+
167
+ create-github-release:
168
+ name: Create GitHub Release
169
+ needs: [build, test-wheel]
170
+ runs-on: ubuntu-latest
171
+ timeout-minutes: 10
172
+ permissions:
173
+ contents: write
174
+
175
+ steps:
176
+ - name: Download tested distribution files
177
+ uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
178
+ with:
179
+ name: python-package-distributions
180
+ path: dist/
181
+
182
+ - name: Create the release and attach distributions
183
+ env:
184
+ GH_TOKEN: ${{ github.token }}
185
+ RELEASE_TAG: ${{ github.ref_name }}
186
+ run: |
187
+ gh release create "$RELEASE_TAG" dist/* \
188
+ --repo "$GITHUB_REPOSITORY" \
189
+ --verify-tag \
190
+ --generate-notes \
191
+ --title "Easy Docker Manager ${RELEASE_TAG#v}"
192
+
193
+ publish-to-pypi:
194
+ name: Publish distributions to PyPI
195
+ needs: create-github-release
196
+ runs-on: ubuntu-latest
197
+ timeout-minutes: 10
198
+ environment:
199
+ name: pypi
200
+ url: https://pypi.org/p/easy-docker-manager
201
+ permissions:
202
+ contents: read
203
+ id-token: write
204
+
205
+ steps:
206
+ - name: Download tested distribution files
207
+ uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
208
+ with:
209
+ name: python-package-distributions
210
+ path: dist/
211
+
212
+ - name: Publish distributions to PyPI
213
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
@@ -0,0 +1,75 @@
1
+ name: Security
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ schedule:
9
+ - cron: "23 6 * * 1"
10
+ workflow_dispatch:
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ concurrency:
16
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
17
+ cancel-in-progress: true
18
+
19
+ jobs:
20
+ dependency-audit:
21
+ name: Dependency audit
22
+ runs-on: ubuntu-latest
23
+ timeout-minutes: 15
24
+
25
+ steps:
26
+ - name: Check out repository
27
+ uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
28
+
29
+ - name: Set up Python
30
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
31
+ with:
32
+ python-version: "3.12"
33
+ cache: pip
34
+
35
+ - name: Install project and audit tool
36
+ run: |
37
+ python -m pip install --upgrade pip
38
+ python -m pip install --group security -e .
39
+
40
+ - name: Audit Python dependencies
41
+ run: make audit
42
+
43
+ dependency-review:
44
+ name: Dependency review
45
+ if: github.event_name == 'pull_request'
46
+ runs-on: ubuntu-latest
47
+ timeout-minutes: 15
48
+
49
+ steps:
50
+ - name: Check out repository
51
+ uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
52
+
53
+ - name: Reject vulnerable dependency changes
54
+ uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
55
+ with:
56
+ fail-on-severity: moderate
57
+
58
+ secret-scan:
59
+ name: Secret scan
60
+ runs-on: ubuntu-latest
61
+ timeout-minutes: 15
62
+ permissions:
63
+ contents: read
64
+
65
+ steps:
66
+ - name: Check out complete Git history
67
+ uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
68
+ with:
69
+ fetch-depth: 0
70
+
71
+ - name: Scan for committed secrets
72
+ uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3.0.0
73
+ env:
74
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
75
+ GITLEAKS_ENABLE_COMMENTS: false