Skip to content

Commit

Permalink
Merge pull request #651 from linode/dev
Browse files Browse the repository at this point in the history
v5.52.0
  • Loading branch information
jriddle-linode authored Oct 1, 2024
2 parents e99d833 + 524fa64 commit 700b935
Show file tree
Hide file tree
Showing 38 changed files with 789 additions and 145 deletions.
68 changes: 67 additions & 1 deletion .github/workflows/e2e-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ on:
- dev

jobs:
integration-tests:
integration_tests:
name: Run integration tests on Ubuntu
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' && inputs.sha != '' || github.event_name == 'push' || github.event_name == 'pull_request'
Expand Down Expand Up @@ -167,3 +167,69 @@ jobs:
conclusion: process.env.conclusion
});
return result;
notify-slack:
runs-on: ubuntu-latest
needs: [integration_tests]
if: always() && github.repository == 'linode/linode-cli' # Run even if integration tests fail and only on main repository

steps:
- name: Notify Slack
uses: slackapi/[email protected]
with:
channel-id: ${{ secrets.SLACK_CHANNEL_ID }}
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":rocket: *${{ github.workflow }} Completed in: ${{ github.repository }}* :white_check_mark:"
}
},
{
"type": "divider"
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Build Result:*\n${{ steps.integration_tests.outcome == 'success' && ':large_green_circle: Build Passed' || ':red_circle: Build Failed' }}"
},
{
"type": "mrkdwn",
"text": "*Branch:*\n`${{ github.ref_name }}`"
}
]
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Commit Hash:*\n<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>"
},
{
"type": "mrkdwn",
"text": "*Run URL:*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run Details>"
}
]
},
{
"type": "divider"
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "Triggered by: :bust_in_silhouette: `${{ github.actor }}`"
}
]
}
]
}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
75 changes: 73 additions & 2 deletions .github/workflows/nightly-smoke-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,25 @@ on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
inputs:
sha:
description: 'Commit SHA to test'
required: false
default: ''
type: string

jobs:
smoke_tests:
if: github.repository == 'linode/linode-cli' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
ref: dev
fetch-depth: 0
submodules: 'recursive'
ref: ${{ github.event.inputs.sha || github.ref }}

- name: Set up Python
uses: actions/setup-python@v4
Expand All @@ -29,7 +38,69 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Run smoke tests
id: smoke_tests
run: |
make smoketest
env:
LINODE_CLI_TOKEN: ${{ secrets.LINODE_TOKEN }}

- name: Notify Slack
if: always() && github.repository == 'linode/linode-cli' # Run even if integration tests fail and only on main repository
uses: slackapi/[email protected]
with:
channel-id: ${{ secrets.SLACK_CHANNEL_ID }}
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":rocket: *${{ github.workflow }} Completed in: ${{ github.repository }}* :white_check_mark:"
}
},
{
"type": "divider"
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Build Result:*\n${{ steps.smoke_tests.outcome == 'success' && ':large_green_circle: Build Passed' || ':red_circle: Build Failed' }}"
},
{
"type": "mrkdwn",
"text": "*Branch:*\n`${{ github.ref_name }}`"
}
]
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Commit Hash:*\n<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>"
},
{
"type": "mrkdwn",
"text": "*Run URL:*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run Details>"
}
]
},
{
"type": "divider"
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "Triggered by: :bust_in_silhouette: `${{ github.actor }}`"
}
]
}
]
}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
3 changes: 2 additions & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,8 @@ disable=raw-checker-failed,
duplicate-code,
too-few-public-methods,
too-many-instance-attributes,
use-symbolic-message-instead
use-symbolic-message-instead,
too-many-positional-arguments

# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
Expand Down
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,12 @@ clean:
rm -rf dist linode_cli.egg-info build

.PHONY: testunit
testunit: export LINODE_CLI_TEST_MODE = 1
testunit:
pytest -v tests/unit
@mkdir -p /tmp/linode/.config
@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

