aws-annoying 0.8.0__tar.gz → 0.8.2__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.
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.devcontainer/devcontainer.json +1 -1
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.github/workflows/ci.yaml +11 -16
- aws_annoying-0.8.2/.github/workflows/prepare-release.yaml +51 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.github/workflows/release.yaml +24 -18
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.vscode/extensions.json +0 -5
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.vscode/settings.json +0 -8
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/Makefile +2 -2
- aws_annoying-0.8.2/PKG-INFO +90 -0
- aws_annoying-0.8.2/README.md +72 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/pyproject.toml +8 -5
- aws_annoying-0.8.2/tests/cli/ecs/snapshots/test_task_definition_lifecycle/test_delete/stdout.txt +19 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/ecs/test_task_definition_lifecycle.py +60 -21
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/test_load_variables.py +2 -1
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/uv.lock +181 -158
- aws_annoying-0.8.0/PKG-INFO +0 -86
- aws_annoying-0.8.0/README.md +0 -51
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.devcontainer/.env.example +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.devcontainer/Dockerfile +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.devcontainer/docker-compose.devcontainer.yaml +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.devcontainer/onCreateCommand.sh +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.devcontainer/postAttachCommand.sh +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.editorconfig +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.gitattributes +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.github/dependabot.yaml +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.gitignore +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.pre-commit-config.yaml +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.python-version +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/.vscode/launch.json +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/LICENSE +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/app.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/ecs/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/ecs/_app.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/ecs/task_definition_lifecycle.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/ecs/wait_for_deployment.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/load_variables.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/logging_handler.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/main.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/mfa/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/mfa/_app.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/mfa/configure.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/session_manager/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/session_manager/_app.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/session_manager/_common.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/session_manager/install.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/session_manager/port_forward.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/session_manager/start.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/cli/session_manager/stop.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/ecs/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/ecs/check.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/ecs/common.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/ecs/errors.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/ecs/wait_for.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/mfa_config.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/session_manager/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/session_manager/errors.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/session_manager/session_manager.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/session_manager/shortcuts.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/utils/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/utils/debugger.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/utils/downloader.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/utils/ec2.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/utils/platform.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/utils/timeout.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/aws_annoying/variable_loader.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/console/ecs-exec/README.md +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/console/ecs-exec/ecs-console.png +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/console/ecs-exec/ecs-exec.user.js +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/console/ecs-exec/session-manager.png +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/examples/dbeaver/README.md +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/examples/dbeaver/after-disconnect.png +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/examples/dbeaver/before-connect.png +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/examples/dbeaver/new-connection.png +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/examples/dbeaver/test-connection.png +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/_helpers.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/_helpers/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/_helpers/boto3.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/_helpers/command_builder.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/_helpers/invoke.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/_helpers/scripts/printenv.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/_helpers/string_.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/ecs/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/ecs/snapshots/test_task_definition_lifecycle/test_basic/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/ecs/snapshots/test_task_definition_lifecycle/test_dry_run/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/ecs/test_wait_for_deployment.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/mfa/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/mfa/snapshots/test_configure/test_basic/persist/aws_config.ini +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/mfa/snapshots/test_configure/test_basic/persist/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/mfa/snapshots/test_configure/test_basic/skip_persist/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/mfa/snapshots/test_configure/test_dry_run/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/mfa/snapshots/test_configure/test_load_existing_config/aws_config.ini +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/mfa/snapshots/test_configure/test_load_existing_config/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/mfa/test_configure.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/session_manager/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/session_manager/test_install.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/session_manager/test_port_forward.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/session_manager/test_start.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/session_manager/test_stop.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/snapshots/test_load_variables/test_basic/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/snapshots/test_load_variables/test_env_prefix/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/snapshots/test_load_variables/test_nothing/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/snapshots/test_load_variables/test_overwrite_env/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/snapshots/test_load_variables/test_replace_quiet/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/snapshots/test_load_variables/test_resource_not_found/ssm/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/snapshots/test_load_variables/test_unsupported_resource/stdout.txt +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/test_app.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/test_logging_handler.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/cli/test_main.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/conftest.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/ecs/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/ecs/test_check.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/ecs/test_common.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/ecs/test_errors.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/ecs/test_wait_for.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/session_manager/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/session_manager/test_errors.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/session_manager/test_session_manager.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/session_manager/test_shortcuts.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/test_mfa_config.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/test_variable_loader.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/utils/__init__.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/utils/test_downloader.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/utils/test_ec2.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/utils/test_platform.py +0 -0
- {aws_annoying-0.8.0 → aws_annoying-0.8.2}/tests/utils/test_timeout.py +0 -0
|
@@ -6,27 +6,24 @@ on:
|
|
|
6
6
|
pull_request:
|
|
7
7
|
branches: [main]
|
|
8
8
|
|
|
9
|
-
permissions: read-all
|
|
10
|
-
|
|
11
9
|
env:
|
|
12
10
|
UV_FROZEN: 1
|
|
13
11
|
|
|
14
12
|
jobs:
|
|
15
13
|
lint:
|
|
16
|
-
name: Lint
|
|
17
14
|
runs-on: ubuntu-latest
|
|
15
|
+
timeout-minutes: 5
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
18
|
steps:
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- name: Set up uv
|
|
23
|
-
uses: astral-sh/setup-uv@v6
|
|
19
|
+
- uses: actions/checkout@v5
|
|
20
|
+
- uses: astral-sh/setup-uv@v7
|
|
24
21
|
with:
|
|
25
22
|
version: latest
|
|
26
23
|
enable-cache: true
|
|
27
24
|
|
|
28
25
|
- name: Install deps
|
|
29
|
-
run: uv sync
|
|
26
|
+
run: uv sync
|
|
30
27
|
|
|
31
28
|
- uses: pre-commit/action@v3.0.1
|
|
32
29
|
env:
|
|
@@ -36,8 +33,9 @@ jobs:
|
|
|
36
33
|
if: always()
|
|
37
34
|
|
|
38
35
|
test:
|
|
39
|
-
name:
|
|
36
|
+
name: test (${{ matrix.os }}, py${{ matrix.python-version }})
|
|
40
37
|
runs-on: ${{ matrix.os }}
|
|
38
|
+
timeout-minutes: 10
|
|
41
39
|
permissions:
|
|
42
40
|
contents: read
|
|
43
41
|
id-token: write
|
|
@@ -48,11 +46,8 @@ jobs:
|
|
|
48
46
|
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
|
49
47
|
|
|
50
48
|
steps:
|
|
51
|
-
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
- name: Set up uv
|
|
55
|
-
uses: astral-sh/setup-uv@v6
|
|
49
|
+
- uses: actions/checkout@v5
|
|
50
|
+
- uses: astral-sh/setup-uv@v7
|
|
56
51
|
with:
|
|
57
52
|
version: latest
|
|
58
53
|
enable-cache: true
|
|
@@ -61,7 +56,7 @@ jobs:
|
|
|
61
56
|
run: uv python pin "${{ matrix.python-version }}"
|
|
62
57
|
|
|
63
58
|
- name: Install deps
|
|
64
|
-
run: uv sync
|
|
59
|
+
run: uv sync
|
|
65
60
|
|
|
66
61
|
- name: Run tests (Ubuntu)
|
|
67
62
|
if: ${{ matrix.os == 'ubuntu-latest' }}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Prepare Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
tag:
|
|
7
|
+
description: Semver-style tag for release (e.g., v1.0.0)
|
|
8
|
+
required: true
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
create-pr:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
timeout-minutes: 5
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
pull-requests: write
|
|
17
|
+
steps:
|
|
18
|
+
- name: Check tag format
|
|
19
|
+
run: |
|
|
20
|
+
if [[ ! "${{ inputs.tag }}" =~ ^v ]]; then
|
|
21
|
+
echo "Tag must start with 'v'"
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
- uses: actions/checkout@v5
|
|
26
|
+
- uses: astral-sh/setup-uv@v7
|
|
27
|
+
with:
|
|
28
|
+
version: latest
|
|
29
|
+
enable-cache: true
|
|
30
|
+
|
|
31
|
+
- name: Set version
|
|
32
|
+
run: |
|
|
33
|
+
tag="${{ inputs.tag }}"
|
|
34
|
+
tag_no_v="${tag#v}"
|
|
35
|
+
uv version "${tag#v}"
|
|
36
|
+
|
|
37
|
+
- name: Generate GitHub App token
|
|
38
|
+
uses: actions/create-github-app-token@v2
|
|
39
|
+
id: generate-token
|
|
40
|
+
with:
|
|
41
|
+
app-id: ${{ vars.GH_APP_ID }}
|
|
42
|
+
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
|
43
|
+
|
|
44
|
+
- name: Create pull request
|
|
45
|
+
uses: peter-evans/create-pull-request@v7.0.8
|
|
46
|
+
with:
|
|
47
|
+
token: ${{ steps.generate-token.outputs.token }}
|
|
48
|
+
sign-commits: true
|
|
49
|
+
title: Release ${{ inputs.tag }}
|
|
50
|
+
branch: release/${{ inputs.tag }}
|
|
51
|
+
delete-branch: true
|
|
@@ -1,59 +1,65 @@
|
|
|
1
1
|
name: Release
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
env:
|
|
8
|
+
UV_FROZEN: 1
|
|
8
9
|
|
|
9
10
|
jobs:
|
|
10
11
|
release:
|
|
11
|
-
name: Release
|
|
12
12
|
runs-on: ubuntu-latest
|
|
13
|
+
timeout-minutes: 5
|
|
13
14
|
permissions:
|
|
14
15
|
contents: write
|
|
15
16
|
steps:
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- name: Set up uv
|
|
20
|
-
uses: astral-sh/setup-uv@v6
|
|
17
|
+
- uses: actions/checkout@v5
|
|
18
|
+
- uses: astral-sh/setup-uv@v7
|
|
21
19
|
with:
|
|
22
20
|
version: latest
|
|
23
21
|
enable-cache: true
|
|
24
22
|
|
|
25
23
|
- name: Install deps
|
|
26
|
-
run: uv sync
|
|
24
|
+
run: uv sync
|
|
27
25
|
|
|
28
26
|
- name: Build package
|
|
29
27
|
run: uv build
|
|
30
28
|
|
|
31
29
|
- name: Create release
|
|
32
|
-
uses: softprops/action-gh-release@v2
|
|
30
|
+
uses: softprops/action-gh-release@v2.4.1
|
|
33
31
|
with:
|
|
32
|
+
tag_name: ${{ github.event.release.tag_name }}
|
|
34
33
|
generate_release_notes: true
|
|
35
34
|
files: dist/*
|
|
36
35
|
|
|
36
|
+
- name: Show files
|
|
37
|
+
run: ls -l --all --recursive dist
|
|
38
|
+
|
|
37
39
|
- name: Upload release distributions
|
|
38
|
-
uses: actions/upload-artifact@
|
|
40
|
+
uses: actions/upload-artifact@v5
|
|
39
41
|
with:
|
|
40
42
|
name: release-dists
|
|
41
43
|
path: dist/
|
|
42
44
|
|
|
43
45
|
publish-pypi:
|
|
44
|
-
|
|
46
|
+
needs: release
|
|
45
47
|
runs-on: ubuntu-latest
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
environment: pypi
|
|
49
|
+
timeout-minutes: 5
|
|
48
50
|
permissions:
|
|
49
51
|
id-token: write
|
|
50
|
-
environment: pypi
|
|
51
52
|
steps:
|
|
52
|
-
- name:
|
|
53
|
-
uses: actions/download-artifact@
|
|
53
|
+
- name: Download release distributions
|
|
54
|
+
uses: actions/download-artifact@v6
|
|
54
55
|
with:
|
|
55
56
|
name: release-dists
|
|
56
57
|
path: dist/
|
|
57
58
|
|
|
59
|
+
- name: Show artifacts
|
|
60
|
+
run: ls -l --all --recursive dist
|
|
61
|
+
|
|
58
62
|
- name: Publish release distributions to PyPI
|
|
59
63
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
64
|
+
with:
|
|
65
|
+
skip-existing: true
|
|
@@ -2,16 +2,11 @@
|
|
|
2
2
|
"recommendations": [
|
|
3
3
|
"ms-python.python",
|
|
4
4
|
"ms-python.vscode-pylance",
|
|
5
|
-
"ldez.ignore-files",
|
|
6
|
-
"gruntfuggly.todo-tree",
|
|
7
|
-
"redhat.vscode-yaml",
|
|
8
|
-
"tamasfe.even-better-toml",
|
|
9
5
|
"streetsidesoftware.code-spell-checker",
|
|
10
6
|
"editorconfig.editorconfig",
|
|
11
7
|
"visualstudioexptteam.vscodeintellicode",
|
|
12
8
|
"charliermarsh.ruff",
|
|
13
9
|
"ms-python.mypy-type-checker",
|
|
14
|
-
"njpwerner.autodocstring",
|
|
15
10
|
"ms-python.debugpy"
|
|
16
11
|
]
|
|
17
12
|
}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
"editor.defaultFormatter": "charliermarsh.ruff",
|
|
7
7
|
"editor.formatOnSave": true
|
|
8
8
|
},
|
|
9
|
-
"autoDocstring.docstringFormat": "google-notypes",
|
|
10
9
|
"cSpell.words": [
|
|
11
10
|
"Deregistering",
|
|
12
11
|
"localstack",
|
|
@@ -17,13 +16,6 @@
|
|
|
17
16
|
],
|
|
18
17
|
"editor.formatOnSave": true,
|
|
19
18
|
"files.eol": "\n",
|
|
20
|
-
"files.exclude": {
|
|
21
|
-
".mypy_cache": true,
|
|
22
|
-
".pytest_cache": true,
|
|
23
|
-
".ruff_cache": true,
|
|
24
|
-
".venv": true,
|
|
25
|
-
"**/__pycache__": true
|
|
26
|
-
},
|
|
27
19
|
"files.insertFinalNewline": true,
|
|
28
20
|
"json.format.enable": true,
|
|
29
21
|
"mypy-type-checker.path": [
|
|
@@ -19,12 +19,12 @@ help: Makefile ## Show help
|
|
|
19
19
|
# =============================================================================
|
|
20
20
|
install: ## Install the app locally
|
|
21
21
|
uv python install
|
|
22
|
-
uv sync --frozen
|
|
22
|
+
uv sync --frozen
|
|
23
23
|
pre-commit install --install-hooks
|
|
24
24
|
.PHONY: install
|
|
25
25
|
|
|
26
26
|
update: ## Update deps and tools
|
|
27
|
-
uv sync --upgrade
|
|
27
|
+
uv sync --upgrade
|
|
28
28
|
pre-commit autoupdate
|
|
29
29
|
.PHONY: update
|
|
30
30
|
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aws-annoying
|
|
3
|
+
Version: 0.8.2
|
|
4
|
+
Summary: Utils to handle some annoying AWS tasks.
|
|
5
|
+
Project-URL: Homepage, https://github.com/lasuillard/aws-annoying
|
|
6
|
+
Project-URL: Repository, https://github.com/lasuillard/aws-annoying.git
|
|
7
|
+
Project-URL: Issues, https://github.com/lasuillard/aws-annoying/issues
|
|
8
|
+
Author-email: Yuchan Lee <lasuillard@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Python: <4.0,>=3.9
|
|
12
|
+
Requires-Dist: boto3<2,>=1
|
|
13
|
+
Requires-Dist: pydantic<3,>=2
|
|
14
|
+
Requires-Dist: requests<3,>=2
|
|
15
|
+
Requires-Dist: tqdm<5,>=4
|
|
16
|
+
Requires-Dist: typer<1,>=0
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# aws-annoying
|
|
20
|
+
|
|
21
|
+
[](https://opensource.org/licenses/MIT)
|
|
22
|
+
[](https://codecov.io/gh/lasuillard-s/aws-annoying)
|
|
23
|
+
[](https://pypi.org/project/aws-annoying/)
|
|
24
|
+
|
|
25
|
+
Utils to handle some annoying AWS tasks.
|
|
26
|
+
|
|
27
|
+
## ❓ About
|
|
28
|
+
|
|
29
|
+
This project aims to provide a set of utilities and examples to help with some annoying tasks when working with AWS.
|
|
30
|
+
|
|
31
|
+
Major directories of the project:
|
|
32
|
+
|
|
33
|
+
- **aws_annoying** Python package containing CLI and utility functions.
|
|
34
|
+
- **console** Utilities to help working with AWS Console.
|
|
35
|
+
- **examples** Examples of how to use the package.
|
|
36
|
+
|
|
37
|
+
## 🚀 Installation
|
|
38
|
+
|
|
39
|
+
It is recommended to use [pipx](https://pipx.pypa.io/stable/) to install `aws-annoying` CLI:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
$ pipx install aws-annoying
|
|
43
|
+
$ aws-annoying --help
|
|
44
|
+
|
|
45
|
+
Usage: aws-annoying [OPTIONS] COMMAND [ARGS]...
|
|
46
|
+
|
|
47
|
+
...
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
As the package also provides some utility functions, you can install `aws-annoying` via pip, if you are going to use those utils.
|
|
51
|
+
|
|
52
|
+
## 💡 Usage
|
|
53
|
+
|
|
54
|
+
Below are brief explanation of available commands. For more detailed information about commands, please refer to the CLI help.
|
|
55
|
+
|
|
56
|
+
### `ecs task-definition-lifecycle`
|
|
57
|
+
|
|
58
|
+
Expire and delete ECS task definitions based on criteria.
|
|
59
|
+
|
|
60
|
+
### `ecs wait-for-deployment`
|
|
61
|
+
|
|
62
|
+
Wait for ECS deployment to start, complete or fail, and stabilize.
|
|
63
|
+
|
|
64
|
+
### `load-variables`
|
|
65
|
+
|
|
66
|
+
Wrapper command to run command with variables from various AWS resources (SSM Parameter Store, Secrets Manager, etc.) injected as environment variables.
|
|
67
|
+
|
|
68
|
+
### `mfa configure`
|
|
69
|
+
|
|
70
|
+
Configure AWS profile or refresh session for MFA.
|
|
71
|
+
|
|
72
|
+
### `session-manager install`
|
|
73
|
+
|
|
74
|
+
Install AWS Session Manager plugin.
|
|
75
|
+
|
|
76
|
+
### `session-manager port-forward`
|
|
77
|
+
|
|
78
|
+
Start a port forwarding session using AWS Session Manager.
|
|
79
|
+
|
|
80
|
+
### `session-manager start`
|
|
81
|
+
|
|
82
|
+
Start new session via Session Manager.
|
|
83
|
+
|
|
84
|
+
### `session-manager stop`
|
|
85
|
+
|
|
86
|
+
Stop running port forwarding session for PID file.
|
|
87
|
+
|
|
88
|
+
## 💖 Contributing
|
|
89
|
+
|
|
90
|
+
Any feedback, suggestions or contributions are welcome! Feel free to open an issue or a pull request.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# aws-annoying
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://codecov.io/gh/lasuillard-s/aws-annoying)
|
|
5
|
+
[](https://pypi.org/project/aws-annoying/)
|
|
6
|
+
|
|
7
|
+
Utils to handle some annoying AWS tasks.
|
|
8
|
+
|
|
9
|
+
## ❓ About
|
|
10
|
+
|
|
11
|
+
This project aims to provide a set of utilities and examples to help with some annoying tasks when working with AWS.
|
|
12
|
+
|
|
13
|
+
Major directories of the project:
|
|
14
|
+
|
|
15
|
+
- **aws_annoying** Python package containing CLI and utility functions.
|
|
16
|
+
- **console** Utilities to help working with AWS Console.
|
|
17
|
+
- **examples** Examples of how to use the package.
|
|
18
|
+
|
|
19
|
+
## 🚀 Installation
|
|
20
|
+
|
|
21
|
+
It is recommended to use [pipx](https://pipx.pypa.io/stable/) to install `aws-annoying` CLI:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
$ pipx install aws-annoying
|
|
25
|
+
$ aws-annoying --help
|
|
26
|
+
|
|
27
|
+
Usage: aws-annoying [OPTIONS] COMMAND [ARGS]...
|
|
28
|
+
|
|
29
|
+
...
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
As the package also provides some utility functions, you can install `aws-annoying` via pip, if you are going to use those utils.
|
|
33
|
+
|
|
34
|
+
## 💡 Usage
|
|
35
|
+
|
|
36
|
+
Below are brief explanation of available commands. For more detailed information about commands, please refer to the CLI help.
|
|
37
|
+
|
|
38
|
+
### `ecs task-definition-lifecycle`
|
|
39
|
+
|
|
40
|
+
Expire and delete ECS task definitions based on criteria.
|
|
41
|
+
|
|
42
|
+
### `ecs wait-for-deployment`
|
|
43
|
+
|
|
44
|
+
Wait for ECS deployment to start, complete or fail, and stabilize.
|
|
45
|
+
|
|
46
|
+
### `load-variables`
|
|
47
|
+
|
|
48
|
+
Wrapper command to run command with variables from various AWS resources (SSM Parameter Store, Secrets Manager, etc.) injected as environment variables.
|
|
49
|
+
|
|
50
|
+
### `mfa configure`
|
|
51
|
+
|
|
52
|
+
Configure AWS profile or refresh session for MFA.
|
|
53
|
+
|
|
54
|
+
### `session-manager install`
|
|
55
|
+
|
|
56
|
+
Install AWS Session Manager plugin.
|
|
57
|
+
|
|
58
|
+
### `session-manager port-forward`
|
|
59
|
+
|
|
60
|
+
Start a port forwarding session using AWS Session Manager.
|
|
61
|
+
|
|
62
|
+
### `session-manager start`
|
|
63
|
+
|
|
64
|
+
Start new session via Session Manager.
|
|
65
|
+
|
|
66
|
+
### `session-manager stop`
|
|
67
|
+
|
|
68
|
+
Stop running port forwarding session for PID file.
|
|
69
|
+
|
|
70
|
+
## 💖 Contributing
|
|
71
|
+
|
|
72
|
+
Any feedback, suggestions or contributions are welcome! Feel free to open an issue or a pull request.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "aws-annoying"
|
|
3
3
|
description = "Utils to handle some annoying AWS tasks."
|
|
4
|
-
version = "0.8.
|
|
4
|
+
version = "0.8.2"
|
|
5
5
|
authors = [{ name = "Yuchan Lee", email = "lasuillard@gmail.com" }]
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
license = "MIT"
|
|
@@ -17,7 +17,7 @@ dependencies = [
|
|
|
17
17
|
[project.scripts]
|
|
18
18
|
"aws-annoying" = "aws_annoying.cli.main:entrypoint"
|
|
19
19
|
|
|
20
|
-
[
|
|
20
|
+
[dependency-groups]
|
|
21
21
|
dev = [
|
|
22
22
|
"boto3-stubs[ecs,secretsmanager,ssm,sts,ec2]>=1.37.1",
|
|
23
23
|
"mypy>=1.15,<1.17",
|
|
@@ -26,12 +26,12 @@ dev = [
|
|
|
26
26
|
]
|
|
27
27
|
test = [
|
|
28
28
|
"coverage>=7.6,<7.9",
|
|
29
|
-
"moto[secretsmanager,server,ssm,ecs]~=5.1.
|
|
30
|
-
"pytest
|
|
29
|
+
"moto[secretsmanager,server,ssm,ecs]~=5.1.8",
|
|
30
|
+
"pytest>=8.3.2,<8.5.0",
|
|
31
31
|
"pytest-cov>=6.0,<6.2",
|
|
32
32
|
"pytest-env~=1.1.1",
|
|
33
33
|
"pytest-snapshot>=0.9.0",
|
|
34
|
-
"pytest-sugar
|
|
34
|
+
"pytest-sugar>=1.0,<1.2",
|
|
35
35
|
"pytest-xdist>=3.6.1",
|
|
36
36
|
"testcontainers[localstack]>=4.9.2",
|
|
37
37
|
"toml>=0.10.2",
|
|
@@ -47,6 +47,9 @@ Issues = "https://github.com/lasuillard/aws-annoying/issues"
|
|
|
47
47
|
requires = ["hatchling"]
|
|
48
48
|
build-backend = "hatchling.build"
|
|
49
49
|
|
|
50
|
+
[tool.uv]
|
|
51
|
+
default-groups = ["dev", "test"]
|
|
52
|
+
|
|
50
53
|
[tool.hatch.build.targets.wheel]
|
|
51
54
|
packages = ["aws_annoying"]
|
|
52
55
|
|
aws_annoying-0.8.2/tests/cli/ecs/snapshots/test_task_definition_lifecycle/test_delete/stdout.txt
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
⚠️ Deregistering 15 task definitions...
|
|
2
|
+
⚠️ Deregistered task definition 'my-task:1'
|
|
3
|
+
⚠️ Deregistered task definition 'my-task:2'
|
|
4
|
+
⚠️ Deregistered task definition 'my-task:3'
|
|
5
|
+
⚠️ Deregistered task definition 'my-task:4'
|
|
6
|
+
⚠️ Deregistered task definition 'my-task:5'
|
|
7
|
+
⚠️ Deregistered task definition 'my-task:6'
|
|
8
|
+
⚠️ Deregistered task definition 'my-task:7'
|
|
9
|
+
⚠️ Deregistered task definition 'my-task:8'
|
|
10
|
+
⚠️ Deregistered task definition 'my-task:9'
|
|
11
|
+
⚠️ Deregistered task definition 'my-task:10'
|
|
12
|
+
⚠️ Deregistered task definition 'my-task:11'
|
|
13
|
+
⚠️ Deregistered task definition 'my-task:12'
|
|
14
|
+
⚠️ Deregistered task definition 'my-task:13'
|
|
15
|
+
⚠️ Deregistered task definition 'my-task:14'
|
|
16
|
+
⚠️ Deregistered task definition 'my-task:15'
|
|
17
|
+
⚠️ Deleting 15 task definitions in chunks of size 10...
|
|
18
|
+
⚠️ Deleted 10 task definitions in 0-th batch.
|
|
19
|
+
⚠️ Deleted 5 task definitions in 1-th batch.
|
|
@@ -50,28 +50,70 @@ def test_basic(snapshot: Snapshot) -> None:
|
|
|
50
50
|
family,
|
|
51
51
|
"--keep-latest",
|
|
52
52
|
str(keep_latest),
|
|
53
|
-
# ? `delete_task_definitions` not implemented in moto yet
|
|
54
|
-
# "--delete",
|
|
55
53
|
],
|
|
56
54
|
)
|
|
57
|
-
task_definitions = [
|
|
58
|
-
ecs.describe_task_definition(taskDefinition=f"{family}:{i}")["taskDefinition"]
|
|
59
|
-
for i in range(1, num_task_defs + 1)
|
|
60
|
-
]
|
|
61
55
|
|
|
62
56
|
# Assert
|
|
63
57
|
assert result.exit_code == 0
|
|
64
58
|
snapshot.assert_match(normalize_console_output(result.stdout), "stdout.txt")
|
|
65
59
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
60
|
+
active_task_definitions = ecs.list_task_definitions(familyPrefix=family, status="ACTIVE")
|
|
61
|
+
assert active_task_definitions["taskDefinitionArns"] == [
|
|
62
|
+
f"arn:aws:ecs:us-east-1:123456789012:task-definition/{family}:{i}" for i in range(16, 26)
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
inactive_task_definitions = ecs.list_task_definitions(familyPrefix=family, status="INACTIVE")
|
|
66
|
+
assert inactive_task_definitions["taskDefinitionArns"] == [
|
|
67
|
+
f"arn:aws:ecs:us-east-1:123456789012:task-definition/{family}:{i}" for i in range(1, 16)
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def test_delete(snapshot: Snapshot) -> None:
|
|
72
|
+
"""The command should deregister the oldest task definitions."""
|
|
73
|
+
# Arrange
|
|
74
|
+
ecs = boto3.client("ecs")
|
|
75
|
+
family = "my-task"
|
|
76
|
+
num_task_defs = 25
|
|
77
|
+
for i in range(1, num_task_defs + 1):
|
|
78
|
+
ecs.register_task_definition(
|
|
79
|
+
family=family,
|
|
80
|
+
containerDefinitions=[
|
|
81
|
+
{
|
|
82
|
+
"name": "my-container",
|
|
83
|
+
"image": f"my-image:{i}",
|
|
84
|
+
"cpu": 0,
|
|
85
|
+
"memory": 0,
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# Act
|
|
91
|
+
keep_latest = 10
|
|
92
|
+
result = runner.invoke(
|
|
93
|
+
app,
|
|
94
|
+
[
|
|
95
|
+
"ecs",
|
|
96
|
+
"task-definition-lifecycle",
|
|
97
|
+
"--family",
|
|
98
|
+
family,
|
|
99
|
+
"--keep-latest",
|
|
100
|
+
str(keep_latest),
|
|
101
|
+
"--delete",
|
|
102
|
+
],
|
|
73
103
|
)
|
|
74
104
|
|
|
105
|
+
# Assert
|
|
106
|
+
assert result.exit_code == 0
|
|
107
|
+
snapshot.assert_match(normalize_console_output(result.stdout), "stdout.txt")
|
|
108
|
+
|
|
109
|
+
active_task_definitions = ecs.list_task_definitions(familyPrefix=family, status="ACTIVE")
|
|
110
|
+
assert active_task_definitions["taskDefinitionArns"] == [
|
|
111
|
+
f"arn:aws:ecs:us-east-1:123456789012:task-definition/{family}:{i}" for i in range(16, 26)
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
inactive_task_definitions = ecs.list_task_definitions(familyPrefix=family, status="INACTIVE")
|
|
115
|
+
assert inactive_task_definitions["taskDefinitionArns"] == []
|
|
116
|
+
|
|
75
117
|
|
|
76
118
|
def test_dry_run(snapshot: Snapshot) -> None:
|
|
77
119
|
"""If `--dry-run` option given, the command should not perform any changes."""
|
|
@@ -107,16 +149,13 @@ def test_dry_run(snapshot: Snapshot) -> None:
|
|
|
107
149
|
"--delete",
|
|
108
150
|
],
|
|
109
151
|
)
|
|
110
|
-
task_definitions = [
|
|
111
|
-
ecs.describe_task_definition(taskDefinition=f"{family}:{i}")["taskDefinition"]
|
|
112
|
-
for i in range(1, num_task_defs + 1)
|
|
113
|
-
]
|
|
114
152
|
|
|
115
153
|
# Assert
|
|
116
154
|
assert result.exit_code == 0
|
|
117
155
|
snapshot.assert_match(normalize_console_output(result.stdout), "stdout.txt")
|
|
118
156
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
157
|
+
active_task_definitions = ecs.list_task_definitions(familyPrefix=family, status="ACTIVE")
|
|
158
|
+
assert len(active_task_definitions["taskDefinitionArns"]) == 25
|
|
159
|
+
|
|
160
|
+
inactive_task_definitions = ecs.list_task_definitions(familyPrefix=family, status="INACTIVE")
|
|
161
|
+
assert len(inactive_task_definitions["taskDefinitionArns"]) == 0
|
|
@@ -221,7 +221,8 @@ def test_unsupported_resource(snapshot: Snapshot) -> None:
|
|
|
221
221
|
@pytest.mark.parametrize(
|
|
222
222
|
argnames="arn",
|
|
223
223
|
argvalues=[
|
|
224
|
-
# TODO(lasuillard):
|
|
224
|
+
# TODO(lasuillard): `batch_get_secret_value` does not raise an error if secret does not exist.
|
|
225
|
+
# Consider implementing new flag for strict mode (e.g. `--if-not-exists={error,ignore}`)
|
|
225
226
|
# "arn:aws:secretsmanager:us-east-1:123456789012:secret:unknown-secret", # noqa: ERA001
|
|
226
227
|
"arn:aws:ssm:us-east-1:123456789012:parameter/unknown-parameter",
|
|
227
228
|
],
|