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.
- easy_docker_manager-1.0.0/.github/ISSUE_TEMPLATE/bug_report.yml +102 -0
- easy_docker_manager-1.0.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- easy_docker_manager-1.0.0/.github/ISSUE_TEMPLATE/feature_request.yml +45 -0
- easy_docker_manager-1.0.0/.github/dependabot.yml +20 -0
- easy_docker_manager-1.0.0/.github/pull_request_template.md +31 -0
- easy_docker_manager-1.0.0/.github/workflows/package.yml +92 -0
- easy_docker_manager-1.0.0/.github/workflows/quality.yml +113 -0
- easy_docker_manager-1.0.0/.github/workflows/release.yml +213 -0
- easy_docker_manager-1.0.0/.github/workflows/security.yml +75 -0
- easy_docker_manager-1.0.0/.gitignore +89 -0
- easy_docker_manager-1.0.0/.pre-commit-config.yaml +41 -0
- easy_docker_manager-1.0.0/CONTRIBUTING.md +77 -0
- easy_docker_manager-1.0.0/DEVELOPMENT_GUIDE.md +656 -0
- easy_docker_manager-1.0.0/LICENSE +21 -0
- easy_docker_manager-1.0.0/Makefile +57 -0
- easy_docker_manager-1.0.0/PKG-INFO +266 -0
- easy_docker_manager-1.0.0/README.md +235 -0
- easy_docker_manager-1.0.0/SECURITY.md +31 -0
- easy_docker_manager-1.0.0/docs/assets/edm-demo.gif +0 -0
- easy_docker_manager-1.0.0/docs/demos/edm-demo.tape +16 -0
- easy_docker_manager-1.0.0/pyproject.toml +123 -0
- easy_docker_manager-1.0.0/requirements.txt +1 -0
- easy_docker_manager-1.0.0/setup.cfg +4 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/__init__.py +0 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/app/__init__.py +3 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/app/app.py +176 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/app/background_notifier.py +206 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/app/background_task_result_handler.py +447 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/app/background_task_runner.py +211 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/app/runtime_factory.py +122 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/app/scheduler.py +422 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/config/__init__.py +3 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/config/app_config_store.py +143 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/constants.py +3 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/core/__init__.py +16 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/core/config.py +54 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/core/containers.py +25 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/core/content_cache.py +129 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/core/log_text.py +103 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/core/tabs.py +17 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/core/ui_session_state.py +142 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/docker/__init__.py +0 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/docker/base.py +143 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/docker/client_factory.py +34 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/docker/container_mapper.py +31 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/docker/error_mapping.py +34 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/docker/local.py +222 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/docker/log_availability.py +60 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/logging/__init__.py +3 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/logging/app_logging.py +94 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/main.py +24 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/tabs/__init__.py +3 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/tabs/config_tab_formatter.py +356 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/tabs/tab_data_loader.py +145 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/ui/__init__.py +5 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/ui/formatting.py +358 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/ui/keyboard_controller.py +167 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/ui/terminal_layout.py +423 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager/ui/ui_controller.py +272 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/PKG-INFO +266 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/SOURCES.txt +89 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/dependency_links.txt +1 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/entry_points.txt +2 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/requires.txt +3 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/scm_file_list.json +85 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/scm_version.json +8 -0
- easy_docker_manager-1.0.0/src/easy_docker_manager.egg-info/top_level.txt +1 -0
- easy_docker_manager-1.0.0/tests/__init__.py +0 -0
- easy_docker_manager-1.0.0/tests/unit_tests/__init__.py +0 -0
- easy_docker_manager-1.0.0/tests/unit_tests/conftest.py +66 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_app.py +255 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_app_config_store.py +94 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_app_logging.py +90 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_background_notifier.py +144 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_background_task_result_handler.py +457 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_background_task_runner.py +91 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_config_tab_formatter.py +141 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_content_cache.py +107 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_core_config.py +76 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_docker_helpers.py +200 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_formatting.py +157 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_keyboard_controller.py +177 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_local_container_data_source.py +312 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_log_text.py +51 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_main.py +27 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_runtime_factory.py +60 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_scheduler.py +402 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_tab_data_loader.py +117 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_terminal_layout.py +137 -0
- easy_docker_manager-1.0.0/tests/unit_tests/test_ui_controller.py +299 -0
- 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,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
|