Skip to content

Commit

Permalink
Merge pull request #4979 from grafana/dev
Browse files Browse the repository at this point in the history
v1.9.21
  • Loading branch information
vadimkerr authored Sep 4, 2024
2 parents c71f255 + cf69289 commit b54fa79
Show file tree
Hide file tree
Showing 27 changed files with 13,745 additions and 13,090 deletions.
4 changes: 2 additions & 2 deletions .github/actions/build-sign-and-package-plugin/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ runs:
GRAFANA_ACCESS_POLICY_TOKEN: ${{ inputs.grafana_access_policy_token }}
run: |
jq --arg v "${{ inputs.plugin_version_number }}" '.version=$v' package.json > package.new && mv package.new package.json && jq '.version' package.json;
yarn build
pnpm build
mage buildAll || true
yarn sign
pnpm sign
if [ ! -f dist/MANIFEST.txt ]; then echo "Sign failed, MANIFEST.txt not created, aborting." && exit 1; fi
mv dist grafana-oncall-app
zip -r grafana-oncall-app.zip ./grafana-oncall-app
Expand Down
42 changes: 11 additions & 31 deletions .github/actions/install-frontend-dependencies/action.yml
Original file line number Diff line number Diff line change
@@ -1,38 +1,18 @@
name: "Install frontend dependencies"
description: "Setup node + install frontend dependencies"
inputs:
working-directory:
description: "Relative path to oncall/grafana-plugin directory"
required: false
default: "."
name: Install frontend dependencies
description: Setup node/pnpm + install frontend dependencies
runs:
using: "composite"
using: composite
steps:
- name: Determine grafana-plugin directory location
id: grafana-plugin-directory
shell: bash
run: echo "grafana-plugin-directory=${{ inputs.working-directory }}/grafana-plugin" >> $GITHUB_OUTPUT
- name: Determine yarn.lock location
id: yarn-lock-location
shell: bash
# yamllint disable rule:line-length
run: echo "yarn-lock-location=${{ steps.grafana-plugin-directory.outputs.grafana-plugin-directory }}/yarn.lock" >> $GITHUB_OUTPUT
# yamllint enable rule:line-length
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 9.1.4
- uses: actions/setup-node@v4
with:
node-version: 20.15.1
cache: "yarn"
cache-dependency-path: ${{ steps.yarn-lock-location.outputs.yarn-lock-location }}
- name: Use cached frontend dependencies
id: cache-frontend-dependencies
uses: actions/cache@v4
with:
path: ${{ inputs.working-directory }}/grafana-plugin/node_modules
# yamllint disable rule:line-length
key: ${{ runner.os }}-frontend-node-modules-${{ hashFiles(steps.yarn-lock-location.outputs.yarn-lock-location) }}
# yamllint enable rule:line-length
cache: pnpm
cache-dependency-path: grafana-plugin/pnpm-lock.yaml
- name: Install frontend dependencies
if: steps.cache-frontend-dependencies.outputs.cache-hit != 'true'
shell: bash
working-directory: ${{ steps.grafana-plugin-directory.outputs.grafana-plugin-directory }}
run: yarn install --frozen-lockfile --prefer-offline --network-timeout 500000
working-directory: grafana-plugin
run: pnpm install --frozen-lockfile --prefer-offline
8 changes: 4 additions & 4 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ jobs:
uses: actions/cache@v4
with:
path: grafana-plugin/dist
key: ${{ runner.os }}-plugin-frontend-${{ hashFiles('grafana-plugin/src/**/*', 'grafana-plugin/yarn.lock') }}
key: ${{ runner.os }}-plugin-frontend-${{ hashFiles('grafana-plugin/src/**/*', 'grafana-plugin/pnpm.lock') }}

- name: Build plugin frontend
if: steps.cache-plugin-frontend.outputs.cache-hit != 'true'
working-directory: grafana-plugin
run: yarn build:dev
run: pnpm build:dev

# helpful reference for properly caching the playwright binaries/dependencies
# https://playwrightsolutions.com/playwright-github-action-to-cache-the-browser-binaries/
Expand All @@ -107,7 +107,7 @@ jobs:
- name: Install Playwright deps
shell: bash
working-directory: grafana-plugin
run: yarn playwright install
run: pnpm playwright install

