Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v5.55.0 #683

Merged
merged 17 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
183646f
test: fix unit tests caused by error output being routed to stderr in…
ykim-akamai Oct 31, 2024
e7a73f2
Enable dependabot checking updates for GitHub Actions (#667)
zliang-akamai Oct 31, 2024
3604ff4
build(deps): bump docker/setup-qemu-action from 2.2.0 to 3.2.0 (#670)
dependabot[bot] Nov 1, 2024
89e47dd
build(deps): bump docker/login-action from 2.2.0 to 3.3.0 (#673)
dependabot[bot] Nov 1, 2024
bb5e7a2
build(deps): bump crazy-max/ghaction-github-labeler from 5.0.0 to 5.1…
dependabot[bot] Nov 1, 2024
b0af0f9
build(deps): bump WyriHaximus/github-action-get-previous-tag from 1.3…
dependabot[bot] Nov 1, 2024
360aec2
build(deps): bump tibdex/github-app-token from 1.8.0 to 2.1.0 (#669)
dependabot[bot] Nov 1, 2024
12b8f25
Fix issue displaying missing action errors when `--help` is specified…
lgarber-akamai Nov 6, 2024
f5d1092
Override placement group view to display members (#675)
yec-akamai Nov 12, 2024
ec73e44
Account for edge case where apiVersion param has no default (#678)
lgarber-akamai Nov 14, 2024
590d99a
test: Improve flaky reboot instance test; Implement retry for execute…
ykim-akamai Nov 14, 2024
3ea0dd6
test: Allow integration and unit tests to run against EOL or desired …
ykim-akamai Nov 14, 2024
41aee24
Improve parsing & formatting of help page descriptions (#680)
lgarber-akamai Nov 19, 2024
7a77276
Exclude parameter values from API request bodies (#681)
lgarber-akamai Nov 19, 2024
03045d4
test: Add test coverage for Disk Encryption, Config, and Disk (#677)
ykim-akamai Nov 19, 2024
89fc86e
test: Update SSH and VLAN test cases (#682)
ykim-akamai Nov 20, 2024
5bab33a
Allow overriding spec when manually triggering E2E test workflow #664…
vshanthe Nov 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ updates:
directory: "/" # Location of package manifests
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
21 changes: 11 additions & 10 deletions .github/workflows/e2e-suite-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@ on:
pull_request:
workflow_dispatch:
inputs:
test_path:
description: "The path from 'test/integration' to the target to be tested, e.g. 'cli'"
module:
description: "The module from 'test/integration' to the target to be tested, e.g. 'cli, domains, events, etc'"
required: false
run_long_tests:
description: "Select True to run long tests, e.g. database, rebuild, etc"
required: false
type: choice
options:
- "True"
- "False"
default: "False"
sha:
description: 'The hash value of the commit.'
required: true
Expand All @@ -21,13 +29,6 @@ jobs:
github.event_name == 'workflow_dispatch' && inputs.sha != ''

steps:
- uses: actions-ecosystem/action-regex-match@v2
id: validate-tests
with:
text: ${{ inputs.test_path }}
regex: '[^a-z0-9-:.\/_]' # Tests validation
flags: gi

# Check out merge commit
- name: Checkout PR
uses: actions/checkout@v4
Expand Down Expand Up @@ -72,7 +73,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- run: make INTEGRATION_TEST_PATH="${{ inputs.test_path }}" testint
- run: make MODULE="${{ inputs.module }}" RUN_LONG_TESTS="${{ inputs.run_long_tests }}" testint
env:
LINODE_CLI_TOKEN: ${{ secrets.LINODE_TOKEN_2 }}

Expand Down
37 changes: 33 additions & 4 deletions .github/workflows/e2e-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,47 @@ on:
module:
description: "The module from 'test/integration' to the target to be tested, e.g. 'cli, domains, events, etc'"
required: false
run_long_tests:
description: "Select True to run long tests, e.g. database, rebuild, etc"
required: false
type: choice
options:
- "True"
- "False"
default: "False"
sha:
description: 'The hash value of the commit.'
required: true
default: ''
pull_request_number:
description: 'The number of the PR. Ensure sha value is provided'
required: false
openapi_spec_url:
description: 'URL of the OpenAPI spec to use for the tests'
required: false
default: ''
python-version:
description: 'Specify Python version to use'
required: false
run-eol-python-version:
description: 'Run EOL python version?'
required: false
default: 'false'
type: choice
options:
- 'true'
- 'false'

push:
branches:
- main
- dev

env:
DEFAULT_PYTHON_VERSION: "3.10"
EOL_PYTHON_VERSION: "3.8"
EXIT_STATUS: 0

jobs:
integration_tests:
name: Run integration tests on Ubuntu
Expand Down Expand Up @@ -74,7 +103,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
python-version: ${{ inputs.run-eol-python-version == 'true' && env.EOL_PYTHON_VERSION || inputs.python-version || env.DEFAULT_PYTHON_VERSION }}

- name: Install Python dependencies and update cert
run: |
Expand All @@ -83,7 +112,7 @@ jobs:
pip install .[obj,dev]

- name: Install Package
run: make install
run: make install SPEC="${{ inputs.OPENAPI_SPEC_URL }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand All @@ -95,7 +124,7 @@ jobs:
run: |
timestamp=$(date +'%Y%m%d%H%M')
report_filename="${timestamp}_cli_test_report.xml"
make testint TEST_ARGS="--junitxml=${report_filename}" MODULE="${{ inputs.module }}"
make testint TEST_ARGS="--junitxml=${report_filename}" MODULE="${{ inputs.module }}" RUN_LONG_TESTS="${{ inputs.run_long_tests }}"
env:
LINODE_CLI_TOKEN: ${{ env.LINODE_CLI_TOKEN }}

Expand Down Expand Up @@ -272,4 +301,4 @@ jobs:
]
}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
uses: actions/checkout@v4
-
name: Run Labeler
uses: crazy-max/ghaction-github-labeler@de749cf181958193cb7debf1a9c5bb28922f3e1b
uses: crazy-max/ghaction-github-labeler@b54af0c25861143e7c8813d7cbbf46d2c341680c
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
yaml-file: .github/labels.yml
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish-oci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ jobs:
run: make requirements

- name: Set up QEMU
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # pin@v2.2.0
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # pin@v3.2.0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@ecf95283f03858871ff00b787d79c419715afc34 # [email protected]

- name: Login to Docker Hub
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # pin@v2.2.0
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # pin@v3.3.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/remote-release-trigger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
steps:
- name: Generate App Installation Token
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 # pin@v1
uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # pin@v1
with:
app_id: ${{ secrets.CLI_RELEASE_APP_ID }}
private_key: ${{ secrets.CLI_RELEASE_PRIVATE_KEY }}
Expand All @@ -23,7 +23,7 @@ jobs:

- name: Get previous tag
id: previoustag
uses: WyriHaximus/github-action-get-previous-tag@385a2a0b6abf6c2efeb95adfac83d96d6f968e0c # pin@v1
uses: WyriHaximus/github-action-get-previous-tag@04e8485ecb6487243907e330d522ff60f02283ce # pin@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
jobs:
unit-tests-on-ubuntu:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '3.9','3.10','3.11', '3.12' ]
steps:
- name: Clone Repository
uses: actions/checkout@v3
Expand All @@ -14,9 +17,9 @@ jobs:
run: sudo apt-get update -y

- name: Setup Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.x'
python-version: ${{ matrix.python-version }}

- name: Install Python wheel
run: pip install wheel boto3
Expand Down
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ testunit:
@orig_xdg_config_home=$${XDG_CONFIG_HOME:-}; \
export LINODE_CLI_TEST_MODE=1 XDG_CONFIG_HOME=/tmp/linode/.config; \
pytest -v tests/unit; \
export XDG_CONFIG_HOME=$$orig_xdg_config_home
exit_code=$$?; \
export XDG_CONFIG_HOME=$$orig_xdg_config_home; \
exit $$exit_code

.PHONY: testint
testint:
Expand Down
1 change: 1 addition & 0 deletions linodecli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,4 +230,5 @@ def main(): # pylint: disable=too-many-branches,too-many-statements
if parsed.help:
print_help_action(cli, parsed.command, parsed.action)
sys.exit(ExitCodes.SUCCESS)

cli.handle_command(parsed.command, parsed.action, args)
4 changes: 3 additions & 1 deletion linodecli/api_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,13 @@ def _build_request_body(ctx, operation, parsed_args) -> Optional[str]:
if ctx.defaults:
parsed_args = ctx.config.update(parsed_args, operation.allowed_defaults)

param_names = {param.name for param in operation.params}

expanded_json = {}

# expand paths
for k, v in vars(parsed_args).items():
if v is None:
if v is None or k in param_names:
continue

cur = expanded_json
Expand Down
31 changes: 28 additions & 3 deletions linodecli/baked/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import openapi3.paths
from openapi3.paths import Operation, Parameter

from linodecli.baked.parsing import simplify_description
from linodecli.baked.request import OpenAPIFilteringRequest, OpenAPIRequest
from linodecli.baked.response import OpenAPIResponse
from linodecli.exit_codes import ExitCodes
Expand Down Expand Up @@ -356,8 +357,12 @@ def __init__(
self.action_aliases = {}
self.action = action

self.summary = operation.summary
self.description = operation.description.split(".")[0]
# Ensure the summary has punctuation
self.summary = operation.summary.rstrip(".") + "."

self.description_rich, self.description = simplify_description(
operation.description or ""
)

# The apiVersion attribute should not be specified as a positional argument
self.params = [
Expand All @@ -366,6 +371,20 @@ def __init__(
if param.name not in {"apiVersion"}
]

# Validation to ensure no conflicting arguments & param names are found.
# This is necessary because arguments and parameters are both parsed into the
# same result namespace by argparse.
if self.request is not None and hasattr(self.request, "attrs"):
param_names = {param.name for param in self.params}

for attr in self.request.attrs:
if attr not in param_names:
continue

raise ValueError(
f"Attribute {attr.name} conflicts with parameter of the same name"
)

(
self.url_base,
self.url_path,
Expand Down Expand Up @@ -447,7 +466,13 @@ def _resolve_api_version(
None,
)
if version_param is not None:
return version_param.schema.default
schema = version_param.schema

if schema.default:
return schema.default

if schema.enum and len(schema.enum) > 0:
return schema.enum[0]

return None

Expand Down
54 changes: 31 additions & 23 deletions linodecli/baked/parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
import functools
import re
from html import unescape
from typing import List, Tuple
from typing import List, Optional, Tuple

# Sentence delimiter, split on a period followed by any type of
# whitespace (space, new line, tab, etc.)
REGEX_SENTENCE_DELIMITER = re.compile(r"\W(?:\s|$)")
REGEX_SENTENCE_DELIMITER = re.compile(r"\.(?:\s|$)", flags=re.M)

# Matches on pattern __prefix__ at the beginning of a description
# or after a comma
REGEX_TECHDOCS_PREFIX = re.compile(r"(?:, |\A)__([\w-]+)__")
REGEX_TECHDOCS_PREFIX = re.compile(r"(?:, |\A)__([^_]+)__")

# Matches on pattern [link title](https://.../)
REGEX_MARKDOWN_LINK = re.compile(r"\[(?P<text>.*?)]\((?P<link>.*?)\)")
Expand Down Expand Up @@ -121,23 +121,35 @@ def get_short_description(description: str) -> str:
:rtype: set
"""

target_lines = description.splitlines()
relevant_lines = None

for i, line in enumerate(target_lines):
def __simplify(sentence: str) -> Optional[str]:
# Edge case for descriptions starting with a note
if line.lower().startswith("__note__"):
continue
if sentence.lower().startswith("__note__"):
return None

sentence = strip_techdocs_prefixes(sentence)

relevant_lines = target_lines[i:]
break
# Check that the sentence still has content after stripping prefixes
if len(sentence) < 2:
return None

if relevant_lines is None:
return sentence + "."

# Find the first relevant sentence
result = next(
simplified
for simplified in iter(
__simplify(sentence)
for sentence in REGEX_SENTENCE_DELIMITER.split(description)
)
if simplified is not None
)

if result is None:
raise ValueError(
f"description does not contain any relevant lines: {description}",
)

return REGEX_SENTENCE_DELIMITER.split("\n".join(relevant_lines), 1)[0] + "."
return result


def strip_techdocs_prefixes(description: str) -> str:
Expand All @@ -150,14 +162,10 @@ def strip_techdocs_prefixes(description: str) -> str:
:returns: The stripped description
:rtype: str
"""
result_description = REGEX_TECHDOCS_PREFIX.sub(
"", description.lstrip()
).lstrip()

return result_description
return REGEX_TECHDOCS_PREFIX.sub("", description.lstrip()).lstrip()


def process_arg_description(description: str) -> Tuple[str, str]:
def simplify_description(description: str) -> Tuple[str, str]:
"""
Processes the given raw request argument description into one suitable
for help pages, etc.
Expand All @@ -173,12 +181,12 @@ def process_arg_description(description: str) -> Tuple[str, str]:
return "", ""

result = get_short_description(description)
result = strip_techdocs_prefixes(result)
result = result.replace("\n", " ").replace("\r", " ")

description, links = extract_markdown_links(result)
# NOTE: Links should only be separated from Rich Markdown links
result_no_links, links = extract_markdown_links(result)

if len(links) > 0:
description += f" See: {'; '.join(links)}"
result_no_links += f" See: {'; '.join(links)}"

return unescape(markdown_to_rich_markup(description)), unescape(description)
return unescape(markdown_to_rich_markup(result_no_links)), unescape(result)
Loading
Loading