.PHONY: testint
testint:
Expand Down
19 changes: 2 additions & 17 deletions linodecli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from .help_pages import (
HELP_TOPICS,
print_help_action,
print_help_command_actions,
print_help_commands,
print_help_default,
print_help_env_vars,
Expand Down Expand Up @@ -224,23 +225,7 @@ def main(): # pylint: disable=too-many-branches,too-many-statements
and parsed.action is None
and parsed.command in cli.ops
):
print(f"linode-cli {parsed.command} [ACTION]")
print()
print("Available actions: ")

content = [
[", ".join([action, *op.action_aliases]), op.summary]
for action, op in cli.ops[parsed.command].items()
]

table = Table(
Column(header="action", no_wrap=True),
Column(header="summary", style="cyan"),
)
for row in content:
table.add_row(*row)

rprint(table)
print_help_command_actions(cli.ops, parsed.command)
sys.exit(ExitCodes.SUCCESS)

if parsed.command is not None and parsed.action is not None:
Expand Down
7 changes: 5 additions & 2 deletions linodecli/api_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import itertools
import json
import os
import sys
import time
from typing import Any, Iterable, List, Optional
Expand Down Expand Up @@ -373,8 +374,10 @@ def _attempt_warn_old_version(ctx, result):
"with --suppress-warnings",
file=sys.stderr,
)

if new_version_exists:
suppress_version_warning = ctx.config.get_bool(
"suppress-version-warning"
) or os.getenv("LINODE_CLI_SUPPRESS_VERSION_WARNING")
if new_version_exists and not suppress_version_warning:
print(
f"The API responded with version {spec_version}, which is newer than "
f"the CLI's version of {ctx.spec_version}. Please update the CLI to get "
Expand Down
27 changes: 27 additions & 0 deletions linodecli/configuration/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,30 @@ def get_value(self, key: str) -> Optional[Any]:

return self.config.get(username, key)

def get_bool(self, key: str) -> bool:
"""
Retrieves and returns an existing config boolean for the current user. This
is intended for plugins to use instead of having to deal with figuring out
who the current user is when accessing their config.
.. warning::
Plugins _MUST NOT_ set values for the user's config except through
``plugin_set_value`` below.
:param key: The key to look up.
:type key: str
:returns: The boolean for that key, or False if the key doesn't exist for the
current user.
:rtype: any
"""
username = self.username or self.default_username()

if not self.config.has_option(username, key):
return False

return self.config.getboolean(username, key)

# plugin methods - these are intended for plugins to utilize to store their
# own persistent config information
def plugin_set_value(self, key: str, value: Any):
Expand Down Expand Up @@ -449,6 +473,9 @@ def configure(
if _bool_input("Configure a custom API target?", default=False):
self._configure_api_target(config)

if _bool_input("Suppress API Version Warnings?", default=False):
config["suppress-version-warning"] = "true"

# save off the new configuration
if username != "DEFAULT" and not self.config.has_section(username):
self.config.add_section(username)
Expand Down
35 changes: 33 additions & 2 deletions linodecli/help_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
help pages.
"""

import sys
import textwrap
from collections import defaultdict
from typing import List, Optional
from typing import Dict, List, Optional

from rich import box
from rich import print as rprint
from rich.console import Console
from rich.padding import Padding
from rich.table import Table
from rich.table import Column, Table
from rich.text import Text

from linodecli import plugins
Expand Down Expand Up @@ -140,6 +141,36 @@ def print_help_default():
)


def print_help_command_actions(
ops: Dict[str, Dict[str, OpenAPIOperation]],
command: Optional[str],
file=sys.stdout,
):
"""
Prints the help page for a single command, including all actions
under the given command.
:param ops: A dictionary mapping CLI commands -> actions -> operations.
:param command: The command to print the help page for.
"""

print(f"linode-cli {command} [ACTION]\n\nAvailable actions: ", file=file)

content = [
[", ".join([action, *op.action_aliases]), op.summary]
for action, op in sorted(ops[command].items(), key=lambda v: v[0])
]

table = Table(
Column(header="action", no_wrap=True),
Column(header="summary", style="cyan"),
)
for row in content:
table.add_row(*row)

rprint(table, file=file)


def print_help_action(
cli: "CLI", command: Optional[str], action: Optional[str]
):
Expand Down
Loading

0 comments on commit 700b935

Please sign in to comment.