# ---------- Expensive e2e tests steps start -----------
- name: Install Go
Expand Down Expand Up @@ -150,7 +150,7 @@ jobs:
if: inputs.run-expensive-tests
shell: bash
env:
E2E_TESTS_CMD: "cd ../../grafana-plugin && yarn test:e2e-expensive"
E2E_TESTS_CMD: "cd ../../grafana-plugin && pnpm test:e2e-expensive"
GRAFANA_VERSION: ${{ inputs.grafana_version }}
GF_FEATURE_TOGGLES_ENABLE: "externalServiceAccounts"
ONCALL_API_URL: "http://oncall-dev-engine:8080"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/linting-and-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
uses: ./.github/actions/install-frontend-dependencies
- name: Build, lint and test frontend
working-directory: grafana-plugin
run: yarn lint && yarn type-check && yarn test && yarn build
run: pnpm lint && pnpm type-check && pnpm test && pnpm build

test-technical-documentation:
name: "Test technical documentation"
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/on-release-published.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ jobs:
repo_secrets: |
GRAFANA_ACCESS_POLICY_TOKEN=github_actions:cloud-access-policy-token
GCS_PLUGIN_PUBLISHER_SERVICE_ACCOUNT_JSON=github_actions:gcs-plugin-publisher
GCOM_PLUGIN_PUBLISHER_API_KEY=github_actions:gcom-plugin-publisher-api-key
- name: Build, sign, and package plugin
id: build-sign-and-package-plugin
uses: ./.github/actions/build-sign-and-package-plugin
Expand All @@ -64,7 +63,7 @@ jobs:
echo url="https://storage.googleapis.com/grafana-oncall-app/releases/grafana-oncall-app-${{ github.ref_name }}.zip" >> $GITHUB_OUTPUT
- name: Publish plugin to grafana.com
run: |
curl -f -w "status=%{http_code}" -s -H "Authorization: Bearer ${{ env.GCOM_PLUGIN_PUBLISHER_API_KEY }}" -d "download[any][url]=${{ steps.gcs-artifact-url.outputs.url }}" -d "download[any][md5]=$(curl -sL ${{ steps.gcs-artifact-url.outputs.url }} | md5sum | cut -d'' '' -f1)" -d url=https://github.com/grafana/oncall/grafana-plugin https://grafana.com/api/plugins
curl -f -w "status=%{http_code}" -s -H "Authorization: Bearer ${{ env.GRAFANA_ACCESS_POLICY_TOKEN }}" -d "download[any][url]=${{ steps.gcs-artifact-url.outputs.url }}" -d "download[any][md5]=$(curl -sL ${{ steps.gcs-artifact-url.outputs.url }} | md5sum | cut -d'' '' -f1)" -d url=https://github.com/grafana/oncall/grafana-plugin https://grafana.com/api/plugins
# yamllint enable rule:line-length

build-engine-docker-image-and-publish-to-dockerhub:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ venv
.DS_Store
.env

yarn.lock
pnpm.lock
node_modules

test-results
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ repos:
rev: v8.25.0
hooks:
- id: eslint
entry: bash -c "cd grafana-plugin && eslint --max-warnings=0 --fix ${@/grafana-plugin\//}" --
entry: bash -c "cd grafana-plugin && eslint --max-warnings=20 --fix ${@/grafana-plugin\//}" --
types: [file]
files: ^grafana-plugin/src/(?:(?!autogenerated).)*\.(js|jsx|ts|tsx)$
additional_dependencies:
Expand Down
6 changes: 3 additions & 3 deletions .tilt/plugin/Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ if is_ci:
"build-ui",
labels=[label],
dir=grafana_plugin_dir,
cmd="yarn build",
cmd="pnpm build",
allow_parallel=True,
)

Expand All @@ -19,9 +19,9 @@ if not is_ci:
"build-ui",
labels=[label],
dir=grafana_plugin_dir,
cmd="yarn install",
cmd="pnpm install",
serve_dir=grafana_plugin_dir,
serve_cmd="yarn watch",
serve_cmd="pnpm watch",
allow_parallel=True,
)

Expand Down
8 changes: 4 additions & 4 deletions .tilt/tests/Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ label = "OnCall.AllTests"

load('ext://uibutton', 'cmd_button', 'location', 'text_input', 'bool_input')

e2e_tests_cmd=os.getenv("E2E_TESTS_CMD", "cd ../../grafana-plugin && yarn test:e2e")
e2e_tests_cmd=os.getenv("E2E_TESTS_CMD", "cd ../../grafana-plugin && pnpm test:e2e")
is_ci=config.tilt_subcommand == "ci"

