Skip to content
Merged
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,35 @@ on:
jobs:
lint:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
steps:
# Enforce TPT-1234: prefix on PR titles, with the following exemptions:
# - PRs labeled 'dependencies' (e.g. Dependabot PRs)
# - PRs labeled 'hotfix' (urgent fixes that may not have a ticket)
# - PRs labeled 'community-contribution' (external contributors without TPT tickets)
# - PRs labeled 'ignore-for-release' (release PRs that don't need a ticket prefix)
- name: Validate PR Title
if: github.event_name == 'pull_request'
uses: amannn/action-semantic-pull-request@v6
with:
types: |
TPT-\d+
requireScope: false
# Override the default header pattern to allow hyphens and digits in the type
# (e.g. "TPT-4298: Description"). The default pattern only matches word
# characters (\w) which excludes hyphens.
headerPattern: '^([\w-]+):\s?(.*)$'
headerPatternCorrespondence: type, subject
ignoreLabels: |
dependencies
hotfix
community-contribution
ignore-for-release
env:
GITHUB_TOKEN: ${{ github.token }}

- name: checkout repo
uses: actions/checkout@v6

Expand Down
37 changes: 37 additions & 0 deletions .github/workflows/clean-release-notes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Clean Release Notes

on:
release:
types: [published]

jobs:
clean-release-notes:
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- name: Remove ticket prefixes from release notes
uses: actions/github-script@v8
with:
script: |
const release = context.payload.release;

let body = release.body;

if (!body) {
console.log("Release body empty, nothing to clean.");
return;
}

// Remove ticket prefixes like "TPT-1234: " or "TPT-1234:"
body = body.replace(/TPT-\d+:\s*/g, '');

await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: release.id,
body: body
});

console.log("Release notes cleaned.");
6 changes: 3 additions & 3 deletions .github/workflows/e2e-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ jobs:

- name: Upload Test Report as Artifact
if: always()
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: test-report-file
if-no-files-found: ignore
Expand Down Expand Up @@ -241,7 +241,7 @@ jobs:
steps:
- name: Notify Slack
id: main_message
uses: slackapi/slack-github-action@v2.1.1
uses: slackapi/slack-github-action@v3
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
Expand Down Expand Up @@ -273,7 +273,7 @@ jobs:

- name: Test summary thread
if: success()
uses: slackapi/slack-github-action@v2.1.1
uses: slackapi/slack-github-action@v3
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly-smoke-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:

- name: Notify Slack
if: always() && github.repository == 'linode/linode_api4-python'
uses: slackapi/slack-github-action@v2.1.1
uses: slackapi/slack-github-action@v3
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-notify-slack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
steps:
- name: Notify Slack - Main Message
id: main_message
uses: slackapi/slack-github-action@v2.1.1
uses: slackapi/slack-github-action@v3
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
Expand Down
1 change: 0 additions & 1 deletion linode_api4/groups/linode.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ def instance_create(
:param firewall: The firewall to attach this Linode to.
:type firewall: int or Firewall
:param disk_encryption: The disk encryption policy for this Linode.
NOTE: Disk encryption may not currently be available to all users.
:type disk_encryption: InstanceDiskEncryptionType or str
:param interfaces: An array of Network Interfaces to add to this Linode’s Configuration Profile.
At least one and up to three Interface objects can exist in this array.
Expand Down
56 changes: 52 additions & 4 deletions linode_api4/groups/monitor.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from typing import Any, Optional
from typing import Any, Optional, Union

from linode_api4 import PaginatedList
from linode_api4.errors import UnexpectedResponseError
from linode_api4.groups import Group
from linode_api4.objects import (
AlertChannel,
AlertDefinition,
AlertDefinitionEntity,
AlertScope,
MonitorDashboard,
MonitorMetricsDefinition,
MonitorService,
Expand Down Expand Up @@ -202,7 +204,7 @@ def alert_channels(self, *filters) -> PaginatedList:

.. note:: This endpoint is in beta and requires using the v4beta base URL.

API Documentation: https://techdocs.akamai.com/linode-api/reference/get-alert-channels
API Documentation: https://techdocs.akamai.com/linode-api/reference/get-notification-channels

:param filters: Optional filter expressions to apply to the collection.
See :doc:`Filtering Collections</linode_api4/objects/filtering>` for details.
Expand All @@ -221,6 +223,8 @@ def create_alert_definition(
trigger_conditions: dict,
entity_ids: Optional[list[str]] = None,
description: Optional[str] = None,
scope: Optional[Union[AlertScope, str]] = None,
regions: Optional[list[str]] = None,
) -> AlertDefinition:
"""
Create a new alert definition for a given service type.
Expand Down Expand Up @@ -252,6 +256,10 @@ def create_alert_definition(
:type entity_ids: Optional[list[str]]
:param description: (Optional) Longer description for the alert definition.
:type description: Optional[str]
:param scope: (Optional) Alert scope (for example: `account`, `entity`, or `region`). Defaults to `entity`.
:type scope: Optional[Union[AlertScope, str]]
:param regions: (Optional) Regions to monitor.
:type regions: Optional[list[str]]

:returns: The newly created :class:`AlertDefinition`.
:rtype: AlertDefinition
Expand All @@ -267,10 +275,15 @@ def create_alert_definition(
"rule_criteria": rule_criteria,
"trigger_conditions": trigger_conditions,
}
if description is not None:
params["description"] = description

if entity_ids is not None:
params["entity_ids"] = entity_ids
if description is not None:
params["description"] = description
if scope is not None:
params["scope"] = scope
if regions is not None:
params["regions"] = regions

# API will validate service_type and return an error if missing
result = self.client.post(
Expand All @@ -284,3 +297,38 @@ def create_alert_definition(
)

return AlertDefinition(self.client, result["id"], service_type, result)

def alert_definition_entities(
self,
service_type: str,
id: int,
*filters,
) -> PaginatedList:
"""
List entities associated with a specific alert definition.

This endpoint supports pagination fields (`page`, `page_size`) in the API.

.. note:: This endpoint is in beta and requires using the v4beta base URL.

API Documentation: TODO

:param service_type: Service type for the alert definition (e.g. `dbaas`).
:type service_type: str
:param id: Alert definition identifier.
:type id: int
:param filters: Optional filter expressions to apply to the collection.
See :doc:`Filtering Collections</linode_api4/objects/filtering>`.

:returns: A paginated list of entities associated with the alert definition.
:rtype: PaginatedList[AlertDefinitionEntity]
"""

endpoint = (
f"/monitor/services/{service_type}/alert-definitions/{id}/entities"
)
return self.client._get_and_filter(
AlertDefinitionEntity,
*filters,
endpoint=endpoint,
)
1 change: 0 additions & 1 deletion linode_api4/groups/volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ def create(self, label, region=None, linode=None, size=20, **kwargs):
:type tags: list[str]
:param encryption: Whether the new Volume should opt in or out of disk encryption.
:type encryption: str
Note: Block Storage Disk Encryption is not currently available to all users.
:returns: The new Volume.
:rtype: Volume
"""
Expand Down
2 changes: 0 additions & 2 deletions linode_api4/objects/linode.py
Original file line number Diff line number Diff line change
Expand Up @@ -1448,7 +1448,6 @@ def disk_create(
should already be set up, see :any:`ProfileGroup.ssh_keys`
for details.
:param disk_encryption: The disk encryption policy for this Linode.
NOTE: Disk encryption may not currently be available to all users.
:type disk_encryption: InstanceDiskEncryptionType or str
:param stackscript: A StackScript object, or the ID of one, to deploy to this
disk. Requires deploying a compatible image.
Expand Down Expand Up @@ -1642,7 +1641,6 @@ def rebuild(
the key.
:type authorized_keys: list or str
:param disk_encryption: The disk encryption policy for this Linode.
NOTE: Disk encryption may not currently be available to all users.
:type disk_encryption: InstanceDiskEncryptionType or str

:returns: The newly generated password, if one was not provided
Expand Down
Loading
Loading