local_resource(
Expand All @@ -16,7 +16,7 @@ local_resource(

cmd_button(
name="E2E Tests - headless run",
argv=["sh", "-c", "yarn --cwd ./grafana-plugin test:e2e $STOP_ON_FIRST_FAILURE $TESTS_FILTER"],
argv=["sh", "-c", "pnpm --dir ./grafana-plugin test:e2e $STOP_ON_FIRST_FAILURE $TESTS_FILTER"],
text="Restart headless run",
resource="e2e-tests",
icon_name="replay",
Expand All @@ -29,15 +29,15 @@ cmd_button(

cmd_button(
name="E2E Tests - open watch mode",
argv=["sh", "-c", "yarn --cwd grafana-plugin test:e2e:watch"],
argv=["sh", "-c", "pnpm --dir grafana-plugin test:e2e:watch"],
text="Open watch mode",
resource="e2e-tests",
icon_name="visibility",
)

cmd_button(
name="E2E Tests - show report",
argv=["sh", "-c", "yarn --cwd grafana-plugin playwright show-report"],
argv=["sh", "-c", "pnpm --dir grafana-plugin playwright show-report"],
text="Show last HTML report",
resource="e2e-tests",
icon_name="assignment",
Expand Down
1 change: 1 addition & 0 deletions .yamllint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ extends: default

ignore: |
helm/oncall/templates/**/*.yaml
pnpm-lock.yaml
rules:
line-length:
Expand Down
18 changes: 9 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ init: ## build the frontend plugin code then run make start
# this makes sure that it will be available when the grafana container starts up without the need to
# restart the grafana container initially
ifeq ($(findstring $(UI_PROFILE),$(COMPOSE_PROFILES)),$(UI_PROFILE))
$(call run_ui_docker_command,yarn install && yarn build:dev)
$(call run_ui_docker_command,pnpm install && pnpm build:dev)
endif

stop: # stop all of the docker containers
Expand All @@ -168,7 +168,7 @@ install-pre-commit:
fi

lint: install-pre-commit ## run both frontend and backend linters
## may need to run `yarn install` from within `grafana-plugin`
## may need to run `pnpm install` from within `grafana-plugin`
## to install several `pre-commit` dependencies
pre-commit run --all-files

Expand Down Expand Up @@ -203,25 +203,25 @@ engine-manage: ## run Django's `manage.py` script, inside of a docker container
$(call run_engine_docker_command,python manage.py $(CMD))

test-e2e: ## run the e2e tests in headless mode
yarn --cwd grafana-plugin test:e2e
pnpm --dir grafana-plugin test:e2e

test-e2e-watch: ## start e2e tests in watch mode
yarn --cwd grafana-plugin test:e2e:watch
pnpm --dir grafana-plugin test:e2e:watch

test-e2e-show-report: ## open last e2e test report
yarn --cwd grafana-plugin playwright show-report
pnpm --dir grafana-plugin playwright show-report

ui-test: ## run the UI tests
$(call run_ui_docker_command,yarn test)
$(call run_ui_docker_command,pnpm test)

ui-lint: ## run the UI linter
$(call run_ui_docker_command,yarn lint)
$(call run_ui_docker_command,pnpm lint)

ui-build: ## build the UI
$(call run_ui_docker_command,yarn build)
$(call run_ui_docker_command,pnpm build)

ui-command: ## run any command, inside of a UI docker container, passing `$CMD` as arguments.
## e.g. `make ui-command CMD="yarn test"`
## e.g. `make ui-command CMD="pnpm test"`
$(call run_ui_docker_command,$(CMD))

exec-engine: ## exec into engine container's bash
Expand Down
4 changes: 2 additions & 2 deletions dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Related: [How to develop integrations](/engine/config_integrations/README.md)
- [tilt-dev/ctlptl: Making local Kubernetes clusters fun and easy to set up](https://github.com/tilt-dev/ctlptl)
- [Kind](https://kind.sigs.k8s.io)
- [Node.js v20.x](https://nodejs.org/en/download)
- [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/#mac-stable)
- [pnpm](https://pnpm.io/installation)

### Launch the environment

Expand Down Expand Up @@ -519,7 +519,7 @@ In order to automate types creation and prevent API usage pitfalls, OnCall proje
### Instruction
1. Whenever API contract changes, run `yarn generate-types` from `grafana-plugin` directory
1. Whenever API contract changes, run `pnpm generate-types` from `grafana-plugin` directory
2. Then you can start consuming types and you can use fully typed http client:
```ts
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.15 on 2024-09-02 13:34

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('alerts', '0057_remove_alertgroup_slack_log_message_db'),
]

operations = [
migrations.AlterField(
model_name='alertgroup',
name='reason_to_skip_escalation',
field=models.IntegerField(choices=[(0, 'account_inactive'), (1, 'is_archived'), (2, 'no_reason'), (3, 'rate_limited'), (4, 'channel_not_specified'), (5, 'restricted_action'), (6, 'invalid_auth')], default=2),
),
]
13 changes: 11 additions & 2 deletions engine/apps/alerts/models/alert_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,14 +365,23 @@ def status(self) -> int:
else:
return AlertGroup.NEW

ACCOUNT_INACTIVE, CHANNEL_ARCHIVED, NO_REASON, RATE_LIMITED, CHANNEL_NOT_SPECIFIED, RESTRICTED_ACTION = range(6)
(
ACCOUNT_INACTIVE,
CHANNEL_ARCHIVED,
NO_REASON,
RATE_LIMITED,
CHANNEL_NOT_SPECIFIED,
RESTRICTED_ACTION,
INVALID_AUTH,
) = range(7)
REASONS_TO_SKIP_ESCALATIONS = (
(ACCOUNT_INACTIVE, "account_inactive"),
(CHANNEL_ARCHIVED, "channel_archived"),
(CHANNEL_ARCHIVED, "is_archived"),
(NO_REASON, "no_reason"),
(RATE_LIMITED, "rate_limited"),
(CHANNEL_NOT_SPECIFIED, "channel_not_specified"),
(RESTRICTED_ACTION, "restricted_action"),
(INVALID_AUTH, "invalid_auth"),
)
reason_to_skip_escalation = models.IntegerField(choices=REASONS_TO_SKIP_ESCALATIONS, default=NO_REASON)

Expand Down
4 changes: 2 additions & 2 deletions engine/apps/grafana_plugin/serializers/sync_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def to_representation(self, instance):
class SyncTeamSerializer(serializers.Serializer):
team_id = serializers.IntegerField()
name = serializers.CharField()
email = serializers.EmailField(allow_blank=True)
avatar_url = serializers.CharField()
email = serializers.CharField(allow_blank=True)
avatar_url = serializers.CharField(allow_blank=True)

def create(self, validated_data):
return SyncTeam(**validated_data)
Expand Down
23 changes: 23 additions & 0 deletions engine/apps/grafana_plugin/tests/test_sync_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import pytest
from django.urls import reverse
from rest_framework import status
from rest_framework.exceptions import ValidationError
from rest_framework.test import APIClient

from apps.api.permissions import LegacyAccessControlRole
from apps.grafana_plugin.serializers.sync_data import SyncTeamSerializer
from apps.grafana_plugin.sync_data import SyncData, SyncSettings, SyncUser
from apps.grafana_plugin.tasks.sync_v2 import start_sync_organizations_v2

Expand Down Expand Up @@ -136,3 +138,24 @@ def test_sync_v2_content_encoding(

assert response.status_code == status.HTTP_200_OK
mock_sync.assert_called()


@pytest.mark.parametrize(
"test_team, validation_pass",
[
({"team_id": 1, "name": "Test Team", "email": "", "avatar_url": ""}, True),
({"team_id": 1, "name": "", "email": "", "avatar_url": ""}, False),
({"name": "ABC", "email": "", "avatar_url": ""}, False),
({"team_id": 1, "name": "ABC", "email": "[email protected]", "avatar_url": ""}, True),
({"team_id": 1, "name": "123", "email": "<invalid email>", "avatar_url": ""}, True),
],
)
@pytest.mark.django_db
def test_sync_team_serialization(test_team, validation_pass):
serializer = SyncTeamSerializer(data=test_team)
validation_error = None
try:
serializer.is_valid(raise_exception=True)
except ValidationError as e:
validation_error = e
assert (validation_error is None) == validation_pass
5 changes: 5 additions & 0 deletions engine/apps/slack/scenarios/distribute_alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
SlackAPIChannelArchivedError,
SlackAPIChannelNotFoundError,
SlackAPIError,
SlackAPIInvalidAuthError,
SlackAPIMessageNotFoundError,
SlackAPIRatelimitError,
SlackAPIRestrictedActionError,
Expand Down Expand Up @@ -161,6 +162,10 @@ def _post_alert_group_to_slack(
alert_group.reason_to_skip_escalation = AlertGroup.ACCOUNT_INACTIVE
alert_group.save(update_fields=["reason_to_skip_escalation"])
logger.info("Not delivering alert due to account_inactive.")
except SlackAPIInvalidAuthError:
alert_group.reason_to_skip_escalation = AlertGroup.INVALID_AUTH
alert_group.save(update_fields=["reason_to_skip_escalation"])
logger.info("Not delivering alert due to invalid_auth.")
except SlackAPIChannelArchivedError:
alert_group.reason_to_skip_escalation = AlertGroup.CHANNEL_ARCHIVED
alert_group.save(update_fields=["reason_to_skip_escalation"])
Expand Down
Loading

0 comments on commit b54fa79

Please sign in to comment.